import { useNavigate } from 'react-router-dom'; import { Box, Typography, Card, CardContent, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination, Chip, TextField, InputAdornment, Button, Skeleton, } from '@mui/material'; import SearchIcon from '@mui/icons-material/Search'; import AddCircleIcon from '@mui/icons-material/AddCircle'; import { usePaginatedList } from '../../../hooks/usePaginatedList'; import { proposalsApi, type ProposalListItem } from '../../../lib/api/proposals'; const STATUS_COLORS: Record = { Draft: 'default', InReview: 'info', Approved: 'success', Sent: 'success', Revised: 'warning', }; function formatCurrency(amount: number): string { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount); } function formatDate(iso: string): string { return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }); } export default function ProposalListPage() { const navigate = useNavigate(); const { rows, search, setSearch, page, setPage, pageSize, setPageSize, totalCount, loading, err, } = usePaginatedList(proposalsApi.getAll); return ( My Proposals setSearch(e.target.value)} sx={{ mb: 2, width: 320 }} slotProps={{ input: { startAdornment: ( ), }, }} /> {err && ( {err} )} Proposal # Customer WO # Category Priority Status Bid Amount Submitted {loading ? Array.from({ length: 5 }).map((_, i) => ( {Array.from({ length: 8 }).map((_, j) => ( ))} )) : rows.map((row) => ( navigate(`/proposals/${row.id}`)} > {row.proposalNumber} {row.customerName} {row.workOrderNumber} {row.serviceCategory} {row.priority} {formatCurrency(row.totalBidAmount)} {formatDate(row.submittedAt)} ))} {!loading && rows.length === 0 && ( No proposals found. Create your first one! )}
setPage(newPage + 1)} rowsPerPage={pageSize} onRowsPerPageChange={(e) => setPageSize(parseInt(e.target.value, 10))} rowsPerPageOptions={[12, 24, 48]} />
); }