Einheitliche EmptyState-Komponente statt uneinheitlicher Empty-Texte pro Kachel, gemeinsames Listen-Pattern (Inline-Styles entfernt, u.a. KennzahlenTile, MaengelTile, AktivitaetTile, AufgabenTile), Status-Textlabel im Kachel-Header zusätzlich zur Randfarbe (Kontrast/Distanz/Farbfehlsichtigkeit), Status-Monitor-Modus jetzt per zoom vergrößert für Wandmonitor-Lesbarkeit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { memo, useState } from "react";
|
|
|
|
import { FristBadge } from "../../../components/status/FristBadge";
|
|
import { EmptyState } from "../EmptyState";
|
|
import type { Qualifikationsablauf } from "../types";
|
|
|
|
const ANZAHL_OHNE_AUFKLAPPEN = 5;
|
|
|
|
interface Props {
|
|
qualifikationsablaeufe: Qualifikationsablauf[];
|
|
}
|
|
|
|
function QualifikationTileKomponente({ qualifikationsablaeufe }: Props) {
|
|
const [alleAnzeigen, setAlleAnzeigen] = useState(false);
|
|
|
|
if (qualifikationsablaeufe.length === 0) {
|
|
return <EmptyState text="Keine bald ablaufenden Qualifikationen." />;
|
|
}
|
|
|
|
const sichtbare = alleAnzeigen ? qualifikationsablaeufe : qualifikationsablaeufe.slice(0, ANZAHL_OHNE_AUFKLAPPEN);
|
|
|
|
return (
|
|
<>
|
|
<ul>
|
|
{sichtbare.map((q) => (
|
|
<li key={q.benutzer_qualifikation_id} className="flex items-center gap-3 border-b border-[var(--color-border)] py-2 last:border-0">
|
|
<FristBadge status={q.status} />
|
|
<div className="min-w-0 flex-1">
|
|
<span className="block truncate font-medium">{q.benutzer_name}</span>
|
|
<span className="text-xs text-[var(--color-text-muted)]">{q.qualifikationstyp_name}</span>
|
|
</div>
|
|
<span className="shrink-0 tabular-nums text-sm font-semibold">{q.verbleibende_tage} Tage</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
{qualifikationsablaeufe.length > ANZAHL_OHNE_AUFKLAPPEN && (
|
|
<button
|
|
className="mt-2 text-sm font-medium text-[var(--color-primary)] underline-offset-2 hover:underline"
|
|
onClick={() => setAlleAnzeigen(!alleAnzeigen)}
|
|
>
|
|
{alleAnzeigen ? "Weniger anzeigen" : `Alle anzeigen (${qualifikationsablaeufe.length})`}
|
|
</button>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
export const QualifikationTile = memo(QualifikationTileKomponente);
|