resetPage(); } public function updatedStatusFilter(): void { $this->resetPage(); } public function updatedTypeFilter(): void { $this->resetPage(); } public function updatedPaymentFilter(): void { $this->resetPage(); } public function updatedDateFrom(): void { $this->resetPage(); } public function updatedDateTo(): void { $this->resetPage(); } public function updatedPerPage(): void { $this->resetPage(); } public function sort(string $column): void { if ($this->sortBy === $column) { $this->sortDir = $this->sortDir === 'asc' ? 'desc' : 'asc'; } else { $this->sortBy = $column; $this->sortDir = 'asc'; } } public function clearFilters(): void { $this->search = ''; $this->statusFilter = ''; $this->typeFilter = ''; $this->paymentFilter = ''; $this->dateFrom = ''; $this->dateTo = ''; $this->resetPage(); } public function markCompleted(int $id): void { DB::transaction(function () use ($id) { $consultation = Consultation::lockForUpdate()->findOrFail($id); $oldStatus = $consultation->status->value; try { $consultation->markAsCompleted(); $this->logStatusChange($consultation, $oldStatus, 'completed'); session()->flash('success', __('messages.marked_completed')); } catch (\InvalidArgumentException $e) { session()->flash('error', $e->getMessage()); } }); } public function markNoShow(int $id): void { DB::transaction(function () use ($id) { $consultation = Consultation::lockForUpdate()->findOrFail($id); $oldStatus = $consultation->status->value; try { $consultation->markAsNoShow(); $this->logStatusChange($consultation, $oldStatus, 'no_show'); session()->flash('success', __('messages.marked_no_show')); } catch (\InvalidArgumentException $e) { session()->flash('error', $e->getMessage()); } }); } public function cancel(int $id): void { DB::transaction(function () use ($id) { $consultation = Consultation::lockForUpdate()->with('user')->findOrFail($id); $oldStatus = $consultation->status->value; try { $consultation->cancel(); // Notify client if ($consultation->user) { $consultation->user->notify(new ConsultationCancelled($consultation)); } $this->logStatusChange($consultation, $oldStatus, 'cancelled'); session()->flash('success', __('messages.consultation_cancelled')); } catch (\InvalidArgumentException $e) { session()->flash('error', $e->getMessage()); } }); } public function markPaymentReceived(int $id): void { DB::transaction(function () use ($id) { $consultation = Consultation::lockForUpdate()->findOrFail($id); try { $consultation->markPaymentReceived(); AdminLog::create([ 'admin_id' => auth()->id(), 'action' => 'payment_received', 'target_type' => 'consultation', 'target_id' => $consultation->id, 'old_values' => ['payment_status' => 'pending'], 'new_values' => ['payment_status' => 'received'], 'ip_address' => request()->ip(), 'created_at' => now(), ]); session()->flash('success', __('messages.payment_marked_received')); } catch (\InvalidArgumentException $e) { session()->flash('error', $e->getMessage()); } }); } private function logStatusChange(Consultation $consultation, string $oldStatus, string $newStatus): void { AdminLog::create([ 'admin_id' => auth()->id(), 'action' => 'status_change', 'target_type' => 'consultation', 'target_id' => $consultation->id, 'old_values' => ['status' => $oldStatus], 'new_values' => ['status' => $newStatus], 'ip_address' => request()->ip(), 'created_at' => now(), ]); } public function with(): array { return [ 'consultations' => Consultation::query() ->with('user:id,full_name,email,phone,user_type') ->when($this->search, fn ($q) => $q->whereHas('user', fn ($uq) => $uq->where('full_name', 'like', "%{$this->search}%") ->orWhere('email', 'like', "%{$this->search}%") )) ->when($this->statusFilter, fn ($q) => $q->where('status', $this->statusFilter)) ->when($this->typeFilter, fn ($q) => $q->where('consultation_type', $this->typeFilter)) ->when($this->paymentFilter, fn ($q) => $q->where('payment_status', $this->paymentFilter)) ->when($this->dateFrom, fn ($q) => $q->where('booking_date', '>=', $this->dateFrom)) ->when($this->dateTo, fn ($q) => $q->where('booking_date', '<=', $this->dateTo)) ->orderBy($this->sortBy, $this->sortDir) ->paginate($this->perPage), 'statuses' => ConsultationStatus::cases(), 'types' => ConsultationType::cases(), 'paymentStatuses' => PaymentStatus::cases(), ]; } }; ?>
{{ __('admin.consultations') }}

{{ __('admin.consultations_description') }}

@if(session('success')) {{ session('success') }} @endif @if(session('error')) {{ session('error') }} @endif
@foreach($statuses as $status) @endforeach @foreach($types as $type) @endforeach @foreach($paymentStatuses as $ps) @endforeach
{{ __('admin.date_from') }} {{ __('admin.date_to') }} {{ __('admin.per_page') }} @if($search || $statusFilter || $typeFilter || $paymentFilter || $dateFrom || $dateTo) {{ __('common.clear') }} @endif
@forelse($consultations as $consultation)
{{ \Carbon\Carbon::parse($consultation->booking_date)->translatedFormat('d M Y') }}
{{ \Carbon\Carbon::parse($consultation->booking_time)->format('g:i A') }}
{{ $consultation->user?->full_name ?? __('common.unknown') }} {{ $consultation->consultation_type->label() }}
{{ $consultation->user?->email ?? '-' }}
@php $statusColor = match($consultation->status) { \App\Enums\ConsultationStatus::Pending => 'amber', \App\Enums\ConsultationStatus::Approved => 'sky', \App\Enums\ConsultationStatus::Completed => 'green', \App\Enums\ConsultationStatus::Cancelled => 'red', \App\Enums\ConsultationStatus::NoShow => 'orange', \App\Enums\ConsultationStatus::Rejected => 'rose', }; @endphp {{ $consultation->status->label() }}
@if($consultation->consultation_type === \App\Enums\ConsultationType::Paid) @php $paymentColor = match($consultation->payment_status) { \App\Enums\PaymentStatus::Pending => 'amber', \App\Enums\PaymentStatus::Received => 'green', default => 'zinc', }; @endphp {{ $consultation->payment_status->label() }} @else - @endif
{{ __('common.edit') }} @if(in_array($consultation->status, [\App\Enums\ConsultationStatus::Approved, \App\Enums\ConsultationStatus::Completed, \App\Enums\ConsultationStatus::NoShow])) @if($consultation->status !== \App\Enums\ConsultationStatus::Completed) {{ __('admin.mark_completed') }} @endif @if($consultation->status !== \App\Enums\ConsultationStatus::NoShow) {{ __('admin.mark_no_show') }} @endif @if($consultation->status === \App\Enums\ConsultationStatus::Approved) {{ __('admin.cancel_consultation') }} @endif @endif @if($consultation->status === \App\Enums\ConsultationStatus::Pending) {{ __('common.cancel') }} @endif @if($consultation->consultation_type === \App\Enums\ConsultationType::Paid && $consultation->payment_status === \App\Enums\PaymentStatus::Pending) {{ __('admin.payment_received') }} @endif
@empty

{{ __('admin.no_consultations') }}

@endforelse
{{ $consultations->links() }}