Complete website for The Computer Guru Show (radio.azcomputerguru.com): - Astro 6.0.4 static site with React islands - 194 episodes imported from gurushow.com RSS feed - Dark/light mode HSL design system - Persistent audio player with session persistence - Episode archive with search and season filtering - Home page with animated hero, stats, latest episodes - All pages: About, Subscribe, Community, Live, Contact, Blog, 404 - Podcast RSS feed with iTunes namespace - Session log updated Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
135 lines
3.6 KiB
Plaintext
135 lines
3.6 KiB
Plaintext
---
|
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
|
import { getCollection } from 'astro:content';
|
|
|
|
const allPosts = await getCollection('blog', ({ data }) => !data.draft);
|
|
const posts = allPosts.sort((a, b) =>
|
|
new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime()
|
|
);
|
|
---
|
|
|
|
<BaseLayout title="Blog" description="Articles, guides, and updates from The Computer Guru Show.">
|
|
<!-- Hero -->
|
|
<section class="hero section">
|
|
<div class="container">
|
|
<span class="badge fade-in">Blog</span>
|
|
<h1 class="hero__title fade-in">Blog</h1>
|
|
<p class="hero__subtitle fade-in">
|
|
{posts.length} {posts.length === 1 ? 'post' : 'posts'} -- articles, updates, and guides.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Posts Grid -->
|
|
<section class="section">
|
|
<div class="container">
|
|
{posts.length === 0 ? (
|
|
<div class="empty-state fade-in">
|
|
<p>No blog posts yet. Check back soon.</p>
|
|
</div>
|
|
) : (
|
|
<div class="grid grid--2">
|
|
{posts.map((post) => (
|
|
<a href={`/blog/${post.id}`} class="card post-card fade-in">
|
|
<div class="post-card__meta">
|
|
<time datetime={post.data.pubDate.toISOString()}>
|
|
{post.data.pubDate.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
})}
|
|
</time>
|
|
</div>
|
|
<h2 class="post-card__title">{post.data.title}</h2>
|
|
<p class="post-card__desc">{post.data.description}</p>
|
|
<div class="post-card__footer">
|
|
{post.data.tags.length > 0 && (
|
|
<div class="post-card__tags">
|
|
{post.data.tags.map((tag: string) => (
|
|
<span class="badge">{tag}</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
<span class="post-card__link">Read More →</span>
|
|
</div>
|
|
</a>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
</BaseLayout>
|
|
|
|
<style>
|
|
.hero {
|
|
text-align: center;
|
|
padding-block: var(--space-16) var(--space-8);
|
|
}
|
|
.hero__title {
|
|
font-size: var(--text-4xl);
|
|
margin-top: var(--space-4);
|
|
margin-bottom: var(--space-4);
|
|
}
|
|
.hero__subtitle {
|
|
font-size: var(--text-lg);
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
/* Empty State */
|
|
.empty-state {
|
|
text-align: center;
|
|
padding: var(--space-16);
|
|
color: var(--color-text-muted);
|
|
font-size: var(--text-lg);
|
|
}
|
|
|
|
/* Post Card */
|
|
.post-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
color: var(--color-text-primary);
|
|
padding: var(--space-8);
|
|
}
|
|
.post-card:hover {
|
|
color: var(--color-text-primary);
|
|
}
|
|
.post-card__meta {
|
|
margin-bottom: var(--space-3);
|
|
}
|
|
.post-card__meta time {
|
|
font-size: var(--text-xs);
|
|
color: var(--color-text-muted);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
.post-card__title {
|
|
font-size: var(--text-xl);
|
|
margin-bottom: var(--space-3);
|
|
line-height: 1.3;
|
|
}
|
|
.post-card__desc {
|
|
color: var(--color-text-secondary);
|
|
font-size: var(--text-sm);
|
|
line-height: 1.7;
|
|
flex: 1;
|
|
}
|
|
.post-card__footer {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-top: var(--space-6);
|
|
flex-wrap: wrap;
|
|
gap: var(--space-3);
|
|
}
|
|
.post-card__tags {
|
|
display: flex;
|
|
gap: var(--space-2);
|
|
flex-wrap: wrap;
|
|
}
|
|
.post-card__link {
|
|
font-size: var(--text-sm);
|
|
font-weight: 600;
|
|
color: var(--color-accent);
|
|
}
|
|
</style>
|