sackey e839d40a99
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Initial commit
2025-07-30 17:15:50 +00:00

444 lines
24 KiB
PHP

<div class="space-y-6">
<!-- Header -->
<div class="flex items-center justify-between">
<div>
<flux:heading size="xl">Service Order {{ $serviceOrder->order_number }}</flux:heading>
<flux:subheading>{{ $serviceOrder->customer->full_name }} {{ $serviceOrder->vehicle->display_name }}</flux:subheading>
</div>
<div class="flex space-x-3">
<flux:button href="/service-orders" variant="outline" size="sm">
<flux:icon name="arrow-left" class="size-4" />
Back to Service Orders
</flux:button>
<flux:button href="/service-orders/{{ $serviceOrder->id }}/edit" variant="outline" size="sm">
<flux:icon name="pencil" class="size-4" />
Edit Order
</flux:button>
@if($serviceOrder->status === 'completed')
<flux:button href="/service-orders/{{ $serviceOrder->id }}/invoice" size="sm">
<flux:icon name="document-text" class="size-4" />
Generate Invoice
</flux:button>
@endif
</div>
</div>
<!-- Flash Messages -->
@if (session()->has('success'))
<div class="bg-green-50 border border-green-200 text-green-800 rounded-md p-4">
<div class="flex">
<flux:icon name="check-circle" class="h-5 w-5 text-green-400" />
<div class="ml-3">
<p class="text-sm font-medium">{{ session('success') }}</p>
</div>
</div>
</div>
@endif
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Main Content -->
<div class="lg:col-span-2 space-y-6">
<!-- Service Order Information -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Service Order Information</flux:heading>
</div>
<div class="p-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<flux:label>Order Number</flux:label>
<div class="mt-1 text-sm font-medium">{{ $serviceOrder->order_number }}</div>
</div>
<div>
<flux:label>Priority</flux:label>
<div class="mt-1">
<flux:badge
:color="$serviceOrder->priority === 'urgent' ? 'red' : ($serviceOrder->priority === 'high' ? 'orange' : ($serviceOrder->priority === 'normal' ? 'blue' : 'gray'))"
size="sm"
>
{{ ucfirst($serviceOrder->priority) }}
</flux:badge>
</div>
</div>
<div>
<flux:label>Status</flux:label>
<div class="mt-1 flex items-center space-x-2">
<flux:badge
:color="$serviceOrder->status === 'completed' ? 'green' : ($serviceOrder->status === 'in_progress' ? 'blue' : ($serviceOrder->status === 'cancelled' ? 'red' : 'gray'))"
size="sm"
>
{{ ucfirst(str_replace('_', ' ', $serviceOrder->status)) }}
</flux:badge>
@if($serviceOrder->status === 'pending')
<button
wire:click="updateStatus('in_progress')"
class="text-xs text-blue-600 hover:underline"
>
Start Work
</button>
@elseif($serviceOrder->status === 'in_progress')
<button
wire:click="updateStatus('completed')"
class="text-xs text-green-600 hover:underline"
>
Complete Work
</button>
@endif
</div>
</div>
<div>
<flux:label>Assigned Technician</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->assignedTechnician?->full_name ?? 'Unassigned' }}</div>
</div>
@if($serviceOrder->scheduled_date)
<div>
<flux:label>Scheduled Date</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->scheduled_date->format('M j, Y') }}</div>
</div>
@endif
<div>
<flux:label>Created</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->created_at->format('M j, Y g:i A') }}</div>
</div>
@if($serviceOrder->started_at)
<div>
<flux:label>Started</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->started_at->format('M j, Y g:i A') }}</div>
</div>
@endif
@if($serviceOrder->completed_at)
<div>
<flux:label>Completed</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->completed_at->format('M j, Y g:i A') }}</div>
</div>
@endif
</div>
<div class="mt-4">
<flux:label>Customer Complaint</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->customer_complaint }}</div>
</div>
@if($serviceOrder->recommended_services)
<div class="mt-4">
<flux:label>Recommended Services</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->recommended_services }}</div>
</div>
@endif
</div>
</div>
<!-- Customer & Vehicle Information -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Customer & Vehicle Information</flux:heading>
</div>
<div class="p-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h4 class="font-medium mb-2">Customer Information</h4>
<div class="space-y-2">
<div>
<flux:label>Name</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->customer->full_name }}</div>
</div>
<div>
<flux:label>Email</flux:label>
<div class="mt-1 text-sm">
<a href="mailto:{{ $serviceOrder->customer->email }}" class="text-blue-600 hover:underline">
{{ $serviceOrder->customer->email }}
</a>
</div>
</div>
<div>
<flux:label>Phone</flux:label>
<div class="mt-1 text-sm">
<a href="tel:{{ $serviceOrder->customer->phone }}" class="text-blue-600 hover:underline">
{{ $serviceOrder->customer->phone }}
</a>
</div>
</div>
</div>
</div>
<div>
<h4 class="font-medium mb-2">Vehicle Information</h4>
<div class="space-y-2">
<div>
<flux:label>Vehicle</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->vehicle->display_name }}</div>
</div>
<div>
<flux:label>License Plate</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->vehicle->license_plate }}</div>
</div>
<div>
<flux:label>VIN</flux:label>
<div class="mt-1 text-sm font-mono">{{ $serviceOrder->vehicle->vin_display }}</div>
</div>
<div>
<flux:label>Mileage</flux:label>
<div class="mt-1 text-sm">{{ number_format($serviceOrder->vehicle->mileage) }} miles</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Service Items -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Service Items</flux:heading>
</div>
<div class="overflow-x-auto">
@if($serviceOrder->serviceItems->count() > 0)
<table class="min-w-full">
<thead>
<tr class="border-b border-zinc-200 dark:border-zinc-700">
<th class="text-left py-2 px-4">Service</th>
<th class="text-left py-2 px-4">Category</th>
<th class="text-left py-2 px-4">Rate</th>
<th class="text-left py-2 px-4">Hours</th>
<th class="text-left py-2 px-4">Status</th>
<th class="text-left py-2 px-4">Cost</th>
</tr>
</thead>
<tbody>
@foreach($serviceOrder->serviceItems as $item)
<tr class="border-b border-zinc-100 dark:border-zinc-700">
<td class="py-2 px-4">
<div class="font-medium">{{ $item->service_name }}</div>
@if($item->description)
<div class="text-sm text-zinc-500 dark:text-zinc-400">{{ $item->description }}</div>
@endif
</td>
<td class="py-2 px-4">{{ $item->category }}</td>
<td class="py-2 px-4">${{ number_format($item->labor_rate, 2) }}</td>
<td class="py-2 px-4">{{ $item->estimated_hours }}h</td>
<td class="py-2 px-4">
<flux:badge
:color="$item->status === 'completed' ? 'green' : ($item->status === 'in_progress' ? 'blue' : 'gray')"
size="sm"
>
{{ ucfirst($item->status) }}
</flux:badge>
</td>
<td class="py-2 px-4 font-medium">${{ number_format($item->labor_cost, 2) }}</td>
</tr>
@endforeach
</tbody>
</table>
@else
<div class="p-4 text-center text-zinc-500 dark:text-zinc-400">
No service items added yet.
</div>
@endif
</div>
</div>
<!-- Parts -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Parts</flux:heading>
</div>
<div class="overflow-x-auto">
@if($serviceOrder->parts->count() > 0)
<table class="min-w-full">
<thead>
<tr class="border-b border-zinc-200 dark:border-zinc-700">
<th class="text-left py-2 px-4">Part</th>
<th class="text-left py-2 px-4">Part Number</th>
<th class="text-left py-2 px-4">Quantity</th>
<th class="text-left py-2 px-4">Unit Price</th>
<th class="text-left py-2 px-4">Status</th>
<th class="text-left py-2 px-4">Total</th>
</tr>
</thead>
<tbody>
@foreach($serviceOrder->parts as $part)
<tr class="border-b border-zinc-100 dark:border-zinc-700">
<td class="py-2 px-4">
<div class="font-medium">{{ $part->name }}</div>
@if($part->pivot->notes)
<div class="text-sm text-zinc-500 dark:text-zinc-400">{{ $part->pivot->notes }}</div>
@endif
</td>
<td class="py-2 px-4">{{ $part->part_number }}</td>
<td class="py-2 px-4">{{ $part->pivot->quantity_used }}</td>
<td class="py-2 px-4">${{ number_format($part->pivot->unit_price, 2) }}</td>
<td class="py-2 px-4">
<flux:badge
:color="$part->pivot->status === 'installed' ? 'green' : ($part->pivot->status === 'ordered' ? 'blue' : 'gray')"
size="sm"
>
{{ ucfirst($part->pivot->status) }}
</flux:badge>
</td>
<td class="py-2 px-4 font-medium">${{ number_format($part->pivot->total_price, 2) }}</td>
</tr>
@endforeach
</tbody>
</table>
@else
<div class="p-4 text-center text-zinc-500 dark:text-zinc-400">
No parts added yet.
</div>
@endif
</div>
</div>
<!-- Notes -->
@if($serviceOrder->internal_notes || $serviceOrder->customer_notes)
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Notes</flux:heading>
</div>
<div class="p-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
@if($serviceOrder->internal_notes)
<div>
<flux:label>Internal Notes</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->internal_notes }}</div>
</div>
@endif
@if($serviceOrder->customer_notes)
<div>
<flux:label>Customer Notes</flux:label>
<div class="mt-1 text-sm">{{ $serviceOrder->customer_notes }}</div>
</div>
@endif
</div>
</div>
</div>
@endif
</div>
<!-- Sidebar -->
<div class="space-y-6">
<!-- Order Totals -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Order Totals</flux:heading>
</div>
<div class="p-4 space-y-3">
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Labor Cost</span>
<span class="font-medium">${{ number_format($serviceOrder->labor_cost, 2) }}</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Parts Cost</span>
<span class="font-medium">${{ number_format($serviceOrder->parts_cost, 2) }}</span>
</div>
@if($serviceOrder->discount_amount > 0)
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Discount</span>
<span class="font-medium text-green-600">-${{ number_format($serviceOrder->discount_amount, 2) }}</span>
</div>
@endif
<div class="flex justify-between border-t pt-2">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Subtotal</span>
<span class="font-medium">${{ number_format($serviceOrder->labor_cost + $serviceOrder->parts_cost - $serviceOrder->discount_amount, 2) }}</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Tax</span>
<span class="font-medium">${{ number_format($serviceOrder->tax_amount, 2) }}</span>
</div>
<div class="flex justify-between border-t pt-2 font-bold text-lg">
<span>Total</span>
<span>${{ number_format($serviceOrder->total_amount, 2) }}</span>
</div>
</div>
</div>
<!-- Quick Stats -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Quick Stats</flux:heading>
</div>
<div class="p-4 space-y-3">
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Service Items</span>
<span class="font-medium">{{ $serviceOrder->serviceItems->count() }}</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Parts Used</span>
<span class="font-medium">{{ $serviceOrder->parts->count() }}</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Estimated Hours</span>
<span class="font-medium">{{ $serviceOrder->estimated_hours ?? 0 }}h</span>
</div>
@if($serviceOrder->actual_hours)
<div class="flex justify-between">
<span class="text-sm text-zinc-600 dark:text-zinc-400">Actual Hours</span>
<span class="font-medium">{{ $serviceOrder->actual_hours }}h</span>
</div>
@endif
</div>
</div>
<!-- Quick Actions -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="border-b border-zinc-200 dark:border-zinc-700 p-4">
<flux:heading size="lg">Quick Actions</flux:heading>
</div>
<div class="p-4 space-y-2">
@if($serviceOrder->status === 'pending')
<flux:button
wire:click="updateStatus('in_progress')"
class="w-full"
size="sm"
>
Start Work
</flux:button>
@elseif($serviceOrder->status === 'in_progress')
<flux:button
wire:click="updateStatus('completed')"
class="w-full"
variant="primary"
size="sm"
>
Complete Work
</flux:button>
<flux:button
wire:click="updateStatus('on_hold')"
class="w-full"
variant="outline"
size="sm"
>
Put on Hold
</flux:button>
@elseif($serviceOrder->status === 'on_hold')
<flux:button
wire:click="updateStatus('in_progress')"
class="w-full"
size="sm"
>
Resume Work
</flux:button>
@endif
@if($serviceOrder->status === 'completed')
<flux:button
href="/service-orders/{{ $serviceOrder->id }}/invoice"
class="w-full"
variant="primary"
size="sm"
>
Generate Invoice
</flux:button>
@endif
<flux:button
href="/appointments/create?service_order={{ $serviceOrder->id }}"
class="w-full"
variant="outline"
size="sm"
>
Schedule Follow-up
</flux:button>
</div>
</div>
</div>
</div>
</div>