"use client"; import { useState, useTransition, useMemo } from "react"; import type { Project } from "@/lib/models"; import { ProjectCard } from "./project-card"; import type { Locale } from "@/i18n/routes"; type StatusTone = "live" | "warm" | "muted"; function statusTone(s: string): StatusTone { const v = s.toLowerCase(); if (v.startsWith("aktiv") || v.startsWith("live") || v === "running") return "live"; if (v.includes("early") || v.includes("draft") || v.includes("hardening")) return "warm"; return "muted"; } export function ProjectFilter({ projects, locale, emptyLabel, }: { projects: Project[]; locale: Locale; emptyLabel: string; }) { // Sammle alle einzigartigen Kategorien + Status-Töne als Filter-Tags. const tags = useMemo(() => { const set = new Set(); projects.forEach((p) => { const [main] = p.category.split("·"); if (main) set.add(main.trim()); set.add(statusTone(p.status)); }); return Array.from(set); }, [projects]); const [active, setActive] = useState(null); const [, start] = useTransition(); const filtered = useMemo(() => { if (!active) return projects; return projects.filter((p) => { if (active === "live" || active === "warm" || active === "muted") { return statusTone(p.status) === active; } const [main] = p.category.split("·"); return main?.trim() === active; }); }, [projects, active]); return (
filter {tags.map((t) => { const count = projects.filter((p) => { if (t === "live" || t === "warm" || t === "muted") return statusTone(p.status) === t; const [main] = p.category.split("·"); return main?.trim() === t; }).length; return ( ); })}
{filtered.length === 0 ? (
{emptyLabel}
) : (
{filtered.map((p) => (
))}
)}
); }