Skip to content

Commit 01e4e47

Browse files
feat: create learn landing (#233)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent f3581e4 commit 01e4e47

File tree

20 files changed

+812
-44
lines changed

20 files changed

+812
-44
lines changed

app.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ export default defineAppConfig({
99
solid: 'shadow-none bg-gray-300/20 hover:bg-gray-300/40 dark:bg-gray-700/40 dark:hover:bg-gray-700/50',
1010
},
1111
},
12+
variant: {
13+
solid: 'shadow-none',
14+
},
1215
},
1316
select: {
1417
base: 'transition ease-in',

components/Header.vue

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
<script lang="ts" setup>
2+
const runtimeConfig = useRuntimeConfig()
23
const website = useWebsite()
34
const github = website.value.socials.github
45
5-
const { data: navigation } = await useAsyncData('content:navigation', () => fetchContentNavigation(queryContent('/')), {
6-
transform: (data) => {
7-
const filteredData = data.filter(item => item._path !== '/').map((item) => {
8-
if (item._path !== '/resources')
9-
delete item.children
10-
11-
return {
12-
title: item.title,
13-
_path: item._path,
14-
icon: item.icon,
15-
children: item.children,
16-
}
17-
})
18-
19-
return filteredData
6+
const navigation = [
7+
{
8+
path: '/packages',
9+
title: 'Packages',
2010
},
21-
})
11+
runtimeConfig.public.learn && {
12+
path: '/learn',
13+
title: 'Learn',
14+
},
15+
{
16+
path: '/blog',
17+
title: 'Blog',
18+
},
19+
].filter(Boolean) as { path: string, title: string }[]
20+
2221
const { data: stars } = await useFetch('/api/content/packages.json', {
2322
transform: (data) => {
2423
const stars: number = data.reduce((acc, curr) => acc + curr.stars, 0)
@@ -59,8 +58,8 @@ function toDesignKit() {
5958

6059
<nav v-if="navigation" class="hidden lg:flex justify-center">
6160
<ol class="text-[1.125rem] flex gap-4 leading-5">
62-
<li v-for="item in navigation" :key="item._path">
63-
<UPopover v-if="item.children" mode="hover" :ui="{ width: 'max-w-[18rem]' }">
61+
<li v-for="item in navigation" :key="item.path">
62+
<!-- <UPopover v-if="item.children" mode="hover" :ui="{ width: 'max-w-[18rem]' }">
6463
<UButton size="md" variant="ghost" color="gray" :to="item._path" :icon="item.icon" :ui="{ size: { md: 'text-base' }, ...uiButton }" :active-class="activeClassButton">
6564
{{ item.title }}
6665
</UButton>
@@ -79,8 +78,8 @@ function toDesignKit() {
7978
</li>
8079
</ol>
8180
</template>
82-
</UPopover>
83-
<UButton v-else size="md" variant="ghost" color="gray" :to="item._path" :ui="{ size: { md: 'text-base' }, ...uiButton }" :active-class="activeClassButton">
81+
</UPopover> -->
82+
<UButton size="md" variant="ghost" color="gray" :to="item.path" :ui="{ size: { md: 'text-base' }, ...uiButton }" :active-class="activeClassButton">
8483
{{ item.title }}
8584
</UButton>
8685
</li>

components/NavigationModal.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<script lang="ts" setup>
22
import { Dialog, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'
3-
import type { NavItem } from '@nuxt/content/dist/runtime/types'
43
54
defineProps<{
65
open: boolean
7-
navigation: NavItem[]
6+
navigation: {
7+
path: string
8+
title: string
9+
}[]
810
}>()
911
1012
defineEmits<{
@@ -47,12 +49,12 @@ const uiSocialButton = { color: { gray: { ghost: 'dark:text-gray-400 dark:hover:
4749
aria-labelledby="Navigation mobile"
4850
class="flex flex-col gap-2 text-2xl font-semibold"
4951
>
50-
<li v-for="item in navigation" :key="item._path">
52+
<li v-for="item in navigation" :key="item.path">
5153
<UButton
5254
size="xl"
5355
color="gray"
5456
variant="ghost"
55-
:to="item._path" :icon="item.icon" :ui="{ ...uiButton }" :active-class="activeClassButton"
57+
:to="item.path" :ui="{ ...uiButton }" :active-class="activeClassButton"
5658
@click="$emit('update:open', false)"
5759
>
5860
{{ item.title }}

components/OgImage/OgImageLearn.vue

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup lang="ts">
2+
defineProps<{
3+
title: string
4+
description: string
5+
}>()
6+
</script>
7+
8+
<template>
9+
<!-- Since we use Nuxt UI which replace color by some vars, we need to explicitly set a color. -->
10+
<div
11+
class="w-full h-full flex justify-between relative bg-[#111827] text-white"
12+
>
13+
<img src="/assets/header/ellipse.png" class="absolute top--64 right--64">
14+
<div class="pt-[80px] px-[60px] pb-[60px]">
15+
<div class="h-full w-full justify-between relative">
16+
<div class="flex flex-row justify-between items-start">
17+
<div class="flex flex-col items-start">
18+
<span class="text-[#f9fafb] text-[24px] px-4 py-2 rounded-full bg-[#F2E78C]/20 border-1 border-[#F2E78C]/70">
19+
Learn
20+
</span>
21+
<h1 class="mt-6 mb-0 font-bold text-[56px] text-white">
22+
{{ title }}
23+
</h1>
24+
<p
25+
class="mt-4 text-[36px] text-[#9ca3af] max-w-[768px]"
26+
>
27+
{{ description }}
28+
</p>
29+
</div>
30+
</div>
31+
<div class="">
32+
<img src="/favicon.svg" class="rounded-sm h-[60px] w-[60px]">
33+
</div>
34+
</div>
35+
</div>
36+
</div>
37+
</template>

components/learn/LearnCard.vue

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<script lang="ts" setup>
2+
import type { Author } from '~/types/blog'
3+
4+
const props = defineProps<{
5+
path: string
6+
title: string
7+
description: string
8+
publishedAt: string
9+
category: 'getting-started' | 'building-blocks'
10+
authors: Author[]
11+
}>()
12+
13+
const categoryName = computed(() => {
14+
switch (props.category) {
15+
case 'getting-started':
16+
return 'Getting Started'
17+
case 'building-blocks':
18+
return 'Building Blocks'
19+
}
20+
})
21+
</script>
22+
23+
<template>
24+
<UCard as="article" :ui="{ base: 'h-full relative flex flex-col', background: 'bg-gray-300/20 hover:bg-gray-300/40 dark:bg-gray-700/40 hover:dark:bg-gray-700/60', divide: '', shadow: 'shadow-sm', ring: 'dark:highlight-white/10', rounded: 'rounded-lg', header: { base: '', padding: 'py-0 pt-4 sm:px-4 sm:pt-4' }, body: { base: 'grow', padding: 'p-4 sm:p-4' }, footer: { padding: 'py-0 pb-4 sm:px-4 sm:pb-4' } }">
25+
<template #header>
26+
<h3 class="text-xl font-semibold dark:text-gray-50">
27+
<NuxtLink :to="path" class="absolute inset-0" />
28+
{{ title }}
29+
</h3>
30+
</template>
31+
32+
<p class="dark:text-zinc-400">
33+
{{ description }}
34+
</p>
35+
36+
<template #footer>
37+
<dl class="dark:text-zinc-400 text-sm flex flex-row justify-between items-center">
38+
<dt class="sr-only">
39+
Category
40+
</dt>
41+
<dd>
42+
<UBadge :label="categoryName" variant="soft" />
43+
</dd>
44+
<dt class="sr-only">
45+
Published at
46+
</dt>
47+
<dd class="sr-only">
48+
<time :datetime="toISODateString(publishedAt)">
49+
{{ toLocaleDateString(publishedAt) }}
50+
</time>
51+
</dd>
52+
<dt class="sr-only">
53+
Authors
54+
</dt>
55+
<dd class="flex">
56+
<UAvatarGroup size="2xs" :max="3" :ui="{ ring: '' }">
57+
<UAvatar v-for="author in authors" :key="author.name" :src="author.picture" :alt="author.name" />
58+
</UAvatarGroup>
59+
</dd>
60+
</dl>
61+
</template>
62+
</UCard>
63+
</template>

composables/useBlog.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { useStorage } from '@vueuse/core'
22
import MiniSearch, { type SearchResult } from 'minisearch'
33
import type { Order } from '~/types/order'
44
import type { LocationQueryValue } from '#vue-router'
5-
import type { Author, BlogPostCard } from '~/types/blog'
5+
import type { BlogPostCard } from '~/types/blog'
6+
import type { Author } from '~/types/author'
67

78
export function useBlog() {
89
const fields = ['_path', 'title', 'description', 'publishedAt', 'authors', 'packages', 'categories']

0 commit comments

Comments
 (0)