import { useMemo, useState } from "react"; import { Alert, Box, Tab, Tabs } from "@mui/material"; import { VendorCreateModal } from "./_components/vendor-create-modal"; import { VendorDetailDrawer } from "./_components/vendor-detail-drawer"; import { VendorDeactivationDialog } from "./_components/vendor-deactivation-dialog"; import { VendorFiltersDrawer } from "./_components/vendor-filters-drawer"; import { VendorAppliedFiltersBar, VendorsListFooter, VendorsListToolbar, } from "./_components/vendors-list-toolbar"; import { VendorsTable } from "./_components/vendors-table"; import { useVendorDeactivation } from "./_components/use-vendor-deactivation"; import { useVendorListState } from "./_components/use-vendor-list-state"; import type { VendorFilters } from "./_components/vendor-filters"; import type { VendorListItem } from "@/domain/vendors/types/vendor"; import { useVendorFacets } from "@/domain/vendors/use-cases/use-vendor-facets"; import { useVendorDirectoryList } from "@/domain/vendors/use-cases/use-vendor-directory-list"; interface AppliedChip { category: keyof VendorFilters; value: string; label: string; } function statusTabLabel(label: string, count: number) { return ( {label} {count} ); } function VendorStatusTabs({ isActive, activeCount, inactiveCount, onChange, }: { isActive: boolean; activeCount: number; inactiveCount: number; onChange: (isActive: boolean) => void; }) { return ( onChange(value === "active")} aria-label="Vendor status" sx={{ minHeight: 36, flexShrink: 0, borderBottom: (theme) => `1px solid ${theme.palette.divider}`, backgroundColor: "var(--color-bg-surface)", mx: -2, px: 1.5, "& .MuiTab-root": { minHeight: 36, px: 2, py: 0, fontSize: 13, fontWeight: 500, textTransform: "none", }, "& .MuiTab-root:first-of-type": { width: 102.84375 }, "& .Mui-selected": { fontWeight: 600 }, "& .MuiTabs-indicator": { height: 2 }, }} > ); } function describeChips( filters: VendorFilters, jobBucketLabels: Map, ): AppliedChip[] { const chips: AppliedChip[] = []; filters.companies.forEach((value) => chips.push({ category: "companies", value, label: `Company: ${value}` }), ); filters.trades.forEach((value) => chips.push({ category: "trades", value, label: `Trade: ${value}` }), ); filters.locations.forEach((value) => chips.push({ category: "locations", value, label: `Location: ${value}` }), ); filters.jobBuckets.forEach((value) => chips.push({ category: "jobBuckets", value, label: `Total Jobs: ${jobBucketLabels.get(value) ?? value}`, }), ); return chips; } export default function VendorsListPage() { const filters = useVendorListState(); const [filtersOpen, setFiltersOpen] = useState(false); const [createOpen, setCreateOpen] = useState(false); const [detailTarget, setDetailTarget] = useState(null); const [detailStartsInEdit, setDetailStartsInEdit] = useState(false); const closeDetail = () => { setDetailTarget(null); setDetailStartsInEdit(false); }; const deactivation = useVendorDeactivation(closeDetail); const { data: facets } = useVendorFacets(filters.isActive); const { data, isLoading, isFetching, error } = useVendorDirectoryList(filters.listParams); const { data: activeCountData } = useVendorDirectoryList({ isActive: true, page: 1, pageSize: 1, }); const { data: inactiveCountData } = useVendorDirectoryList({ isActive: false, page: 1, pageSize: 1, }); const rows = data?.items ?? []; const totalCount = data?.totalCount ?? 0; const activeCount = activeCountData?.totalCount ?? 0; const inactiveCount = inactiveCountData?.totalCount ?? 0; const jobBucketLabels = useMemo( () => new Map((facets?.jobBuckets ?? []).map((bucket) => [bucket.id, bucket.label])), [facets], ); const appliedChips = describeChips(filters.appliedFilters, jobBucketLabels); return ( setFiltersOpen(true)} onAddVendor={() => setCreateOpen(true)} /> ({ key: `${chip.category}-${chip.value}`, label: chip.label, onRemove: () => filters.removeFilter(chip.category, chip.value), }))} onClearAll={filters.clearFilters} /> {Boolean(error) && ( {error instanceof Error ? error.message : "Failed to load vendors"} )} 0 || Boolean(filters.debouncedSearch)} isLoading={isLoading} showError={Boolean(error)} onOpenDetail={(row) => { setDetailStartsInEdit(false); setDetailTarget(row); }} onOpenEdit={(row) => { setDetailStartsInEdit(true); setDetailTarget(row); }} /> 0 || Boolean(filters.debouncedSearch)} page={filters.page} pageSize={filters.pageSize} onPageChange={filters.setPage} onPageSizeChange={filters.setPageSizeWithReset} /> setCreateOpen(false)} /> setFiltersOpen(false)} facets={facets} appliedFilters={filters.appliedFilters} onApply={filters.setAppliedFiltersWithReset} /> ); }