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