mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-09 01:18:18 +00:00
feat(bookings): Integrate booking list and detail pages with backend API
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
AlertCircle,
|
||||
AlertTriangle,
|
||||
@@ -27,14 +27,9 @@ import {
|
||||
|
||||
import Breadcrumbs from "@/components/ui/Breadcrumbs";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
getBookingRequestById,
|
||||
getBookingRequests,
|
||||
saveBookingRequestsToStorage,
|
||||
updateBookingRequestStatus,
|
||||
BOOKING_STATUSES,
|
||||
type BookingRequest,
|
||||
} from "./booking-requests.mock";
|
||||
import { api } from "@/services/api";
|
||||
import { useUpdateBookingStatus } from "@/hooks/useBookings";
|
||||
import { mapBookingToRequest, BOOKING_STATUSES } from "./booking-requests.mock";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
@@ -233,9 +228,16 @@ const STATUS_CONFIG: Record<
|
||||
export default function BookingRequestDetailPage() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const navigate = useNavigate();
|
||||
const [booking, setBooking] = useState<BookingRequest | undefined>(
|
||||
id ? getBookingRequestById(id) : undefined,
|
||||
|
||||
const { data: bookingData } = useQuery(
|
||||
api.bookings.getById.queryOptions({
|
||||
input: { id: id ?? "" },
|
||||
enabled: Boolean(id),
|
||||
}),
|
||||
);
|
||||
const updateStatus = useUpdateBookingStatus();
|
||||
|
||||
const booking = bookingData ? mapBookingToRequest(bookingData) : undefined;
|
||||
|
||||
if (!booking) {
|
||||
return (
|
||||
@@ -270,20 +272,20 @@ export default function BookingRequestDetailPage() {
|
||||
booking.status,
|
||||
);
|
||||
|
||||
const isPending = updateStatus.isPending;
|
||||
|
||||
function handleApprove() {
|
||||
if (!booking) return;
|
||||
const nextStatus =
|
||||
const action =
|
||||
booking.status === "RFQ_SUBMITTED"
|
||||
? ("QUOTATION_SENT" as const)
|
||||
: ("APPROVED" as const);
|
||||
updateBookingRequestStatus(booking.id, nextStatus);
|
||||
setBooking(getBookingRequestById(booking.id));
|
||||
? "SEND_QUOTATION"
|
||||
: "APPROVE";
|
||||
updateStatus.mutate({ id: booking.id, action });
|
||||
}
|
||||
|
||||
function handleReject() {
|
||||
if (!booking) return;
|
||||
updateBookingRequestStatus(booking.id, "CANCELLED");
|
||||
setBooking(getBookingRequestById(booking.id));
|
||||
updateStatus.mutate({ id: booking.id, action: "CANCEL", reason: "Cancelled by backoffice" });
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
AlertCircle,
|
||||
ArrowRight,
|
||||
@@ -18,10 +19,11 @@ import {
|
||||
|
||||
import Breadcrumbs from "@/components/ui/Breadcrumbs";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { api } from "@/services/api";
|
||||
import {
|
||||
getBookingRequests,
|
||||
BOOKING_STATUSES,
|
||||
type BookingRequest,
|
||||
mapBookingToRequest,
|
||||
} from "./booking-requests.mock";
|
||||
import {
|
||||
DataTable,
|
||||
@@ -153,7 +155,13 @@ export default function BookingRequestsPage() {
|
||||
const [query, setQuery] = useState("");
|
||||
const [statusFilter, setStatusFilter] = useState<string | null>(null);
|
||||
|
||||
const bookingRequests = useMemo(() => getBookingRequests(), []);
|
||||
const { data: bookingData } = useQuery(
|
||||
api.bookings.list.queryOptions({ input: { filter: { page: pagination.pageIndex + 1, pageSize: pagination.pageSize } } }),
|
||||
);
|
||||
const bookingRequests = useMemo(
|
||||
() => (bookingData?.items ?? []).map(mapBookingToRequest),
|
||||
[bookingData],
|
||||
);
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
const q = query.trim().toLowerCase();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { Freight } from "@edr/types";
|
||||
|
||||
export interface BookingRequest {
|
||||
id: string;
|
||||
reference: string;
|
||||
@@ -131,6 +133,36 @@ export function updateBookingRequestStatus(id: string, newStatus: (typeof BOOKIN
|
||||
saveBookingRequestsToStorage(requests);
|
||||
}
|
||||
|
||||
export function mapBookingToRequest(booking: Freight.IBooking): BookingRequest {
|
||||
return {
|
||||
id: booking.id,
|
||||
reference: booking.reference,
|
||||
customer: booking.customerId,
|
||||
status: booking.status as BookingRequest["status"],
|
||||
scheduledDate: booking.scheduledDate,
|
||||
totalAmount: booking.totalAmount,
|
||||
paymentStatus: booking.paymentStatus,
|
||||
contractType: booking.contractType,
|
||||
serviceType:
|
||||
booking.serviceType === "RAIL_ONLY" ? "RAIL" : (booking.serviceType as string),
|
||||
tradeDirection: booking.tradeDirection as string,
|
||||
originYard: booking.originStation,
|
||||
destinationYard: booking.destinationStation,
|
||||
cargoType: booking.freightType ?? booking.freightSubtype ?? "",
|
||||
cargoTotalWeightVgm: booking.cargoTotalWeightVgm,
|
||||
isHazardous: booking.isHazardous,
|
||||
paymentCurrency: booking.paymentCurrency,
|
||||
priorityScore: booking.priorityScore,
|
||||
firstMilePickupAddress: booking.firstMilePickupAddress ?? null,
|
||||
lastMileDeliveryAddress: booking.lastMileDeliveryAddress ?? null,
|
||||
shippingLine: null,
|
||||
pnrCode: null,
|
||||
createdBy: booking.customerId,
|
||||
createdAt: booking.createdAt,
|
||||
updatedAt: booking.updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
export function getBookingRequests(): BookingRequest[] {
|
||||
if (typeof window === "undefined" || !window.localStorage) {
|
||||
return INITIAL_REQUESTS;
|
||||
|
||||
Reference in New Issue
Block a user