import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { getProjects } from "@/lib/directus"; import Board from "./Board"; import Deck from "./Deck"; import { PROJECT_COLORS, type TischLabels, type TischObject } from "./types"; interface TischSectionProps { locale: string; } // Abgabe der Masterarbeit, Grundlage für das Ticket const THESIS_DEADLINE = new Date("2027-02-15T12:00:00+01:00"); /** * Der Tisch: Projekte und ein paar Dinge aus meinem Alltag als Objekte. * Desktop zeigt den freien Tisch, das Handy einen Kartenstapel. Beides wird * serverseitig gerendert und per CSS umgeschaltet, damit nichts springt. */ export default async function TischSection({ locale }: TischSectionProps) { const t = await getTranslations({ locale, namespace: "home.tisch" }); const projects = (await getProjects(locale, { published: true, limit: 6 }).catch(() => null)) ?? []; const daysLeft = Math.max(0, Math.ceil((THESIS_DEADLINE.getTime() - Date.now()) / 86_400_000)); const labels: TischLabels = { hintBoard: t("hintBoard"), hintDeck: t("hintDeck"), tidy: t("tidy"), mess: t("mess"), flip: t("flip"), details: t("details"), prev: t("prev"), next: t("next"), ticketTitle: t("ticketTitle"), ticketDays: t("ticketDays"), ticketJob: t("ticketJob"), ticketStub: t("ticketStub"), serverTitle: t("serverTitle"), servers: [ { name: t("servers.ingress.name"), detail: t("servers.ingress.detail") }, { name: t("servers.mail.name"), detail: t("servers.mail.detail") }, { name: t("servers.home.name"), detail: t("servers.home.detail") }, ], serverNote: t("serverNote"), bookLabel: t("bookLabel"), bookFallback: t("bookFallback"), photoCaption: t("photoCaption"), sticker: t("sticker"), }; const projectObjects: TischObject[] = projects.map((p, i) => { const color = PROJECT_COLORS[i % PROJECT_COLORS.length]; return { kind: "project", id: `project-${p.slug}`, index: i, title: p.title, description: p.description, year: p.created_at ? String(new Date(p.created_at).getFullYear()) : "", tags: p.tags?.length ? p.tags : p.technologies ?? [], href: `/${locale}/projects/${p.slug}`, color: color.bg, textColor: color.text, liveUrl: p.live_url && p.live_url !== "#" ? p.live_url : undefined, githubUrl: p.github_url && p.github_url !== "#" ? p.github_url : undefined, }; }); // Reihenfolge = Startplätze auf dem Tisch; Projekte zuerst, damit sie oben liegen const objects: TischObject[] = [ ...projectObjects, { kind: "ticket", id: "ticket", daysLeft }, { kind: "server", id: "server" }, { kind: "book", id: "book", href: `/${locale}/books` }, { kind: "photo", id: "photo" }, { kind: "sticker", id: "sticker" }, ]; // Im Stapel wäre der runde Sticker eine Ellipse und wiederholt nur den Claim const deckObjects = objects.filter((o) => o.kind !== "sticker"); return (

{t("title")}

{t("allProjects")}
); }