mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 22:22:08 +00:00
Add the Completion Docs page under Data Management: a searchable template table, a read-only detail panel, add and edit with a live document preview, and delete behind a confirmation that counts the open work orders still using the template and links to them. Add, edit and delete are hidden for users whose role lacks the matching template permission. The preview shares the work-order completion document's page frame, header, safety bullets and procedure heading so the two stay identical.
133 lines
4.4 KiB
TypeScript
133 lines
4.4 KiB
TypeScript
import { FileText } from "lucide-react";
|
|
import { Text } from "@/components/ui/text";
|
|
import { CompDocDocumentFrame } from "@/app/(protected)/workorders/_components/comp-doc/comp-doc-document-frame";
|
|
import { CompDocPreviewHeader } from "@/app/(protected)/workorders/_components/comp-doc/comp-doc-preview-header";
|
|
import { CompDocProcedureHeading } from "@/app/(protected)/workorders/_components/comp-doc/comp-doc-procedure-heading";
|
|
import { CompDocSafetyBullets } from "@/app/(protected)/workorders/_components/comp-doc/comp-doc-safety-bullets";
|
|
import {
|
|
AUTO_POPULATED_FIELDS,
|
|
COMPLETION_TEMPLATE_COPY,
|
|
} from "@/domain/completion-templates/constants/completion-template-constants";
|
|
import type { CompletionTemplateProcedure } from "@/domain/completion-templates/types/completion-template";
|
|
import { descriptionLines } from "@/domain/completion-templates/utils/description-lines";
|
|
|
|
export interface CompletionTemplatePreviewValues {
|
|
name: string;
|
|
extraSafetyNote: string | null;
|
|
procedures: CompletionTemplateProcedure[];
|
|
}
|
|
|
|
type CompletionTemplatePreviewProps = {
|
|
values: CompletionTemplatePreviewValues;
|
|
isEditing: boolean;
|
|
};
|
|
|
|
function PreviewPill({ isEditing }: { isEditing: boolean }) {
|
|
return (
|
|
<div className="flex shrink-0 items-center justify-center" style={{ padding: "12px 0" }}>
|
|
<span
|
|
className="inline-flex items-center gap-1.5"
|
|
style={{
|
|
height: 28,
|
|
padding: "0 12px",
|
|
borderRadius: 9999,
|
|
background: "var(--color-bg-surface)",
|
|
border: "1px solid var(--color-border)",
|
|
fontSize: 12,
|
|
fontWeight: 500,
|
|
color: "var(--muted-foreground)",
|
|
}}
|
|
>
|
|
<FileText size={13} />
|
|
{isEditing ? "Live preview" : "Document preview"}
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PreviewTitle({ name }: { name: string }) {
|
|
const title = name.trim();
|
|
return (
|
|
<>
|
|
<Text
|
|
as="h2"
|
|
variant="title"
|
|
family="body"
|
|
sx={{
|
|
fontSize: 13,
|
|
fontWeight: 700,
|
|
letterSpacing: "0.02em",
|
|
color: title ? "#161E38" : "#9CA3AF",
|
|
margin: "16px 0 4px",
|
|
}}
|
|
>
|
|
{title ? title.toUpperCase() : COMPLETION_TEMPLATE_COPY.untitledDocument}
|
|
</Text>
|
|
<Text variant="body" sx={{ fontSize: 12, color: "#58595B", margin: "2px 0 12px" }}>
|
|
{AUTO_POPULATED_FIELDS.join(" · ")} {COMPLETION_TEMPLATE_COPY.autoFilledSuffix}
|
|
</Text>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function PreviewProcedures({ procedures }: { procedures: CompletionTemplateProcedure[] }) {
|
|
if (procedures.length === 0) {
|
|
return (
|
|
<Text
|
|
variant="body"
|
|
sx={{ fontSize: 12.5, color: "#9CA3AF", margin: "16px 0 0", fontStyle: "italic" }}
|
|
>
|
|
{COMPLETION_TEMPLATE_COPY.noProcedurePreview}
|
|
</Text>
|
|
);
|
|
}
|
|
return (
|
|
<>
|
|
{procedures.map((procedure, index) => (
|
|
<section key={index} aria-label={`Preview procedure ${index + 1}`}>
|
|
<CompDocProcedureHeading>
|
|
{procedure.name.trim() || `Procedure ${index + 1}`}
|
|
</CompDocProcedureHeading>
|
|
{descriptionLines(procedure.description).map((line, lineIndex) => (
|
|
<Text
|
|
key={lineIndex}
|
|
variant="body"
|
|
sx={{ fontSize: 13, lineHeight: 1.5, color: "#161E38", margin: "4px 0" }}
|
|
>
|
|
{line}
|
|
</Text>
|
|
))}
|
|
</section>
|
|
))}
|
|
</>
|
|
);
|
|
}
|
|
|
|
/** The template rendered on the same page, header and safety bullets as a work order's document. */
|
|
export function CompletionTemplatePreview({ values, isEditing }: CompletionTemplatePreviewProps) {
|
|
const note = values.extraSafetyNote?.trim() ?? "";
|
|
return (
|
|
<div
|
|
className="flex min-h-0 flex-col"
|
|
style={{
|
|
width: "58%",
|
|
borderRight: "1px solid var(--color-border)",
|
|
background: "var(--color-bg-muted)",
|
|
}}
|
|
>
|
|
<PreviewPill isEditing={isEditing} />
|
|
<div
|
|
className="min-h-0 flex-1 overflow-x-hidden overflow-y-auto"
|
|
style={{ padding: "0 20px 20px" }}
|
|
data-testid="completion-template-preview"
|
|
>
|
|
<CompDocDocumentFrame>
|
|
<CompDocPreviewHeader />
|
|
<PreviewTitle name={values.name} />
|
|
<CompDocSafetyBullets extra={note === "" ? [] : [note]} />
|
|
<PreviewProcedures procedures={values.procedures} />
|
|
</CompDocDocumentFrame>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|