Fix CSS formatting for bookings table class to ensure proper styling and layout.

This commit is contained in:
marshalyordanos
2026-07-20 22:35:01 +03:00
parent 8aaccf3f36
commit 8e74604a07
2 changed files with 65 additions and 80 deletions

View File

@@ -7,6 +7,7 @@ import {
MultiSelect, MultiSelect,
Select, Select,
Stack, Stack,
Tabs,
Text, Text,
TextInput, TextInput,
} from "@mantine/core"; } from "@mantine/core";
@@ -32,6 +33,7 @@ import { useNavigate } from "react-router-dom";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { BookingActionsMenu } from "@/components/bookings/BookingActionsMenu"; import { BookingActionsMenu } from "@/components/bookings/BookingActionsMenu";
import { BookingApprovalProgressCell } from "@/components/bookings/BookingApprovalProgressCell";
import { BookingPriorityBadge } from "@/components/bookings/BookingPriorityBadge"; import { BookingPriorityBadge } from "@/components/bookings/BookingPriorityBadge";
import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge"; import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge";
// BookingStatusTabs / Operations* queues removed — replaced by booking-kind tabs. // BookingStatusTabs / Operations* queues removed — replaced by booking-kind tabs.
@@ -58,12 +60,10 @@ import {
type ColumnDef, type ColumnDef,
} from "@edr/ui-common"; } from "@edr/ui-common";
import "./booking-requests-table.css"; /** The two booking-kind tabs: one-time vs general-contract bookings. */
type BookingKindTab = "ONE_TIME" | "GENERAL_CONTRACT";
/** Booking kind: one-time vs general-contract bookings. Now a filter, not a tab. */ const BOOKING_KIND_TABS: { value: BookingKindTab; label: string }[] = [
type BookingKind = "ONE_TIME" | "GENERAL_CONTRACT";
const BOOKING_KIND_OPTIONS: { value: BookingKind; label: string }[] = [
{ value: "ONE_TIME", label: "One-time booking" }, { value: "ONE_TIME", label: "One-time booking" },
{ value: "GENERAL_CONTRACT", label: "General booking" }, { value: "GENERAL_CONTRACT", label: "General booking" },
]; ];
@@ -128,9 +128,9 @@ export default function BookingRequestsPage() {
const { pagination, setPagination } = usePagination({ pageSize: 10 }); const { pagination, setPagination } = usePagination({ pageSize: 10 });
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [debouncedQuery] = useDebouncedValue(query, 300); const [debouncedQuery] = useDebouncedValue(query, 300);
// Booking kind is a filter now — one list holds both kinds (null = "all"). // Booking-kind tabs (one-time vs general contract) replace the old status tabs.
const [kindFilter, setKindFilter] = useState<BookingKind | null>(null); const [kindTab, setKindTab] = useState<BookingKindTab>("ONE_TIME");
// Filter controls (empty/null = "all"). // Per-tab filter controls (empty/null = "all").
const [statusFilter, setStatusFilter] = useState<string[]>([]); const [statusFilter, setStatusFilter] = useState<string[]>([]);
const [directionFilter, setDirectionFilter] = useState<string | null>(null); const [directionFilter, setDirectionFilter] = useState<string | null>(null);
const [freightTypeFilter, setFreightTypeFilter] = useState<string | null>(null); const [freightTypeFilter, setFreightTypeFilter] = useState<string | null>(null);
@@ -158,9 +158,9 @@ export default function BookingRequestsPage() {
pageSize: pagination.pageSize, pageSize: pagination.pageSize,
sortBy: "createdAt", sortBy: "createdAt",
sortOrder: "DESC", sortOrder: "DESC",
// React Query cache key per kind selection ("ALL" when unfiltered). // React Query cache key per kind tab.
tab: kindFilter ?? "ALL", tab: kindTab,
...(kindFilter ? { bookingType: kindFilter } : {}), bookingType: kindTab,
// Server-side free-text search (booking ref, customer, contract ref). // Server-side free-text search (booking ref, customer, contract ref).
...(debouncedQuery.trim() ? { search: debouncedQuery.trim() } : {}), ...(debouncedQuery.trim() ? { search: debouncedQuery.trim() } : {}),
...(statusFilter.length ? { statuses: statusFilter.join(",") } : {}), ...(statusFilter.length ? { statuses: statusFilter.join(",") } : {}),
@@ -182,7 +182,7 @@ export default function BookingRequestsPage() {
}, [ }, [
pagination.pageIndex, pagination.pageIndex,
pagination.pageSize, pagination.pageSize,
kindFilter, kindTab,
debouncedQuery, debouncedQuery,
statusFilter, statusFilter,
directionFilter, directionFilter,
@@ -226,7 +226,6 @@ export default function BookingRequestsPage() {
}, [setPagination, pagination.pageSize]); }, [setPagination, pagination.pageSize]);
const activeFilterCount = const activeFilterCount =
(kindFilter ? 1 : 0) +
(statusFilter.length ? 1 : 0) + (statusFilter.length ? 1 : 0) +
(directionFilter ? 1 : 0) + (directionFilter ? 1 : 0) +
(freightTypeFilter ? 1 : 0) + (freightTypeFilter ? 1 : 0) +
@@ -238,7 +237,6 @@ export default function BookingRequestsPage() {
(scheduledFrom || scheduledTo ? 1 : 0); (scheduledFrom || scheduledTo ? 1 : 0);
const clearFilters = useCallback(() => { const clearFilters = useCallback(() => {
setKindFilter(null);
setStatusFilter([]); setStatusFilter([]);
setDirectionFilter(null); setDirectionFilter(null);
setFreightTypeFilter(null); setFreightTypeFilter(null);
@@ -284,8 +282,6 @@ export default function BookingRequestsPage() {
const columns: ColumnDef<BookingListRow>[] = [ const columns: ColumnDef<BookingListRow>[] = [
{ {
id: "booking", id: "booking",
size: 60,
minSize: 40,
header: () => <span className={bookingTable.headerCell}>Booking</span>, header: () => <span className={bookingTable.headerCell}>Booking</span>,
cell: ({ row }) => { cell: ({ row }) => {
const b = row.original; const b = row.original;
@@ -307,8 +303,6 @@ export default function BookingRequestsPage() {
}, },
{ {
id: "contract", id: "contract",
size: 60,
minSize: 40,
header: () => <span className={bookingTable.headerCell}>Contract</span>, header: () => <span className={bookingTable.headerCell}>Contract</span>,
cell: ({ row }) => { cell: ({ row }) => {
const ref = row.original.contractReference; const ref = row.original.contractReference;
@@ -333,29 +327,8 @@ export default function BookingRequestsPage() {
); );
}, },
}, },
{
id: "bookingKind",
size: 60,
minSize: 40,
header: () => <span className={bookingTable.headerCell}>Type</span>,
cell: ({ row }) => {
const isGeneral = row.original.bookingKind === "GENERAL_CONTRACT";
return (
<div className="py-1">
<Badge
variant={isGeneral ? "secondary" : "outline"}
className="h-5 px-1.5 text-[10px] font-medium"
>
{isGeneral ? "General" : "One-time"}
</Badge>
</div>
);
},
},
{ {
id: "route", id: "route",
size: 60,
minSize: 40,
header: () => <span className={bookingTable.headerCell}>Route</span>, header: () => <span className={bookingTable.headerCell}>Route</span>,
cell: ({ row }) => { cell: ({ row }) => {
const b = row.original; const b = row.original;
@@ -386,8 +359,8 @@ export default function BookingRequestsPage() {
}, },
{ {
id: "status", id: "status",
size: 60, size: 200,
minSize: 40, minSize: 180,
header: () => <span className={bookingTable.headerCell}>Status</span>, header: () => <span className={bookingTable.headerCell}>Status</span>,
cell: ({ row }) => ( cell: ({ row }) => (
<div className="py-1"> <div className="py-1">
@@ -398,11 +371,20 @@ export default function BookingRequestsPage() {
/> />
</div> </div>
), ),
meta: {
headerClassName: "min-w-[11rem]",
cellClassName: "min-w-[11rem]",
},
},
{
id: "approval",
header: () => (
<span className={bookingTable.headerCell}>Approval</span>
),
cell: ({ row }) => <BookingApprovalProgressCell row={row.original} />,
}, },
{ {
id: "scheduled", id: "scheduled",
size: 60,
minSize: 40,
header: () => <span className={bookingTable.headerCell}>Scheduled</span>, header: () => <span className={bookingTable.headerCell}>Scheduled</span>,
cell: ({ row }) => ( cell: ({ row }) => (
<span className="inline-flex items-center gap-1.5 text-sm text-muted-foreground"> <span className="inline-flex items-center gap-1.5 text-sm text-muted-foreground">
@@ -413,8 +395,6 @@ export default function BookingRequestsPage() {
}, },
{ {
id: "priority", id: "priority",
size: 60,
minSize: 40,
header: () => <span className={bookingTable.headerCell}>Priority</span>, header: () => <span className={bookingTable.headerCell}>Priority</span>,
cell: ({ row }) => ( cell: ({ row }) => (
<BookingPriorityBadge score={row.original.priorityScore} /> <BookingPriorityBadge score={row.original.priorityScore} />
@@ -422,8 +402,7 @@ export default function BookingRequestsPage() {
}, },
{ {
id: "actions", id: "actions",
size: 60, size: 140,
minSize: 40,
cell: ({ row }) => ( cell: ({ row }) => (
<BookingActionsMenu <BookingActionsMenu
row={row.original} row={row.original}
@@ -503,6 +482,22 @@ export default function BookingRequestsPage() {
/> />
*/} */}
<Tabs
value={kindTab}
onChange={(value) => {
setKindTab((value as BookingKindTab) ?? "ONE_TIME");
setPagination({ pageIndex: 0, pageSize: pagination.pageSize });
}}
>
<Tabs.List>
{BOOKING_KIND_TABS.map((t) => (
<Tabs.Tab key={t.value} value={t.value}>
{t.label}
</Tabs.Tab>
))}
</Tabs.List>
</Tabs>
<Card p={0}> <Card p={0}>
<Stack gap={0}> <Stack gap={0}>
<Box px="md" pt="md" pb="sm" w="100%"> <Box px="md" pt="md" pb="sm" w="100%">
@@ -540,18 +535,6 @@ export default function BookingRequestsPage() {
</Text> </Text>
</Group> </Group>
<Group gap="sm" wrap="wrap"> <Group gap="sm" wrap="wrap">
<Select
placeholder="All booking types"
data={BOOKING_KIND_OPTIONS}
value={kindFilter}
onChange={(v) => {
setKindFilter((v as BookingKind | null) ?? null);
resetPage();
}}
clearable
radius="lg"
style={{ minWidth: 190 }}
/>
<MultiSelect <MultiSelect
placeholder={statusFilter.length ? undefined : "All statuses"} placeholder={statusFilter.length ? undefined : "All statuses"}
data={STATUS_OPTIONS} data={STATUS_OPTIONS}
@@ -713,26 +696,28 @@ export default function BookingRequestsPage() {
/> />
</Box> </Box>
) : ( ) : (
<DataTable <Box style={{ overflowX: "auto" }} w="100%">
columns={columns} <DataTable
data={rows} columns={columns}
status={isLoading ? "loading" : isError ? "error" : "success"} data={rows}
onRowClick={handleRowClick} status={isLoading ? "loading" : isError ? "error" : "success"}
pagination={{ onRowClick={handleRowClick}
pageIndex: pagination.pageIndex, pagination={{
pageSize: pagination.pageSize, pageIndex: pagination.pageIndex,
pageCount, pageSize: pagination.pageSize,
totalCount: total, pageCount,
}} totalCount: total,
tableOptions={{ }}
state: { pagination }, tableOptions={{
onPaginationChange: setPagination, state: { pagination },
manualPagination: true, onPaginationChange: setPagination,
pageCount, manualPagination: true,
}} pageCount,
containerClassName="edr-booking-requests-table border-0 shadow-none bg-transparent" }}
footer={DataTableFooter} containerClassName="border-0 shadow-none bg-transparent"
/> footer={DataTableFooter}
/>
</Box>
)} )}
</Stack> </Stack>
</Card> </Card>

View File

@@ -4,7 +4,7 @@
* content-sized columns with a 40px floor, horizontal scroll when the table * content-sized columns with a 40px floor, horizontal scroll when the table
* outgrows the card, and a sticky shadowed action column. * outgrows the card, and a sticky shadowed action column.
*/ */
.edr-bookings-table { .edr-bookings-table {
overflow-x: auto; overflow-x: auto;
} }