diff --git a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png index 3a0601f5..233cd701 100644 Binary files a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png and b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png differ diff --git a/src/app/(protected)/workorders/_components/uplifts/uplift-attachment-picker.tsx b/src/app/(protected)/workorders/_components/uplifts/uplift-attachment-picker.tsx index 48bfe671..bb8d8d57 100644 --- a/src/app/(protected)/workorders/_components/uplifts/uplift-attachment-picker.tsx +++ b/src/app/(protected)/workorders/_components/uplifts/uplift-attachment-picker.tsx @@ -6,8 +6,8 @@ import { Text } from "@/components/ui/text"; const ACCEPTED_TYPES = new Set(["application/pdf", "image/jpeg", "image/jpg", "image/png"]); type UpliftAttachmentPickerProps = { - file: File | null; - onChange: (file: File | null) => void; + files: File[]; + onChange: (files: File[]) => void; }; function isAllowedUpliftEvidenceFile(file: File): boolean { @@ -15,9 +15,9 @@ function isAllowedUpliftEvidenceFile(file: File): boolean { return /\.(pdf|jpe?g|png)$/i.test(file.name); } -function firstAllowedFile(incoming: FileList | null): File | null { - if (!incoming || incoming.length === 0) return null; - return Array.from(incoming).find(isAllowedUpliftEvidenceFile) ?? null; +function allowedFiles(incoming: FileList | null): File[] { + if (!incoming || incoming.length === 0) return []; + return Array.from(incoming).filter(isAllowedUpliftEvidenceFile); } function UpliftStagedFile({ file, onRemove }: { file: File; onRemove: () => void }) { @@ -46,19 +46,20 @@ function UpliftStagedFile({ file, onRemove }: { file: File; onRemove: () => void ); } -export function UpliftAttachmentPicker({ file, onChange }: UpliftAttachmentPickerProps) { +export function UpliftAttachmentPicker({ files, onChange }: UpliftAttachmentPickerProps) { const inputRef = useRef(null); - const stageFile = (incoming: FileList | null) => { - const next = firstAllowedFile(incoming); - if (next) onChange(next); + const stageFiles = (incoming: FileList | null) => { + const next = allowedFiles(incoming); + if (next.length === 0) return; + onChange([...files, ...next]); }; return (
Attachment - Optional — PDF, JPG, or PNG. + Optional — one or more PDF, JPG, or PNG files. { - stageFile(event.target.files); + stageFiles(event.target.files); event.target.value = ""; }} /> - {file != null && ( -
- onChange(null)} /> + {files.length > 0 && ( +
+ {files.map((file, index) => ( + onChange(files.filter((_, itemIndex) => itemIndex !== index))} + /> + ))}
)}
diff --git a/src/app/(protected)/workorders/_components/uplifts/work-order-uplift-create-form.tsx b/src/app/(protected)/workorders/_components/uplifts/work-order-uplift-create-form.tsx index 39995a86..77ae243d 100644 --- a/src/app/(protected)/workorders/_components/uplifts/work-order-uplift-create-form.tsx +++ b/src/app/(protected)/workorders/_components/uplifts/work-order-uplift-create-form.tsx @@ -13,11 +13,7 @@ import { type WorkOrderUpliftCreateFormProps = { pending?: boolean; remainingAllowance: number; - onSubmit: (input: { - amount: number; - notes: string; - file: File | null; - }) => void | Promise; + onSubmit: (input: { amount: number; notes: string; files: File[] }) => void | Promise; }; function canSubmitUplift(amount: number, notes: string): boolean { @@ -64,17 +60,17 @@ export function WorkOrderUpliftCreateForm({ }: WorkOrderUpliftCreateFormProps) { const [amount, setAmount] = useState(""); const [notes, setNotes] = useState(""); - const [file, setFile] = useState(null); + const [files, setFiles] = useState([]); const parsedAmount = Number(amount); const helper = upliftAllowanceHelper(parsedAmount, remainingAllowance); const canSubmit = canSubmitUplift(parsedAmount, notes); const handleSubmit = async () => { try { - await onSubmit({ amount: parsedAmount, notes: notes.trim(), file }); + await onSubmit({ amount: parsedAmount, notes: notes.trim(), files }); setAmount(""); setNotes(""); - setFile(null); + setFiles([]); } catch { // why: the mutation toasts onError, so a failed submit keeps the typed values. } @@ -113,7 +109,7 @@ export function WorkOrderUpliftCreateForm({ />
- +