From 240fb505ec8f4d36c14239fdb28a47ddea02d83c Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Thu, 28 May 2026 16:27:22 +0300 Subject: [PATCH] refactor(bookings): Streamline new booking process, integrate useAuth for customer data, and simplify API payloads --- .../portal/src/pages/bookings/MyBookings.tsx | 3 --- .../src/pages/bookings/NewBookingPage.tsx | 12 +++++------ .../pages/bookings/new-booking-form/schema.ts | 2 +- .../bookings/new-booking-form/step4-route.tsx | 12 +++++++---- .../new-booking-form/step5-cargo-details.tsx | 4 +++- .../portal/src/services/bookings.service.ts | 20 ++++++------------- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/apps/edr-freight-web/portal/src/pages/bookings/MyBookings.tsx b/apps/edr-freight-web/portal/src/pages/bookings/MyBookings.tsx index dd7a54900..9d8501df0 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/MyBookings.tsx +++ b/apps/edr-freight-web/portal/src/pages/bookings/MyBookings.tsx @@ -13,7 +13,6 @@ import { Truck, } from "lucide-react"; -import Breadcrumbs from "@/components/Breadcrumbs"; import DeleteBookingDialog from "./DeleteBookingDialog"; import { getMyBookings } from "@/lib/currentCustomer"; import { deleteBooking, type Booking, type BookingStatus } from "./bookings.mock"; @@ -183,8 +182,6 @@ export default function MyBookings() { return (
- - {/* Header Section Card */}
diff --git a/apps/edr-freight-web/portal/src/pages/bookings/NewBookingPage.tsx b/apps/edr-freight-web/portal/src/pages/bookings/NewBookingPage.tsx index da777d491..f96e76b51 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/NewBookingPage.tsx +++ b/apps/edr-freight-web/portal/src/pages/bookings/NewBookingPage.tsx @@ -1,12 +1,11 @@ import { useEffect, useMemo, useState } from "react"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { useNavigate } from "react-router-dom"; import { CheckCircle2, ChevronLeft, ChevronRight } from "lucide-react"; import { Button } from "@edr/ui-common"; import Breadcrumbs from "@/components/Breadcrumbs"; -import { getCurrentCustomer } from "@/lib/currentCustomer"; import { api } from "@/services/api"; import type { CreateBookingPayload } from "@/services/bookings.service"; import { @@ -30,6 +29,7 @@ import { Step7Documents, Step8Review, } from "./new-booking-form/steps"; +import useAuth from "@/hooks/useAuth"; export default function NewBookingPage() { const navigate = useNavigate(); @@ -37,6 +37,7 @@ export default function NewBookingPage() { const [step, setStep] = useState(1); const [renewalValidating, setRenewalValidating] = useState(false); const [renewalValid, setRenewalValid] = useState(null); + const { customer } = useAuth(); const createMutation = useMutation({ mutationFn: (payload: CreateBookingPayload) => api.bookings.create.call(payload), @@ -129,7 +130,6 @@ export default function NewBookingPage() { return; } - const me = getCurrentCustomer(); const reference = data.previousContractRef; const totalWeight = @@ -142,7 +142,7 @@ export default function NewBookingPage() { const apiPayload = { reference, - customerId: String(me.id), + customerId: customer!.id, scheduledDate: new Date().toISOString().slice(0, 10), totalAmount: 0, contractType: @@ -194,7 +194,7 @@ export default function NewBookingPage() { createMutation.mutate(apiPayload); }); - if (createMutation.isSuccess && createMutation.data) { + if (createMutation.isSuccess) { return (
@@ -207,7 +207,7 @@ export default function NewBookingPage() { notified once approved.

- {createMutation.data.reference} + {createMutation.data?.reference}

diff --git a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/schema.ts b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/schema.ts index 2a34eb843..5ea5d4ded 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/schema.ts +++ b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/schema.ts @@ -161,7 +161,7 @@ export const bookingFormSchema = z destinationYard: z.string(), cargoType: z.enum(["container", "bulk"], "Select a cargo type."), cargoWeight: z.string(), - freightType: z.enum(["bulk", "break_bulk"]), + freightType: z.enum(["bulk", "break_bulk"]).optional(), bulkCommodity: z.string(), bulkCommodityOther: z.string(), breakBulkType: z.string(), diff --git a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step4-route.tsx b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step4-route.tsx index 1e56a8f25..18b4c581b 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step4-route.tsx +++ b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step4-route.tsx @@ -2,7 +2,13 @@ import { Controller, type UseFormReturn } from "react-hook-form"; import { Flame, MapPin, Snowflake } from "lucide-react"; import { Field, SelectItem, Separator, Switch } from "@edr/ui-common"; import { type BookingFormValues, getRouteDirection, STATIONS } from "./schema"; -import { SelectField, SelectOptions, StepHeader, StepLabel } from "./shared"; +import { + AlertBox, + SelectField, + SelectOptions, + StepHeader, + StepLabel, +} from "./shared"; import { useDropdownSettingByCode } from "@/hooks/useDropdownSettings"; import { DropdownOption } from "@/types/dropdownSettings"; @@ -145,12 +151,10 @@ export function Step4Route({ form }: { form: BookingForm }) { ); } - function getStationOptions(options?: DropdownOption[]): DropdownOption[] { return [...(options ?? [])].sort((a, b) => a.order - b.order); } - function StationSelectOptions({ options, excludeValue, @@ -193,4 +197,4 @@ function StationSelectOptions({ ))} ); -} \ No newline at end of file +} diff --git a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step5-cargo-details.tsx b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step5-cargo-details.tsx index 9f02e3ced..a26bf1876 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step5-cargo-details.tsx +++ b/apps/edr-freight-web/portal/src/pages/bookings/new-booking-form/step5-cargo-details.tsx @@ -78,7 +78,9 @@ export function Step5CargoDetails({ selected={cargoType === "container"} onClick={() => { field.onChange("container"); - form.setValue("freightType", "", { shouldDirty: true }); + form.setValue("freightType", undefined, { + shouldDirty: true, + }); form.setValue("cargoWeight", "", { shouldDirty: true }); }} > diff --git a/apps/edr-freight-web/portal/src/services/bookings.service.ts b/apps/edr-freight-web/portal/src/services/bookings.service.ts index 8b436c14c..7d1ef1d2f 100644 --- a/apps/edr-freight-web/portal/src/services/bookings.service.ts +++ b/apps/edr-freight-web/portal/src/services/bookings.service.ts @@ -1,31 +1,23 @@ import type { Freight, PaginatedResponse } from "@edr/types"; -import { client as api } from "@/utils/api"; + +import { client } from "../utils/api"; export type CreateBookingPayload = Freight.CreateBookingDto; export const bookingsService = { list: async (): Promise> => { - const { data } = await api.get("/bookings"); + const { data } = await client.get("/bookings"); return data.data; }, get: async (id: string): Promise => { - const { data } = await api.get(`/bookings/${id}`); + const { data } = await client.get(`/bookings/${id}`); return data.data; }, create: async (payload: CreateBookingPayload): Promise => { - const fd = new FormData(); - for (const [key, value] of Object.entries(payload)) { - if (value === undefined || value === null) continue; - if (Array.isArray(value) || typeof value === "object") { - fd.append(key, JSON.stringify(value)); - } else { - fd.append(key, String(value)); - } - } - const { data } = await api.post("/api/bookings", fd); + const { data } = await client.post("/api/bookings", payload); return data.data; }, remove: async (id: string): Promise => { - await api.delete(`/bookings/${id}`); + await client.delete(`/bookings/${id}`); }, };