"use client"; import { useMemo, useId } from "react"; import { Terminal, Smartphone, Globe, Code, LayoutDashboard, MessageSquare, Cloud, Wrench, Cpu, Shield, Boxes, type LucideIcon, } from "lucide-react"; interface ProjectThumbnailProps { title: string; category?: string; tags?: string[]; slug?: string; size?: "card" | "hero"; } // Plakatflächen statt Pastellverläufe: jede Kategorie bekommt eine feste Ton-Kombination // aus den Plakat-Tokens. Tinte/Papier tauschen im Dark Mode von selbst die Rollen. const tones = { signal: "bg-signal text-ink", ink: "bg-ink text-paper", paper: "bg-paper-2 text-ink", ok: "bg-ok text-ink", } as const; const categoryThemes: Record< string, { icon: LucideIcon; tone: keyof typeof tones; pattern: "dots" | "grid" | "diagonal" | "circuit" | "waves" | "terminal"; } > = { "Web Development": { icon: Code, tone: "signal", pattern: "circuit" }, "Mobile Development": { icon: Smartphone, tone: "ink", pattern: "waves" }, "Web Application": { icon: Globe, tone: "paper", pattern: "dots" }, "Backend Development": { icon: Cpu, tone: "ink", pattern: "grid" }, "Full-Stack Development": { icon: Boxes, tone: "signal", pattern: "grid" }, DevOps: { icon: Shield, tone: "ok", pattern: "diagonal" }, default: { icon: Wrench, tone: "paper", pattern: "dots" }, }; const slugIcons: Record = { "kernel-panic-404-interactive-terminal": Terminal, "portfolio-website": LayoutDashboard, "real-time-chat-application": MessageSquare, "weather-forecast-app": Cloud, "clarity": Smartphone, "e-commerce-platform-api": Boxes, "task-management-dashboard": LayoutDashboard, }; function PatternOverlay({ pattern, id }: { pattern: string; id: string }) { const patterns: Record = { dots: ( ), grid: ( ), diagonal: ( ), circuit: ( ), waves: ( ), terminal: ( $_ │ 404 │ ERR ), }; return patterns[pattern] || patterns.dots; } export default function ProjectThumbnail({ title, category, tags, slug, size = "card", }: ProjectThumbnailProps) { const uniqueId = useId(); const theme = useMemo(() => { if (slug && slugIcons[slug]) { const matchedTheme = categoryThemes[category || ""] || categoryThemes.default; return { ...matchedTheme, icon: slugIcons[slug] }; } return categoryThemes[category || ""] || categoryThemes.default; }, [category, slug]); const Icon = theme.icon; const isHero = size === "hero"; const displayTags = tags?.slice(0, isHero ? 5 : 3) ?? []; return (
{displayTags.join(" · ")}
{title}
); }