Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import Link from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
import { Download, ListChecks } from "lucide-react";
|
||||
import { requireSession } from "@/server/auth";
|
||||
import { dbForTenant } from "@/server/db";
|
||||
import { PageHead, Pill } from "@/components/mockup-ui";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { buildAbgabeRows } from "@/server/export-context";
|
||||
import { PRUEFZIEL_LABEL } from "@/lib/export/vda-isa";
|
||||
|
||||
/**
|
||||
* ABGABE-Vorschau (VDA-ISA-Prüfungsdokumentation) — Seite des Audit-Wizards.
|
||||
* Zeigt je Control den zusammengesetzten „Beschreibung der Umsetzung"-Text
|
||||
* (übernommene ControlDescription je Anforderung), den bestätigten Reifegrad
|
||||
* und die Referenz-Dokumentation. Download über die geteilte Export-Route als CSV
|
||||
* (`?format=abgabe`) oder als echte xlsx (`?format=abgabe-xlsx`).
|
||||
*/
|
||||
export default async function AbgabePreviewPage({ params }: { params: Promise<{ auditId: string }> }) {
|
||||
const session = await requireSession();
|
||||
const { auditId } = await params;
|
||||
const db = dbForTenant(session.user.tenantId);
|
||||
|
||||
const audit = await db.audit.findFirst({ where: { id: auditId } });
|
||||
if (!audit) notFound();
|
||||
|
||||
const rows = await buildAbgabeRows(db, session.user.tenantId);
|
||||
const withText = rows.filter((r) => r.umsetzung).length;
|
||||
|
||||
return (
|
||||
<main className="flex-1 p-6">
|
||||
<PageHead
|
||||
crumb={`Audit · ${audit.title}`}
|
||||
title="ABGABE-Vorschau (VDA ISA)"
|
||||
sub={`${withText} von ${rows.length} Controls mit übernommener Umsetzungsbeschreibung.`}
|
||||
actions={
|
||||
<>
|
||||
<Button variant="outline" size="sm" nativeButton={false} render={<Link href={`/audit-readiness/${auditId}/controls`} />}>
|
||||
<ListChecks className="size-3.5" /> Zu den Beschreibungen
|
||||
</Button>
|
||||
{/* Datei-Download über einen Route-Handler (kein Page-Route) — bewusst `<a>`, nicht `<Link>`. */}
|
||||
{/* eslint-disable-next-line @next/next/no-html-link-for-pages */}
|
||||
<Button variant="outline" size="sm" nativeButton={false} render={<a href="/audit-readiness/export?format=abgabe" />}>
|
||||
<Download className="size-3.5" /> ABGABE (CSV)
|
||||
</Button>
|
||||
{/* eslint-disable-next-line @next/next/no-html-link-for-pages */}
|
||||
<Button variant="outline" size="sm" nativeButton={false} render={<a href="/audit-readiness/export?format=abgabe-xlsx" />}>
|
||||
<Download className="size-3.5" /> ABGABE (xlsx)
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
{rows.length === 0 ? (
|
||||
<p className="text-[12.5px] text-muted-foreground">Keine Controls vorhanden.</p>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{rows.map((r) => (
|
||||
<section key={r.control} className="shadow-card rounded-xl border bg-card p-4">
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
<h2 className="font-heading text-sm font-semibold">{r.control} · {r.frage}</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
<Pill tone="info">{PRUEFZIEL_LABEL[r.pruefziel]}</Pill>
|
||||
<Pill tone={r.reifegrad === null ? "mut" : "ok"}>
|
||||
Reifegrad {r.reifegrad ?? "—"}{r.zielReifegrad !== null ? ` / Ziel ${r.zielReifegrad}` : ""}
|
||||
</Pill>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{r.umsetzung ? (
|
||||
<p className="mt-2 text-[12.5px] whitespace-pre-wrap">{r.umsetzung}</p>
|
||||
) : (
|
||||
<p className="mt-2 text-[12px] text-muted-foreground">Noch keine übernommene Beschreibung — im Beschreibungs-Schritt erzeugen und übernehmen.</p>
|
||||
)}
|
||||
|
||||
{r.referenzen && (
|
||||
<p className="mt-2 border-t pt-2 text-[11.5px] text-muted-foreground">
|
||||
<span className="font-semibold">Referenz Dokumentation:</span> {r.referenzen}
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="mt-4 text-[11.5px] text-muted-foreground">
|
||||
Download als CSV (DE-Excel, semikolongetrennt) oder als xlsx im VDA-ISA-ABGABE-Layout.
|
||||
</p>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user