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

186 lines
13 KiB
PHP

<div>
<div class="max-w-4xl mx-auto 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">Schedule Appointment</h1>
<p class="text-zinc-600 dark:text-zinc-400">Create a new appointment for a customer</p>
</div>
<a href="{{ route('appointments.index') }}" 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="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
Back to Appointments
</a>
</div>
<!-- Success Message -->
@if (session()->has('message'))
<div class="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-4">
<div class="flex">
<svg class="w-5 h-5 text-green-400 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
<p class="text-green-800 dark:text-green-200">{{ session('message') }}</p>
</div>
</div>
@endif
<!-- Error Message -->
@if ($errors->has('general'))
<div class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4">
<div class="flex">
<svg class="w-5 h-5 text-red-400 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<p class="text-red-800 dark:text-red-200">{{ $errors->first('general') }}</p>
</div>
</div>
@endif
<form wire:submit="save" class="space-y-6">
<!-- Customer & Vehicle Information -->
<div class="bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg">
<div class="flex items-center gap-3 p-4 border-b border-zinc-200 dark:border-zinc-700">
<svg class="text-blue-500 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
<h3 class="text-lg font-medium text-zinc-900 dark:text-zinc-100">Customer & Vehicle</h3>
</div>
<div class="p-6 space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Customer Selection -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Customer *</label>
<select wire:model.live="customer_id" 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="">Select customer...</option>
@foreach($customers as $customer)
<option value="{{ $customer->id }}">{{ $customer->first_name }} {{ $customer->last_name }}</option>
@endforeach
</select>
@error('customer_id') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
</div>
<!-- Vehicle Selection -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Vehicle *</label>
<select wire:model="vehicle_id" {{ !$customer_id ? 'disabled' : '' }} 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 disabled:opacity-50">
<option value="">Select vehicle...</option>
@foreach($vehicles as $vehicle)
<option value="{{ $vehicle->id }}">
{{ $vehicle->year }} {{ $vehicle->make }} {{ $vehicle->model }}
</option>
@endforeach
</select>
@error('vehicle_id') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
</div>
</div>
</div>
</div>
<!-- Appointment Details -->
<div class="bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg">
<div class="flex items-center gap-3 p-4 border-b border-zinc-200 dark:border-zinc-700">
<svg class="text-green-500 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
<h3 class="text-lg font-medium text-zinc-900 dark:text-zinc-100">Appointment Details</h3>
</div>
<div class="p-6 space-y-6">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Date -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Date *</label>
<input type="date" wire:model.live="scheduled_date" 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">
@error('scheduled_date') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
</div>
<!-- Time -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Time *</label>
<select wire:model="scheduled_time" 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="">Select time...</option>
@foreach($availableTimeSlots as $slot)
<option value="{{ $slot['value'] }}">{{ $slot['label'] }}</option>
@endforeach
</select>
@error('scheduled_time') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
</div>
<!-- Duration -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Duration</label>
<select wire:model.live="estimated_duration_minutes" 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">
@foreach($durationOptions as $minutes => $label)
<option value="{{ $minutes }}">{{ $label }}</option>
@endforeach
</select>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Appointment Type -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Type</label>
<select wire:model="appointment_type" 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">
@foreach($appointmentTypes as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</select>
</div>
<!-- Technician -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Assigned Technician (Optional)</label>
<select wire:model.live="assigned_technician_id" 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="">Auto-assign later</option>
@foreach($technicians as $technician)
<option value="{{ $technician->id }}">{{ $technician->first_name }} {{ $technician->last_name }}</option>
@endforeach
</select>
</div>
</div>
<!-- Service Requested -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Service Requested *</label>
<textarea wire:model="service_requested" rows="3" 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" placeholder="Describe the service requested..."></textarea>
@error('service_requested') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Customer Notes -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Customer Notes</label>
<textarea wire:model="customer_notes" rows="3" 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" placeholder="Customer comments or special requests..."></textarea>
</div>
<!-- Internal Notes -->
<div>
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">Internal Notes</label>
<textarea wire:model="internal_notes" rows="3" 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" placeholder="Internal notes for staff..."></textarea>
</div>
</div>
</div>
</div>
<!-- Actions -->
<div class="bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg p-6">
<div class="flex flex-col sm:flex-row gap-4 justify-end">
<a href="{{ route('appointments.index') }}" class="inline-flex items-center justify-center px-6 py-3 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">
Cancel
</a>
<button type="submit" class="inline-flex items-center justify-center px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white 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="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
Schedule Appointment
</button>
</div>
</div>
</form>
</div>
</div>