import { useParams, useNavigate } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { Box, Typography, Card, CardContent, Grid, Chip, Divider, Button, Skeleton, Stepper, Step, StepLabel, } from '@mui/material'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import { proposalsApi, type ProposalDetail } from '../../../lib/api/proposals'; import { STATUS_COLORS } from '../../../constants'; import { formatCurrency, formatDateTime } from '../../../lib/format'; import { useDocumentTitle } from '../../../hooks/useDocumentTitle'; const STATUS_ORDER = ['Draft', 'InReview', 'Approved', 'Sent']; function InfoRow({ label, value }: { label: string; value: React.ReactNode }) { return ( {label} {value || '-'} ); } export default function ProposalDetailPage() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const { data: proposal, isLoading, error } = useQuery({ queryKey: ['proposals', id], queryFn: () => proposalsApi.getById(id!), enabled: !!id, }); useDocumentTitle(proposal?.proposalNumber ?? 'Proposal'); if (isLoading) { return ( ); } if (error || !proposal) { return ( {error instanceof Error ? error.message : 'Proposal not found'} ); } const activeStep = STATUS_ORDER.indexOf(proposal.status); return ( {proposal.proposalNumber} Status Timeline {proposal.status === 'Revised' ? ( ) : ( = 0 ? activeStep : 0} alternativeLabel> {STATUS_ORDER.map((label) => ( {label} ))} )} Proposal Details Scope of Work {proposal.refinedScope || proposal.scopeOfWork} {proposal.notes && ( <> Notes {proposal.notes} )} {(proposal.approvedAt || proposal.sentAt) && ( Approval & Delivery {proposal.vendorTotalCost !== null && ( )} )} ); }