- Increased icon sizes in service items, service orders, users, and technician management for better visibility. - Added custom loading indicators with appropriate icons in search fields for vehicles, work orders, and technicians. - Introduced invoice management routes for better organization and access control. - Created a new test for the estimate PDF functionality to ensure proper rendering and data integrity.
140 lines
11 KiB
PHP
140 lines
11 KiB
PHP
<div>
|
|
<div class="space-y-6">
|
|
<!-- Header -->
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-zinc-900 dark:text-zinc-100">Work Orders</h1>
|
|
<p class="text-zinc-600 dark:text-zinc-400">Manage active work orders and service tasks</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg p-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div class="relative">
|
|
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Search</label>
|
|
<input type="text" wire:model.live="search" placeholder="Search work orders, job numbers, or customers..." class="w-full px-3 py-2 border border-zinc-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-700 text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 pr-10">
|
|
<!-- Custom loading indicator with hammer icon -->
|
|
<div wire:loading wire:target="search" class="absolute right-3 top-10 transform -translate-y-1/2">
|
|
<flux:icon.hammer class="w-6 h-6 text-zinc-400 animate-pulse" />
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Status</label>
|
|
<select wire:model.live="statusFilter" class="w-full px-3 py-2 border border-zinc-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-700 text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
<option value="">All Statuses</option>
|
|
<option value="pending">Pending</option>
|
|
<option value="in_progress">In Progress</option>
|
|
<option value="waiting_parts">Waiting for Parts</option>
|
|
<option value="quality_check">Quality Check</option>
|
|
<option value="completed">Completed</option>
|
|
<option value="cancelled">Cancelled</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Priority</label>
|
|
<select wire:model.live="priorityFilter" class="w-full px-3 py-2 border border-zinc-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-700 text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
|
<option value="">All Priorities</option>
|
|
<option value="low">Low</option>
|
|
<option value="normal">Normal</option>
|
|
<option value="high">High</option>
|
|
<option value="urgent">Urgent</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Work Orders List -->
|
|
<div class="bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg">
|
|
@if($workOrders->count() > 0)
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full divide-y divide-zinc-200 dark:divide-zinc-700">
|
|
<thead class="bg-zinc-50 dark:bg-zinc-900">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Work Order #</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Customer</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Vehicle</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Status</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Priority</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Technician</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Due Date</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white dark:bg-zinc-800 divide-y divide-zinc-200 dark:divide-zinc-700">
|
|
@foreach($workOrders as $workOrder)
|
|
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-700">
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
|
{{ $workOrder->work_order_number }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
|
|
{{ $workOrder->jobCard->customer->first_name }} {{ $workOrder->jobCard->customer->last_name }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
|
|
{{ $workOrder->jobCard->vehicle->year }} {{ $workOrder->jobCard->vehicle->make }} {{ $workOrder->jobCard->vehicle->model }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full
|
|
@if($workOrder->status === 'completed') bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200
|
|
@elseif($workOrder->status === 'in_progress') bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
|
|
@elseif($workOrder->status === 'pending') bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200
|
|
@elseif($workOrder->status === 'waiting_parts') bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200
|
|
@elseif($workOrder->status === 'quality_check') bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200
|
|
@else bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200 @endif">
|
|
{{ str_replace('_', ' ', ucfirst($workOrder->status)) }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full
|
|
@if($workOrder->priority === 'urgent') bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200
|
|
@elseif($workOrder->priority === 'high') bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200
|
|
@elseif($workOrder->priority === 'normal') bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
|
|
@else bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200 @endif">
|
|
{{ ucfirst($workOrder->priority) }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
|
|
{{ $workOrder->assignedTechnician->first_name ?? 'Unassigned' }} {{ $workOrder->assignedTechnician->last_name ?? '' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
|
|
{{ $workOrder->target_completion_date ? $workOrder->target_completion_date->format('M j, Y') : 'Not set' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
|
<div class="flex space-x-2">
|
|
<a href="{{ route('work-orders.show', $workOrder) }}" class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300">
|
|
View
|
|
</a>
|
|
<a href="{{ route('work-orders.edit', $workOrder) }}" class="text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
|
Edit
|
|
</a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
<div class="px-6 py-4 border-t border-zinc-200 dark:border-zinc-700">
|
|
{{ $workOrders->links() }}
|
|
</div>
|
|
@else
|
|
<div class="p-12 text-center">
|
|
<svg class="mx-auto h-12 w-12 text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
|
</svg>
|
|
<h3 class="mt-2 text-sm font-medium text-zinc-900 dark:text-zinc-100">No work orders found</h3>
|
|
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
|
@if($search || $statusFilter || $priorityFilter)
|
|
Try adjusting your search criteria.
|
|
@else
|
|
Work orders will appear here once estimates are approved.
|
|
@endif
|
|
</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|