Visual redesign: indigo accent palette, lucide icons per section, lighter/softer cards and dark mode
Deploy App / deploy (push) Successful in 2m59s
Deploy App / deploy (push) Successful in 2m59s
This commit is contained in:
+30
-23
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { LogOut, PiggyBank, Plus, Settings, X } from "lucide-react";
|
||||
import { PhaseCard } from "@/components/PhaseCard";
|
||||
import { TransitionPanel } from "@/components/TransitionPanel";
|
||||
import { Dashboard } from "@/components/Dashboard";
|
||||
@@ -91,15 +92,17 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
return (
|
||||
<div className="mx-auto flex w-full max-w-5xl flex-1 flex-col gap-6 px-4 py-8">
|
||||
<header className="flex items-center justify-between">
|
||||
<h1 className="text-xl font-semibold text-zinc-900 dark:text-zinc-50">
|
||||
<h1 className="flex items-center gap-2 text-xl font-semibold text-zinc-900 dark:text-zinc-50">
|
||||
<PiggyBank className="h-6 w-6 text-indigo-600 dark:text-indigo-400" />
|
||||
Financial Planning Tool
|
||||
</h1>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowSettings((v) => !v)}
|
||||
className="rounded-md border border-zinc-300 px-3 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
className="flex items-center gap-1.5 rounded-lg border border-zinc-300 bg-white px-3 py-1.5 text-xs font-medium text-zinc-700 shadow-sm hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700"
|
||||
>
|
||||
<Settings className="h-3.5 w-3.5" />
|
||||
Grundprofil
|
||||
</button>
|
||||
<button
|
||||
@@ -108,8 +111,9 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
await api.post("/api/auth/logout");
|
||||
window.location.href = "/login";
|
||||
}}
|
||||
className="rounded-md border border-zinc-300 px-3 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
className="flex items-center gap-1.5 rounded-lg border border-zinc-300 bg-white px-3 py-1.5 text-xs font-medium text-zinc-700 shadow-sm hover:bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700"
|
||||
>
|
||||
<LogOut className="h-3.5 w-3.5" />
|
||||
Abmelden
|
||||
</button>
|
||||
</div>
|
||||
@@ -124,15 +128,15 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
)}
|
||||
|
||||
{/* Tab-Leiste */}
|
||||
<div className="flex flex-wrap items-center gap-2 border-b border-zinc-200 pb-2 dark:border-zinc-700">
|
||||
<div className="flex flex-wrap items-center gap-2 border-b border-zinc-200 pb-2 dark:border-zinc-800">
|
||||
{plans.map((p) => (
|
||||
<div key={p.id} className="flex items-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSelectedPlanId(p.id)}
|
||||
className={`rounded-t-md px-3 py-1.5 text-sm font-medium ${
|
||||
className={`rounded-t-lg px-3 py-1.5 text-sm font-medium transition-colors ${
|
||||
selectedPlanId === p.id
|
||||
? "bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900"
|
||||
? "bg-indigo-600 text-white shadow-sm dark:bg-indigo-500"
|
||||
: "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
}`}
|
||||
>
|
||||
@@ -142,10 +146,10 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleDeletePlan(p.id)}
|
||||
className="ml-1 text-xs text-zinc-400 hover:text-red-600"
|
||||
className="ml-1 text-zinc-400 hover:text-red-600"
|
||||
aria-label="Plan loeschen"
|
||||
>
|
||||
✕
|
||||
<X className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -154,9 +158,10 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowNewPlan((v) => !v)}
|
||||
className="rounded-md px-2 py-1.5 text-sm text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
||||
className="flex items-center gap-1 rounded-lg px-2 py-1.5 text-sm text-indigo-600 hover:bg-indigo-50 dark:text-indigo-400 dark:hover:bg-indigo-500/10"
|
||||
>
|
||||
+ Plan
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
Plan
|
||||
</button>
|
||||
{showNewPlan && (
|
||||
<NewPlanPopover
|
||||
@@ -174,9 +179,10 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowScenario((v) => !v)}
|
||||
className="rounded-md px-2 py-1.5 text-sm text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
||||
className="flex items-center gap-1 rounded-lg px-2 py-1.5 text-sm text-indigo-600 hover:bg-indigo-50 dark:text-indigo-400 dark:hover:bg-indigo-500/10"
|
||||
>
|
||||
+ Szenario
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
Szenario
|
||||
</button>
|
||||
{showScenario && (
|
||||
<ScenarioPopover
|
||||
@@ -235,9 +241,10 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleAddPhase}
|
||||
className="self-start rounded-md border border-zinc-300 px-3 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
className="flex items-center gap-1.5 self-start rounded-lg border border-dashed border-indigo-300 bg-indigo-50/50 px-3 py-2 text-sm font-medium text-indigo-700 hover:bg-indigo-50 dark:border-indigo-500/30 dark:bg-indigo-500/10 dark:text-indigo-300 dark:hover:bg-indigo-500/20"
|
||||
>
|
||||
+ Phase hinzufuegen
|
||||
<Plus className="h-4 w-4" />
|
||||
Phase hinzufuegen
|
||||
</button>
|
||||
|
||||
{detail.plan.phases.length > 0 && (
|
||||
@@ -252,9 +259,9 @@ export function AppShell({ initialHousehold }: { initialHousehold: HouseholdInpu
|
||||
function NewPlanPopover({ onCreate, onClose }: { onCreate: (name: string) => void; onClose: () => void }) {
|
||||
const [name, setName] = useState("Basisplan");
|
||||
return (
|
||||
<div className="absolute left-0 top-10 z-10 w-64 rounded-md border border-zinc-200 bg-white p-3 shadow-lg dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div className="absolute left-0 top-10 z-10 w-64 rounded-lg border border-zinc-200 bg-white p-3 shadow-lg dark:border-zinc-700 dark:bg-zinc-800">
|
||||
<input
|
||||
className="mb-2 w-full rounded-md border border-zinc-300 px-2 py-1 text-sm dark:border-zinc-600 dark:bg-zinc-800"
|
||||
className="mb-2 w-full rounded-lg border border-zinc-300 px-2 py-1 text-sm focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-zinc-600 dark:bg-zinc-900"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Name des Plans"
|
||||
@@ -263,11 +270,11 @@ function NewPlanPopover({ onCreate, onClose }: { onCreate: (name: string) => voi
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onCreate(name)}
|
||||
className="rounded-md bg-zinc-900 px-2 py-1 text-xs text-white dark:bg-zinc-100 dark:text-zinc-900"
|
||||
className="rounded-lg bg-indigo-600 px-2 py-1 text-xs font-medium text-white hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400"
|
||||
>
|
||||
Erstellen
|
||||
</button>
|
||||
<button type="button" onClick={onClose} className="text-xs text-zinc-500">
|
||||
<button type="button" onClick={onClose} className="text-xs text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300">
|
||||
Abbrechen
|
||||
</button>
|
||||
</div>
|
||||
@@ -287,16 +294,16 @@ function ScenarioPopover({
|
||||
const [name, setName] = useState("Neues Szenario");
|
||||
const [branchFromPhaseId, setBranchFromPhaseId] = useState(phases[phases.length - 1]?.id ?? "");
|
||||
return (
|
||||
<div className="absolute left-0 top-10 z-10 w-72 rounded-md border border-zinc-200 bg-white p-3 shadow-lg dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div className="absolute left-0 top-10 z-10 w-72 rounded-lg border border-zinc-200 bg-white p-3 shadow-lg dark:border-zinc-700 dark:bg-zinc-800">
|
||||
<input
|
||||
className="mb-2 w-full rounded-md border border-zinc-300 px-2 py-1 text-sm dark:border-zinc-600 dark:bg-zinc-800"
|
||||
className="mb-2 w-full rounded-lg border border-zinc-300 px-2 py-1 text-sm focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-zinc-600 dark:bg-zinc-900"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Name des Szenarios"
|
||||
/>
|
||||
<label className="mb-1 block text-xs text-zinc-500">Verzweigen ab Phase</label>
|
||||
<select
|
||||
className="mb-2 w-full rounded-md border border-zinc-300 px-2 py-1 text-sm dark:border-zinc-600 dark:bg-zinc-800"
|
||||
className="mb-2 w-full rounded-lg border border-zinc-300 px-2 py-1 text-sm focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:border-zinc-600 dark:bg-zinc-900"
|
||||
value={branchFromPhaseId}
|
||||
onChange={(e) => setBranchFromPhaseId(e.target.value)}
|
||||
>
|
||||
@@ -310,11 +317,11 @@ function ScenarioPopover({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onCreate(name, branchFromPhaseId)}
|
||||
className="rounded-md bg-zinc-900 px-2 py-1 text-xs text-white dark:bg-zinc-100 dark:text-zinc-900"
|
||||
className="rounded-lg bg-indigo-600 px-2 py-1 text-xs font-medium text-white hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400"
|
||||
>
|
||||
Erstellen
|
||||
</button>
|
||||
<button type="button" onClick={onClose} className="text-xs text-zinc-500">
|
||||
<button type="button" onClick={onClose} className="text-xs text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300">
|
||||
Abbrechen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user