UI-Gesamtumbau: Du-Form, Inspector-Panel, Onboarding-Assistent, Tour, Palette
Deploy App / deploy (push) Successful in 1m1s
Deploy App / deploy (push) Successful in 1m1s
Rein an der Oberflaeche -- Berechnung, Datenmodell und API-Semantik unveraendert (103 Tests unveraendert gruen). Paket A (Fundament): - durchgehend Du-Form und echte Umlaute in allen sichtbaren Texten, inkl. API-Fehlermeldungen (vorher Mix aus Sie/Du und ae/oe/ue) - neue UI-Primitiven (ui.tsx): Button, Modal mit ESC/Fokus-Falle/Animation, Bestaetigungs-Dialog statt window.confirm, Toasts statt alert, Skeleton-Loader, EmptyState - eigene Attention-Farbe (Amber) fuer offene Entscheide, getrennt vom Akzent - Micro-Interactions mit prefers-reduced-motion-Fallback Paket B (Onboarding, Roadmap Nr. 10): - gefuehrter Plan-Assistent in 5 Schritten; Einkommen bewusst pro Person (raeumt die 9.9-AHV-Falle aus); reine Orchestrierung bestehender Endpunkte - Beispielplan mit einem Klick; Uebergaenge absichtlich offen - interaktive Tour ueber die Planansicht (localStorage, jederzeit neu startbar) - abgeleitete "Naechste Schritte"-Karte (offene Entscheide, fehlende Elemente, fehlende Pensionsphase, Ruin -> Einflussfaktoren) Paket C (Struktur): - Inspector-Panel rechts statt Modals fuer alle Einzel-Bearbeitungen; Matrix bleibt sichtbar, Zellklick wechselt den Inhalt - Phasenkopf auf vier Kern-Infos entschlackt (Rest in der 0.11-Detailansicht) - Matrix mit eigenem Scrollbereich, Koepfe beidachsig fixiert - Sidebar-Gruppen "Meine Plaene" / "Wissen"; "So rechnet FPT" statt SPEZIFIKATION; "Szenario-Profil" statt "Plan-Einstellungen" - Aktions-Icons ohne Hover sichtbar (Touch) Paket D (Extras): - Sparklines je Element-Zeile aus den 0.11-Verlaufswerten - Befehls-Palette (Ctrl/Cmd+K) - Ruin-Banner verlinkt auf die Einflussfaktoren Nebenbei: der ProfileMenu-Lint-Fehler und der Selection-Rest (9.17) sind behoben -- npm run lint laeuft erstmals fehlerfrei. SPEZIFIKATION auf 0.13: neue Kapitel 3.2.8, 3.7.6-3.7.9, 9.23, 9.24; 3.6.3 und 3.7.1 ueberarbeitet, 9.17 bereinigt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,17 +6,17 @@ import { getCurrentUserId } from "@/lib/session";
|
||||
|
||||
const copySchema = z.object({ name: z.string().min(1).max(120) });
|
||||
|
||||
// Erstellt ein neues Szenario als vollstaendige Kopie eines bestehenden. Das Original wird
|
||||
// zum Elternteil -- damit haengt der Baum in der Seitenleiste und der Diff hat seine Basis.
|
||||
// Jede kopierte Phase/jedes kopierte Element traegt einen Herkunfts-Verweis auf sein
|
||||
// Gegenstueck im Original; darauf beruht die Abweichungs-Markierung im UI.
|
||||
// Erstellt ein neues Szenario als vollständige Kopie eines bestehenden. Das Original wird
|
||||
// zum Elternteil -- damit hängt der Baum in der Seitenleiste und der Diff hat seine Basis.
|
||||
// Jede kopierte Phase/jedes kopierte Element trägt einen Herkunfts-Verweis auf sein
|
||||
// Gegenstück im Original; darauf beruht die Abweichungs-Markierung im UI.
|
||||
export async function POST(request: NextRequest, { params }: { params: Promise<{ scenarioId: string }> }) {
|
||||
const userId = await getCurrentUserId();
|
||||
if (!userId) return NextResponse.json({ error: "Nicht authentifiziert." }, { status: 401 });
|
||||
const { scenarioId } = await params;
|
||||
|
||||
const parsed = copySchema.safeParse(await request.json());
|
||||
if (!parsed.success) return NextResponse.json({ error: "Ungueltige Eingabe." }, { status: 400 });
|
||||
if (!parsed.success) return NextResponse.json({ error: "Ungültige Eingabe." }, { status: 400 });
|
||||
|
||||
const source = await getOwnedScenario(scenarioId, userId);
|
||||
if (!source) return NextResponse.json({ error: "Ursprungs-Szenario nicht gefunden." }, { status: 404 });
|
||||
@@ -43,7 +43,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
|
||||
},
|
||||
});
|
||||
|
||||
// Phasen kopieren (alte -> neue Id merken, fuer die Werte-Zuordnung).
|
||||
// Phasen kopieren (alte -> neue Id merken, für die Werte-Zuordnung).
|
||||
const phaseIdMap = new Map<string, string>();
|
||||
for (const phase of source.phases) {
|
||||
const p = await tx.phase.create({
|
||||
@@ -59,7 +59,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
|
||||
phaseIdMap.set(phase.id, p.id);
|
||||
}
|
||||
|
||||
// Elemente inkl. Phasen- und Uebergangswerten kopieren.
|
||||
// Elemente inkl. Phasen- und Übergangswerten kopieren.
|
||||
for (const el of source.elements) {
|
||||
const newEl = await tx.financialElement.create({
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user