sackey e3b2b220d2
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Enhance UI and functionality across various components
- 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.
2025-08-16 14:36:58 +00:00

201 lines
14 KiB
PHP

<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<!-- Page Header -->
<div class="mb-8">
<div class="flex items-center justify-between">
<div>
<h1 class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100">Diagnoses</h1>
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Manage vehicle diagnostic records and analysis
</p>
</div>
<div class="flex items-center space-x-3">
<button wire:click="refreshList" class="inline-flex items-center px-4 py-2 border border-zinc-300 dark:border-zinc-600 hover:bg-zinc-50 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 font-medium rounded-lg transition-colors">
<svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
</svg>
Refresh
</button>
</div>
</div>
</div>
<!-- Filters -->
<div class="bg-white dark:bg-zinc-800 rounded-xl border border-zinc-200 dark:border-zinc-700 shadow-sm mb-8">
<div class="p-6">
<div class="grid grid-cols-1 md:grid-cols-4 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 by job card number, customer..."
class="w-full rounded-lg border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 shadow-sm focus:border-blue-500 focus:ring-blue-500 pr-10">
<!-- Custom loading indicator with medical bag icon -->
<div wire:loading wire:target="search" class="absolute right-3 top-10 transform -translate-y-1/2">
<flux:icon.clipboard-document-check 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 rounded-lg border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 shadow-sm focus:border-blue-500 focus:ring-blue-500">
<option value="">All Statuses</option>
<option value="in_progress">In Progress</option>
<option value="completed">Completed</option>
<option value="pending_approval">Pending Approval</option>
<option value="approved">Approved</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 rounded-lg border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 shadow-sm focus:border-blue-500 focus:ring-blue-500">
<option value="">All Priorities</option>
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
<option value="critical">Critical</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Date Range</label>
<input type="date" wire:model.live="dateFrom"
class="w-full rounded-lg border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 shadow-sm focus:border-blue-500 focus:ring-blue-500">
</div>
</div>
</div>
</div>
<!-- Diagnoses List -->
<div class="bg-white dark:bg-zinc-800 rounded-xl border border-zinc-200 dark:border-zinc-700 shadow-sm">
<div class="px-6 py-4 border-b border-zinc-200 dark:border-zinc-700">
<h2 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
Diagnosis Records
<span class="text-sm font-normal text-zinc-500 dark:text-zinc-400 ml-2">({{ $diagnoses->total() }} total)</span>
</h2>
</div>
@if($diagnoses->count() > 0)
<div class="overflow-x-auto">
<table class="w-full">
<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">Job Card</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">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="divide-y divide-zinc-200 dark:divide-zinc-700">
@foreach($diagnoses as $diagnosis)
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-700/50">
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
{{ $diagnosis->jobCard->job_card_number }}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-zinc-900 dark:text-zinc-100">{{ $diagnosis->jobCard->customer->name }}</div>
<div class="text-xs text-zinc-500 dark:text-zinc-400">{{ $diagnosis->jobCard->customer->phone }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-zinc-900 dark:text-zinc-100">
{{ $diagnosis->jobCard->vehicle->year }} {{ $diagnosis->jobCard->vehicle->make }} {{ $diagnosis->jobCard->vehicle->model }}
</div>
<div class="text-xs text-zinc-500 dark:text-zinc-400">{{ $diagnosis->jobCard->vehicle->license_plate }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="inline-flex px-2 py-1 text-xs font-semibold rounded-full
@switch($diagnosis->diagnosis_status)
@case('in_progress')
bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200
@break
@case('completed')
bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200
@break
@case('pending_approval')
bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
@break
@case('approved')
bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200
@break
@default
bg-zinc-100 text-zinc-800 dark:bg-zinc-900 dark:text-zinc-200
@endswitch
">
{{ str_replace('_', ' ', $diagnosis->diagnosis_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
@switch($diagnosis->priority_level)
@case('low')
bg-zinc-100 text-zinc-800 dark:bg-zinc-900 dark:text-zinc-200
@break
@case('medium')
bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
@break
@case('high')
bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200
@break
@case('critical')
bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200
@break
@endswitch
">
{{ ucfirst($diagnosis->priority_level) }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-zinc-100">
{{ $diagnosis->serviceCoordinator->name }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400">
{{ $diagnosis->diagnosis_date?->format('M j, Y') ?? $diagnosis->created_at->format('M j, Y') }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2">
<a href="{{ route('diagnosis.show', $diagnosis) }}" class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300">
View
</a>
<a href="{{ route('diagnosis.edit', $diagnosis) }}" class="text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-300">
Edit
</a>
@if(!$diagnosis->estimate)
<a href="{{ route('estimates.create', $diagnosis) }}" class="text-green-600 hover:text-green-900 dark:text-green-400 dark:hover:text-green-300">
Estimate
</a>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="px-6 py-4 border-t border-zinc-200 dark:border-zinc-700">
{{ $diagnoses->links() }}
</div>
@else
<div class="p-12 text-center">
<svg class="mx-auto h-12 w-12 text-zinc-400 mb-4" 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="text-lg font-medium text-zinc-900 dark:text-zinc-100 mb-2">No diagnoses found</h3>
<p class="text-sm text-zinc-500 dark:text-zinc-400 mb-4">
@if($search || $statusFilter || $priorityFilter || $dateFrom)
No diagnoses match your current filters.
@else
Get started by creating a diagnosis from a job card.
@endif
</p>
@if($search || $statusFilter || $priorityFilter || $dateFrom)
<button wire:click="clearFilters" class="inline-flex items-center px-4 py-2 border border-zinc-300 dark:border-zinc-600 hover:bg-zinc-50 dark:hover:bg-zinc-700 text-zinc-700 dark:text-zinc-300 font-medium rounded-lg transition-colors">
Clear Filters
</button>
@endif
</div>
@endif
</div>
</div>