mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 08:48:11 +00:00
153 lines
5.0 KiB
TypeScript
153 lines
5.0 KiB
TypeScript
import { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import {
|
|
Badge,
|
|
Button,
|
|
Card,
|
|
Center,
|
|
Group,
|
|
Loader,
|
|
SimpleGrid,
|
|
Stack,
|
|
Text,
|
|
ThemeIcon,
|
|
} from "@mantine/core";
|
|
import { Boxes, Container, Eye, FileSignature, Pencil } from "lucide-react";
|
|
|
|
import { PageContainer, PageHeader } from "@/components/page";
|
|
import { useContractTemplates } from "@/hooks/contract-templates/useContractTemplates";
|
|
import type { ContractTemplate } from "@/services/contract-templates.service";
|
|
import TemplatePreviewModal from "./TemplatePreviewModal";
|
|
|
|
const DIRECTION_LABEL: Record<string, string> = {
|
|
IMPORT: "Import",
|
|
EXPORT: "Export",
|
|
INTERCITY: "Intercity",
|
|
};
|
|
|
|
const DIRECTION_COLOR: Record<string, string> = {
|
|
IMPORT: "edr-green",
|
|
EXPORT: "teal",
|
|
INTERCITY: "lime",
|
|
};
|
|
|
|
function templateDirection(code: ContractTemplate["code"]): string {
|
|
return code.split("_")[0];
|
|
}
|
|
|
|
function isBulk(code: ContractTemplate["code"]): boolean {
|
|
return code.endsWith("_BULK");
|
|
}
|
|
|
|
export default function ContractTemplatesPage() {
|
|
const navigate = useNavigate();
|
|
const { data: templates, isLoading } = useContractTemplates();
|
|
const [previewCode, setPreviewCode] = useState<string | null>(null);
|
|
|
|
const previewTemplate = templates?.find((t) => t.code === previewCode);
|
|
|
|
return (
|
|
<PageContainer>
|
|
<PageHeader
|
|
title="Contract templates"
|
|
subtitle="The six contract documents generated when a contract is approved — one per trade direction and freight type. Articles are fully editable."
|
|
/>
|
|
|
|
{isLoading ? (
|
|
<Center h={320}>
|
|
<Loader color="edr-green" />
|
|
</Center>
|
|
) : (
|
|
<SimpleGrid cols={{ base: 1, md: 2, xl: 3 }} spacing="lg">
|
|
{(templates ?? []).map((template) => {
|
|
const direction = templateDirection(template.code);
|
|
return (
|
|
<Card key={template.code} withBorder radius="xl" padding="lg">
|
|
<Stack gap="sm" h="100%">
|
|
<Group justify="space-between" align="flex-start">
|
|
<ThemeIcon
|
|
size={44}
|
|
radius="md"
|
|
variant="light"
|
|
color="edr-green"
|
|
>
|
|
{isBulk(template.code) ? (
|
|
<Boxes size={24} />
|
|
) : (
|
|
<Container size={24} />
|
|
)}
|
|
</ThemeIcon>
|
|
<Group gap={6}>
|
|
<Badge
|
|
variant="light"
|
|
color={DIRECTION_COLOR[direction] ?? "edr-green"}
|
|
>
|
|
{DIRECTION_LABEL[direction] ?? direction}
|
|
</Badge>
|
|
<Badge variant="outline" color="gray">
|
|
{isBulk(template.code) ? "Bulk" : "Container"}
|
|
</Badge>
|
|
{!template.isActive && (
|
|
<Badge variant="light" color="red">
|
|
Inactive
|
|
</Badge>
|
|
)}
|
|
</Group>
|
|
</Group>
|
|
|
|
<div>
|
|
<Text fw={700} size="lg">
|
|
{template.name}
|
|
</Text>
|
|
<Text size="sm" c="dimmed" lineClamp={3}>
|
|
{template.description || template.documentTitle}
|
|
</Text>
|
|
</div>
|
|
|
|
<Group gap="xs" mt="auto">
|
|
<FileSignature size={14} className="text-edr-primary" />
|
|
<Text size="xs" c="dimmed">
|
|
{template.articles.length} articles · updated{" "}
|
|
{new Date(template.updatedAt).toLocaleDateString("en-GB", {
|
|
day: "numeric",
|
|
month: "short",
|
|
year: "numeric",
|
|
})}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Group grow>
|
|
<Button
|
|
variant="light"
|
|
color="edr-green"
|
|
leftSection={<Eye size={16} />}
|
|
onClick={() => setPreviewCode(template.code)}
|
|
>
|
|
Preview
|
|
</Button>
|
|
<Button
|
|
color="edr-green"
|
|
leftSection={<Pencil size={16} />}
|
|
onClick={() =>
|
|
navigate(`/dashboard/contract-templates/${template.code}`)
|
|
}
|
|
>
|
|
Edit articles
|
|
</Button>
|
|
</Group>
|
|
</Stack>
|
|
</Card>
|
|
);
|
|
})}
|
|
</SimpleGrid>
|
|
)}
|
|
|
|
<TemplatePreviewModal
|
|
code={previewCode}
|
|
title={previewTemplate ? `${previewTemplate.name} — preview` : undefined}
|
|
onClose={() => setPreviewCode(null)}
|
|
/>
|
|
</PageContainer>
|
|
);
|
|
}
|