fix(vendors): align list header, Total Jobs, and Filters with design (SH-219)

This commit is contained in:
arthur.bassi 2026-08-04 14:17:03 -03:00
parent a0214cc01f
commit 0a3cfe2d6a

View file

@ -1,7 +1,6 @@
import { useMemo, useState, type KeyboardEvent, type MouseEvent } from "react"; import { useMemo, useState, type KeyboardEvent, type MouseEvent } from "react";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutlined"; import DeleteOutlineIcon from "@mui/icons-material/DeleteOutlined";
import EditOutlinedIcon from "@mui/icons-material/EditOutlined"; import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
import FilterListIcon from "@mui/icons-material/FilterList";
import VisibilityOutlinedIcon from "@mui/icons-material/VisibilityOutlined"; import VisibilityOutlinedIcon from "@mui/icons-material/VisibilityOutlined";
import { import {
Alert, Alert,
@ -34,10 +33,13 @@ import {
Tooltip, Tooltip,
Typography, Typography,
} from "@mui/material"; } from "@mui/material";
import { SlidersHorizontal } from "lucide-react";
import { VendorCreateModal } from "./_components/vendor-create-modal"; import { VendorCreateModal } from "./_components/vendor-create-modal";
import { VendorDetailDrawer } from "./_components/vendor-detail-drawer"; import { VendorDetailDrawer } from "./_components/vendor-detail-drawer";
import { VendorFiltersDrawer } from "./_components/vendor-filters-drawer"; import { VendorFiltersDrawer } from "./_components/vendor-filters-drawer";
import { emptyVendorFilters, type VendorFilters } from "./_components/vendor-filters"; import { emptyVendorFilters, type VendorFilters } from "./_components/vendor-filters";
import { PageHeader } from "@/components/ui/page-header";
import { ToolbarButton } from "@/components/ui/toolbar-button";
import type { VendorListItem } from "@/domain/vendors/types/vendor"; import type { VendorListItem } from "@/domain/vendors/types/vendor";
import { useDeleteVendor } from "@/domain/vendors/use-cases/use-delete-vendor"; import { useDeleteVendor } from "@/domain/vendors/use-cases/use-delete-vendor";
import { useVendorDeactivationImpact } from "@/domain/vendors/use-cases/use-vendor-deactivation-impact"; import { useVendorDeactivationImpact } from "@/domain/vendors/use-cases/use-vendor-deactivation-impact";
@ -218,55 +220,37 @@ export default function VendorsListPage() {
return ( return (
<Box className="flex flex-col gap-4 p-4"> <Box className="flex flex-col gap-4 p-4">
<Stack <PageHeader
direction={{ xs: "column", md: "row" }} title="Vendors / Technicians"
spacing={2} subtitle={`${globalCount} technicians · ${activeCount} active`}
sx={{ actions={
alignItems: { xs: "stretch", md: "center" }, <>
justifyContent: "space-between", <TextField
}} size="small"
> value={search}
<Stack direction="row" spacing={2} sx={{ alignItems: "baseline" }}> onChange={(e) => {
<Typography variant="h5" component="h1"> setSearch(e.target.value);
Vendors / Technicians setPage(0);
</Typography> }}
<Typography variant="body2" sx={{ color: "text.secondary" }}> placeholder="Search name, company, trade..."
{globalCount} technicians · {activeCount} active className="min-w-[260px]"
</Typography> />
{isFetching && !isLoading && <CircularProgress size={16} />} <ToolbarButton
</Stack> variant="outline"
icon={<SlidersHorizontal size={13} />}
<Stack onClick={() => setFiltersOpen(true)}
direction={{ xs: "column", sm: "row" }} aria-label="Open vendor filters"
spacing={2} badge={appliedChips.length}
sx={{ alignItems: { xs: "stretch", sm: "center" } }} >
> Filters
<TextField </ToolbarButton>
size="small" <Button variant="contained" onClick={() => setCreateOpen(true)}>
value={search} + Add Vendor
onChange={(e) => { </Button>
setSearch(e.target.value); {Boolean(isFetching && !isLoading) && <CircularProgress size={16} />}
setPage(0); </>
}} }
placeholder="Search name, company, trade..." />
className="min-w-[260px]"
/>
<Button
variant="outlined"
onClick={() => setFiltersOpen(true)}
startIcon={<FilterListIcon />}
aria-label="Open vendor filters"
>
Filters
{appliedChips.length > 0 && (
<Chip size="small" color="primary" label={appliedChips.length} sx={{ ml: 1 }} />
)}
</Button>
<Button variant="contained" onClick={() => setCreateOpen(true)}>
+ Add Vendor
</Button>
</Stack>
</Stack>
<Tabs <Tabs
value={isActive ? "active" : "inactive"} value={isActive ? "active" : "inactive"}
@ -313,7 +297,11 @@ export default function VendorsListPage() {
{TABLE_COLUMNS.map((column) => ( {TABLE_COLUMNS.map((column) => (
<TableCell <TableCell
key={column} key={column}
align={column === "View" || column === "Edit" ? "center" : "left"} align={
column === "View" || column === "Edit" || column === "Total Jobs"
? "center"
: "left"
}
className="font-semibold" className="font-semibold"
> >
{column} {column}
@ -408,7 +396,7 @@ export default function VendorsListPage() {
"—" "—"
)} )}
</TableCell> </TableCell>
<TableCell>{row.totalJobs ?? 0}</TableCell> <TableCell align="center">{row.totalJobs ?? 0}</TableCell>
<TableCell> <TableCell>
<Chip <Chip
size="small" size="small"