import { createFileRoute, useNavigate } from '@tanstack/react-router' import { useQuery } from '@tanstack/react-query' import { useState } from 'react' import { repairTicketListOptions } from '@/api/repairs' import { usePagination } from '@/hooks/use-pagination' import { DataTable, type Column } from '@/components/shared/data-table' import { RepairFilterPanel, DEFAULT_FILTERS, type RepairFilters } from '@/components/repairs/repair-filters' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { Plus, Search } from 'lucide-react' import { useAuthStore } from '@/stores/auth.store' import type { RepairTicket } from '@/types/repair' import type { PaginationInput } from '@forte/shared/schemas' export const Route = createFileRoute('/_authenticated/repairs/')({ validateSearch: (search: Record) => ({ page: Number(search.page) || 1, limit: Number(search.limit) || 25, q: (search.q as string) || undefined, sort: (search.sort as string) || undefined, order: (search.order as 'asc' | 'desc') || 'desc', }), component: RepairsListPage, }) function statusBadge(status: string) { const variants: Record = { in_transit: 'secondary', intake: 'outline', diagnosing: 'secondary', pending_approval: 'secondary', approved: 'default', in_progress: 'default', pending_parts: 'secondary', ready: 'default', picked_up: 'outline', delivered: 'outline', cancelled: 'destructive', } const labels: Record = { in_transit: 'In Transit', intake: 'Intake', diagnosing: 'Diagnosing', pending_approval: 'Pending Approval', approved: 'Approved', in_progress: 'In Progress', pending_parts: 'Pending Parts', ready: 'Ready', picked_up: 'Picked Up', delivered: 'Delivered', cancelled: 'Cancelled', } return {labels[status] ?? status} } const columns: Column[] = [ { key: 'ticket_number', header: 'Ticket #', sortable: true, render: (t) => {t.ticketNumber ?? '-'}, }, { key: 'customer_name', header: 'Customer', sortable: true, render: (t) => {t.customerName}, }, { key: 'instrument', header: 'Instrument', render: (t) => <>{t.instrumentDescription ?? '-'}, }, { key: 'status', header: 'Status', sortable: true, render: (t) => statusBadge(t.status), }, { key: 'batch', header: 'Batch', render: (t) => t.repairBatchId ? Batch : -, }, { key: 'intake_date', header: 'Intake', sortable: true, render: (t) => <>{new Date(t.intakeDate).toLocaleDateString()}, }, { key: 'promised_date', header: 'Promised', sortable: true, render: (t) => <>{t.promisedDate ? new Date(t.promisedDate).toLocaleDateString() : '-'}, }, { key: 'estimated_cost', header: 'Estimate', render: (t) => <>{t.estimatedCost ? `$${t.estimatedCost}` : '-'}, }, ] function RepairsListPage() { const navigate = useNavigate() const hasPermission = useAuthStore((s) => s.hasPermission) const { params, setPage, setSearch, setSort } = usePagination() const [searchInput, setSearchInput] = useState(params.q ?? '') const [filters, setFilters] = useState(DEFAULT_FILTERS) // Build query params with filters const queryParams: Record = { ...params } if (filters.status?.length) queryParams.status = filters.status.join(',') if (filters.conditionIn?.length) queryParams.conditionIn = filters.conditionIn.join(',') if (filters.isBatch !== undefined) queryParams.isBatch = String(filters.isBatch) if (filters.intakeDateFrom) queryParams.intakeDateFrom = filters.intakeDateFrom if (filters.intakeDateTo) queryParams.intakeDateTo = filters.intakeDateTo if (filters.promisedDateFrom) queryParams.promisedDateFrom = filters.promisedDateFrom if (filters.promisedDateTo) queryParams.promisedDateTo = filters.promisedDateTo const { data, isLoading } = useQuery(repairTicketListOptions(queryParams as PaginationInput)) function handleSearchSubmit(e: React.FormEvent) { e.preventDefault() setSearch(searchInput) } function handleRowClick(ticket: RepairTicket) { navigate({ to: '/repairs/$ticketId', params: { ticketId: ticket.id }, search: {} as any }) } return (

Repairs

{hasPermission('repairs.edit') && ( )}
setSearchInput(e.target.value)} className="pl-9" />
) }