diff --git a/pflegepilot_v3/frontend/package-lock.json b/pflegepilot_v3/frontend/package-lock.json index ff990f0..f1bdc3e 100644 --- a/pflegepilot_v3/frontend/package-lock.json +++ b/pflegepilot_v3/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.1.0", "dependencies": { + "@tabler/icons-react": "^3.45.0", "@tanstack/react-query": "^5.101.2", "next": "16.2.10", "react": "19.2.4", @@ -1263,6 +1264,32 @@ "tslib": "^2.8.0" } }, + "node_modules/@tabler/icons": { + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.45.0.tgz", + "integrity": "sha512-jiATwV8+zGYLTZ7gMLGivCic+KtsMZXcDmufIG8umlLxoHhI6902hGYIEt0Oa9Y9SXblNzUlrisHm5jOFMxOQA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.45.0.tgz", + "integrity": "sha512-t/AuKs7ALMDDTY+B9IvfZnlO0mbLlP/lJxP/HnGC49QkM8mCsTN38kYyxjXxgrb1+TeK53ioVBJqIV7n/eysXQ==", + "license": "MIT", + "dependencies": { + "@tabler/icons": "3.45.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": ">= 16" + } + }, "node_modules/@tailwindcss/node": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", diff --git a/pflegepilot_v3/frontend/package.json b/pflegepilot_v3/frontend/package.json index d9d2418..c2b28f7 100644 --- a/pflegepilot_v3/frontend/package.json +++ b/pflegepilot_v3/frontend/package.json @@ -9,6 +9,7 @@ "lint": "eslint" }, "dependencies": { + "@tabler/icons-react": "^3.45.0", "@tanstack/react-query": "^5.101.2", "next": "16.2.10", "react": "19.2.4", diff --git a/pflegepilot_v3/frontend/src/app/(app)/admin/einstellungen/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/admin/einstellungen/page.tsx index df848a5..2d8400d 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/admin/einstellungen/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/admin/einstellungen/page.tsx @@ -54,7 +54,7 @@ export default function BackendEinstellungenPage() { if (data) setForm(data); }, [data]); - if (isLoading) return
Lädt…
; + if (isLoading) return
Lädt…
; return (
diff --git a/pflegepilot_v3/frontend/src/app/(app)/admin/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/admin/page.tsx index 2e54549..29dd07f 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/admin/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/admin/page.tsx @@ -59,7 +59,7 @@ export default function AdminPage() { render: (n) => (
{n.name || n.benutzername} - + {n.rolle} {n.ist_demo && " · demo"} @@ -79,7 +79,7 @@ export default function AdminPage() { label: "Aktionen", render: (n) => n.id === eigeneId ? ( - eigenes Konto + eigenes Konto ) : (
{n.aktiv ? ( @@ -163,7 +163,7 @@ export default function AdminPage() {

Konten

{rechnungFehler &&

{rechnungFehler}

} {isLoading ? ( -

Lädt…

+

Lädt…

) : ( n.id} /> )} diff --git a/pflegepilot_v3/frontend/src/app/(app)/aufgaben/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/aufgaben/page.tsx index c452287..5f8e377 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/aufgaben/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/aufgaben/page.tsx @@ -95,7 +95,7 @@ export default function AufgabenPage() { {anlegen.isError &&

{(anlegen.error as Error).message}

} {isLoading ? ( -

Lädt…

+

Lädt…

) : ( a.id} /> )} diff --git a/pflegepilot_v3/frontend/src/app/(app)/changelog/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/changelog/page.tsx index 7f69aa0..03e9675 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/changelog/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/changelog/page.tsx @@ -61,7 +61,7 @@ export default function ChangelogPage() {
-

+

Version {e.version} · {new Date(e.datum).toLocaleDateString("de-DE")}

{e.titel}

diff --git a/pflegepilot_v3/frontend/src/app/(app)/dashboard/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/dashboard/page.tsx index 06485a1..e8ad93d 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/dashboard/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/dashboard/page.tsx @@ -12,7 +12,7 @@ export default function DashboardPage() {

Dashboard

{isLoading || !data ? ( -

Lädt…

+

Lädt…

) : ( @@ -37,14 +37,14 @@ export default function DashboardPage() {

Zuletzt bearbeitete Patienten

{data.letzte_patienten.length === 0 ? ( -

Noch keine Patienten angelegt.

+

Noch keine Patienten angelegt.

) : (
    {data.letzte_patienten.map((p) => (
  • {p.vorname} {p.nachname} - Pflegegrad {p.pflegegrad} + Pflegegrad {p.pflegegrad}
  • ))} diff --git a/pflegepilot_v3/frontend/src/app/(app)/kalender/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/kalender/page.tsx index ad23335..ff44b86 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/kalender/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/kalender/page.tsx @@ -26,7 +26,7 @@ export default function KalenderPage() {

    Kalender & Fristen

    {isLoading ? ( -

    Lädt…

    +

    Lädt…

    ) : ( <> @@ -34,7 +34,7 @@ export default function KalenderPage() { )} -

    heute: {heute}

    +

    heute: {heute}

); } @@ -49,10 +49,10 @@ function Gruppe({ titel, farbe, events }: { titel: string; farbe: string; events
{e.titel} - {TYP_LABEL[e.typ] ?? e.typ} + {TYP_LABEL[e.typ] ?? e.typ}

{e.beschreibung}

-

+

{e.datum} {e.patient_name && `· ${e.patient_name}`}

diff --git a/pflegepilot_v3/frontend/src/app/(app)/katalog/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/katalog/page.tsx index 19e8156..15c4f92 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/katalog/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/katalog/page.tsx @@ -62,7 +62,7 @@ export default function KatalogPage() {
{isLoading ? ( -

Lädt…

+

Lädt…

) : ( <>

{data?.total} Einträge gefunden

@@ -75,7 +75,7 @@ export default function KatalogPage() {

{item.name}

{item.kurz}

-

{item.rechtsgrundlage}

+

{item.rechtsgrundlage}

{item.betrag}

))} diff --git a/pflegepilot_v3/frontend/src/app/(app)/layout.tsx b/pflegepilot_v3/frontend/src/app/(app)/layout.tsx index b5e0ff5..89806c7 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/layout.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/layout.tsx @@ -1,12 +1,75 @@ "use client"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; +import { + IconLayoutDashboard, + IconUsers, + IconBook2, + IconCalculator, + IconScale, + IconMail, + IconChecklist, + IconCalendarEvent, + IconCreditCard, + IconSparkles, + IconSettings, + IconUsersGroup, + IconMenu2, + IconX, + IconLogout, +} from "@tabler/icons-react"; import { useAuth } from "@/lib/auth"; import { AuthOverlay } from "@/components/AuthOverlay"; import { ChangelogModal } from "@/components/ChangelogModal"; +type NavItem = { href: string; label: string; icon: typeof IconUsers }; +type NavSection = { title?: string; items: NavItem[] }; + +const NUTZER_SECTIONS: NavSection[] = [ + { items: [{ href: "/dashboard", label: "Dashboard", icon: IconLayoutDashboard }] }, + { + title: "Patienten", + items: [ + { href: "/patienten", label: "Patienten", icon: IconUsers }, + { href: "/katalog", label: "Katalog", icon: IconBook2 }, + { href: "/rechner", label: "Rechner", icon: IconCalculator }, + ], + }, + { + title: "Recht & Briefe", + items: [ + { href: "/widerspruch", label: "Widerspruch", icon: IconScale }, + { href: "/musterbrief", label: "Musterbrief", icon: IconMail }, + ], + }, + { + title: "Verwaltung", + items: [ + { href: "/aufgaben", label: "Aufgaben", icon: IconChecklist }, + { href: "/kalender", label: "Kalender", icon: IconCalendarEvent }, + ], + }, + { + title: "Konto", + items: [ + { href: "/meinabo", label: "Mein Abo", icon: IconCreditCard }, + { href: "/changelog", label: "Was ist neu?", icon: IconSparkles }, + ], + }, +]; + +const ADMIN_SECTIONS: NavSection[] = [ + { + items: [ + { href: "/admin", label: "Admin-Dashboard", icon: IconUsersGroup }, + { href: "/admin/einstellungen", label: "Einstellungen", icon: IconSettings }, + ], + }, + { title: "Konto", items: [{ href: "/changelog", label: "Was ist neu?", icon: IconSparkles }] }, +]; + const NUTZER_NUR_PFADE = [ "/dashboard", "/patienten", "/katalog", "/rechner", "/widerspruch", "/musterbrief", "/meinabo", "/aufgaben", "/kalender", @@ -17,6 +80,7 @@ export default function AppLayout({ children }: { children: React.ReactNode }) { const me = meQuery.data; const pathname = usePathname(); const router = useRouter(); + const [mobileOpen, setMobileOpen] = useState(false); useEffect(() => { if (!me) return; @@ -28,74 +92,106 @@ export default function AppLayout({ children }: { children: React.ReactNode }) { } }, [me, pathname, router]); + useEffect(() => { + setMobileOpen(false); + }, [pathname]); + if (meQuery.isLoading) { - return
Lädt…
; + return
Lädt…
; } if (!me) { return ; } + const sections = me.rolle === "admin" ? ADMIN_SECTIONS : NUTZER_SECTIONS; + return ( -
-
-
-
{children}
+ + +
+
+ + Pflegepilot +
+ +
{children}
+
{me.changelog_ungesehen.length > 0 && }
diff --git a/pflegepilot_v3/frontend/src/app/(app)/meinabo/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/meinabo/page.tsx index 7b94c63..a982f00 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/meinabo/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/meinabo/page.tsx @@ -17,7 +17,7 @@ export default function MeinAboPage() { }; if (isLoading || !data) { - return
Lädt…
; + return
Lädt…
; } return ( diff --git a/pflegepilot_v3/frontend/src/app/(app)/musterbrief/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/musterbrief/page.tsx index 4119626..e1fbd8c 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/musterbrief/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/musterbrief/page.tsx @@ -202,7 +202,7 @@ export default function MusterbriefPage() {
) : ( -

Noch kein Brief erstellt.

+

Noch kein Brief erstellt.

)}
diff --git a/pflegepilot_v3/frontend/src/app/(app)/patienten/[id]/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/patienten/[id]/page.tsx index 5c409a4..cdd1798 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/patienten/[id]/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/patienten/[id]/page.tsx @@ -27,7 +27,7 @@ export default function PatientDetailPage({ params }: { params: Promise<{ id: st const [tbForm, setTbForm] = useState({ datum: new Date().toISOString().slice(0, 10), allgemein: "" }); if (isLoading || !patient) { - return
Lädt…
; + return
Lädt…
; } const notizSpeichern = (e: React.FormEvent) => { @@ -142,15 +142,15 @@ export default function PatientDetailPage({ params }: { params: Promise<{ id: st
{!antraege || antraege.length === 0 ? ( -

Noch keine Anträge oder Briefe.

+

Noch keine Anträge oder Briefe.

) : ( @@ -261,7 +261,7 @@ export default function PatientDetailPage({ params }: { params: Promise<{ id: st ))} {(!dokumente || dokumente.length === 0) && ( -

Noch keine Dokumente.

+

Noch keine Dokumente.

)} @@ -272,7 +272,7 @@ export default function PatientDetailPage({ params }: { params: Promise<{ id: st function Field({ label, value }: { label: string; value?: string | null }) { return (
-

{label}

+

{label}

{value || "–"}

); diff --git a/pflegepilot_v3/frontend/src/app/(app)/patienten/neu/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/patienten/neu/page.tsx index e7f44a0..e123dbd 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/patienten/neu/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/patienten/neu/page.tsx @@ -189,7 +189,7 @@ export default function NeuerPatientPage() { {state.step === 3 && } {state.step === 4 && (fragenLoading || !fragenData ? ( -

Lädt…

+

Lädt…

) : ( ))} @@ -249,7 +249,7 @@ function StepDots({ current }: { current: number }) { ? "bg-slate-800 text-white" : done ? "bg-emerald-500 text-white" - : "border border-slate-300 text-slate-400" + : "border border-slate-300 text-slate-500" }`} > {done ? "✓" : n} diff --git a/pflegepilot_v3/frontend/src/app/(app)/patienten/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/patienten/page.tsx index 9a54634..84cf38e 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/patienten/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/patienten/page.tsx @@ -71,7 +71,7 @@ export default function PatientenPage() { {isLoading ? ( -

Lädt…

+

Lädt…

) : ( p.id} /> )} diff --git a/pflegepilot_v3/frontend/src/app/(app)/rechner/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/rechner/page.tsx index 24ca600..b395579 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/rechner/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/rechner/page.tsx @@ -87,7 +87,7 @@ export default function RechnerPage() { ))} -

+

{data.relevant_count} passende Leistungen im Katalog gefunden.

diff --git a/pflegepilot_v3/frontend/src/app/(app)/widerspruch/page.tsx b/pflegepilot_v3/frontend/src/app/(app)/widerspruch/page.tsx index b99dd00..d45990f 100644 --- a/pflegepilot_v3/frontend/src/app/(app)/widerspruch/page.tsx +++ b/pflegepilot_v3/frontend/src/app/(app)/widerspruch/page.tsx @@ -255,7 +255,7 @@ export default function WiderspruchPage() { ) : ( -

Noch kein Widerspruch erstellt.

+

Noch kein Widerspruch erstellt.

)} diff --git a/pflegepilot_v3/frontend/src/app/globals.css b/pflegepilot_v3/frontend/src/app/globals.css index 6ba7fc8..891a1ce 100644 --- a/pflegepilot_v3/frontend/src/app/globals.css +++ b/pflegepilot_v3/frontend/src/app/globals.css @@ -1,8 +1,14 @@ @import "tailwindcss"; +/* Bewusst kein prefers-color-scheme-Dark-Mode: keine Komponente in dieser + App ist dark-mode-bewusst (durchgehend hartcodierte helle Tailwind-Klassen + wie bg-white/text-slate-800). Ein automatischer Hell/Dunkel-Wechsel nur + ueber diese zwei CSS-Variablen wuerde helle Schrift auf hellem Hintergrund + erzeugen (kaum lesbar) statt eines echten Dark Mode - die App rendert + deshalb immer hell, bis es einen richtigen Dark Mode gibt. */ :root { - --background: #ffffff; - --foreground: #171717; + --background: #f8fafc; + --foreground: #1e293b; } @theme inline { @@ -12,17 +18,11 @@ --font-mono: var(--font-geist-mono); } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - body { background: var(--background); color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-sans), ui-sans-serif, system-ui, sans-serif; + -webkit-font-smoothing: antialiased; } /* Responsive-Tabelle: normale ab 700px, darunter Akkordeon-Karten. diff --git a/pflegepilot_v3/frontend/src/components/ChangelogModal.tsx b/pflegepilot_v3/frontend/src/components/ChangelogModal.tsx index 200365d..1ac0596 100644 --- a/pflegepilot_v3/frontend/src/components/ChangelogModal.tsx +++ b/pflegepilot_v3/frontend/src/components/ChangelogModal.tsx @@ -16,7 +16,7 @@ export function ChangelogModal({ eintraege }: { eintraege: ChangelogEintrag[] })
{eintraege.map((e) => (
-

+

Version {e.version} · {new Date(e.datum).toLocaleDateString("de-DE")}

{e.titel}

diff --git a/pflegepilot_v3/frontend/src/components/DateWheelPicker.tsx b/pflegepilot_v3/frontend/src/components/DateWheelPicker.tsx index 0a30a56..43b0616 100644 --- a/pflegepilot_v3/frontend/src/components/DateWheelPicker.tsx +++ b/pflegepilot_v3/frontend/src/components/DateWheelPicker.tsx @@ -64,7 +64,7 @@ function WheelColumn({
{item} diff --git a/pflegepilot_v3/frontend/src/components/ResponsiveTable.tsx b/pflegepilot_v3/frontend/src/components/ResponsiveTable.tsx index 9fa05d3..7ce172c 100644 --- a/pflegepilot_v3/frontend/src/components/ResponsiveTable.tsx +++ b/pflegepilot_v3/frontend/src/components/ResponsiveTable.tsx @@ -24,7 +24,7 @@ export function ResponsiveTable({ ); if (rows.length === 0) { - return

Keine Einträge.

; + return

Keine Einträge.

; } return (