238 lines
7.4 KiB
PHP
238 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Appointments;
|
|
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
use Livewire\Attributes\On;
|
|
use App\Models\Appointment;
|
|
use App\Models\Technician;
|
|
use Carbon\Carbon;
|
|
|
|
class Index extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
public $search = '';
|
|
public $statusFilter = '';
|
|
public $technicianFilter = '';
|
|
public $dateFilter = '';
|
|
public $typeFilter = '';
|
|
public $view = 'list'; // list or calendar
|
|
public $selectedDate;
|
|
public $showForm = false;
|
|
public $selectedAppointment = null;
|
|
|
|
protected $queryString = [
|
|
'search' => ['except' => ''],
|
|
'statusFilter' => ['except' => ''],
|
|
'technicianFilter' => ['except' => ''],
|
|
'dateFilter' => ['except' => ''],
|
|
'typeFilter' => ['except' => ''],
|
|
'view' => ['except' => 'list']
|
|
];
|
|
|
|
public function mount()
|
|
{
|
|
$this->selectedDate = now()->format('Y-m-d');
|
|
}
|
|
|
|
public function updatingSearch()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingStatusFilter()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingTechnicianFilter()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingDateFilter()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingTypeFilter()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function setView($view)
|
|
{
|
|
$this->view = $view;
|
|
}
|
|
|
|
public function clearFilters()
|
|
{
|
|
$this->search = '';
|
|
$this->statusFilter = '';
|
|
$this->technicianFilter = '';
|
|
$this->dateFilter = '';
|
|
$this->typeFilter = '';
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function createAppointment()
|
|
{
|
|
$this->selectedAppointment = null;
|
|
$this->showForm = true;
|
|
}
|
|
|
|
public function editAppointment($appointmentId)
|
|
{
|
|
$this->selectedAppointment = Appointment::find($appointmentId);
|
|
$this->showForm = true;
|
|
}
|
|
|
|
#[On('appointment-saved')]
|
|
public function refreshAppointments()
|
|
{
|
|
$this->showForm = false;
|
|
$this->resetPage();
|
|
}
|
|
|
|
#[On('close-appointment-form')]
|
|
public function closeForm()
|
|
{
|
|
$this->showForm = false;
|
|
}
|
|
|
|
#[On('appointment-updated')]
|
|
public function refreshData()
|
|
{
|
|
// This will trigger a re-render
|
|
}
|
|
|
|
public function confirmAppointment($appointmentId)
|
|
{
|
|
$appointment = Appointment::find($appointmentId);
|
|
if ($appointment && $appointment->confirm()) {
|
|
session()->flash('message', 'Appointment confirmed successfully!');
|
|
$this->dispatch('appointment-updated');
|
|
}
|
|
}
|
|
|
|
public function checkInAppointment($appointmentId)
|
|
{
|
|
$appointment = Appointment::find($appointmentId);
|
|
if ($appointment && $appointment->checkIn()) {
|
|
session()->flash('message', 'Customer checked in successfully!');
|
|
$this->dispatch('appointment-updated');
|
|
}
|
|
}
|
|
|
|
public function completeAppointment($appointmentId)
|
|
{
|
|
$appointment = Appointment::find($appointmentId);
|
|
if ($appointment && $appointment->complete()) {
|
|
session()->flash('message', 'Appointment completed successfully!');
|
|
$this->dispatch('appointment-updated');
|
|
}
|
|
}
|
|
|
|
public function cancelAppointment($appointmentId)
|
|
{
|
|
$appointment = Appointment::find($appointmentId);
|
|
if ($appointment && $appointment->cancel()) {
|
|
session()->flash('message', 'Appointment cancelled successfully!');
|
|
$this->dispatch('appointment-updated');
|
|
}
|
|
}
|
|
|
|
public function markNoShow($appointmentId)
|
|
{
|
|
$appointment = Appointment::find($appointmentId);
|
|
if ($appointment && $appointment->markNoShow()) {
|
|
session()->flash('message', 'Appointment marked as no-show.');
|
|
$this->dispatch('appointment-updated');
|
|
}
|
|
}
|
|
|
|
public function getAppointmentsProperty()
|
|
{
|
|
$query = Appointment::query()
|
|
->with(['customer', 'vehicle', 'assignedTechnician'])
|
|
->when($this->search, function ($q) {
|
|
$q->whereHas('customer', function ($customer) {
|
|
$customer->where('first_name', 'like', '%' . $this->search . '%')
|
|
->orWhere('last_name', 'like', '%' . $this->search . '%')
|
|
->orWhere('email', 'like', '%' . $this->search . '%');
|
|
})->orWhereHas('vehicle', function ($vehicle) {
|
|
$vehicle->where('make', 'like', '%' . $this->search . '%')
|
|
->orWhere('model', 'like', '%' . $this->search . '%')
|
|
->orWhere('license_plate', 'like', '%' . $this->search . '%');
|
|
})->orWhere('service_requested', 'like', '%' . $this->search . '%');
|
|
})
|
|
->when($this->statusFilter, function ($q) {
|
|
$q->where('status', $this->statusFilter);
|
|
})
|
|
->when($this->technicianFilter, function ($q) {
|
|
$q->where('assigned_technician_id', $this->technicianFilter);
|
|
})
|
|
->when($this->typeFilter, function ($q) {
|
|
$q->where('appointment_type', $this->typeFilter);
|
|
})
|
|
->when($this->dateFilter, function ($q) {
|
|
switch ($this->dateFilter) {
|
|
case 'today':
|
|
$q->whereDate('scheduled_datetime', today());
|
|
break;
|
|
case 'tomorrow':
|
|
$q->whereDate('scheduled_datetime', today()->addDay());
|
|
break;
|
|
case 'this_week':
|
|
$q->whereBetween('scheduled_datetime', [
|
|
now()->startOfWeek(),
|
|
now()->endOfWeek()
|
|
]);
|
|
break;
|
|
case 'next_week':
|
|
$q->whereBetween('scheduled_datetime', [
|
|
now()->addWeek()->startOfWeek(),
|
|
now()->addWeek()->endOfWeek()
|
|
]);
|
|
break;
|
|
case 'overdue':
|
|
$q->where('status', 'scheduled')
|
|
->where('scheduled_datetime', '<', now());
|
|
break;
|
|
}
|
|
})
|
|
->orderBy('scheduled_datetime', 'asc');
|
|
|
|
return $query->paginate(15);
|
|
}
|
|
|
|
public function getTechniciansProperty()
|
|
{
|
|
return Technician::where('status', 'active')
|
|
->orderBy('first_name')
|
|
->get();
|
|
}
|
|
|
|
public function getTodayStatsProperty()
|
|
{
|
|
$today = today();
|
|
return [
|
|
'total' => Appointment::whereDate('scheduled_datetime', $today)->count(),
|
|
'confirmed' => Appointment::whereDate('scheduled_datetime', $today)->where('status', 'confirmed')->count(),
|
|
'in_progress' => Appointment::whereDate('scheduled_datetime', $today)->where('status', 'in_progress')->count(),
|
|
'completed' => Appointment::whereDate('scheduled_datetime', $today)->where('status', 'completed')->count(),
|
|
];
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
return view('livewire.appointments.index', [
|
|
'appointments' => $this->appointments,
|
|
'technicians' => $this->technicians,
|
|
'todayStats' => $this->todayStats,
|
|
]);
|
|
}
|
|
}
|