Kartenansicht je Lebensphase, Icon-Schiene links, Steuerung rechts
Deploy App / deploy (push) Successful in 1m10s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 21:29:42 +02:00
parent 113616cc1f
commit f41c3614b5
6 changed files with 1294 additions and 46 deletions
+19 -4
View File
@@ -20,6 +20,8 @@ export function Timeline({
ruinAge,
startYear,
actualYears = [],
activePhaseId,
onSelectPhase,
}: {
phases: PhaseComputed[];
persons: PersonAxis[];
@@ -28,6 +30,11 @@ export function Timeline({
// Kalenderjahre, für die effektive Werte erfasst sind (aufsteigend). Der jüngste Satz
// wird hervorgehoben, ältere bleiben blass -- sie sind überholt, aber nicht bedeutungslos.
actualYears?: number[];
// Seit 0.42 ist die Zeitachse nicht mehr nur Anzeige, sondern der NAVIGATOR der
// Kartenansicht: Das Segment der offenen Karte ist hervorgehoben, ein Klick springt hin.
// Zeit läuft von links nach rechts -- das versteht man ohne Erklärung.
activePhaseId?: string | null;
onSelectPhase?: (phaseId: string) => void;
}) {
if (phases.length === 0 || persons.length === 0) return null;
@@ -135,14 +142,22 @@ export function Timeline({
<div className="flex w-full overflow-hidden rounded-lg border border-border">
{segments.map((s, i) => {
const soft = s.phase.type === "PENSION" || s.phase.type === "MIXED";
const active = activePhaseId === s.phase.id;
const clickable = !!onSelectPhase;
return (
<div
<button
key={s.phase.id}
type="button"
disabled={!clickable}
onClick={() => onSelectPhase?.(s.phase.id)}
aria-current={active ? "true" : undefined}
style={{ width: `${(s.phase.durationYears / span) * 100}%` }}
title={`${s.phase.name} · ${s.phase.durationYears} Jahre`}
className={`flex min-w-0 flex-col justify-center px-2 py-1.5 ${
className={`flex min-w-0 flex-col justify-center px-2 py-1.5 text-left transition-all ${
i > 0 ? "border-l border-border" : ""
} ${s.phase.type === "PENSION" ? "bg-accent-soft" : s.phase.type === "MIXED" ? "bg-accent/25" : "bg-accent/70"}`}
} ${clickable ? "cursor-pointer hover:brightness-105" : ""} ${
s.phase.type === "PENSION" ? "bg-accent-soft" : s.phase.type === "MIXED" ? "bg-accent/25" : "bg-accent/70"
} ${active ? "ring-2 ring-inset ring-fg/70" : clickable ? "opacity-70" : ""}`}
>
<span className={`truncate text-[10px] font-semibold ${soft ? "text-accent-soft-fg" : "text-accent-fg"}`}>
{s.phase.name}
@@ -151,7 +166,7 @@ export function Timeline({
{s.phase.durationYears} J.
{yearOf(s.from) ? ` · ${yearOf(s.from)}${yearOf(s.to)}` : ""}
</span>
</div>
</button>
);
})}
</div>