From 2835ea669b17dcf4befc171b508e1c6b4bdd6106 Mon Sep 17 00:00:00 2001 From: HugoRCD Date: Mon, 23 Jun 2025 16:46:51 +0200 Subject: [PATCH] up --- docs/app/pages/blog/[...slug].vue | 161 +++++++++++++++++++++++------- docs/app/pages/blog/index.vue | 40 +++++--- 2 files changed, 150 insertions(+), 51 deletions(-) diff --git a/docs/app/pages/blog/[...slug].vue b/docs/app/pages/blog/[...slug].vue index 8d2f41c5..58266ae7 100644 --- a/docs/app/pages/blog/[...slug].vue +++ b/docs/app/pages/blog/[...slug].vue @@ -11,6 +11,7 @@ const [{ data: page }, { data: surround }] = await Promise.all([ }).order('date', 'DESC') }) ]) + if (!page.value) { throw createError({ statusCode: 404, statusMessage: 'Article not found', fatal: true }) } @@ -40,59 +41,143 @@ const formatDate = (dateString: string) => { year: 'numeric', month: 'short', day: 'numeric' - }) + }).toUpperCase() +} + +const getCategoryVariant = (category: string) => { + switch (category?.toLowerCase()) { + case 'release': return 'solid' + case 'tutorial': return 'soft' + case 'improvement': return 'soft' + default: return 'soft' + } +} + +const getCategoryIcon = (category: string) => { + switch (category?.toLowerCase()) { + case 'release': return 'i-lucide-rocket' + case 'tutorial': return 'i-lucide-book-open' + case 'improvement': return 'i-lucide-trending-up' + default: return 'i-lucide-file-text' + } } diff --git a/docs/app/pages/blog/index.vue b/docs/app/pages/blog/index.vue index 06b74dd8..e562f02d 100644 --- a/docs/app/pages/blog/index.vue +++ b/docs/app/pages/blog/index.vue @@ -20,12 +20,31 @@ const selectedFilter = ref('all') const searchQuery = ref('') const availableFilters = computed(() => { - return [ - { key: 'all', label: 'ALL', count: posts.value?.length || 0 }, - { key: 'release', label: 'NEW RELEASES', count: posts.value?.filter(p => p.category?.toLowerCase() === 'release').length || 0 }, - { key: 'tutorial', label: 'TUTORIALS', count: posts.value?.filter(p => p.category?.toLowerCase() === 'tutorial').length || 0 }, - { key: 'improvement', label: 'IMPROVEMENTS', count: posts.value?.filter(p => p.category?.toLowerCase() === 'improvement').length || 0 } + if (!posts.value?.length) return [{ key: 'all', label: 'ALL', count: 0 }] + + const postsData = posts.value + const categories = new Set(postsData.map(post => post.category?.toLowerCase()).filter(Boolean)) + + const filters = [ + { key: 'all', label: 'ALL', count: postsData.length } ] + + categories.forEach((category) => { + const count = postsData.filter(p => p.category?.toLowerCase() === category).length + const label = category.replace(/\b\w/g, l => l.toUpperCase()).replace(/([a-z])([A-Z])/g, '$1 $2') + + filters.push({ + key: category, + label: label, + count + }) + }) + + return filters.sort((a, b) => { + if (a.key === 'all') return -1 + if (b.key === 'all') return 1 + return b.count - a.count + }) }) const filteredPosts = computed(() => { @@ -128,22 +147,17 @@ const getCategoryIcon = (category: string) => { - - + />