Files
MABEA/frontend/src/pages/dashboard/tiles/QualifikationTile.tsx
T
patrickandClaude Sonnet 5 d38c7adbc7
CI / backend-tests (push) Failing after 2m11s
CI / frontend-build (push) Successful in 22s
feat(dashboard): Design-Review umgesetzt - EmptyStates, Statuslabel, Monitor-Skalierung
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
2026-09-07 22:38:36 +02:00

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);