Files
mintel.me/apps/web/app/blog/[slug]/page.tsx
Marc Mintel 6244425551
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 1m4s
Build & Deploy / 🏗️ Build (push) Failing after 3m47s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
feat: enhance components and layouts
- fix: prevent code components from growing width during animation
- feat: enforce 100% width on browser frames (CodeWindow)
- feat: remove "Zurück" links project-wide from PageHeader
- feat: enable imgproxy face detection support for about page avatar
2026-02-15 19:02:58 +01:00

105 lines
3.8 KiB
TypeScript

import * as React from "react";
import { notFound } from "next/navigation";
import { blogPosts } from "../../../src/data/blogPosts";
import { PageHeader } from "../../../src/components/PageHeader";
import { Section } from "../../../src/components/Section";
import { BlogPostClient } from "../../../src/components/BlogPostClient";
import { PostComponents } from "../../../src/components/blog/posts";
import { Card } from "../../../src/components/Layout";
export async function generateStaticParams() {
return blogPosts.map((post) => ({
slug: post.slug,
}));
}
export default async function BlogPostPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const post = blogPosts.find((p) => p.slug === slug);
if (!post) {
notFound();
}
const formattedDate = new Date(post.date).toLocaleDateString("de-DE", {
month: "long",
day: "numeric",
year: "numeric",
});
const wordCount = post.description.split(/\s+/).length + 300; // Average post length
const readingTime = Math.max(1, Math.ceil(wordCount / 200));
const PostContent = PostComponents[slug];
return (
<div className="flex flex-col gap-12 py-12 md:py-24 overflow-hidden">
<BlogPostClient readingTime={readingTime} title={post.title} />
<PageHeader
variant="blog"
title={post.title}
description={post.description}
backgroundSymbol={slug.charAt(0).toUpperCase()}
/>
<main id="post-content">
<Section containerVariant="wide" className="pt-0 md:pt-0">
<div className="max-w-5xl mx-auto">
<Card
variant="glass"
techBorder
className="relative overflow-hidden"
>
{/* Decorative background grid inside the card */}
<div className="absolute inset-0 opacity-[0.03] bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]" />
<div className="relative z-10 px-6 py-12 md:px-16 md:py-20">
<div className="flex flex-wrap items-center justify-between gap-4 text-[10px] font-bold text-slate-400 mb-12 uppercase tracking-[0.2em] border-b border-slate-100 pb-6">
<div className="flex items-center gap-3">
<span className="w-2 h-2 rounded-full bg-slate-300" />
<time dateTime={post.date}>{formattedDate}</time>
</div>
<div className="flex items-center gap-4">
<span>{readingTime} min Lesezeit</span>
<span className="text-slate-200">|</span>
<span>
{slug.substring(0, 4).toUpperCase()}-
{Math.floor(Math.random() * 999)}
</span>
</div>
</div>
{post.tags && post.tags.length > 0 && (
<div className="flex flex-wrap gap-2 mb-12">
{post.tags.map((tag, index) => (
<span
key={tag}
className="px-3 py-1 bg-slate-50 border border-slate-100 rounded text-[10px] font-mono text-slate-500 uppercase tracking-widest"
>
#{tag}
</span>
))}
</div>
)}
{PostContent ? (
<PostContent />
) : (
<div className="p-8 bg-slate-50 border border-slate-200 rounded-lg italic text-slate-500">
Inhalt wird bald veröffentlicht...
</div>
)}
</div>
</Card>
</div>
</Section>
</main>
</div>
);
}