mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 19:58:11 +00:00
138 lines
4.1 KiB
TypeScript
138 lines
4.1 KiB
TypeScript
import { Anchor, Group, Stack, Text } from "@mantine/core";
|
|
import { Paperclip } from "lucide-react";
|
|
|
|
import { SmartFileInput } from "@edr/ui-common";
|
|
import type { IFileUploadSetting } from "@edr/types/freight";
|
|
|
|
import type { LicenseFile } from "@/services/companies.service";
|
|
|
|
const ROLE_LABELS: Record<string, string> = {
|
|
importer: "Importer",
|
|
exporter: "Exporter",
|
|
freight_forwarder: "Freight Forwarder",
|
|
dj_freight_forwarder: "DJ Freight Forwarder",
|
|
transporter: "Transporter",
|
|
};
|
|
|
|
/** Field key the synthesized per-profile upload setting is keyed on. */
|
|
const LICENSE_FILE_KEY = "business_license";
|
|
|
|
/**
|
|
* Build a single-field upload setting so each profile's license input can reuse
|
|
* the shared SmartFileInput (same dropzone + "uploaded" state as the documents
|
|
* step), instead of a bespoke file picker.
|
|
*/
|
|
function buildLicenseSetting(
|
|
profileId: string,
|
|
profileName: string,
|
|
): IFileUploadSetting {
|
|
return {
|
|
id: `license-setting-${profileId}`,
|
|
createdAt: "",
|
|
updatedAt: "",
|
|
deletedAt: null,
|
|
code: "business_license",
|
|
label: "Business license",
|
|
description: null,
|
|
entity: "customer",
|
|
fields: [
|
|
{
|
|
id: `${LICENSE_FILE_KEY}-${profileId}`,
|
|
createdAt: "",
|
|
updatedAt: "",
|
|
deletedAt: null,
|
|
settingId: `license-setting-${profileId}`,
|
|
fileKey: LICENSE_FILE_KEY,
|
|
fileLabel: `Upload ${profileName} Business license file(s)`,
|
|
helpText: null,
|
|
isRequired: true,
|
|
isMultiple: true,
|
|
maxFiles: 10,
|
|
allowedExtensions: ["pdf", "png", "jpg", "jpeg"],
|
|
maxSizeMb: 10,
|
|
order: 1,
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
export interface RoleLicenseProfile {
|
|
id: string;
|
|
type: string;
|
|
reference: string;
|
|
/** License files already uploaded for this profile (rehydration). */
|
|
existingFiles: LicenseFile[];
|
|
}
|
|
|
|
interface RoleLicenseStepProps {
|
|
/** One card per operational role/profile. */
|
|
profiles: RoleLicenseProfile[];
|
|
/** Newly-selected files per profile id (not yet uploaded). */
|
|
value: Record<string, File[]>;
|
|
onChange: (value: Record<string, File[]>) => void;
|
|
}
|
|
|
|
/**
|
|
* Final onboarding step: collect a business license (one or more files) for
|
|
* each operational role the company holds. Each role gets its own SmartFileInput
|
|
* dropzone; already-uploaded files are listed (with download links) for context
|
|
* and surface the input's "uploaded" state.
|
|
*/
|
|
export default function RoleLicenseStep({
|
|
profiles,
|
|
value,
|
|
onChange,
|
|
}: RoleLicenseStepProps) {
|
|
const setFiles = (profileId: string, files: File[]) => {
|
|
onChange({ ...value, [profileId]: files });
|
|
};
|
|
|
|
return (
|
|
<Stack gap="md">
|
|
<Text size="sm" c="edr-muted">
|
|
Upload the business license for each of your operational profiles. You
|
|
can attach more than one document per profile.
|
|
</Text>
|
|
|
|
{profiles.map((profile) => {
|
|
const label = ROLE_LABELS[profile.type] ?? profile.type;
|
|
const selected = value[profile.id] ?? [];
|
|
const hasExisting = profile.existingFiles.length > 0;
|
|
|
|
return (
|
|
<>
|
|
{hasExisting && (
|
|
<Stack gap={4} mb="sm">
|
|
{profile.existingFiles.map((f) => (
|
|
<Group key={f.url} gap={6} wrap="nowrap">
|
|
<Paperclip size={13} className="text-edr-muted" />
|
|
<Anchor
|
|
href={f.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
size="xs"
|
|
>
|
|
{f.name}
|
|
</Anchor>
|
|
</Group>
|
|
))}
|
|
</Stack>
|
|
)}
|
|
|
|
<SmartFileInput
|
|
file={buildLicenseSetting(profile.id, label)}
|
|
value={{ [LICENSE_FILE_KEY]: selected }}
|
|
uploadedKeys={hasExisting ? [LICENSE_FILE_KEY] : undefined}
|
|
onChange={(v) => {
|
|
const next = v[LICENSE_FILE_KEY];
|
|
const files = Array.isArray(next) ? next : next ? [next] : [];
|
|
setFiles(profile.id, files);
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
})}
|
|
</Stack>
|
|
);
|
|
}
|