Anstehende Meilensteine im Dashboard anzeigen
ci / quality (push) Failing after 38s
ci / build (push) Has been skipped
deploy / deploy (push) Successful in 52s

Projektübergreifende Liste offener/überfälliger Meilensteine mit Datum,
sortiert nach Fälligkeit. Überfällige rot markiert, relative Tagesangabe
("in 3 Tagen" / "überfällig"), direkt verlinkt aufs Projekt. Sitzt oben
zwischen Showstoppern und kritischen Modi.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 4.8 committed 2026-06-06 20:29:16 +02:00
1 parent e46d107b2d
commit 1b186d8be6
2 files changed
+90 -4

No files matched your search

+52
View File
@@ -104,6 +104,45 @@ export function DashboardRoute() {
</section>
)}
{q.data.meilensteine.length > 0 && (
<section>
<h2 className="mb-2 text-lg font-semibold">Anstehende Meilensteine</h2>
<Card.Root>
<Card.Body className="p-0">
<ul className="divide-y divide-[var(--color-border)]">
{q.data.meilensteine.map((m) => (
<li key={m.id} className="flex items-center justify-between gap-3 px-4 py-3">
<div className="min-w-0">
<p className="truncate text-sm font-medium">{m.title}</p>
<div className="mt-0.5 flex items-center gap-2 text-xs">
<span
className={clsx(
m.ueberfaellig
? 'font-medium text-[var(--color-ampel-red-fg)]'
: 'text-[var(--color-ink-muted)]',
)}
>
{formatDate(m.due!)}
{m.ueberfaellig && ' · überfällig'}
</span>
<span className="text-[var(--color-ink-faint)]">·</span>
<span className="text-[var(--color-ink-muted)]">{relativeDays(m.due!, q.data.date)}</span>
</div>
</div>
<Link
to={`/projekt/${m.projectId}`}
className="shrink-0 text-xs text-[var(--color-ink-muted)] hover:text-[var(--color-ink)] hover:underline"
>
{m.projectName} →
</Link>
</li>
))}
</ul>
</Card.Body>
</Card.Root>
</section>
)}
{q.data.kritischeModi.length > 0 && (
<section>
<h2 className="mb-2 text-lg font-semibold">Projekte in Eskalation / Taskforce</h2>
@@ -364,5 +403,18 @@ function formatDate(input: string | Date): string {
}).format(dt);
}
// Relative Tagesangabe für Meilensteine ("heute", "in 3 Tagen", "vor 2 Tagen").
function relativeDays(dueIso: string, todayIso: string): string {
const due = new Date(`${dueIso}T00:00:00`);
const today = new Date(`${todayIso}T00:00:00`);
if (Number.isNaN(due.getTime()) || Number.isNaN(today.getTime())) return '';
const diff = Math.round((due.getTime() - today.getTime()) / 86_400_000);
if (diff === 0) return 'heute';
if (diff === 1) return 'morgen';
if (diff === -1) return 'gestern';
if (diff > 0) return `in ${diff} Tagen`;
return `vor ${Math.abs(diff)} Tagen`;
}
// Button als referenz behalten (Linter)
void Button;