79 lines
2.8 KiB
Plaintext
79 lines
2.8 KiB
Plaintext
---
|
|
import Layout from '../layouts/Layout.astro';
|
|
|
|
const API_URL = (typeof process !== 'undefined' ? process.env.PUBLIC_API_URL : import.meta.env.PUBLIC_API_URL) || 'http://localhost:3000';
|
|
console.log('Connecting to backend at:', API_URL);
|
|
|
|
interface Post {
|
|
slug: string;
|
|
}
|
|
|
|
let posts: Post[] = [];
|
|
let error = '';
|
|
|
|
try {
|
|
const response = await fetch(`${API_URL}/api/posts`);
|
|
if (response.ok) {
|
|
posts = await response.json();
|
|
} else {
|
|
error = 'Failed to fetch posts';
|
|
}
|
|
} catch (e) {
|
|
const cause = (e as any)?.cause;
|
|
error = `Could not connect to backend at ${API_URL}: ${e instanceof Error ? e.message : String(e)}${cause ? ' (Cause: ' + (cause.message || cause.code || JSON.stringify(cause)) + ')' : ''}`;
|
|
console.error(error);
|
|
}
|
|
|
|
function formatSlug(slug: string) {
|
|
return slug
|
|
.split('-')
|
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
.join(' ');
|
|
}
|
|
---
|
|
|
|
<Layout title="Home">
|
|
<div class="space-y-6 md:space-y-8">
|
|
<section class="text-center py-6 md:py-12">
|
|
<h1 class="text-3xl md:text-5xl font-extrabold mb-3 md:mb-4 pb-2 md:pb-4 leading-tight bg-clip-text text-transparent bg-gradient-to-r from-mauve via-blue to-teal">
|
|
Welcome to my blog
|
|
</h1>
|
|
<p class="text-subtext1 text-base md:text-lg max-w-2xl mx-auto px-4 md:px-0">
|
|
Thoughts on software, design, and building things with Rust and Astro.
|
|
</p>
|
|
</section>
|
|
|
|
<div class="flex flex-col space-y-6">
|
|
{error && (
|
|
<div class="glass p-4 md:p-6 text-red text-center border-red/20 text-sm md:text-base">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
{posts.length === 0 && !error && (
|
|
<div class="glass p-8 md:p-12 text-center text-subtext0 text-sm md:text-base">
|
|
<p>No posts found yet. Add some .md files to the data/posts directory!</p>
|
|
</div>
|
|
)}
|
|
|
|
{posts.map((post) => (
|
|
<a href={`/posts/${post.slug}`} class="group block">
|
|
<article class="glass p-5 md:p-8 transition-all hover:scale-[1.01] hover:bg-surface0/80 active:scale-[0.99] flex flex-col md:flex-row justify-between md:items-center gap-4 md:gap-6">
|
|
<div class="flex-1">
|
|
<h2 class="text-xl md:text-3xl font-bold text-lavender group-hover:text-mauve transition-colors mb-2 md:mb-3">
|
|
{formatSlug(post.slug)}
|
|
</h2>
|
|
<p class="text-subtext1 text-sm md:text-base leading-relaxed line-clamp-3">
|
|
{post.excerpt || `Read more about ${formatSlug(post.slug)}...`}
|
|
</p>
|
|
</div>
|
|
<div class="text-mauve opacity-0 group-hover:opacity-100 transition-opacity self-end md:self-auto shrink-0 hidden md:block">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="md:w-8 md:h-8"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
|
</div>
|
|
</article>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</Layout>
|