import { useMemo, useState } from "react"; import { Alert, Box, Button, Chip, CircularProgress, Stack, Tab, Tabs, Typography, } from "@mui/material"; import type { GridRowParams, GridRowSelectionModel } from "@mui/x-data-grid"; import { isReadyToPay } from "@seahaven-ap/shared"; import { CreatePayRunButton } from "@/dashboard/CreatePayRunButton"; import { InvoiceDataGrid } from "@/dashboard/InvoiceDataGrid"; import { pendingApprovalColumns, readyToPayColumns } from "@/dashboard/columns"; import { countSelectedRows } from "@/dashboard/selection"; import { useInvoices, useUpdateInvoicePayDate } from "@/domain/invoices/use-invoices"; import type { MockInvoice } from "@/mocks"; import { useNavigate } from "@/router"; type PaymentTab = "outside" | "select" | "pending" | "scheduled" | "errors" | "outbox"; const emptySelection: GridRowSelectionModel = { type: "include", ids: new Set(), }; const rowClickSx = { border: 1, borderColor: "divider", backgroundColor: "background.paper", cursor: "pointer", borderRadius: 1, } as const; export function PaymentProcessingGrids() { const navigate = useNavigate(); const [tab, setTab] = useState("select"); 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 selectRows = useMemo( () => invoices.filter((invoice) => isReadyToPay(invoice.status)), [invoices], ); const pendingRows = useMemo( () => invoices.filter((invoice) => invoice.status === "pending_approval"), [invoices], ); const scheduledRows = useMemo( () => invoices.filter((invoice) => invoice.status === "scheduled"), [invoices], ); const selectedCount = countSelectedRows( selection, selectRows.map((invoice) => invoice.id), ); const totalDue = selectRows.reduce((sum, row) => sum + row.amountDue, 0); 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 payments"} ); } return ( { setTab(value); setSelection(emptySelection); }} variant="scrollable" aria-label="Payment Processing tabs" sx={{ minHeight: 44, "& .MuiTab-root": { bgcolor: "rgba(47,128,237,0.18)", mr: 0.5, borderTopLeftRadius: 6, borderTopRightRadius: 6, color: "text.primary", }, "& .Mui-selected": { bgcolor: "#fff !important", color: "text.primary !important", }, "& .MuiTabs-indicator": { display: "none" }, }} > Expedited payments are currently unavailable for you due to various factors. (parity stub) {tab === "select" && ( setSelection(model)} processRowUpdate={processRowUpdate} onProcessRowUpdateError={(processError) => { console.error(processError); }} onRowClick={openInvoice} sx={rowClickSx} /> )} {tab === "pending" && ( )} {tab === "scheduled" && ( )} {(tab === "outside" || tab === "errors" || tab === "outbox") && ( No Result Found parity stub )} Total Due:{" "} {totalDue.toLocaleString("en-US", { style: "currency", currency: "USD" })} Total To Pay:{" "} $0.00 Estimated USD:{" "} $0.00 ); }