import { Box, Button, Chip, CircularProgress, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip, } from "@mui/material"; import { formatUpliftMoney, isGrantedAmount, } from "@/app/(protected)/uplifts/_components/format-uplift-money"; import { UPLIFT_APPROVAL_HEADER_CELLS, type UpliftApprovalTab, } from "@/app/(protected)/uplifts/_components/uplift-approval-tabs"; import { RejectedEmptyState, RejectedRowCells, } from "@/app/(protected)/uplifts/_components/uplift-rejected-cells"; import { Text } from "@/components/ui/text"; import { useUpliftsCanApprove } from "@/domain/uplifts/use-cases/use-uplifts-can-approve"; import { upliftAmount } from "@/domain/uplifts/utils/uplift-amount"; import type { UpliftQueueItem } from "@/domain/uplifts/types/uplift"; import { formatDateTime, getWaitTimeTextClass, timeSince, waitTimeColor } from "@/lib/time-utils"; const CLOSED_WO_TOOLTIP = "This work order is closed. Uplifts can no longer be revoked."; const ADMIN_ONLY_REVOKE_TOOLTIP = "Only admins can revoke uplifts"; function workOrderLabel(row: UpliftQueueItem): string { return row.woNumber || row.dispatchNumber || "—"; } function WaitingCell({ row }: { row: UpliftQueueItem }) { if (!row.requestedAt) { return ( — ); } const color = waitTimeColor(row.requestedAt); const className = getWaitTimeTextClass(color); return ( {timeSince(row.requestedAt)} ); } function AttachmentsCell({ row, onOpenAttachment, }: { row: UpliftQueueItem; onOpenAttachment: (row: UpliftQueueItem) => void; }) { if (row.evidenceDocumentId == null && !row.evidenceFileName) { return ( — ); } const extraCount = typeof row.attachmentCount === "number" && row.attachmentCount > 1 ? row.attachmentCount - 1 : 0; return ( onOpenAttachment(row) : undefined} clickable={row.evidenceDocumentId != null} /> {extraCount > 0 && } ); } function PendingRowActions({ row, onApprove, onReject, isDecisionPending, }: { row: UpliftQueueItem; onApprove: (row: UpliftQueueItem) => void; onReject: (row: UpliftQueueItem) => void; isDecisionPending: boolean; }) { const canApproveTier = useUpliftsCanApprove(row.requiredTier); const canDecide = row.canDecide && canApproveTier.data === true; const tooltip = canDecide ? "" : `Requires Tier ${row.requiredTier} role`; return ( e.stopPropagation()}> ); } function ApprovedRowActions({ row, canRevoke, onRevoke, isDecisionPending, }: { row: UpliftQueueItem; canRevoke: boolean; onRevoke: (row: UpliftQueueItem) => void; isDecisionPending: boolean; }) { const closed = row.workOrderClosed === true; const tooltip = !canRevoke ? ADMIN_ONLY_REVOKE_TOOLTIP : closed ? CLOSED_WO_TOOLTIP : ""; return ( e.stopPropagation()}> ); } function UpliftApprovalRow({ row, tab, canRevoke, onOpenDetail, onApprove, onReject, onRevoke, onOpenAttachment, isDecisionPending, }: { row: UpliftQueueItem; tab: UpliftApprovalTab; canRevoke: boolean; onOpenDetail: (row: UpliftQueueItem) => void; onApprove: (row: UpliftQueueItem) => void; onReject: (row: UpliftQueueItem) => void; onRevoke: (row: UpliftQueueItem) => void; onOpenAttachment: (row: UpliftQueueItem) => void; isDecisionPending: boolean; }) { return ( onOpenDetail(row)} onKeyDown={(e) => { if (e.key === "Enter") onOpenDetail(row); }} tabIndex={0} aria-label={`Open uplift details for ${workOrderLabel(row)}`} > {workOrderLabel(row)} {Boolean(row.site) && ( {row.site} )} {Boolean(row.serviceName) && ( {row.serviceName} )} {row.vendorCompanyName || "—"} {formatUpliftMoney(upliftAmount(row))} {isGrantedAmount(row.approvedOnWoTotal) ? ( {formatUpliftMoney(row.approvedOnWoTotal)} ) : ( — )} {row.vendorReason} {row.requestedByVendorName || "—"} {tab === "pending" && ( <> )} {tab === "approved" && ( <> {row.decidedByName || "—"} {row.decidedAt ? formatDateTime(row.decidedAt) : "—"} )} {tab === "rejected" && } ); } function UpliftApprovalsEmptyState({ tab }: { tab: UpliftApprovalTab }) { if (tab === "rejected") return ; if (tab === "approved") { return ( No approved uplifts yet Uplifts you approve are archived here for reference. ); } return ( No uplifts waiting for approval. ); } // A failed queue is not an empty one: the page's error alert explains it, so the // empty-state copy must not also claim the list has nothing in it. function UpliftApprovalsEmptyRow({ tab, colSpan, hasError, }: { tab: UpliftApprovalTab; colSpan: number; hasError: boolean; }) { if (hasError) return null; return ( ); } export function UpliftApprovalsTable({ tab, isLoading, hasError, rows, canRevoke, onOpenDetail, onApprove, onReject, onRevoke, onOpenAttachment, isDecisionPending, }: { tab: UpliftApprovalTab; isLoading: boolean; hasError: boolean; rows: UpliftQueueItem[]; canRevoke: boolean; onOpenDetail: (row: UpliftQueueItem) => void; onApprove: (row: UpliftQueueItem) => void; onReject: (row: UpliftQueueItem) => void; onRevoke: (row: UpliftQueueItem) => void; onOpenAttachment: (row: UpliftQueueItem) => void; isDecisionPending: boolean; }) { const headerCells = UPLIFT_APPROVAL_HEADER_CELLS[tab]; return ( {headerCells.map((label) => ( {label} ))} {isLoading ? ( ) : rows.length === 0 ? ( ) : ( rows.map((row) => ( )) )}
); }