Bienenstände
+Bienenstände
}> + Neuer Bienenstand @@ -66,7 +66,7 @@ export default function ApiariesPage() { {isLoading ?Lädt…
: null} {isError ? ( -+
Bienenstände konnten nicht geladen werden.
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/colonies/[id]/page.tsx b/ApiCore-Frontend/src/app/(app)/colonies/[id]/page.tsx index 79fd3f2..a517a91 100644 --- a/ApiCore-Frontend/src/app/(app)/colonies/[id]/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/colonies/[id]/page.tsx @@ -23,7 +23,7 @@ export default function ColonyDetailPage() { } if (isError || !colony) { return ( -+
Volk konnte nicht geladen werden.
); diff --git a/ApiCore-Frontend/src/app/(app)/colonies/new/page.tsx b/ApiCore-Frontend/src/app/(app)/colonies/new/page.tsx index 735857c..e7105a2 100644 --- a/ApiCore-Frontend/src/app/(app)/colonies/new/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/colonies/new/page.tsx @@ -114,7 +114,7 @@ export default function NewColonyPage() {+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/colonies/page.tsx b/ApiCore-Frontend/src/app/(app)/colonies/page.tsx index f1d2e59..2f779c2 100644 --- a/ApiCore-Frontend/src/app/(app)/colonies/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/colonies/page.tsx @@ -6,6 +6,7 @@ import { useMutation, useQuery } from "@tanstack/react-query"; import { fetchColonies } from "@/lib/colonies/api"; import { ColonyStatus } from "@/lib/colonies/types"; import { exportColoniesCsv } from "@/lib/export/api"; +import { statusTone } from "@/lib/status-tone"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { @@ -48,7 +49,7 @@ export default function ColoniesPage() { return (Völker
+Völker
+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/harvests/[id]/page.tsx b/ApiCore-Frontend/src/app/(app)/harvests/[id]/page.tsx index a281ce2..0063825 100644 --- a/ApiCore-Frontend/src/app/(app)/harvests/[id]/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/harvests/[id]/page.tsx @@ -19,7 +19,7 @@ export default function HarvestDetailPage() { } if (isError || !harvest) { return ( -+
Ernte konnte nicht geladen werden.
); diff --git a/ApiCore-Frontend/src/app/(app)/harvests/new/page.tsx b/ApiCore-Frontend/src/app/(app)/harvests/new/page.tsx index 1b22be7..f4d2599 100644 --- a/ApiCore-Frontend/src/app/(app)/harvests/new/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/harvests/new/page.tsx @@ -176,7 +176,7 @@ export default function NewHarvestPage() { />+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/add-measurement-dialog.tsx b/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/add-measurement-dialog.tsx index 10d6d3c..d8fd8cc 100644 --- a/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/add-measurement-dialog.tsx +++ b/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/add-measurement-dialog.tsx @@ -94,7 +94,7 @@ export function AddMeasurementDialog({ honeyBatchId }: { honeyBatchId: string }) /> {error ? ( -+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/page.tsx b/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/page.tsx index aa6c9a7..2171026 100644 --- a/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/honey-batches/[id]/page.tsx @@ -29,7 +29,7 @@ export default function HoneyBatchDetailPage() { } if (isError || !honeyBatch) { return ( -+
Honigcharge konnte nicht geladen werden.
); diff --git a/ApiCore-Frontend/src/app/(app)/honey-batches/create-honey-batch-dialog.tsx b/ApiCore-Frontend/src/app/(app)/honey-batches/create-honey-batch-dialog.tsx index 454d0d9..bfdd8a9 100644 --- a/ApiCore-Frontend/src/app/(app)/honey-batches/create-honey-batch-dialog.tsx +++ b/ApiCore-Frontend/src/app/(app)/honey-batches/create-honey-batch-dialog.tsx @@ -122,7 +122,7 @@ export function CreateHoneyBatchDialog() { /> {error ? ( -+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/honey-batches/page.tsx b/ApiCore-Frontend/src/app/(app)/honey-batches/page.tsx index 0670f57..15ebda7 100644 --- a/ApiCore-Frontend/src/app/(app)/honey-batches/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/honey-batches/page.tsx @@ -6,6 +6,7 @@ import { useMutation, useQuery } from "@tanstack/react-query"; import { fetchHoneyBatches } from "@/lib/honey-batches/api"; import { HoneyBatchStatus } from "@/lib/honey-batches/types"; import { exportHoneyBatchesCsv } from "@/lib/export/api"; +import { statusTone } from "@/lib/status-tone"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { @@ -49,7 +50,7 @@ export default function HoneyBatchesPage() { return (Honigchargen
+Honigchargen
+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/layout.tsx b/ApiCore-Frontend/src/app/(app)/layout.tsx index e24c72b..74c0c97 100644 --- a/ApiCore-Frontend/src/app/(app)/layout.tsx +++ b/ApiCore-Frontend/src/app/(app)/layout.tsx @@ -2,14 +2,53 @@ import { ReactNode, useEffect } from "react"; import Link from "next/link"; -import { useRouter } from "next/navigation"; +import { usePathname, useRouter } from "next/navigation"; +import { Hexagon, MoreHorizontal } from "lucide-react"; import { useAuth } from "@/lib/auth/auth-context"; import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { BottomNav } from "./bottom-nav"; import { QuickAddMenu } from "./quick-add-menu"; +const NAV_LINK_CLASS = + "shrink-0 rounded-md px-2.5 py-1.5 text-sm font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground aria-[current=page]:bg-primary/10 aria-[current=page]:text-primary"; + +const PRIMARY_LINKS = [ + { label: "Dashboard", href: "/dashboard" }, + { label: "Bienenstände", href: "/apiaries" }, + { label: "Völker", href: "/colonies" }, + { label: "Königinnen", href: "/queens" }, + { label: "Aufgaben", href: "/tasks" }, + { label: "Honigchargen", href: "/honey-batches" }, + { label: "Lager", href: "/storage" }, + { label: "Suche", href: "/search" }, +]; + +const ADMIN_LINKS = [ + { label: "Benutzer", href: "/settings/users" }, + { label: "Audit-Log", href: "/settings/audit-log" }, +]; + +function NavLink({ href, label, pathname }: { href: string; label: string; pathname: string }) { + return ( + + {label} + + ); +} + export default function AppLayout({ children }: { children: ReactNode }) { const router = useRouter(); + const pathname = usePathname(); const { user, isLoading, logout } = useAuth(); useEffect(() => { @@ -24,53 +63,33 @@ export default function AppLayout({ children }: { children: ReactNode }) { return (+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/storage/page.tsx b/ApiCore-Frontend/src/app/(app)/storage/page.tsx index 2e922e0..10160c7 100644 --- a/ApiCore-Frontend/src/app/(app)/storage/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/storage/page.tsx @@ -29,7 +29,7 @@ export default function StoragePage() {Lagerbehälter
+Lagerbehälter
Lädt…
: null} @@ -63,7 +63,7 @@ export default function StoragePage() {Lagerartikel
+Lagerartikel
Lädt…
: null} diff --git a/ApiCore-Frontend/src/app/(app)/storage/record-movement-dialog.tsx b/ApiCore-Frontend/src/app/(app)/storage/record-movement-dialog.tsx index 2fc18d1..0e27765 100644 --- a/ApiCore-Frontend/src/app/(app)/storage/record-movement-dialog.tsx +++ b/ApiCore-Frontend/src/app/(app)/storage/record-movement-dialog.tsx @@ -94,7 +94,7 @@ export function RecordMovementDialog({ stockItemId }: { stockItemId: string }) { />+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/tasks/new/page.tsx b/ApiCore-Frontend/src/app/(app)/tasks/new/page.tsx index 2af2d19..0ce88dc 100644 --- a/ApiCore-Frontend/src/app/(app)/tasks/new/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/tasks/new/page.tsx @@ -104,7 +104,7 @@ export default function NewTaskPage() { /> {error ? ( -+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/tasks/page.tsx b/ApiCore-Frontend/src/app/(app)/tasks/page.tsx index 8212bbd..fbb5f4b 100644 --- a/ApiCore-Frontend/src/app/(app)/tasks/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/tasks/page.tsx @@ -57,7 +57,7 @@ export default function TasksPage() { return (Aufgaben
+Aufgaben
}> + Neue Aufgabe @@ -110,7 +110,7 @@ export default function TasksPage() { {isLoading ?Lädt…
: null} {isError ? ( -+
Aufgaben konnten nicht geladen werden.
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/treatments/new/page.tsx b/ApiCore-Frontend/src/app/(app)/treatments/new/page.tsx index 059b425..0a4c29a 100644 --- a/ApiCore-Frontend/src/app/(app)/treatments/new/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/treatments/new/page.tsx @@ -153,7 +153,7 @@ export default function NewTreatmentPage() { />+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(app)/varroa/new/page.tsx b/ApiCore-Frontend/src/app/(app)/varroa/new/page.tsx index fb86236..3db9a45 100644 --- a/ApiCore-Frontend/src/app/(app)/varroa/new/page.tsx +++ b/ApiCore-Frontend/src/app/(app)/varroa/new/page.tsx @@ -173,7 +173,7 @@ export default function NewVarroaMeasurementPage() { /> {error ? ( -+
{error}
) : null} diff --git a/ApiCore-Frontend/src/app/(auth)/login/page.tsx b/ApiCore-Frontend/src/app/(auth)/login/page.tsx index a46768b..5d172ce 100644 --- a/ApiCore-Frontend/src/app/(auth)/login/page.tsx +++ b/ApiCore-Frontend/src/app/(auth)/login/page.tsx @@ -2,6 +2,7 @@ import { FormEvent, useState } from "react"; import { useRouter } from "next/navigation"; +import { Hexagon } from "lucide-react"; import { useAuth } from "@/lib/auth/auth-context"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -14,6 +15,33 @@ import { CardTitle, } from "@/components/ui/card"; +function HoneycombBackdrop() { + return ( + + ); +} + export default function LoginPage() { const router = useRouter(); const { login } = useAuth(); @@ -37,11 +65,15 @@ export default function LoginPage() { } return ( -