import { useMemo, useState } from "react"; import { Alert, Box, CircularProgress, Stack, Tab, Tabs, Typography } from "@mui/material"; import type { GridRowParams, GridRowSelectionModel } from "@mui/x-data-grid"; import { CreatePayRunButton } from "@/dashboard/CreatePayRunButton"; import { InvoiceDataGrid } from "@/dashboard/InvoiceDataGrid"; import { allInvoicesColumns, pendingApprovalColumns, readyToPayColumns } from "@/dashboard/columns"; import { countSelectedRows } from "@/dashboard/selection"; import { useInvoices, useUpdateInvoicePayDate } from "@/domain/invoices/use-invoices"; import { areMocksEnabled, type MockInvoice } from "@/mocks"; import { useNavigate } from "@/router"; type DashboardTab = "pending" | "ready" | "all"; const emptySelection: GridRowSelectionModel = { type: "include", ids: new Set(), }; const rowClickSx = { border: 1, borderColor: "divider", backgroundColor: "background.paper", cursor: "pointer", } as const; export function DashboardGrids() { const navigate = useNavigate(); const [tab, setTab] = useState("pending"); const [selection, setSelection] = useState(emptySelection); const { data: invoices = [], isLoading, isError, error } = useInvoices(); const updatePayDate = useUpdateInvoicePayDate(); const openInvoice = (params: GridRowParams) => { navigate("/invoices/:id", { params: { id: params.row.id } }); }; const pendingRows = useMemo( () => invoices.filter((invoice) => invoice.status === "pending_approval"), [invoices], ); const readyRows = useMemo( () => invoices.filter((invoice) => invoice.status === "approved"), [invoices], ); const selectedCount = countSelectedRows( selection, readyRows.map((invoice) => invoice.id), ); const processRowUpdate = async (newRow: MockInvoice, oldRow: MockInvoice) => { if (newRow.payDate === oldRow.payDate) { return oldRow; } const nextPayDate = newRow.payDate?.trim() ? newRow.payDate.trim() : null; return updatePayDate.mutateAsync({ id: newRow.id, payDate: nextPayDate }); }; if (isLoading) { return ( ); } if (isError) { return ( {error instanceof Error ? error.message : "Failed to load invoices"} ); } return ( { setTab(value); setSelection(emptySelection); }} aria-label="Invoice dashboard tabs" > {tab === "pending" && ( )} {tab === "ready" && ( setSelection(model)} processRowUpdate={processRowUpdate} onProcessRowUpdateError={(processError) => { console.error(processError); }} sx={rowClickSx} /> Double-click Pay Date to edit (ISO YYYY-MM-DD). Changes update mock state only. Open detail from the Invoice # link. )} {tab === "all" && ( )} Mocks {areMocksEnabled() ? "enabled" : "disabled"} — {invoices.length} invoices ); }