Schnellerfassung im Alarmfall, sechs Zeitstempel mit Ausrueckzeit, Anfahrt und Hilfsfrist, Staerke nach FwDV 3, Personalvorschlag mit Qualifikationsstand, Einsatzbericht als PDF, Jahresexport fuer die Gemeinde, Statistik und Uebungen mit Anwesenheitsliste. Dazu das Einsatzportal fuer Fremdwehren: ein signierter Link ohne Anmeldung, zeitlich und mengenbegrenzt, der Stichwort, Ort, Zeiten und Lagemeldungen zeigt und Meldungen mit Foto annimmt. Es sind die ersten oeffentlich erreichbaren Endpunkte in FLORIAN. Acht neue Tabellen, alle mit organisationId und Row Level Security. Ein freigegebener Einsatzbericht ist unveraenderlich; ein Datenbanktrigger setzt das durch. Koordinaten liegen doppelt — als Dezimalgrad und als PostGIS-Punkt, zusammengehalten von einem Trigger. 57 neue Tests (32 Unit, 14 gegen eine echte Datenbank, 11 E2E). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
33 lines
1022 B
TypeScript
33 lines
1022 B
TypeScript
import { redirect } from "next/navigation";
|
|
import Link from "next/link";
|
|
import { ArrowLeft } from "lucide-react";
|
|
import { aktuelleSitzung } from "@/lib/auth";
|
|
import { hatRecht } from "@/lib/authz";
|
|
import { Button } from "@/components/ui/button";
|
|
import { UebungDetail } from "@/app/(app)/uebungen/[id]/uebung-detail";
|
|
|
|
export const metadata = { title: "Übung" };
|
|
|
|
/** Eine Übung mit Anwesenheitsliste. */
|
|
export default async function UebungSeite({ params }: { params: Promise<{ id: string }> }) {
|
|
const sitzung = await aktuelleSitzung();
|
|
if (!sitzung) redirect("/anmelden");
|
|
|
|
const { id } = await params;
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<Button variant="ghost" size="sm" asChild className="-ml-2 mb-1">
|
|
<Link href="/uebungen">
|
|
<ArrowLeft aria-hidden />
|
|
Zurück zu den Übungen
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
|
|
<UebungDetail uebungId={id} darfBearbeiten={hatRecht(sitzung, "ausbildung.bearbeiten")} />
|
|
</div>
|
|
);
|
|
}
|