mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat: enhance booking and scheduling features with shipping line support and improved search functionality
This commit is contained in:
@@ -500,7 +500,7 @@ export default function BookingRequestsPage() {
|
||||
<FilterBar
|
||||
defs={bookingFilterDefs}
|
||||
controls={controls}
|
||||
searchPlaceholder="Search booking, contract or customer…"
|
||||
searchPlaceholder="Search booking, contract, customer or shipping line…"
|
||||
viewId="booking-requests"
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -14,7 +14,7 @@ import { DatePickerInput } from "@mantine/dates";
|
||||
import { getDateRangePresets } from "@/components/common/dateRangePresets";
|
||||
import { useDebouncedValue } from "@mantine/hooks";
|
||||
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
||||
import { FileText, Inbox, RefreshCw, Search, User, X } from "lucide-react";
|
||||
import { FileText, Inbox, RefreshCw, Search, Ship, User, X } from "lucide-react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
@@ -75,6 +75,12 @@ const OWNERSHIP_OPTIONS = [
|
||||
{ value: "false", label: "Private" },
|
||||
];
|
||||
|
||||
/** Who booked: shipping lines own bookings via `shippingLineCompanyId`, not a customer company. */
|
||||
const CUSTOMER_KIND_OPTIONS = [
|
||||
{ value: "SHIPPING_LINE", label: "Shipping line" },
|
||||
{ value: "CUSTOMER", label: "Customer" },
|
||||
];
|
||||
|
||||
function startOfDayIso(d: Date): string {
|
||||
const x = new Date(d);
|
||||
x.setHours(0, 0, 0, 0);
|
||||
@@ -98,6 +104,7 @@ export default function ClearanceDocumentsPage() {
|
||||
const [directionFilter, setDirectionFilter] = useState<string | null>(null);
|
||||
const [freightTypeFilter, setFreightTypeFilter] = useState<string | null>(null);
|
||||
const [ownershipFilter, setOwnershipFilter] = useState<string | null>(null);
|
||||
const [customerKindFilter, setCustomerKindFilter] = useState<string | null>(null);
|
||||
const [createdFrom, setCreatedFrom] = useState<Date | null>(null);
|
||||
const [createdTo, setCreatedTo] = useState<Date | null>(null);
|
||||
const { pagination, setPagination } = usePagination({ pageSize: PAGE_SIZE });
|
||||
@@ -118,6 +125,7 @@ export default function ClearanceDocumentsPage() {
|
||||
directionFilter,
|
||||
freightTypeFilter,
|
||||
ownershipFilter,
|
||||
customerKindFilter,
|
||||
createdFrom,
|
||||
createdTo,
|
||||
page,
|
||||
@@ -138,6 +146,9 @@ export default function ClearanceDocumentsPage() {
|
||||
...(ownershipFilter
|
||||
? { isGovernment: ownershipFilter as "true" | "false" }
|
||||
: {}),
|
||||
...(customerKindFilter
|
||||
? { customerKind: customerKindFilter as "SHIPPING_LINE" | "CUSTOMER" }
|
||||
: {}),
|
||||
...(createdFrom ? { createdFrom: startOfDayIso(createdFrom) } : {}),
|
||||
...(createdTo ? { createdTo: endOfDayIso(createdTo) } : {}),
|
||||
}),
|
||||
@@ -153,17 +164,29 @@ export default function ClearanceDocumentsPage() {
|
||||
header: () => <span className={bookingTable.headerCell}>Customer</span>,
|
||||
cell: ({ row }) => {
|
||||
const b = row.original;
|
||||
const customer = b.isGovernment
|
||||
? (b.governmentInstitution ?? "Government")
|
||||
: (b.company?.name ?? "—");
|
||||
const isShippingLine = Boolean(b.shippingLineCompany ?? b.shippingLineCompanyId);
|
||||
const customer = isShippingLine
|
||||
? (b.shippingLineCompany?.name ?? "Shipping line")
|
||||
: b.isGovernment
|
||||
? (b.governmentInstitution ?? "Government")
|
||||
: (b.company?.name ?? "—");
|
||||
return (
|
||||
<div className="flex items-center gap-3 py-1.5">
|
||||
<div className={bookingTable.rowIcon}>
|
||||
<User className="size-4" strokeWidth={1.75} />
|
||||
{isShippingLine ? (
|
||||
<Ship className="size-4" strokeWidth={1.75} />
|
||||
) : (
|
||||
<User className="size-4" strokeWidth={1.75} />
|
||||
)}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<p className="font-medium text-foreground">
|
||||
<p className="flex items-center gap-1.5 font-medium text-foreground">
|
||||
{customer}
|
||||
{isShippingLine ? (
|
||||
<Badge variant="secondary" className="h-4 shrink-0 px-1 text-[9px] font-medium">
|
||||
Shipping line
|
||||
</Badge>
|
||||
) : null}
|
||||
</p>
|
||||
<p className="mt-0.5 flex items-center gap-1 text-xs text-muted-foreground">
|
||||
<FileText className="size-3 shrink-0 opacity-70" />
|
||||
@@ -267,7 +290,7 @@ export default function ClearanceDocumentsPage() {
|
||||
<Box px="md" pt="md" pb="sm" w="100%">
|
||||
<Group justify="space-between" gap="md" wrap="wrap">
|
||||
<TextInput
|
||||
placeholder="Search booking, contract or customer…"
|
||||
placeholder="Search booking, contract, customer or shipping line…"
|
||||
leftSection={<Search size={18} />}
|
||||
value={query}
|
||||
onChange={(e) => {
|
||||
@@ -333,6 +356,19 @@ export default function ClearanceDocumentsPage() {
|
||||
style={{ minWidth: 140 }}
|
||||
aria-label="Filter by freight type"
|
||||
/>
|
||||
<Select
|
||||
placeholder="Booked by"
|
||||
data={CUSTOMER_KIND_OPTIONS}
|
||||
value={customerKindFilter}
|
||||
onChange={(v) => {
|
||||
setCustomerKindFilter(v);
|
||||
resetPage();
|
||||
}}
|
||||
clearable
|
||||
radius="lg"
|
||||
style={{ minWidth: 140 }}
|
||||
aria-label="Filter by booked by"
|
||||
/>
|
||||
<Select
|
||||
placeholder="Gov / Private"
|
||||
data={OWNERSHIP_OPTIONS}
|
||||
|
||||
Reference in New Issue
Block a user