Add 'new' status as default, in_transit becomes branch state
New tickets start as 'new' (just created, not yet examined). In Transit is now a branch status off New for school pickups and shipped instruments. Intake means the instrument has been physically received and documented. Status progress bar, labels, filters, and default status all updated. Removed debug logging from file upload endpoint.
This commit is contained in:
@@ -6,6 +6,7 @@ import { Label } from '@/components/ui/label'
|
||||
import { Filter, X } from 'lucide-react'
|
||||
|
||||
const ALL_STATUSES = [
|
||||
{ value: 'new', label: 'New' },
|
||||
{ value: 'in_transit', label: 'In Transit' },
|
||||
{ value: 'intake', label: 'Intake' },
|
||||
{ value: 'diagnosing', label: 'Diagnosing' },
|
||||
@@ -19,7 +20,7 @@ const ALL_STATUSES = [
|
||||
{ value: 'cancelled', label: 'Cancelled' },
|
||||
]
|
||||
|
||||
const ACTIVE_STATUSES = ['in_transit', 'intake', 'diagnosing', 'pending_approval', 'approved', 'in_progress', 'pending_parts', 'ready']
|
||||
const ACTIVE_STATUSES = ['new', 'in_transit', 'intake', 'diagnosing', 'pending_approval', 'approved', 'in_progress', 'pending_parts', 'ready']
|
||||
|
||||
const CONDITIONS = [
|
||||
{ value: 'excellent', label: 'Excellent' },
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Check, Truck, ClipboardList, Search, Clock, ThumbsUp, Wrench, Package, HandMetal, Ban } from 'lucide-react'
|
||||
import { Check, Truck, ClipboardList, Search, Clock, ThumbsUp, Wrench, Package, HandMetal, Ban, FilePlus } from 'lucide-react'
|
||||
|
||||
const STEPS = [
|
||||
{ key: 'in_transit', label: 'In Transit', icon: Truck },
|
||||
{ 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 },
|
||||
@@ -12,6 +12,7 @@ const STEPS = [
|
||||
] 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' },
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ export function TicketNotes({ ticketId }: TicketNotesProps) {
|
||||
// Upload attached photos to the note
|
||||
for (const photo of photos) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', photo)
|
||||
formData.append('entityType', 'repair_note')
|
||||
formData.append('entityId', note.id)
|
||||
formData.append('category', 'attachment')
|
||||
formData.append('file', photo)
|
||||
const uploadRes = await fetch('/v1/files', {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
|
||||
@@ -39,6 +39,7 @@ export const Route = createFileRoute('/_authenticated/repairs/$ticketId')({
|
||||
})
|
||||
|
||||
const STATUS_LABELS: Record<string, string> = {
|
||||
new: 'New',
|
||||
in_transit: 'In Transit',
|
||||
intake: 'Intake',
|
||||
diagnosing: 'Diagnosing',
|
||||
@@ -52,7 +53,7 @@ const STATUS_LABELS: Record<string, string> = {
|
||||
cancelled: 'Cancelled',
|
||||
}
|
||||
|
||||
const STATUS_FLOW = ['in_transit', 'intake', 'diagnosing', 'pending_approval', 'approved', 'in_progress', 'ready', 'picked_up']
|
||||
const STATUS_FLOW = ['new', 'intake', 'diagnosing', 'pending_approval', 'approved', 'in_progress', 'ready', 'picked_up']
|
||||
|
||||
const TABS = [
|
||||
{ key: 'details', label: 'Details' },
|
||||
@@ -217,6 +218,11 @@ function RepairTicketDetailPage() {
|
||||
Move to {STATUS_LABELS[nextStatus]}
|
||||
</Button>
|
||||
)}
|
||||
{ticket.status === 'new' && (
|
||||
<Button variant="secondary" onClick={() => statusMutation.mutate('in_transit')} disabled={statusMutation.isPending}>
|
||||
In Transit
|
||||
</Button>
|
||||
)}
|
||||
{ticket.status === 'in_progress' && (
|
||||
<Button variant="secondary" onClick={() => statusMutation.mutate('pending_parts')} disabled={statusMutation.isPending}>
|
||||
Pending Parts
|
||||
@@ -235,7 +241,7 @@ function RepairTicketDetailPage() {
|
||||
</>
|
||||
)}
|
||||
{ticket.status === 'cancelled' && hasPermission('repairs.admin') && (
|
||||
<Button variant="outline" onClick={() => statusMutation.mutate('intake')} disabled={statusMutation.isPending}>
|
||||
<Button variant="outline" onClick={() => statusMutation.mutate('new')} disabled={statusMutation.isPending}>
|
||||
<RotateCcw className="mr-2 h-4 w-4" />Reopen
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -26,6 +26,7 @@ export const Route = createFileRoute('/_authenticated/repairs/')({
|
||||
|
||||
function statusBadge(status: string) {
|
||||
const variants: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {
|
||||
new: 'outline',
|
||||
in_transit: 'secondary',
|
||||
intake: 'outline',
|
||||
diagnosing: 'secondary',
|
||||
@@ -39,6 +40,7 @@ function statusBadge(status: string) {
|
||||
cancelled: 'destructive',
|
||||
}
|
||||
const labels: Record<string, string> = {
|
||||
new: 'New',
|
||||
in_transit: 'In Transit',
|
||||
intake: 'Intake',
|
||||
diagnosing: 'Diagnosing',
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface RepairTicket {
|
||||
conditionInNotes: string | null
|
||||
problemDescription: string
|
||||
technicianNotes: string | null
|
||||
status: 'in_transit' | 'intake' | 'diagnosing' | 'pending_approval' | 'approved' | 'in_progress' | 'pending_parts' | 'ready' | 'picked_up' | 'delivered' | 'cancelled'
|
||||
status: 'new' | 'in_transit' | 'intake' | 'diagnosing' | 'pending_approval' | 'approved' | 'in_progress' | 'pending_parts' | 'ready' | 'picked_up' | 'delivered' | 'cancelled'
|
||||
assignedTechnicianId: string | null
|
||||
estimatedCost: string | null
|
||||
actualCost: string | null
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TYPE "repair_ticket_status" ADD VALUE 'new' BEFORE 'in_transit';
|
||||
@@ -134,6 +134,13 @@
|
||||
"when": 1774780000000,
|
||||
"tag": "0018_repair_notes",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 19,
|
||||
"version": "7",
|
||||
"when": 1774790000000,
|
||||
"tag": "0019_repair_new_status",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import { users } from './users.js'
|
||||
// --- Enums ---
|
||||
|
||||
export const repairTicketStatusEnum = pgEnum('repair_ticket_status', [
|
||||
'new',
|
||||
'in_transit',
|
||||
'intake',
|
||||
'diagnosing',
|
||||
@@ -112,7 +113,7 @@ export const repairTickets = pgTable('repair_ticket', {
|
||||
conditionInNotes: text('condition_in_notes'),
|
||||
problemDescription: text('problem_description').notNull(),
|
||||
technicianNotes: text('technician_notes'),
|
||||
status: repairTicketStatusEnum('status').notNull().default('intake'),
|
||||
status: repairTicketStatusEnum('status').notNull().default('new'),
|
||||
assignedTechnicianId: uuid('assigned_technician_id').references(() => users.id),
|
||||
estimatedCost: numeric('estimated_cost', { precision: 10, scale: 2 }),
|
||||
actualCost: numeric('actual_cost', { precision: 10, scale: 2 }),
|
||||
|
||||
@@ -8,7 +8,7 @@ function opt<T extends z.ZodTypeAny>(schema: T) {
|
||||
// --- Status / Type enums ---
|
||||
|
||||
export const RepairTicketStatus = z.enum([
|
||||
'in_transit', 'intake', 'diagnosing', 'pending_approval', 'approved',
|
||||
'new', 'in_transit', 'intake', 'diagnosing', 'pending_approval', 'approved',
|
||||
'in_progress', 'pending_parts', 'ready', 'picked_up', 'delivered', 'cancelled',
|
||||
])
|
||||
export type RepairTicketStatus = z.infer<typeof RepairTicketStatus>
|
||||
|
||||
Reference in New Issue
Block a user