"use client"; import { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { api } from "@/lib/api"; import type { CaseReport, DeadlineReport, WorkloadReport, BillingReport, } from "@/lib/types"; import { Breadcrumb } from "@/components/layout/Breadcrumb"; import { Skeleton } from "@/components/ui/Skeleton"; import { AlertTriangle, RefreshCw, Download, Printer, FolderOpen, Clock, Users, Receipt, } from "lucide-react"; import { CasesTab } from "@/components/reports/CasesTab"; import { DeadlinesTab } from "@/components/reports/DeadlinesTab"; import { WorkloadTab } from "@/components/reports/WorkloadTab"; import { BillingTab } from "@/components/reports/BillingTab"; type TabKey = "cases" | "deadlines" | "workload" | "billing"; const TABS: { key: TabKey; label: string; icon: typeof FolderOpen }[] = [ { key: "cases", label: "Akten", icon: FolderOpen }, { key: "deadlines", label: "Fristen", icon: Clock }, { key: "workload", label: "Auslastung", icon: Users }, { key: "billing", label: "Abrechnung", icon: Receipt }, ]; function getDefaultDateRange(): { from: string; to: string } { const now = new Date(); const from = new Date(now.getFullYear() - 1, now.getMonth(), 1); return { from: from.toISOString().split("T")[0], to: now.toISOString().split("T")[0], }; } function ReportSkeleton() { return (
{[1, 2, 3].map((i) => ( ))}
); } export default function BerichtePage() { const [activeTab, setActiveTab] = useState("cases"); const defaults = getDefaultDateRange(); const [from, setFrom] = useState(defaults.from); const [to, setTo] = useState(defaults.to); const queryParams = `?from=${from}&to=${to}`; const casesQuery = useQuery({ queryKey: ["reports", "cases", from, to], queryFn: () => api.get(`/reports/cases${queryParams}`), enabled: activeTab === "cases", }); const deadlinesQuery = useQuery({ queryKey: ["reports", "deadlines", from, to], queryFn: () => api.get(`/reports/deadlines${queryParams}`), enabled: activeTab === "deadlines", }); const workloadQuery = useQuery({ queryKey: ["reports", "workload", from, to], queryFn: () => api.get(`/reports/workload${queryParams}`), enabled: activeTab === "workload", }); const billingQuery = useQuery({ queryKey: ["reports", "billing", from, to], queryFn: () => api.get(`/reports/billing${queryParams}`), enabled: activeTab === "billing", }); const currentQuery = { cases: casesQuery, deadlines: deadlinesQuery, workload: workloadQuery, billing: billingQuery, }[activeTab]; function exportCSV() { if (!currentQuery.data) return; let csv = ""; const data = currentQuery.data; if (activeTab === "cases") { const d = data as CaseReport; csv = "Monat,Eroeffnet,Geschlossen,Aktiv\n"; csv += d.monthly .map((r) => `${r.period},${r.opened},${r.closed},${r.active}`) .join("\n"); } else if (activeTab === "deadlines") { const d = data as DeadlineReport; csv = "Monat,Gesamt,Eingehalten,Versaeumt,Ausstehend,Quote (%)\n"; csv += d.monthly .map( (r) => `${r.period},${r.total},${r.met},${r.missed},${r.pending},${r.compliance_rate.toFixed(1)}`, ) .join("\n"); } else if (activeTab === "workload") { const d = data as WorkloadReport; csv = "Benutzer-ID,Aktive Akten,Fristen,Ueberfaellig,Erledigt\n"; csv += d.users .map( (r) => `${r.user_id},${r.active_cases},${r.deadlines},${r.overdue},${r.completed}`, ) .join("\n"); } else if (activeTab === "billing") { const d = data as BillingReport; csv = "Monat,Aktiv,Geschlossen,Neu\n"; csv += d.monthly .map( (r) => `${r.period},${r.cases_active},${r.cases_closed},${r.cases_new}`, ) .join("\n"); } const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = `bericht-${activeTab}-${from}-${to}.csv`; link.click(); URL.revokeObjectURL(url); } return (

Berichte

Statistiken und Auswertungen

setFrom(e.target.value)} className="rounded-md border border-neutral-200 bg-white px-2.5 py-1.5 text-sm text-neutral-900 outline-none focus:border-neutral-400" /> setTo(e.target.value)} className="rounded-md border border-neutral-200 bg-white px-2.5 py-1.5 text-sm text-neutral-900 outline-none focus:border-neutral-400" />
{/* Tabs */}
{/* Tab content */} {currentQuery.isLoading && } {currentQuery.error && (

Bericht konnte nicht geladen werden

Bitte versuchen Sie es erneut.

)} {!currentQuery.isLoading && !currentQuery.error && currentQuery.data && ( <> {activeTab === "cases" && ( )} {activeTab === "deadlines" && ( )} {activeTab === "workload" && ( )} {activeTab === "billing" && ( )} )}
); }