import { useNavigate } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { Box, Typography, Card, CardContent, Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Chip, Button, Skeleton, } from '@mui/material'; import AddCircleIcon from '@mui/icons-material/AddCircle'; import DescriptionIcon from '@mui/icons-material/Description'; import HourglassTopIcon from '@mui/icons-material/HourglassTop'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import SendIcon from '@mui/icons-material/Send'; import { proposalsApi, type ProposalListItem, type ProposalStats } from '../../lib/api/proposals'; import { QUERY_KEYS } from '../../constants/queryKeys'; import { STATUS_COLORS, STATUS_LABELS, PRIORITY_ROW_SX } from '../../constants'; import { formatBidAmount, formatDate } from '../../lib/format'; import { useDocumentTitle } from '../../hooks/useDocumentTitle'; import { useAuth } from '../../hooks/useAuth'; function KpiCard({ icon, label, value }: { icon: React.ReactNode; label: string; value: string }) { return ( {icon} {label} {value} ); } export default function Dashboard() { useDocumentTitle('Dashboard'); const navigate = useNavigate(); const { user } = useAuth(); const isAdmin = user?.role === 'Admin' || user?.role === 'SysAdmin'; const { data: recentData, isLoading: recentLoading, error: recentError } = useQuery<{ items: ProposalListItem[]; totalCount: number }>({ queryKey: [QUERY_KEYS.proposals, 'dashboard-recent', isAdmin], queryFn: () => proposalsApi.getAll({ page: 1, pageSize: 5, mine: !isAdmin }), }); const { data: stats, isLoading: statsLoading } = useQuery({ queryKey: [QUERY_KEYS.proposals, 'stats'], queryFn: () => proposalsApi.getStats(), }); const isLoading = recentLoading || statsLoading; const proposals = recentData?.items ?? []; const total = stats?.totalCount ?? 0; const counts = { inReview: stats?.inReviewCount ?? 0, approved: stats?.approvedCount ?? 0, sent: stats?.sentCount ?? 0, }; return ( Dashboard {isLoading ? ( ) : ( } label="Total Submitted" value={String(total)} /> )} {isLoading ? ( ) : ( } label="In Review" value={String(counts.inReview)} /> )} {isLoading ? ( ) : ( } label="Approved" value={String(counts.approved)} /> )} {isLoading ? ( ) : ( } label="Sent" value={String(counts.sent)} /> )} Recent Proposals Proposal # Customer Category Status Bid Amount Submitted {isLoading ? Array.from({ length: 5 }).map((_, i) => ( {Array.from({ length: 6 }).map((_, j) => ( ))} )) : proposals.map((row) => ( navigate(`/proposals/${row.id}`)} > {row.proposalNumber} {row.customerName} {row.serviceCategory} {formatBidAmount(row.totalBidAmount)} {formatDate(row.submittedAt)} ))} {!isLoading && recentError && ( Failed to load proposals. Please try again. )} {!isLoading && !recentError && proposals.length === 0 && ( No proposals yet. Submit your first one! )}
); }