198 lines
15 KiB
PHP
198 lines
15 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">Job Cards</h1>
|
|
<p class="text-zinc-600 dark:text-zinc-400">Manage vehicle service job cards</p>
|
|
</div>
|
|
<a href="{{ route('job-cards.create') }}" class="inline-flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors">
|
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
|
|
</svg>
|
|
New Job Card
|
|
</a>
|
|
</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-5 gap-4">
|
|
<div>
|
|
<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 job cards..." 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">
|
|
</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>
|
|
@foreach($statusOptions as $value => $label)
|
|
<option value="{{ $value }}">{{ $label }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Branch</label>
|
|
<select wire:model.live="branchFilter" 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 branches</option>
|
|
@foreach($branchOptions as $value => $label)
|
|
<option value="{{ $value }}">{{ $label }}</option>
|
|
@endforeach
|
|
</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>
|
|
@foreach($priorityOptions as $value => $label)
|
|
<option value="{{ $value }}">{{ $label }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Sort By</label>
|
|
<select wire:model.live="sortBy" 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="created_at">Created Date</option>
|
|
<option value="arrival_datetime">Arrival Date</option>
|
|
<option value="job_card_number">Job Card #</option>
|
|
<option value="priority">Priority</option>
|
|
<option value="status">Status</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Job Cards List -->
|
|
<div class="bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg">
|
|
@if($jobCards->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 cursor-pointer" wire:click="sortBy('job_card_number')">
|
|
Job Card #
|
|
@if($sortBy === 'job_card_number')
|
|
<span class="ml-1">{{ $sortDirection === 'asc' ? '↑' : '↓' }}</span>
|
|
@endif
|
|
</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 cursor-pointer" wire:click="sortBy('status')">
|
|
Status
|
|
@if($sortBy === 'status')
|
|
<span class="ml-1">{{ $sortDirection === 'asc' ? '↑' : '↓' }}</span>
|
|
@endif
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider cursor-pointer" wire:click="sortBy('priority')">
|
|
Priority
|
|
@if($sortBy === 'priority')
|
|
<span class="ml-1">{{ $sortDirection === 'asc' ? '↑' : '↓' }}</span>
|
|
@endif
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider cursor-pointer" wire:click="sortBy('arrival_datetime')">
|
|
Arrival Date
|
|
@if($sortBy === 'arrival_datetime')
|
|
<span class="ml-1">{{ $sortDirection === 'asc' ? '↑' : '↓' }}</span>
|
|
@endif
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">Service Advisor</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($jobCards as $jobCard)
|
|
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-700">
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<a href="{{ route('job-cards.show', $jobCard) }}" class="font-semibold text-blue-600 hover:text-blue-800">
|
|
{{ $jobCard->job_card_number }}
|
|
</a>
|
|
<div class="text-xs text-zinc-500 dark:text-zinc-400">{{ $jobCard->branch_code }}</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<div>
|
|
<div class="font-medium text-zinc-900 dark:text-zinc-100">{{ $jobCard->customer->first_name }} {{ $jobCard->customer->last_name }}</div>
|
|
<div class="text-sm text-zinc-500 dark:text-zinc-400">{{ $jobCard->customer->phone }}</div>
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<div>
|
|
<div class="font-medium text-zinc-900 dark:text-zinc-100">{{ $jobCard->vehicle->year }} {{ $jobCard->vehicle->make }} {{ $jobCard->vehicle->model }}</div>
|
|
<div class="text-sm text-zinc-500 dark:text-zinc-400">{{ $jobCard->vehicle->license_plate }}</div>
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
@php
|
|
$statusColors = [
|
|
'received' => 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
|
|
'in_diagnosis' => 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
'estimate_sent' => 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200',
|
|
'approved' => 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
'in_progress' => 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200',
|
|
'quality_check' => 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-200',
|
|
'completed' => 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
|
'delivered' => 'bg-zinc-100 text-zinc-800 dark:bg-zinc-700 dark:text-zinc-200',
|
|
'cancelled' => 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'
|
|
];
|
|
@endphp
|
|
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full {{ $statusColors[$jobCard->status] ?? 'bg-zinc-100 text-zinc-800 dark:bg-zinc-700 dark:text-zinc-200' }}">
|
|
{{ $statusOptions[$jobCard->status] ?? ucwords(str_replace('_', ' ', $jobCard->status)) }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
@php
|
|
$priorityColors = [
|
|
'urgent' => 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
'high' => 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200',
|
|
'medium' => 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
|
|
'low' => 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'
|
|
];
|
|
@endphp
|
|
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full {{ $priorityColors[$jobCard->priority] ?? 'bg-zinc-100 text-zinc-800 dark:bg-zinc-700 dark:text-zinc-200' }}">
|
|
{{ $priorityOptions[$jobCard->priority] ?? ucfirst($jobCard->priority) }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
|
|
{{ $jobCard->arrival_datetime->format('M d, Y H:i') }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
|
|
{{ $jobCard->serviceAdvisor?->name ?? 'Unassigned' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
|
<div class="flex space-x-2">
|
|
<a href="{{ route('job-cards.show', $jobCard) }}" class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300">View</a>
|
|
<a href="{{ route('job-cards.edit', $jobCard) }}" class="text-green-600 hover:text-green-900 dark:text-green-400 dark:hover:text-green-300">Edit</a>
|
|
@if($jobCard->status === 'received')
|
|
<a href="{{ route('job-cards.workflow', $jobCard) }}" class="text-purple-600 hover:text-purple-900 dark:text-purple-400 dark:hover:text-purple-300">Start Workflow</a>
|
|
@endif
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
@if($jobCards->hasPages())
|
|
<div class="px-6 py-4 border-t border-zinc-200 dark:border-zinc-700">
|
|
{{ $jobCards->links() }}
|
|
</div>
|
|
@endif
|
|
@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 job cards found</h3>
|
|
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
|
@if($search || $statusFilter || $branchFilter || $priorityFilter)
|
|
Try adjusting your search criteria.
|
|
@else
|
|
Job cards will appear here once they are created.
|
|
@endif
|
|
</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|