mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 18:48:11 +00:00
feat(filters): route filter, select-styled trigger, tune default pin set
- New "route" FilterType: RouteBody popover (searchable origin + destination selects, apply once both are picked), wired into ContractRequestsPage and BookingRequestsPage. Bookings already had server-side originYardId/destinationYardId; contracts gets both new (contract_routes is one-to-many, so origin/destination are separate EXISTS subqueries, not a join). - Inactive FilterPill trigger restyled to read like a closed Mantine Select (opaque solid border, trailing chevron) instead of a dashed "+" pill — trigger only, popover body/position unchanged. - Search box text set to regular weight. - A couple more filters (Direction, Freight) pinned by default per page on top of the existing always-pinned ones; the rest stay behind More filters.
This commit is contained in:
@@ -136,9 +136,9 @@ export default function BookingRequestsPage() {
|
||||
{ key: "statuses", label: "Status", type: "enum", options: STATUS_OPTIONS },
|
||||
{
|
||||
key: "tradeDirection", label: "Direction", type: "enum", multiple: false,
|
||||
options: filterOptions(TRADE_DIRECTION_OPTIONS), secondary: true,
|
||||
options: filterOptions(TRADE_DIRECTION_OPTIONS),
|
||||
},
|
||||
{ key: "freightType", label: "Freight", type: "enum", multiple: false, options: FREIGHT_TYPE_OPTIONS, secondary: true },
|
||||
{ key: "freightType", label: "Freight", type: "enum", multiple: false, options: FREIGHT_TYPE_OPTIONS },
|
||||
{ key: "paymentStatus", label: "Payment", type: "enum", multiple: false, options: PAYMENT_STATUS_OPTIONS, secondary: true },
|
||||
{
|
||||
// Wins over the `paymentStatus` filter above — the queue is by
|
||||
@@ -149,8 +149,10 @@ export default function BookingRequestsPage() {
|
||||
toParams: (v) => (v.v[0] === "true" ? { paymentStatus: "PAID", assignedToSchedule: "false" } : {}),
|
||||
},
|
||||
{ key: "isGovernment", label: "Ownership", type: "enum", multiple: false, options: OWNERSHIP_OPTIONS, secondary: true },
|
||||
{ key: "originYardId", label: "Origin", type: "enum", multiple: false, options: yardOptions, secondary: true },
|
||||
{ key: "destinationYardId", label: "Destination", type: "enum", multiple: false, options: yardOptions, secondary: true },
|
||||
{
|
||||
key: "route", label: "Route", type: "route", options: yardOptions, secondary: true,
|
||||
toParams: ({ v }) => ({ originYardId: v[0], destinationYardId: v[1] }),
|
||||
},
|
||||
{ key: "created", label: "Created", type: "date", secondary: true, toParams: ({ v }) => ({ createdFrom: v[0], createdTo: v[1] }) },
|
||||
{ key: "scheduled", label: "Scheduled", type: "date", secondary: true, toParams: ({ v }) => ({ scheduledFrom: v[0], scheduledTo: v[1] }) },
|
||||
],
|
||||
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
} from "lucide-react";
|
||||
import { useCallback, useMemo, type ReactNode } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { api } from "@/services/api";
|
||||
|
||||
import { ContractStatusBadge } from "@/components/contracts/ContractStatusBadge";
|
||||
import { bookingTable } from "@/components/bookings/booking-ui.styles";
|
||||
@@ -103,6 +105,16 @@ export default function ContractRequestsPage() {
|
||||
const navigate = useNavigate();
|
||||
const { filterOptions } = useMyTradeAccess();
|
||||
|
||||
// Yard options for the route filter (shared routes reference list, same
|
||||
// query BookingRequestsPage uses).
|
||||
const { data: yardRefs } = useQuery(
|
||||
api.routes.yards.queryOptions({ staleTime: 5 * 60_000 }),
|
||||
);
|
||||
const yardOptions = useMemo(
|
||||
() => (yardRefs ?? []).map((y) => ({ value: y.id, label: y.label ?? y.code })),
|
||||
[yardRefs],
|
||||
);
|
||||
|
||||
// Static shape only (no facet counts) — this is what useFilters needs to
|
||||
// parse the URL and build API params. Counts are attached separately below,
|
||||
// for rendering only, once the summary query (which itself depends on
|
||||
@@ -123,7 +135,6 @@ export default function ContractRequestsPage() {
|
||||
type: "enum",
|
||||
multiple: false,
|
||||
options: filterOptions(TRADE_DIRECTION_OPTIONS),
|
||||
secondary: true,
|
||||
},
|
||||
{
|
||||
key: "freightType",
|
||||
@@ -131,7 +142,6 @@ export default function ContractRequestsPage() {
|
||||
type: "enum",
|
||||
multiple: false,
|
||||
options: FREIGHT_TYPE_OPTIONS,
|
||||
secondary: true,
|
||||
},
|
||||
{
|
||||
key: "paymentCurrency",
|
||||
@@ -150,8 +160,16 @@ export default function ContractRequestsPage() {
|
||||
// onChange, so this just routes to the API's existing param names.
|
||||
toParams: ({ v }) => ({ createdFrom: v[0], createdTo: v[1] }),
|
||||
},
|
||||
{
|
||||
key: "route",
|
||||
label: "Route",
|
||||
type: "route",
|
||||
options: yardOptions,
|
||||
secondary: true,
|
||||
toParams: ({ v }) => ({ originYardId: v[0], destinationYardId: v[1] }),
|
||||
},
|
||||
],
|
||||
[filterOptions],
|
||||
[filterOptions, yardOptions],
|
||||
);
|
||||
|
||||
const controls = useFilters(filterDefs, {
|
||||
|
||||
Reference in New Issue
Block a user