Files
TREK/client/src/components/Planner/useBookingFileAttach.ts
T
Maurice b06e3e6266 fix(bookings): keep the editor open until a booking's files are uploaded
Saving a booking or a transport closed the editor and reported success
before the travellers and picked files were written. A failed upload left
a booking without some of its PDFs, no list to retry from, and a create
form that would add a duplicate when saved again. On desktop a file picked
on an existing booking went up at once and vanished when that failed.

The planner's save now takes the editor's follow-up as a step it waits
for: it stores the booking, runs the traveller write and the uploads, and
only then says so and closes. Each file that lands leaves the list, so a
failure leaves exactly the files still to send, and the editor keeps the
stored booking so the retry updates it instead of creating another one,
without a second linked cost or stay. All four editors (desktop booking
and transport dialogs, both phone sheets) share this through
useBookingFollowUp, an import review only moves on once an item's files
are up, and desktop files picked on a saved booking wait for Update like
on the phone.

Closes #2883
2026-10-29 14:20:57 +01:00

39 lines
1.6 KiB
TypeScript

import type React from 'react';
import { type Dispatch, type SetStateAction, useState } from 'react';
import type { TripFile } from '../../types';
import { attachedBookingFiles } from './bookingFormModel';
export interface BookingFileAttachOptions {
/** The booking being edited; unset while it is being created. */
reservation: { id: number } | null | undefined;
/** The trip's files. */
files: TripFile[];
setPendingFiles: Dispatch<SetStateAction<File[]>>;
}
/**
* The Files row of the desktop booking and transport dialogs. A picked file waits
* in `pendingFiles` and goes up with the save, on a new booking and a saved one
* alike, as on the phone (#2534): one that fails stays in the list to try again
* instead of vanishing with its toast (#2883). The files linked or detached in the
* dialog show on the booking right away.
*/
export function useBookingFileAttach({ reservation, files, setPendingFiles }: BookingFileAttachOptions) {
const [linkedFileIds, setLinkedFileIds] = useState<number[]>([]);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) setPendingFiles((prev) => [...prev, file]);
e.target.value = '';
};
return {
handleFileChange,
attachedFiles: attachedBookingFiles(files, reservation?.id, linkedFileIds),
removePending: (index: number) => setPendingFiles((prev) => prev.filter((_, j) => j !== index)),
linkFile: (fileId: number) => setLinkedFileIds((prev) => [...prev, fileId]),
detachFile: (fileId: number) => setLinkedFileIds((prev) => prev.filter((id) => id !== fileId)),
};
}