import Link from "next/link";
import { getFormatter, getTranslations } from "next-intl/server";
import { Pencil, Plus, Trash2, X } from "lucide-react";
import type { Prisma } from "@prisma/client";
import {
addAssessment,
addContract,
addDecision,
addEvidence,
addNda,
approveMaturity,
createGateRisk,
createSupplier,
deleteChild,
deleteSupplier,
updateSupplier,
} from "@/server/actions/suppliers";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Modal } from "@/components/modal";
import { SegmentedRating } from "@/components/segmented-rating";
import { Pill } from "@/components/mockup-ui";
import { SupplierRequirements } from "@/components/supplier-cockpit";
import {
supplierRef,
withQuery,
SUPPLIER_LIFECYCLE_TONE,
protectionLevel,
PROTECTION_LABEL,
buildReqContext,
REQUIREMENTS,
conformity,
computedMaturity,
CONFORMITY_TONE,
CONFORMITY_LABEL,
TARGET_MATURITY,
isExpired,
isExpiring,
} from "@/lib/supplier";
export type SupplierAssetDetail = Prisma.AssetGetPayload<{
include: {
supplierProfile: true;
contracts: true;
ndas: true;
evidence: true;
assessments: true;
subcontractors: true;
decisions: true;
maturity: true;
riskAssets: { include: { risk: { select: { id: true; refNo: true; title: true; score: true } } } };
relationsFrom: { include: { relatedAsset: { select: { name: true; confidentiality: true; integrity: true; availability: true } } } };
relationsTo: { include: { asset: { select: { name: true; confidentiality: true; integrity: true; availability: true } } } };
};
}>;
const inputCls = "h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm";
function contextOf(s: SupplierAssetDetail) {
const linkedAssets = [
{ name: s.name, c: s.confidentiality, i: s.integrity, a: s.availability },
...s.relationsFrom.map((r) => ({ name: r.relatedAsset.name, c: r.relatedAsset.confidentiality, i: r.relatedAsset.integrity, a: r.relatedAsset.availability })),
...s.relationsTo.map((r) => ({ name: r.asset.name, c: r.asset.confidentiality, i: r.asset.integrity, a: r.asset.availability })),
];
const maxCia = Math.max(...linkedAssets.map((a) => Math.max(a.c, a.i, a.a)));
const level = protectionLevel(maxCia);
const ctx = buildReqContext({
contracts: s.contracts,
ndas: s.ndas,
evidence: s.evidence,
assessments: s.assessments,
subcontractors: s.subcontractors,
nextReview: s.supplierProfile?.nextReview ?? null,
linkedRiskCount: s.riskAssets.length,
decisionCount: s.decisions.length,
});
return { linkedAssets: linkedAssets.slice(1), maxCia, level, ctx };
}
/* ─────────────────────── Cockpit (Detail) ─────────────────────── */
export async function SupplierDetailModal({ supplier, canWrite, backHref = "/suppliers" }: { supplier: SupplierAssetDetail; canWrite: boolean; backHref?: string }) {
const t = await getTranslations("suppliers");
const tLife = await getTranslations("supplierStatus");
const tEKind = await getTranslations("evidenceKind");
const tc = await getTranslations("common");
const fmt = await getFormatter();
const date = (d: Date | null) => (d ? fmt.dateTime(d, { dateStyle: "medium" }) : tc("none"));
const p = supplier.supplierProfile!;
const { linkedAssets, maxCia, level, ctx } = contextOf(supplier);
const conf = conformity(level, ctx);
const computed = computedMaturity(level, ctx);
const reqs = REQUIREMENTS.map((r) => ({ key: r.key, label: r.label, control: r.control, tier: r.tier, theme: r.theme, met: r.met(ctx) }));
const editHref = withQuery(backHref, "edit", supplier.id);
const gateEvidenceHref = editHref;
const gateDecisionHref = editHref;
return (
{t("risks")} {tc("none")} {t("contracts")} & {t("ndas")} {t("evidence")} {t("isbApproval")} {t("approvalNote")}
{supplier.riskAssets.map((ra) => (
{supplier.contracts.map((c) => (
{supplier.evidence.map((e) => (
{title}