feat(frontend): Suche und Filter (Modul 14)

/search-Seite über Bienenstände, Völker, Königinnen, Aufgaben und
Honigchargen. Filterleisten (Status/Standort) in den Listen-Views
für Bienenstände, Völker, Königinnen und Honigchargen.
This commit is contained in:
Nick Szaunig committed 2026-08-22 05:39:59 +02:00
1 parent 146b56d683
commit 166979ff3c
21 files changed
+314 -28

No files matched your search

@@ -1,10 +1,20 @@
"use client";
import { useState } from "react";
import Link from "next/link";
import { useQuery } from "@tanstack/react-query";
import { fetchApiaries } from "@/lib/apiaries/api";
import { ApiaryStatus } from "@/lib/apiaries/types";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Table,
TableBody,
@@ -15,9 +25,12 @@ import {
} from "@/components/ui/table";
export default function ApiariesPage() {
const [status, setStatus] = useState<ApiaryStatus | "">("");
const [location, setLocation] = useState("");
const { data: apiaries, isLoading, isError } = useQuery({
queryKey: ["apiaries"],
queryFn: fetchApiaries,
queryKey: ["apiaries", status, location],
queryFn: () => fetchApiaries({ status: status || undefined, location: location || undefined }),
});
return (
@@ -29,6 +42,28 @@ export default function ApiariesPage() {
</Button>
</div>
<div className="flex flex-wrap items-center gap-3">
<Select
value={status || "ALL"}
onValueChange={(value) => setStatus(value === "ALL" ? "" : ((value ?? "") as ApiaryStatus))}
>
<SelectTrigger className="w-40">
<SelectValue placeholder="Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="ALL">Alle Status</SelectItem>
<SelectItem value="ACTIVE">Aktiv</SelectItem>
<SelectItem value="INACTIVE">Inaktiv</SelectItem>
</SelectContent>
</Select>
<Input
className="w-48"
placeholder="Standort"
value={location}
onChange={(event) => setLocation(event.target.value)}
/>
</div>
{isLoading ? <p className="text-sm text-muted-foreground">Lädt…</p> : null}
{isError ? (
<p role="alert" className="text-sm text-red-600">