mirror of
https://github.com/LukeHagar/website.git
synced 2025-12-07 21:07:44 +00:00
Change tutorials to follow design
This commit is contained in:
@@ -52,58 +52,57 @@
|
|||||||
<header class="aw-article-header">
|
<header class="aw-article-header">
|
||||||
<div class="aw-article-header-start u-flex-vertical aw-u-cross-start">
|
<div class="aw-article-header-start u-flex-vertical aw-u-cross-start">
|
||||||
<div class="u-position-relative u-flex u-cross-center">
|
<div class="u-position-relative u-flex u-cross-center">
|
||||||
<h1 class="aw-title">Platforms</h1>
|
<h1 class="aw-title">Tutorials</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="aw-article-header-end" />
|
<div class="aw-article-header-end" />
|
||||||
</header>
|
</header>
|
||||||
<div class="aw-article-content aw-u-gap-80">
|
<div class="aw-article-content aw-u-gap-80">
|
||||||
<section class="u-flex-vertical u-gap-24">
|
{#each data.tutorials as category}
|
||||||
<h2 class="aw-eyebrow">Client</h2>
|
<section class="u-flex-vertical u-gap-24">
|
||||||
<ul class="tutorial-grid">
|
<h2 class="aw-eyebrow">{category.title}</h2>
|
||||||
{#each data.tutorials as tutorial}
|
<ul class="aw-grid-row-4 aw-grid-row-4-mobile-2">
|
||||||
<li>
|
{#each category.tutorials as tutorial}
|
||||||
<a href={tutorial.href} class="aw-card is-normal">
|
<li>
|
||||||
<header>
|
{#if tutorial.draft === true}
|
||||||
<span
|
<a
|
||||||
class="{getIcon(tutorial)} aw-u-font-size-24"
|
href={tutorial.href}
|
||||||
aria-hidden="true"
|
class="aw-card is-normal draft"
|
||||||
/>
|
aria-disabled="true"
|
||||||
<h3 class="aw-sub-body-500 aw-u-color-text-primary">
|
tabindex="-1"
|
||||||
{tutorial.framework}
|
>
|
||||||
</h3>
|
<header class="u-flex u-cross-baseline u-gap-4">
|
||||||
</header>
|
<span
|
||||||
<p class="aw-sub-body-400 u-margin-block-start-4">
|
class="{getIcon(tutorial)} aw-u-font-size-24"
|
||||||
{tutorial.title}
|
aria-hidden="true"
|
||||||
</p>
|
/>
|
||||||
</a>
|
<h3 class="aw-sub-body-500 aw-u-color-text-primary">
|
||||||
</li>
|
{tutorial.framework}
|
||||||
{/each}
|
</h3>
|
||||||
</ul>
|
<span class="badge aw-caption-400">Coming Soon</span>
|
||||||
<ul class="tutorial-grid">
|
</header>
|
||||||
{#each data.drafts as draft}
|
</a>
|
||||||
<li>
|
{:else}
|
||||||
<a
|
<a href={tutorial.href} class="aw-card is-normal">
|
||||||
href={draft.href}
|
<header class="u-flex u-cross-baseline u-gap-4">
|
||||||
class="aw-card is-normal draft"
|
<span
|
||||||
aria-disabled="true"
|
class="{getIcon(tutorial)} aw-u-font-size-24"
|
||||||
tabindex="-1"
|
aria-hidden="true"
|
||||||
>
|
/>
|
||||||
<header>
|
<h3 class="aw-sub-body-500 aw-u-color-text-primary">
|
||||||
<span
|
{tutorial.framework}
|
||||||
class="{getIcon(draft)} aw-u-font-size-24"
|
</h3>
|
||||||
aria-hidden="true"
|
</header>
|
||||||
/>
|
<p class="aw-sub-body-400 u-margin-block-start-4">
|
||||||
<h3 class="aw-sub-body-500 aw-u-color-text-primary">
|
{tutorial.title}
|
||||||
{draft.framework}
|
</p>
|
||||||
</h3>
|
</a>
|
||||||
<span class="badge aw-caption-400">Coming Soon</span>
|
{/if}
|
||||||
</header>
|
</li>
|
||||||
</a>
|
{/each}
|
||||||
</li>
|
</ul>
|
||||||
{/each}
|
</section>
|
||||||
</ul>
|
{/each}
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
@@ -111,35 +110,6 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.tutorial-grid {
|
|
||||||
display: grid;
|
|
||||||
gap: 1.5rem; // 24px
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
||||||
|
|
||||||
.aw-card {
|
|
||||||
padding: 1.25rem;
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.25rem;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
> [class*='icon'] {
|
|
||||||
position: relative;
|
|
||||||
width: 1.5rem;
|
|
||||||
height: 1.5rem;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, calc(-50%));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
background: rgba(253, 54, 110, 0.24);
|
background: rgba(253, 54, 110, 0.24);
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { base } from '$app/paths';
|
|||||||
import type { Tutorial } from '$markdoc/layouts/Tutorial.svelte';
|
import type { Tutorial } from '$markdoc/layouts/Tutorial.svelte';
|
||||||
|
|
||||||
const framework_order = ['React', 'Vue', 'SvelteKit', 'Stripe', 'Refine'];
|
const framework_order = ['React', 'Vue', 'SvelteKit', 'Stripe', 'Refine'];
|
||||||
|
const category_order = ['Web', 'Mobile and native', 'Server', 'Auth', 'Databases', 'Storage', 'Functions'];
|
||||||
|
|
||||||
|
|
||||||
export async function load() {
|
export async function load() {
|
||||||
const tutorialsGlob = import.meta.glob('./**/step-1/+page.markdoc', {
|
const tutorialsGlob = import.meta.glob('./**/step-1/+page.markdoc', {
|
||||||
@@ -18,11 +20,12 @@ export async function load() {
|
|||||||
.replace('/+page.markdoc', '')
|
.replace('/+page.markdoc', '')
|
||||||
.replace('/step-1', '');
|
.replace('/step-1', '');
|
||||||
const tutorialName = slug.slice(slug.lastIndexOf('/') + 1);
|
const tutorialName = slug.slice(slug.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: frontmatter.title,
|
title: frontmatter.title,
|
||||||
framework: frontmatter.framework,
|
framework: frontmatter.framework,
|
||||||
draft: frontmatter.draft,
|
draft: frontmatter.draft || false,
|
||||||
|
category: frontmatter.category,
|
||||||
href: `${base}/docs/tutorials/${tutorialName}`
|
href: `${base}/docs/tutorials/${tutorialName}`
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -41,12 +44,23 @@ export async function load() {
|
|||||||
// Else, sort by title
|
// Else, sort by title
|
||||||
return a.title.toLowerCase().localeCompare(b.title.toLowerCase());
|
return a.title.toLowerCase().localeCompare(b.title.toLowerCase());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tutorials = Object.entries(
|
||||||
|
allTutorials.reduce((acc: { [key: string]: any[] }, item) => {
|
||||||
|
// If the category does not exist in the accumulator, initialize it
|
||||||
|
if (!acc[item.category]) {
|
||||||
|
acc[item.category] = [];
|
||||||
|
}
|
||||||
|
|
||||||
const drafts = allTutorials.filter((tutorial) => tutorial.draft);
|
// Push the current item into the appropriate category
|
||||||
const tutorials = allTutorials.filter((tutorial) => !tutorial.draft);
|
acc[item.category].push(item);
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
).map(([title, tutorials]) => ({ title, tutorials }));
|
||||||
|
|
||||||
|
tutorials.sort((a, b) => category_order.indexOf(a.title) - category_order.indexOf(b.title));
|
||||||
return {
|
return {
|
||||||
tutorials,
|
tutorials,
|
||||||
drafts
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ layout: tutorial
|
|||||||
title: Coming soon
|
title: Coming soon
|
||||||
description: Learn to build an Android app with no backend code using an Appwrite backend.
|
description: Learn to build an Android app with no backend code using an Appwrite backend.
|
||||||
framework: Android
|
framework: Android
|
||||||
|
category: Mobile and native
|
||||||
step: 1
|
step: 1
|
||||||
draft: true
|
draft: true
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ layout: tutorial
|
|||||||
title: Coming soon
|
title: Coming soon
|
||||||
description: Learn to build an Apple app with no backend code using an Appwrite backend.
|
description: Learn to build an Apple app with no backend code using an Appwrite backend.
|
||||||
framework: Apple
|
framework: Apple
|
||||||
|
category: Mobile and native
|
||||||
step: 1
|
step: 1
|
||||||
draft: true
|
draft: true
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ layout: tutorial
|
|||||||
title: Coming soon
|
title: Coming soon
|
||||||
description: Learn to build an Flutter app with no backend code using an Appwrite backend.
|
description: Learn to build an Flutter app with no backend code using an Appwrite backend.
|
||||||
framework: Flutter
|
framework: Flutter
|
||||||
|
category: Mobile and native
|
||||||
step: 1
|
step: 1
|
||||||
draft: true
|
draft: true
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ description: Learn to build a React app with no backend code using an Appwrite b
|
|||||||
step: 1
|
step: 1
|
||||||
difficulty: beginner
|
difficulty: beginner
|
||||||
readtime: 10
|
readtime: 10
|
||||||
|
category: Web
|
||||||
framework: React
|
framework: React
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ step: 1
|
|||||||
difficulty: beginner
|
difficulty: beginner
|
||||||
readtime: 10
|
readtime: 10
|
||||||
framework: Refine
|
framework: Refine
|
||||||
|
category: Web
|
||||||
---
|
---
|
||||||
|
|
||||||
**Blog admin panel**: a CRUD app to manage Blog content.
|
**Blog admin panel**: a CRUD app to manage Blog content.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ step: 1
|
|||||||
difficulty: easy
|
difficulty: easy
|
||||||
readtime: 10
|
readtime: 10
|
||||||
framework: Stripe
|
framework: Stripe
|
||||||
|
category: Functions
|
||||||
---
|
---
|
||||||
As you app grows, you may start offering paid services or features.
|
As you app grows, you may start offering paid services or features.
|
||||||
This is an important part of growing your idea into a business.
|
This is an important part of growing your idea into a business.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ step: 1
|
|||||||
difficulty: beginner
|
difficulty: beginner
|
||||||
readtime: 20
|
readtime: 20
|
||||||
framework: SvelteKit
|
framework: SvelteKit
|
||||||
|
category: Auth
|
||||||
---
|
---
|
||||||
|
|
||||||
Appwrite takes away your stress of building and maintaining a backend. Appwrite helps you implement authentication, databases, file storage, and respond to real-time events with **secure** APIs out of the box.
|
Appwrite takes away your stress of building and maintaining a backend. Appwrite helps you implement authentication, databases, file storage, and respond to real-time events with **secure** APIs out of the box.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ step: 1
|
|||||||
difficulty: beginner
|
difficulty: beginner
|
||||||
readtime: 10
|
readtime: 10
|
||||||
framework: SvelteKit
|
framework: SvelteKit
|
||||||
|
category: Web
|
||||||
---
|
---
|
||||||
|
|
||||||
**Idea tracker**: an app to track all the side project ideas that you'll start, but probably never finish.
|
**Idea tracker**: an app to track all the side project ideas that you'll start, but probably never finish.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ description: Learn to build an idea tracker app with Appwrite and Vue with authe
|
|||||||
step: 1
|
step: 1
|
||||||
back: /docs
|
back: /docs
|
||||||
framework: Vue
|
framework: Vue
|
||||||
|
category: Web
|
||||||
---
|
---
|
||||||
|
|
||||||
**Idea tracker**: an app to track all the side project ideas that you'll start, but probably never finish.
|
**Idea tracker**: an app to track all the side project ideas that you'll start, but probably never finish.
|
||||||
|
|||||||
Reference in New Issue
Block a user