'use client'; import { useEffect, useState } from 'react'; interface FahrkostenRow { ID: number; Kuerzel: string; Name: string; Anzahl: number; } const SATZ = Number(process.env.NEXT_PUBLIC_FAHRKOSTEN_SATZ ?? 15); function defaultAb(): string { const d = new Date(); return `${d.getFullYear()}-01-01`; } export default function Fahrkosten() { const [ab, setAb] = useState(defaultAb); const [rows, setRows] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); useEffect(() => { let cancelled = false; setLoading(true); setError(''); fetch(`/api/fahrkosten?ab=${ab}`) .then((r) => { if (!r.ok) throw new Error(); return r.json(); }) .then((d: FahrkostenRow[]) => { if (!cancelled) { setRows(d); setLoading(false); } }) .catch(() => { if (!cancelled) { setError('Fehler beim Laden.'); setLoading(false); } }); return () => { cancelled = true; }; }, [ab]); const gesamt = rows ? rows.reduce((s, r) => s + r.Anzahl * SATZ, 0) : 0; const thCls = 'px-3 py-2 border border-gray-300 text-xs font-semibold bg-gray-100 text-left whitespace-nowrap text-gray-900'; const thNarrowCls = `${thCls} w-16`; const tdCls = 'px-3 py-2 border border-gray-200 text-sm text-gray-900'; const tdNarrowCls = `${tdCls} w-16`; const tdNumCls = 'px-3 py-2 border border-gray-200 text-sm text-right tabular-nums w-20 text-gray-900'; const abFormatted = new Date(ab + 'T00:00:00').toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', }); return (
setAb(e.target.value)} className="px-2 py-1 border-2 border-gray-400 rounded-lg bg-white text-gray-900 text-sm focus:border-blue-500 focus:outline-none" />
{/* Druckkopf */}
Sternwarte Welzheim — Fahrkostenabrechnung
Führungen ab {abFormatted} · {SATZ} € pro Führung
Ausdruck vom {new Date().toLocaleDateString('de-DE')}
{loading &&
Lade...
} {error &&
{error}
} {!loading && !error && rows && ( <> {rows.length === 0 ? (
Keine Führungen in diesem Zeitraum gefunden.
) : (
{rows.map((r) => ( ))}
Name Kürzel Führungen Fahrkosten
{r.Name} {r.Kuerzel} {r.Anzahl} {(r.Anzahl * SATZ).toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })}
Gesamt {rows.reduce((s, r) => s + r.Anzahl, 0)} {gesamt.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })}
)} )}
); }