117 lines
4.6 KiB
TypeScript
117 lines
4.6 KiB
TypeScript
import { Check, ClipboardList, Search, Clock, ThumbsUp, Wrench, Package, HandMetal, Ban, FilePlus } from 'lucide-react'
|
|
|
|
const STEPS = [
|
|
{ key: 'new', label: 'New', icon: FilePlus },
|
|
{ key: 'intake', label: 'Intake', icon: ClipboardList },
|
|
{ key: 'diagnosing', label: 'Diagnosing', icon: Search },
|
|
{ key: 'pending_approval', label: 'Pending Approval', icon: Clock },
|
|
{ key: 'approved', label: 'Approved', icon: ThumbsUp },
|
|
{ key: 'in_progress', label: 'In Progress', icon: Wrench },
|
|
{ key: 'ready', label: 'Ready', icon: Package },
|
|
{ key: 'picked_up', label: 'Picked Up', icon: HandMetal },
|
|
] as const
|
|
|
|
const BRANCH_STATUSES: Record<string, { label: string; parentStep: string }> = {
|
|
in_transit: { label: 'In Transit', parentStep: 'new' },
|
|
pending_parts: { label: 'Pending Parts', parentStep: 'in_progress' },
|
|
delivered: { label: 'Delivered', parentStep: 'picked_up' },
|
|
}
|
|
|
|
interface StatusProgressProps {
|
|
currentStatus: string
|
|
onStatusClick?: (status: string) => void
|
|
}
|
|
|
|
export function StatusProgress({ currentStatus, onStatusClick }: StatusProgressProps) {
|
|
const isCancelled = currentStatus === 'cancelled'
|
|
const isBranch = currentStatus in BRANCH_STATUSES
|
|
|
|
// Find the effective step index for branch statuses
|
|
const effectiveStatus = isBranch ? BRANCH_STATUSES[currentStatus].parentStep : currentStatus
|
|
const currentIdx = STEPS.findIndex((s) => s.key === effectiveStatus)
|
|
|
|
return (
|
|
<div className="space-y-2">
|
|
<div className="flex items-center w-full">
|
|
{STEPS.map((step, idx) => {
|
|
const isCompleted = !isCancelled && currentIdx > idx
|
|
const isCurrent = !isCancelled && currentIdx === idx
|
|
const isFuture = isCancelled || currentIdx < idx
|
|
|
|
return (
|
|
<div key={step.key} className="flex items-center flex-1 last:flex-none">
|
|
{/* Step circle */}
|
|
<button
|
|
type="button"
|
|
disabled={!onStatusClick || isCancelled}
|
|
onClick={() => onStatusClick?.(step.key)}
|
|
className={`
|
|
relative flex flex-col items-center gap-1 group
|
|
${onStatusClick && !isCancelled ? 'cursor-pointer' : 'cursor-default'}
|
|
`}
|
|
>
|
|
<div
|
|
className={`
|
|
flex items-center justify-center h-9 w-9 rounded-full border-2 transition-colors
|
|
${isCompleted ? 'bg-primary border-primary text-primary-foreground' : ''}
|
|
${isCurrent ? 'border-primary bg-primary/10 text-primary ring-2 ring-primary/30' : ''}
|
|
${isFuture ? 'border-muted-foreground/30 text-muted-foreground/40' : ''}
|
|
${isCancelled ? 'border-destructive/30 text-destructive/40' : ''}
|
|
${onStatusClick && !isCancelled ? 'group-hover:border-primary group-hover:text-primary' : ''}
|
|
`}
|
|
>
|
|
{isCompleted ? (
|
|
<Check className="h-4 w-4" />
|
|
) : (
|
|
<step.icon className="h-4 w-4" />
|
|
)}
|
|
</div>
|
|
<span
|
|
className={`
|
|
text-[10px] font-medium text-center leading-tight max-w-[70px]
|
|
${isCompleted ? 'text-primary' : ''}
|
|
${isCurrent ? 'text-primary font-semibold' : ''}
|
|
${isFuture ? 'text-muted-foreground/50' : ''}
|
|
${isCancelled ? 'text-destructive/50' : ''}
|
|
`}
|
|
>
|
|
{step.label}
|
|
</span>
|
|
</button>
|
|
|
|
{/* Connector line */}
|
|
{idx < STEPS.length - 1 && (
|
|
<div
|
|
className={`
|
|
flex-1 h-0.5 mx-1 mt-[-18px]
|
|
${!isCancelled && currentIdx > idx ? 'bg-primary' : 'bg-muted-foreground/20'}
|
|
${isCancelled ? 'bg-destructive/20' : ''}
|
|
`}
|
|
/>
|
|
)}
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
{/* Branch status indicator */}
|
|
{isBranch && (
|
|
<div className="flex items-center gap-2 pl-4">
|
|
<div className="h-3 w-3 rounded-full bg-amber-500" />
|
|
<span className="text-sm font-medium text-amber-600">
|
|
{BRANCH_STATUSES[currentStatus].label}
|
|
</span>
|
|
</div>
|
|
)}
|
|
|
|
{/* Cancelled overlay */}
|
|
{isCancelled && (
|
|
<div className="flex items-center gap-2 pl-4">
|
|
<Ban className="h-4 w-4 text-destructive" />
|
|
<span className="text-sm font-medium text-destructive">Cancelled</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|