feat(frontend): PageHeader auf den restlichen Hauptseiten

Inventar, Produkte, Lager, Kalender, Suche und Audit-Log bekommen den
gleichen Gradient-Icon-Header wie die uebrigen Seiten. Lager-Seite hatte
zwei h1-artige Ueberschriften fuer zwei Abschnitte (Lagerbehaelter/
Lagerartikel) auf einer Seite; jetzt ein PageHeader fuer die Seite plus
gleich grosse Unterueberschriften fuer beide Abschnitte statt
uneinheitlicher Groessen.
This commit is contained in:
Nick Szaunig committed 2026-08-23 20:48:03 +02:00
1 parent 805effb60b
commit 6c764bf885
6 files changed
+46 -18

No files matched your search

@@ -4,6 +4,7 @@ import { useMemo, useState } from "react";
import Link from "next/link"; import Link from "next/link";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { import {
CalendarDays,
ChevronLeft, ChevronLeft,
ChevronRight, ChevronRight,
ClipboardCheck, ClipboardCheck,
@@ -18,6 +19,7 @@ import { fetchCalendarEvents } from "@/lib/calendar/api";
import { CalendarEvent, CalendarEventType } from "@/lib/calendar/types"; import { CalendarEvent, CalendarEventType } from "@/lib/calendar/types";
import { fetchApiaries } from "@/lib/apiaries/api"; import { fetchApiaries } from "@/lib/apiaries/api";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/page-header";
import { import {
Select, Select,
SelectContent, SelectContent,
@@ -108,10 +110,12 @@ export default function CalendarPage() {
return ( return (
<main className="flex flex-col gap-4 p-4 sm:p-6"> <main className="flex flex-col gap-4 p-4 sm:p-6">
<div className="flex flex-wrap items-center justify-between gap-3"> <PageHeader
<h1 className="text-2xl font-semibold tracking-tight"> icon={CalendarDays}
{month.toLocaleDateString("de-DE", { month: "long", year: "numeric" })} title={month.toLocaleDateString("de-DE", { month: "long", year: "numeric" })}
</h1> description="Kalender"
gradient="var(--gradient-sky)"
actions={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Select <Select
value={apiaryId || "ALL"} value={apiaryId || "ALL"}
@@ -150,7 +154,8 @@ export default function CalendarPage() {
<ChevronRight className="size-4" /> <ChevronRight className="size-4" />
</Button> </Button>
</div> </div>
</div> }
/>
{isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null} {isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null}
{isError ? ( {isError ? (
@@ -1,11 +1,13 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { Wrench } from "lucide-react";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { fetchEquipmentList } from "@/lib/equipment/api"; import { fetchEquipmentList } from "@/lib/equipment/api";
import { statusTone } from "@/lib/status-tone"; import { statusTone } from "@/lib/status-tone";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/page-header";
import { import {
Table, Table,
TableBody, TableBody,
@@ -23,12 +25,17 @@ export default function EquipmentPage() {
return ( return (
<main className="flex flex-col gap-4 p-4 sm:p-6"> <main className="flex flex-col gap-4 p-4 sm:p-6">
<div className="flex items-center justify-between"> <PageHeader
<h1 className="text-2xl font-semibold tracking-tight">Inventar</h1> icon={Wrench}
title="Inventar"
description="Ausrüstung und Zustand im Blick"
gradient="var(--gradient-sage)"
actions={
<Button nativeButton={false} render={<Link href="/equipment/new" />}> <Button nativeButton={false} render={<Link href="/equipment/new" />}>
+ Neuer Gegenstand + Neuer Gegenstand
</Button> </Button>
</div> }
/>
{isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null} {isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null}
{isError ? ( {isError ? (
@@ -1,10 +1,12 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { ShoppingBag } from "lucide-react";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { fetchProducts } from "@/lib/products/api"; import { fetchProducts } from "@/lib/products/api";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/page-header";
import { import {
Table, Table,
TableBody, TableBody,
@@ -22,12 +24,16 @@ export default function ProductsPage() {
return ( return (
<main className="flex flex-col gap-4 p-4 sm:p-6"> <main className="flex flex-col gap-4 p-4 sm:p-6">
<div className="flex items-center justify-between"> <PageHeader
<h1 className="text-2xl font-semibold tracking-tight">Produkte</h1> icon={ShoppingBag}
title="Produkte"
description="Verkaufsfertige Produkte"
actions={
<Button nativeButton={false} render={<Link href="/products/new" />}> <Button nativeButton={false} render={<Link href="/products/new" />}>
+ Neues Produkt + Neues Produkt
</Button> </Button>
</div> }
/>
{isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null} {isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null}
{isError ? ( {isError ? (
@@ -2,11 +2,13 @@
import { useState } from "react"; import { useState } from "react";
import Link from "next/link"; import Link from "next/link";
import { Search as SearchIcon } from "lucide-react";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { search } from "@/lib/search/api"; import { search } from "@/lib/search/api";
import { SearchResult, SearchResultType } from "@/lib/search/types"; import { SearchResult, SearchResultType } from "@/lib/search/types";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { PageHeader } from "@/components/page-header";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
const TYPE_LABELS: Record<SearchResultType, string> = { const TYPE_LABELS: Record<SearchResultType, string> = {
@@ -43,7 +45,7 @@ export default function SearchPage() {
return ( return (
<main className="flex flex-col gap-4 p-4 sm:p-6"> <main className="flex flex-col gap-4 p-4 sm:p-6">
<h1 className="text-2xl font-semibold tracking-tight">Suche</h1> <PageHeader icon={SearchIcon} title="Suche" description="Alles auf einen Blick finden" />
<Input <Input
className="h-11 max-w-lg" className="h-11 max-w-lg"
placeholder="Bienenstand, Volk, Königin, Aufgabe, Charge…" placeholder="Bienenstand, Volk, Königin, Aufgabe, Charge…"
@@ -1,10 +1,12 @@
"use client"; "use client";
import { useState } from "react"; import { useState } from "react";
import { History } from "lucide-react";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { fetchAuditLog } from "@/lib/audit-log/api"; import { fetchAuditLog } from "@/lib/audit-log/api";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/page-header";
import { import {
Table, Table,
TableBody, TableBody,
@@ -30,7 +32,7 @@ export default function AuditLogPage() {
return ( return (
<main className="flex flex-col gap-4 p-4 sm:p-6"> <main className="flex flex-col gap-4 p-4 sm:p-6">
<h1 className="text-2xl font-semibold tracking-tight">Audit-Log</h1> <PageHeader icon={History} title="Audit-Log" description="Nachvollziehbare Änderungen" gradient="var(--gradient-sage)" />
<form <form
className="flex flex-wrap items-end gap-3" className="flex flex-wrap items-end gap-3"
@@ -1,8 +1,10 @@
"use client"; "use client";
import { Warehouse } from "lucide-react";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { fetchStockItems, fetchStorageContainers } from "@/lib/storage/api"; import { fetchStockItems, fetchStorageContainers } from "@/lib/storage/api";
import { QrCodeDialog } from "@/components/qr-code-dialog"; import { QrCodeDialog } from "@/components/qr-code-dialog";
import { PageHeader } from "@/components/page-header";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { import {
Table, Table,
@@ -29,10 +31,14 @@ export default function StoragePage() {
return ( return (
<main className="flex flex-col gap-8 p-4 sm:p-6"> <main className="flex flex-col gap-8 p-4 sm:p-6">
<section className="flex flex-col gap-4"> <section className="flex flex-col gap-4">
<div className="flex items-center justify-between"> <PageHeader
<h1 className="text-2xl font-semibold tracking-tight">Lagerbehälter</h1> icon={Warehouse}
<CreateStorageContainerDialog /> title="Lager"
</div> description="Lagerbehälter und Lagerartikel"
gradient="var(--gradient-sky)"
actions={<CreateStorageContainerDialog />}
/>
<h2 className="text-lg font-semibold tracking-tight">Lagerbehälter</h2>
{containersLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null} {containersLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null}
{containers ? ( {containers ? (
<Table> <Table>
@@ -68,7 +74,7 @@ export default function StoragePage() {
<section className="flex flex-col gap-4"> <section className="flex flex-col gap-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-2xl font-semibold tracking-tight">Lagerartikel</h2> <h2 className="text-lg font-semibold tracking-tight">Lagerartikel</h2>
<CreateStockItemDialog /> <CreateStockItemDialog />
</div> </div>
{itemsLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null} {itemsLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null}