Skip to content

Commit bad9f79

Browse files
committed
Move all tags page to be new all articles page
1 parent 7e03d2c commit bad9f79

2 files changed

Lines changed: 55 additions & 205 deletions

File tree

‎src/pages/articles/index.astro‎

Lines changed: 55 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,68 @@
11
---
2-
import { getCollection } from 'astro:content'
3-
import { Picture } from 'astro:assets'
2+
import { type CollectionEntry, getCollection } from 'astro:content'
43
import { isDev } from '@lib/config/environmentServer'
5-
import PageLayout from '@layouts/PageLayout.astro'
4+
import BaseLayout from '@layouts/BaseLayout.astro'
65
7-
const allArticles = await getCollection('articles', ({ data }) => {
8-
return isDev() || data.isDraft !== true
9-
})
6+
import Carousel from '@components/Carousel/index.astro'
107
11-
/** Sort by publish date (newest first) */
12-
const sortedArticles = allArticles.sort(
13-
(a, b) => new Date(b.data.publishDate).getTime() - new Date(a.data.publishDate).getTime()
14-
)
8+
const allArticles = await getCollection('articles', ({ data }) => isDev() || data.isDraft !== true)
159
16-
const pageDescription = 'Webstack Builders Articles List'
17-
const pageTitle = 'All Articles'
18-
const path = '/articles/'
19-
const section = 'Articles'
20-
---
10+
const allTags = await getCollection('tags')
2111
22-
<PageLayout
23-
description={pageDescription}
24-
pageTitle={pageTitle}
25-
path={path}
26-
section={section}
27-
subtitle="Insights, tutorials, and thoughts on web development"
28-
>
29-
<section class="space-y-12">
30-
{
31-
sortedArticles.map(article => (
32-
<article class="bg-content-inverse rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 overflow-hidden group">
33-
<a href={`/articles/${article.id}`} class="block">
34-
{article.data.cover && (
35-
<div class="relative aspect-video overflow-hidden">
36-
<Picture
37-
src={article.data.cover}
38-
alt={article.data.coverAlt}
39-
widths={[320, 640, 960, 1280]}
40-
sizes="(min-width: 1280px) 25vw, (min-width: 768px) 50vw, 100vw"
41-
formats={['avif', 'webp', 'jpeg']}
42-
layout="constrained"
43-
fit="cover"
44-
position="center"
45-
class="absolute inset-0 h-full w-full"
46-
/>
47-
</div>
48-
)}
12+
const getArticlesForTag = (tagEntry: CollectionEntry<'tags'>) => {
13+
return allArticles.filter(article => {
14+
return article.data.tags.some(tagRef => tagRef.id === tagEntry.id)
15+
})
16+
}
4917
50-
<div class="p-6 md:p-8 space-y-4">
51-
<div class="flex flex-wrap items-center gap-3 text-sm">
52-
<time
53-
datetime={article.data.publishDate.toISOString()}
54-
class="flex items-center gap-1"
55-
>
56-
<svg
57-
class="w-4 h-4"
58-
aria-hidden="true"
59-
focusable="false"
60-
fill="none"
61-
stroke="currentColor"
62-
viewBox="0 0 24 24"
63-
>
64-
<path
65-
stroke-linecap="round"
66-
stroke-linejoin="round"
67-
stroke-width="2"
68-
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
69-
/>
70-
</svg>
71-
{article.data.publishDate.toLocaleDateString('en-US', {
72-
year: 'numeric',
73-
month: 'long',
74-
day: 'numeric',
75-
})}
76-
</time>
18+
const tagsWithContent = allTags.filter(tag => getArticlesForTag(tag).length > 0)
7719
78-
{article.data.tags && article.data.tags.length > 0 && (
79-
<div class="flex flex-wrap gap-2">
80-
{article.data.tags.slice(0, 3).map(tag => (
81-
<span class="text-xs font-medium text-primary bg-blue-100 px-2 py-1 rounded-full uppercase tracking-wide">
82-
{typeof tag === 'string' ? tag : tag.id}
83-
</span>
84-
))}
85-
</div>
86-
)}
20+
const tagsWithNoContent = allTags.filter(tag => getArticlesForTag(tag).length === 0)
8721
88-
{article.data.isDraft && (
89-
<span class="inline-block bg-secondary-bg text-secondary px-3 py-1 rounded-full text-xs font-medium uppercase tracking-wide">
90-
Draft
91-
</span>
92-
)}
93-
</div>
22+
for (const tag of tagsWithNoContent) {
23+
console.warn(
24+
`Warning: there were no content items for tag ${tag.data.displayName}. You might consider removing this tag if it is unused.`
25+
)
26+
}
9427
95-
<h2 class="text-2xl md:text-3xl font-bold leading-tight group-hover:text-primary transition-colors duration-300">
96-
{article.data.title}
97-
</h2>
28+
const pageDescription = 'Browse all article tags'
29+
const pageTitle = 'All Tags'
30+
const path = '/tags'
31+
const section = 'Tags'
32+
---
9833

99-
{article.data.description && (
100-
<p class="leading-relaxed line-clamp-3">
101-
{article.data.description}
102-
</p>
103-
)}
34+
<BaseLayout description={pageDescription} pageTitle={pageTitle} path={path} section={section}>
35+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
36+
<header class="text-center mb-16">
37+
<h1 class="text-4xl md:text-5xl font-bold mb-4">Technical Index</h1>
38+
<p class="text-xl max-w-3xl mx-auto">
39+
Browse documentation and guides structured by specific topics like Kubernetes, developer experience, and release engineering
40+
</p>
41+
</header>
10442

105-
<div class="flex items-center justify-between pt-4">
106-
<div class="flex items-center gap-2 text-sm">
107-
<svg
108-
class="w-4 h-4"
109-
aria-hidden="true"
110-
focusable="false"
111-
fill="none"
112-
stroke="currentColor"
113-
viewBox="0 0 24 24"
114-
>
115-
<path
116-
stroke-linecap="round"
117-
stroke-linejoin="round"
118-
stroke-width="2"
119-
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
120-
/>
121-
</svg>
122-
~5 min read
123-
</div>
43+
<div class="space-y-12">
44+
{
45+
tagsWithContent
46+
.sort((a, b) => a.data.displayName.localeCompare(b.data.displayName, 'en'))
47+
.map(tag => {
48+
const tagSlug = tag.data.slug
49+
const displayName = tag.data.displayName
50+
const articlesForTag = getArticlesForTag(tag)
12451

125-
<div class="flex items-center text-primary font-medium group-hover:text-primary-hover transition-colors duration-300">
126-
Read more
127-
<svg
128-
class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform duration-300"
129-
aria-hidden="true"
130-
focusable="false"
131-
fill="none"
132-
stroke="currentColor"
133-
viewBox="0 0 24 24"
134-
>
135-
<path
136-
stroke-linecap="round"
137-
stroke-linejoin="round"
138-
stroke-width="2"
139-
d="M9 5l7 7-7 7"
140-
/>
141-
</svg>
142-
</div>
143-
</div>
144-
</div>
145-
</a>
146-
</article>
147-
))
148-
}
149-
</section>
150-
</PageLayout>
52+
return (
53+
<section class="border-b border-trim pb-12 last:border-b-0">
54+
<Carousel
55+
title={displayName}
56+
titleHref={`/tags/${tagSlug}`}
57+
variant="suggested"
58+
limit={articlesForTag.length}
59+
type="articles"
60+
items={articlesForTag}
61+
/>
62+
</section>
63+
)
64+
})
65+
}
66+
</div>
67+
</div>
68+
</BaseLayout>

‎src/pages/tags/index.astro‎

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)