V3: 3 Farbschemata, Grundprofil auf Plan-Ebene, Erstellungs-Popups, integer-Zahlenfelder mit Beschleunigungs-Spinner, Carry-Forward des Zielwerts, gefuehrter Uebergang
Deploy App / deploy (push) Successful in 1m51s
Deploy App / deploy (push) Successful in 1m51s
- Theming: semantische CSS-Tokens + 3 waehlbare Schemata (Hell/Dunkel/Warm/Sunset), Umschalter im Profil-Menue, FOUC-frei via Inline-Script, localStorage; Klassen-Sweep aller Komponenten, Recharts aus Tokens - Datenmodell: Household entfaellt; Plan traegt Haushaltsform/Personen/Inflation selbst (Person -> planId, Plan -> userId); destruktive Migration (TRUNCATE); Onboarding/HouseholdSettings entfernt; Plan-Erstellung & -Einstellungen mit Profilfeldern - Popups: Element-Erstellung mit Inline-Feldern (geteilte ElementPhaseFields/ElementTransitionFields), Phase- und Plan-Popups mit Direkteingabe - Zahlenfelder: 1'000er-Runden entfernt (floorToThousand/roundToHundred weg), integer MoneyInput mit beschleunigendem Press-and-Hold-Spinner, 0-Bug-Fix, harte Live-Caps - Quote: Amortisation + Tilgung neu quotenwirksam; Restquote sichtbar (sinkt beim Verteilen); Invest-Deckel = verfuegbares Kapital + fortgeschriebener Zielwert - Carry-Forward: Startwert der Folgephase = Zielwert der Vorphase minus Uebergangs-Bezug (live abgeleitet); optionale Zusatzinvestition aus verfuegbarem Kapital - Matrix: Zelle zeigt Start -> Ziel; Uebergangs-Spaltenkopf mit "n offen"-Badge + gefuehrtem Pruef-Panel Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+71
-105
@@ -12,10 +12,10 @@ import {
|
||||
} from "lucide-react";
|
||||
import { PlanView } from "@/components/PlanView";
|
||||
import { Dashboard } from "@/components/Dashboard";
|
||||
import { HouseholdSettings } from "@/components/HouseholdSettings";
|
||||
import { ProfileMenu } from "@/components/ProfileMenu";
|
||||
import { PlanProfileFields, emptyProfileDraft, type ProfileDraft } from "@/components/PlanProfileFields";
|
||||
import { api } from "@/lib/api-client";
|
||||
import type { HouseholdInput, PlanInput } from "@/lib/types";
|
||||
import type { PlanInput } from "@/lib/types";
|
||||
import type { PlanComputed } from "@/lib/calculations";
|
||||
|
||||
interface PlanListItem {
|
||||
@@ -26,15 +26,7 @@ interface PlanListItem {
|
||||
phases: { id: string; name: string; sequenceNumber: number }[];
|
||||
}
|
||||
|
||||
export function AppShell({
|
||||
initialHousehold,
|
||||
username,
|
||||
}: {
|
||||
initialHousehold: HouseholdInput;
|
||||
username: string;
|
||||
}) {
|
||||
const [household, setHousehold] = useState(initialHousehold);
|
||||
const [showSettings, setShowSettings] = useState(false);
|
||||
export function AppShell({ username }: { username: string }) {
|
||||
const [plans, setPlans] = useState<PlanListItem[]>([]);
|
||||
const [selectedPlanId, setSelectedPlanId] = useState<string | null>(null);
|
||||
const [detail, setDetail] = useState<{ plan: PlanInput; computed: PlanComputed } | null>(null);
|
||||
@@ -46,9 +38,7 @@ export function AppShell({
|
||||
const loadPlans = useCallback(async (preferId?: string) => {
|
||||
const data = await api.get<{ plans: PlanListItem[] }>("/api/plans");
|
||||
setPlans(data.plans);
|
||||
if (preferId) {
|
||||
setSelectedPlanId(preferId);
|
||||
}
|
||||
if (preferId) setSelectedPlanId(preferId);
|
||||
return data.plans;
|
||||
}, []);
|
||||
|
||||
@@ -84,9 +74,7 @@ export function AppShell({
|
||||
if (!confirm("Diesen Plan wirklich loeschen?")) return;
|
||||
await api.delete(`/api/plans/${id}`);
|
||||
await loadPlans();
|
||||
if (selectedPlanId === id) {
|
||||
setSelectedPlanId(null);
|
||||
}
|
||||
if (selectedPlanId === id) setSelectedPlanId(null);
|
||||
}
|
||||
|
||||
const activePlan = plans.find((p) => p.id === selectedPlanId) ?? null;
|
||||
@@ -94,10 +82,10 @@ export function AppShell({
|
||||
const sidebar = (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex items-center gap-2 px-4 py-4">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-xl bg-indigo-600 dark:bg-indigo-500">
|
||||
<PiggyBank className="h-5 w-5 text-white" />
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-xl bg-accent">
|
||||
<PiggyBank className="h-5 w-5 text-accent-fg" />
|
||||
</div>
|
||||
<span className="text-sm font-semibold text-zinc-900 dark:text-zinc-50">FPT</span>
|
||||
<span className="text-sm font-semibold text-fg">FPT</span>
|
||||
</div>
|
||||
|
||||
<nav className="flex flex-1 flex-col gap-1 overflow-y-auto px-3 pb-4">
|
||||
@@ -108,9 +96,7 @@ export function AppShell({
|
||||
setSidebarOpen(false);
|
||||
}}
|
||||
className={`flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium ${
|
||||
selectedPlanId === null
|
||||
? "bg-indigo-50 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300"
|
||||
: "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
selectedPlanId === null ? "bg-accent-soft text-accent-soft-fg" : "text-muted hover:bg-surface-2"
|
||||
}`}
|
||||
>
|
||||
<LayoutDashboard className="h-4 w-4" />
|
||||
@@ -118,19 +104,17 @@ export function AppShell({
|
||||
</button>
|
||||
|
||||
<div className="mt-4 flex items-center justify-between px-3">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-wide text-zinc-400">Plaene</span>
|
||||
<span className="text-[11px] font-semibold uppercase tracking-wide text-faint">Plaene</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowNewPlan(true)}
|
||||
aria-label="Neuen Plan erstellen"
|
||||
className="rounded-md p-1 text-indigo-600 hover:bg-indigo-50 dark:text-indigo-400 dark:hover:bg-indigo-500/10"
|
||||
className="rounded-md p-1 text-accent hover:bg-accent-soft"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
{plans.length === 0 && (
|
||||
<p className="px-3 py-2 text-xs text-zinc-400">Noch keine Plaene.</p>
|
||||
)}
|
||||
{plans.length === 0 && <p className="px-3 py-2 text-xs text-faint">Noch keine Plaene.</p>}
|
||||
{plans.map((p) => (
|
||||
<button
|
||||
key={p.id}
|
||||
@@ -140,14 +124,12 @@ export function AppShell({
|
||||
setSidebarOpen(false);
|
||||
}}
|
||||
className={`flex items-center gap-2 rounded-lg px-3 py-2 text-left text-sm ${
|
||||
selectedPlanId === p.id
|
||||
? "bg-indigo-50 font-medium text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300"
|
||||
: "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
selectedPlanId === p.id ? "bg-accent-soft font-medium text-accent-soft-fg" : "text-muted hover:bg-surface-2"
|
||||
}`}
|
||||
>
|
||||
<FolderKanban className="h-4 w-4 shrink-0" />
|
||||
<span className="min-w-0 flex-1 truncate">{p.name}</span>
|
||||
<span className="text-[11px] text-zinc-400">{p.phases.length}</span>
|
||||
<span className="text-[11px] text-faint">{p.phases.length}</span>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
@@ -157,20 +139,18 @@ export function AppShell({
|
||||
return (
|
||||
<div className="flex min-h-screen w-full">
|
||||
{/* Sidebar Desktop */}
|
||||
<aside className="hidden w-60 shrink-0 border-r border-zinc-200 bg-white lg:block dark:border-zinc-800 dark:bg-zinc-900">
|
||||
{sidebar}
|
||||
</aside>
|
||||
<aside className="hidden w-60 shrink-0 border-r border-border bg-surface lg:block">{sidebar}</aside>
|
||||
|
||||
{/* Sidebar Mobile (Overlay) */}
|
||||
{sidebarOpen && (
|
||||
<div className="fixed inset-0 z-40 lg:hidden">
|
||||
<div className="absolute inset-0 bg-black/40" onClick={() => setSidebarOpen(false)} />
|
||||
<aside className="absolute left-0 top-0 h-full w-64 border-r border-zinc-200 bg-white shadow-xl dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<aside className="absolute left-0 top-0 h-full w-64 border-r border-border bg-surface shadow-xl">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
aria-label="Menue schliessen"
|
||||
className="absolute right-2 top-3 rounded-md p-1.5 text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
||||
className="absolute right-2 top-3 rounded-md p-1.5 text-faint hover:bg-surface-2"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -181,33 +161,23 @@ export function AppShell({
|
||||
|
||||
{/* Hauptbereich */}
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
<header className="flex items-center gap-3 border-b border-zinc-200 bg-white px-4 py-3 dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<header className="flex items-center gap-3 border-b border-border bg-surface px-4 py-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSidebarOpen(true)}
|
||||
aria-label="Menue oeffnen"
|
||||
className="rounded-lg border border-zinc-200 p-2 text-zinc-600 lg:hidden dark:border-zinc-700 dark:text-zinc-300"
|
||||
className="rounded-lg border border-border p-2 text-muted lg:hidden"
|
||||
>
|
||||
<Menu className="h-4 w-4" />
|
||||
</button>
|
||||
<h1 className="min-w-0 flex-1 truncate text-base font-semibold text-zinc-900 dark:text-zinc-50">
|
||||
<h1 className="min-w-0 flex-1 truncate text-base font-semibold text-fg">
|
||||
{activePlan ? activePlan.name : "Uebersicht"}
|
||||
</h1>
|
||||
<ProfileMenu username={username} onOpenHouseholdSettings={() => setShowSettings(true)} />
|
||||
<ProfileMenu username={username} />
|
||||
</header>
|
||||
|
||||
<main className="flex-1 px-4 py-6 lg:px-8">
|
||||
{showSettings && (
|
||||
<div className="mb-6">
|
||||
<HouseholdSettings
|
||||
household={household}
|
||||
onUpdated={setHousehold}
|
||||
onClose={() => setShowSettings(false)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading && <p className="text-sm text-zinc-500">Laedt…</p>}
|
||||
{loading && <p className="text-sm text-muted">Laedt…</p>}
|
||||
|
||||
{!loading && selectedPlanId === null && (
|
||||
<DashboardHome
|
||||
@@ -226,7 +196,7 @@ export function AppShell({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowScenario(true)}
|
||||
className="flex items-center gap-1.5 rounded-lg border border-zinc-300 px-3 py-1.5 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-sm font-medium text-muted hover:bg-surface-2"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Szenario
|
||||
@@ -235,23 +205,16 @@ export function AppShell({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleDeletePlan(selectedPlanId)}
|
||||
className="flex items-center gap-1.5 rounded-lg border border-zinc-300 px-3 py-1.5 text-sm font-medium text-zinc-500 hover:border-red-200 hover:bg-red-50 hover:text-red-600 dark:border-zinc-700 dark:hover:border-red-500/30 dark:hover:bg-red-950"
|
||||
className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-sm font-medium text-muted hover:border-danger hover:bg-danger-soft hover:text-danger"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
Plan loeschen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<PlanView
|
||||
plan={detail.plan}
|
||||
household={household}
|
||||
computed={detail.computed}
|
||||
onChanged={refreshCurrent}
|
||||
/>
|
||||
<PlanView plan={detail.plan} computed={detail.computed} onChanged={refreshCurrent} />
|
||||
|
||||
{detail.plan.phases.length > 0 && (
|
||||
<Dashboard plan={detail.plan} computed={detail.computed} allPlans={plans} />
|
||||
)}
|
||||
{detail.plan.phases.length > 0 && <Dashboard plan={detail.plan} computed={detail.computed} allPlans={plans} />}
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
@@ -260,10 +223,8 @@ export function AppShell({
|
||||
{/* Dialoge */}
|
||||
{showNewPlan && (
|
||||
<PlanDialog
|
||||
title="Neuen Plan erstellen"
|
||||
defaultName="Basisplan"
|
||||
onCreate={async (name) => {
|
||||
const { plan } = await api.post<{ plan: { id: string } }>("/api/plans", { name });
|
||||
onCreate={async (name, profile) => {
|
||||
const { plan } = await api.post<{ plan: { id: string } }>("/api/plans", { name, ...profile });
|
||||
setShowNewPlan(false);
|
||||
await loadPlans(plan.id);
|
||||
}}
|
||||
@@ -305,10 +266,8 @@ function DashboardHome({
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
<div>
|
||||
<h2 className="text-xl font-semibold text-zinc-900 dark:text-zinc-50">
|
||||
Willkommen, {username}
|
||||
</h2>
|
||||
<p className="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<h2 className="text-xl font-semibold text-fg">Willkommen, {username}</h2>
|
||||
<p className="mt-1 text-sm text-muted">
|
||||
Waehlen Sie einen Plan oder erstellen Sie einen neuen, um Ihre finanzielle Zukunft zu planen.
|
||||
</p>
|
||||
</div>
|
||||
@@ -317,16 +276,16 @@ function DashboardHome({
|
||||
{plans.map((p) => (
|
||||
<div
|
||||
key={p.id}
|
||||
className="group relative flex cursor-pointer flex-col gap-2 rounded-xl border border-zinc-200/70 bg-white p-4 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
|
||||
className="group relative flex cursor-pointer flex-col gap-2 rounded-xl border border-border bg-surface p-4 shadow-sm transition-shadow hover:shadow-md"
|
||||
onClick={() => onSelect(p.id)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-indigo-100 dark:bg-indigo-500/20">
|
||||
<FolderKanban className="h-5 w-5 text-indigo-600 dark:text-indigo-300" />
|
||||
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-accent-soft">
|
||||
<FolderKanban className="h-5 w-5 text-accent-soft-fg" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="truncate font-medium text-zinc-900 dark:text-zinc-100">{p.name}</div>
|
||||
<div className="text-xs text-zinc-500">
|
||||
<div className="truncate font-medium text-fg">{p.name}</div>
|
||||
<div className="text-xs text-muted">
|
||||
{p.phases.length} {p.phases.length === 1 ? "Phase" : "Phasen"}
|
||||
{p.parentPlanId ? " · Szenario" : ""}
|
||||
</div>
|
||||
@@ -338,7 +297,7 @@ function DashboardHome({
|
||||
e.stopPropagation();
|
||||
onDelete(p.id);
|
||||
}}
|
||||
className="rounded-md p-1.5 text-zinc-300 opacity-0 transition-opacity hover:bg-red-50 hover:text-red-600 group-hover:opacity-100 dark:hover:bg-red-950"
|
||||
className="rounded-md p-1.5 text-faint opacity-0 transition-opacity hover:bg-danger-soft hover:text-danger group-hover:opacity-100"
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -349,7 +308,7 @@ function DashboardHome({
|
||||
<button
|
||||
type="button"
|
||||
onClick={onCreate}
|
||||
className="flex min-h-20 items-center justify-center gap-2 rounded-xl border border-dashed border-indigo-300 bg-indigo-50/40 text-sm font-medium text-indigo-700 hover:bg-indigo-50 dark:border-indigo-500/30 dark:bg-indigo-500/5 dark:text-indigo-300 dark:hover:bg-indigo-500/15"
|
||||
className="flex min-h-20 items-center justify-center gap-2 rounded-xl border border-dashed border-accent bg-accent-soft text-sm font-medium text-accent-soft-fg hover:bg-accent-soft"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
Neuer Plan
|
||||
@@ -360,43 +319,50 @@ function DashboardHome({
|
||||
}
|
||||
|
||||
function PlanDialog({
|
||||
title,
|
||||
defaultName,
|
||||
onCreate,
|
||||
onClose,
|
||||
}: {
|
||||
title: string;
|
||||
defaultName: string;
|
||||
onCreate: (name: string) => void;
|
||||
onCreate: (name: string, profile: ProfileDraft) => void;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const [name, setName] = useState(defaultName);
|
||||
const [name, setName] = useState("Basisplan");
|
||||
const [draft, setDraft] = useState<ProfileDraft>(emptyProfileDraft);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-40 flex items-center justify-center bg-black/40 px-4" onClick={onClose}>
|
||||
<div className="fixed inset-0 z-40 flex items-start justify-center overflow-y-auto bg-black/40 px-4 py-8" onClick={onClose}>
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="flex w-full max-w-sm flex-col gap-3 rounded-2xl border border-zinc-200 bg-white p-6 shadow-xl dark:border-zinc-700 dark:bg-zinc-900"
|
||||
className="flex w-full max-w-md flex-col gap-4 rounded-2xl border border-border bg-surface p-6 shadow-xl"
|
||||
>
|
||||
<h2 className="text-base font-semibold text-zinc-900 dark:text-zinc-50">{title}</h2>
|
||||
<input
|
||||
autoFocus
|
||||
className="w-full rounded-lg border border-zinc-300 px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-zinc-600 dark:bg-zinc-950"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Name des Plans"
|
||||
/>
|
||||
<h2 className="text-base font-semibold text-fg">Neuen Plan erstellen</h2>
|
||||
<div>
|
||||
<label className="mb-1 block text-xs font-medium text-muted">Name des Plans</label>
|
||||
<input
|
||||
autoFocus
|
||||
className="w-full rounded-lg border border-border bg-input px-3 py-2 text-sm text-fg focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/25"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Name des Plans"
|
||||
/>
|
||||
</div>
|
||||
<PlanProfileFields draft={draft} onChange={setDraft} />
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onCreate(name)}
|
||||
className="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400"
|
||||
disabled={saving}
|
||||
onClick={() => {
|
||||
setSaving(true);
|
||||
onCreate(name.trim() || "Plan", draft);
|
||||
}}
|
||||
className="rounded-lg bg-accent px-4 py-2 text-sm font-medium text-accent-fg shadow-sm hover:bg-accent-hover disabled:opacity-50"
|
||||
>
|
||||
Erstellen
|
||||
{saving ? "..." : "Erstellen"}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className="rounded-lg border border-zinc-300 px-4 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
className="rounded-lg border border-border px-4 py-2 text-sm font-medium text-muted hover:bg-surface-2"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
@@ -421,19 +387,19 @@ function ScenarioDialog({
|
||||
<div className="fixed inset-0 z-40 flex items-center justify-center bg-black/40 px-4" onClick={onClose}>
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="flex w-full max-w-sm flex-col gap-3 rounded-2xl border border-zinc-200 bg-white p-6 shadow-xl dark:border-zinc-700 dark:bg-zinc-900"
|
||||
className="flex w-full max-w-sm flex-col gap-3 rounded-2xl border border-border bg-surface p-6 shadow-xl"
|
||||
>
|
||||
<h2 className="text-base font-semibold text-zinc-900 dark:text-zinc-50">Szenario erstellen</h2>
|
||||
<h2 className="text-base font-semibold text-fg">Szenario erstellen</h2>
|
||||
<input
|
||||
autoFocus
|
||||
className="w-full rounded-lg border border-zinc-300 px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-zinc-600 dark:bg-zinc-950"
|
||||
className="w-full rounded-lg border border-border bg-input px-3 py-2 text-sm text-fg focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/25"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Name des Szenarios"
|
||||
/>
|
||||
<label className="text-xs text-zinc-500">Verzweigen ab Phase</label>
|
||||
<label className="text-xs text-muted">Verzweigen ab Phase</label>
|
||||
<select
|
||||
className="w-full rounded-lg border border-zinc-300 px-3 py-2 text-sm focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-zinc-600 dark:bg-zinc-950"
|
||||
className="w-full rounded-lg border border-border bg-input px-3 py-2 text-sm text-fg focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/25"
|
||||
value={branchFromPhaseId}
|
||||
onChange={(e) => setBranchFromPhaseId(e.target.value)}
|
||||
>
|
||||
@@ -447,14 +413,14 @@ function ScenarioDialog({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onCreate(name, branchFromPhaseId)}
|
||||
className="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400"
|
||||
className="rounded-lg bg-accent px-4 py-2 text-sm font-medium text-accent-fg shadow-sm hover:bg-accent-hover"
|
||||
>
|
||||
Erstellen
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
className="rounded-lg border border-zinc-300 px-4 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
className="rounded-lg border border-border px-4 py-2 text-sm font-medium text-muted hover:bg-surface-2"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user