Files
portfolio/src/pages/workshop/index.astro
2025-10-21 19:54:07 +02:00

99 lines
4.3 KiB
Plaintext

<!-- ---
import "../../styles/global.css"
import Layout from "../../layouts/Layout.astro"
import { getCollection } from 'astro:content';
import { Image } from 'astro:assets';
const posts = (await getCollection('workshop'))
.filter(post => !post.data.private)
.sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
);
---
<Layout>
<section class="max-w-7xl mb-10 sm:mb-14">
<h1 class="text-4xl sm:text-5xl font-bold mb-6 text-neutral-900 dark:text-neutral-100">Workshop</h1>
<p class="text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed text-justify max-w-3xl">
I like to experiment, investigate and make mistakes. Here I archive my projects, ideas and failures.
</p>
</section>
{/* Grid layout for posts */}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6">
{posts.map((post) => (
<article class="group rounded-xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-800 hover:shadow-lg transition-all duration-300 overflow-hidden flex flex-col">
<a href={`/workshop/${post.id}/`} class="block flex flex-col h-full">
{/* Hero Image */}
{post.data.heroImage && (
<div class="aspect-video overflow-hidden">
<Image
src={post.data.heroImage}
alt={post.data.title}
width={800}
height={450}
class="w-full h-full object-cover grayscale group-hover:grayscale-0 group-hover:scale-105 transition-all duration-300"
loading="lazy"
/>
</div>
)}
<div class="p-4 sm:p-6 flex flex-col flex-grow">
{/* Title */}
<h2 class="text-lg sm:text-xl font-semibold text-neutral-900 dark:text-neutral-100 group-hover:text-neutral-700 dark:group-hover:text-neutral-300 transition-colors mb-2 line-clamp-2">
{post.data.title}
</h2>
{post.data.description && (
<p class="text-sm sm:text-base text-neutral-600 dark:text-neutral-400 mb-4 line-clamp-3 leading-relaxed flex-grow">
{post.data.description}
</p>
)}
{post.data.tags && post.data.tags.length > 0 && (
<div class="flex flex-wrap gap-1.5 mb-4">
{post.data.tags.slice(0, 3).map((tag) => (
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 transition-colors">
#{tag}
</span>
))}
{post.data.tags.length > 3 && (
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-neutral-100 dark:bg-neutral-700 text-neutral-500 dark:text-neutral-400">
+{post.data.tags.length - 3}
</span>
)}
</div>
)}
{post.data.pubDate && (
<div class="flex items-center text-xs sm:text-sm text-neutral-500 dark:text-neutral-400 mt-auto">
<svg class="w-3 h-3 sm:w-4 sm:h-4 mr-1.5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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"></path>
</svg>
<time datetime={post.data.pubDate.toISOString()}>
{new Date(post.data.pubDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})}
</time>
{post.data.updatedDate && (
<span class="ml-1 sm:ml-2 text-xs hidden sm:inline">
(Updated {new Date(post.data.updatedDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})})
</span>
)}
</div>
)}
</div>
</a>
</article>
))}
</div>
</Layout> -->
---
import WorkInProgress from "../../components/WorkInProgress.astro"
---
<WorkInProgress />