feat: auto-populate yard and zone from selected warehouse

When warehouse is selected in standalone return modal, yard and zone
fields are automatically populated from warehouse data (yard from
warehouse.yard or warehouse.code, zone from warehouse.zone). Fields are
read-only/disabled to prevent manual editing.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Hagernesh
2026-07-31 06:57:15 +00:00
parent 1bae13aec4
commit 08e0fe2db2
3 changed files with 45 additions and 15 deletions

View File

@@ -1,7 +1,9 @@
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import toast from "react-hot-toast";
import {
ArrowLeft,
FileSignature,
FileText,
FolderOpen,
Layers,
LayoutGrid,
@@ -50,6 +52,7 @@ import {
useBookingMutations,
} from "@/hooks/bookings/useBookings";
import { useScrollToHash } from "@/hooks/useScrollToHash";
import { bookingsService } from "@/services/bookings.service";
export default function BookingRequestDetailPage() {
const { id } = useParams<{ id: string }>();
@@ -269,6 +272,33 @@ export default function BookingRequestDetailPage() {
View / sign contract
</Button>
)}
<Button
fullWidth
variant="default"
leftSection={<FileText size={16} />}
onClick={async () => {
try {
const blob =
await bookingsService.downloadCarriageAcceptanceSheet(
booking.id,
);
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `carriage-acceptance-${booking.reference}.pdf`;
a.click();
URL.revokeObjectURL(url);
} catch (error) {
toast.error(
error instanceof Error
? error.message
: "Carriage acceptance sheet is not available yet",
);
}
}}
>
Carriage acceptance sheet
</Button>
{booking.customsClearingEnabled && (
<Button
fullWidth

View File

@@ -1,4 +1,4 @@
import { Fragment, useMemo, useState } from "react";
import { Fragment, useMemo, useState, useEffect } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
ActionIcon,
@@ -576,7 +576,7 @@ function StandaloneReturnModal({ opened, onClose, onSubmit, loading }: Standalon
const warehouses = (warehousesResponse as any)?.data ?? warehousesResponse ?? [];
const selectedWarehouseData = warehouse && Array.isArray(warehouses) ? warehouses.find((wh: any) => wh.id === warehouse) : null;
React.useEffect(() => {
useEffect(() => {
if (selectedWarehouseData) {
setYard(selectedWarehouseData.yard || selectedWarehouseData.code || "");
setZone(selectedWarehouseData.zone || "");
@@ -585,16 +585,7 @@ function StandaloneReturnModal({ opened, onClose, onSubmit, loading }: Standalon
setZone("");
}
}, [selectedWarehouseData]);
const [handoverNote, setHandoverNote] = useState<string>("");
const { data: warehousesResponse } = useQuery({
queryKey: ["warehouses-list"],
queryFn: async () => {
return await warehouseService.list({});
},
});
const warehouses = (warehousesResponse as any)?.data ?? warehousesResponse ?? [];
const warehouseOptions = Array.isArray(warehouses)
? warehouses.map((wh: any) => ({
value: wh.id,
@@ -663,16 +654,18 @@ function StandaloneReturnModal({ opened, onClose, onSubmit, loading }: Standalon
<TextInput
label="Yard"
placeholder="e.g., Yard A, Main Yard"
placeholder="Auto-populated from warehouse"
value={yard}
onChange={(e) => setYard(e.currentTarget.value)}
disabled
readOnly
/>
<TextInput
label="Zone"
placeholder="e.g., Zone 1, North Zone"
placeholder="Auto-populated from warehouse"
value={zone}
onChange={(e) => setZone(e.currentTarget.value)}
disabled
readOnly
/>
<input

View File

@@ -455,6 +455,13 @@ export const bookingsService = {
return (unwrap(response.data) ?? []) as BookingDetail[];
},
downloadCarriageAcceptanceSheet: async (id: string): Promise<Blob> => {
const response = await client.get(B.CARRIAGE_ACCEPTANCE_SHEET(id), {
responseType: "blob",
});
return ensurePdfBlob(response.data as Blob);
},
getDjClearanceQueue: async (): Promise<BookingDetail[]> => {
const response = await client.get(B.CLEARANCE_DJ_QUEUE);
return (unwrap(response.data) ?? []) as BookingDetail[];