mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 08:32:54 +00:00
107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
import { useState } from "react";
|
|
import { Button, Paper, Stack, Text } from "@mantine/core";
|
|
import { Upload } from "lucide-react";
|
|
|
|
import { PhasedMultiFileDropzone } from "@/components/contracts/PhasedFileDropzone";
|
|
import { PhasedUploadedFileRow } from "@/components/contracts/PhasedUploadedFileRow";
|
|
|
|
export type TransitPermitUploadedRow = {
|
|
code: string;
|
|
label: string;
|
|
file: { id: string; name: string };
|
|
};
|
|
|
|
export interface TransitPermitMultiUploadProps {
|
|
title?: string;
|
|
uploaded?: TransitPermitUploadedRow[];
|
|
replaceMode?: boolean;
|
|
submitLabel?: string;
|
|
fileFieldPrefix: string;
|
|
disabled?: boolean;
|
|
onSubmit: (files: Record<string, File>) => Promise<void>;
|
|
onViewFile?: (file: { name: string; url: string }) => void;
|
|
onDownloadFile?: (file: { id: string; name: string }) => void;
|
|
}
|
|
|
|
/** Multi-file transit permit upload — import pre-booking and export post-booking. */
|
|
export function TransitPermitMultiUpload({
|
|
title = "Transit Permit",
|
|
uploaded = [],
|
|
replaceMode = false,
|
|
submitLabel,
|
|
fileFieldPrefix,
|
|
disabled = false,
|
|
onSubmit,
|
|
onViewFile,
|
|
onDownloadFile,
|
|
}: TransitPermitMultiUploadProps) {
|
|
const [files, setFiles] = useState<File[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const label = submitLabel ?? (replaceMode ? "Replace transit permit" : "Upload transit permit");
|
|
|
|
return (
|
|
<Stack gap="md">
|
|
<Text size="sm" fw={700}>
|
|
{title}
|
|
</Text>
|
|
|
|
{uploaded.length > 0 ? (
|
|
<Stack gap={8}>
|
|
<Text size="xs" fw={700} c="dimmed" tt="uppercase">
|
|
Current file{uploaded.length > 1 ? "s" : ""}
|
|
</Text>
|
|
{uploaded.map((row) => (
|
|
<PhasedUploadedFileRow
|
|
key={row.code}
|
|
label={row.label}
|
|
file={row.file}
|
|
onView={onViewFile}
|
|
onDownload={onDownloadFile}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
) : null}
|
|
|
|
<Paper withBorder radius="md" p="md" bg="var(--mantine-color-gray-0)">
|
|
<PhasedMultiFileDropzone
|
|
label="Transit permit documents"
|
|
description={
|
|
replaceMode
|
|
? "Replace transit permit files — upload one or more documents (PDF or image)."
|
|
: "Upload one or more transit permit documents (PDF or image)."
|
|
}
|
|
value={files}
|
|
onChange={setFiles}
|
|
replaceMode={replaceMode}
|
|
disabled={disabled || loading}
|
|
/>
|
|
</Paper>
|
|
|
|
<Button
|
|
color="edr-green"
|
|
loading={loading}
|
|
disabled={disabled || files.length === 0}
|
|
leftSection={<Upload size={16} />}
|
|
fullWidth
|
|
onClick={async () => {
|
|
setLoading(true);
|
|
try {
|
|
const payload = Object.fromEntries(
|
|
files.map((file, index) => [`${fileFieldPrefix}_${index}`, file]),
|
|
) as Record<string, File>;
|
|
await onSubmit(payload);
|
|
setFiles([]);
|
|
} catch {
|
|
// Caller shows toast for upload errors.
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}}
|
|
>
|
|
{label}
|
|
</Button>
|
|
</Stack>
|
|
);
|
|
}
|