"use client"; import Link from "next/link"; import { useState } from "react"; import { AlertTriangle, CheckSquare, GitBranch, GitCommitHorizontal, NotebookPen, Star, Tag, } from "lucide-react"; import { CiBadge } from "@/components/CiBadge"; import { Sparkline } from "@/components/Sparkline"; import { StatusSelect } from "@/components/StatusSelect"; import { repoTitle } from "@/lib/git/meta"; import { PRIORITY_META, accentOf } from "@/lib/status"; import { cn, formatRelative, truncate } from "@/lib/utils"; import { asArray, type ProjectListItem } from "@/types"; const PROVIDER_LABEL: Record = { GITHUB: "GitHub", GITLAB: "GitLab", GITEA: "Gitea", }; /** * Karte im Board. Die gesamte Flaeche ist ein Link (per "stretched link"), * interaktive Elemente liegen darueber und bekommen pointer-events zurueck. */ export function ProjectCard({ project, index = 0, selected = false, onToggleSelect, }: { project: ProjectListItem; index?: number; selected?: boolean; onToggleSelect?: (id: string, selected: boolean) => void; }) { const accent = accentOf(project.accent); const priority = PRIORITY_META[project.priority] ?? PRIORITY_META[2]; // Auf der Karte ist nur fuer eines Platz: das fuehrende. Wie viele es // insgesamt sind, sagt die Zahl daneben. const leading = project.repositories[0] ?? null; const snapshot = leading?.snapshot ?? null; const weitere = project.repositories.length - 1; // Ein Fehler an irgendeinem Repo gehoert auf die Karte, nicht nur einer am // fuehrenden – sonst bliebe er unbemerkt. const syncError = project.repositories.find((repo) => repo.syncError)?.syncError ?? null; const activity = asArray(snapshot?.commitActivity); const [favorite, setFavorite] = useState(project.favorite); async function toggleFavorite() { const next = !favorite; setFavorite(next); try { const response = await fetch(`/api/projects/${project.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ favorite: next }), }); if (!response.ok) throw new Error("failed"); } catch { setFavorite(!next); } } return (
); }