158 lines
7.1 KiB
PHP
158 lines
7.1 KiB
PHP
<?php
|
|
|
|
use App\Enums\ConsultationStatus;
|
|
use App\Models\Consultation;
|
|
use App\Models\User;
|
|
use Livewire\Volt\Component;
|
|
use Livewire\WithPagination;
|
|
|
|
new class extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
public User $user;
|
|
|
|
public function mount(User $user): void
|
|
{
|
|
$this->user = $user;
|
|
}
|
|
|
|
public function with(): array
|
|
{
|
|
return [
|
|
'consultations' => Consultation::query()
|
|
->where('user_id', $this->user->id)
|
|
->orderBy('booking_date', 'desc')
|
|
->orderBy('booking_time', 'desc')
|
|
->paginate(15),
|
|
'statistics' => [
|
|
'total' => Consultation::where('user_id', $this->user->id)->count(),
|
|
'completed' => Consultation::where('user_id', $this->user->id)
|
|
->where('status', ConsultationStatus::Completed)->count(),
|
|
'cancelled' => Consultation::where('user_id', $this->user->id)
|
|
->where('status', ConsultationStatus::Cancelled)->count(),
|
|
'no_show' => Consultation::where('user_id', $this->user->id)
|
|
->where('status', ConsultationStatus::NoShow)->count(),
|
|
],
|
|
];
|
|
}
|
|
}; ?>
|
|
|
|
<div class="max-w-5xl mx-auto">
|
|
<div class="mb-6">
|
|
@if($user->user_type->value === 'individual')
|
|
<flux:button href="{{ route('admin.clients.individual.show', $user) }}" variant="outline" icon="arrow-left" wire:navigate>
|
|
{{ __('common.back') }}
|
|
</flux:button>
|
|
@else
|
|
<flux:button href="{{ route('admin.clients.company.show', $user) }}" variant="outline" icon="arrow-left" wire:navigate>
|
|
{{ __('common.back') }}
|
|
</flux:button>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-6">
|
|
<div>
|
|
<flux:heading size="xl">{{ __('admin.client_consultations') }}</flux:heading>
|
|
<p class="text-sm text-zinc-500 mt-1">{{ $user->full_name }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics -->
|
|
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6">
|
|
<div class="bg-white rounded-lg p-4 border border-zinc-200 text-center">
|
|
<p class="text-2xl font-bold text-zinc-900">{{ $statistics['total'] }}</p>
|
|
<p class="text-sm text-zinc-500">{{ __('admin.total_consultations') }}</p>
|
|
</div>
|
|
<div class="bg-white rounded-lg p-4 border border-zinc-200 text-center">
|
|
<p class="text-2xl font-bold text-green-600">{{ $statistics['completed'] }}</p>
|
|
<p class="text-sm text-zinc-500">{{ __('admin.completed_consultations') }}</p>
|
|
</div>
|
|
<div class="bg-white rounded-lg p-4 border border-zinc-200 text-center">
|
|
<p class="text-2xl font-bold text-red-600">{{ $statistics['cancelled'] }}</p>
|
|
<p class="text-sm text-zinc-500">{{ __('admin.cancelled_consultations') }}</p>
|
|
</div>
|
|
<div class="bg-white rounded-lg p-4 border border-zinc-200 text-center">
|
|
<p class="text-2xl font-bold text-amber-600">{{ $statistics['no_show'] }}</p>
|
|
<p class="text-sm text-zinc-500">{{ __('admin.no_show_consultations') }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Consultations List -->
|
|
<div class="space-y-4">
|
|
@forelse($consultations as $consultation)
|
|
<div wire:key="consultation-{{ $consultation->id }}" class="bg-white rounded-lg p-4 border border-zinc-200">
|
|
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<span class="font-medium text-zinc-900">
|
|
{{ $consultation->booking_date->translatedFormat('l, d M Y') }}
|
|
</span>
|
|
<span class="text-zinc-500">
|
|
{{ \Carbon\Carbon::parse($consultation->booking_time)->format('g:i A') }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
@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
|
|
<flux:badge color="{{ $statusColor }}" size="sm">
|
|
{{ $consultation->status->label() }}
|
|
</flux:badge>
|
|
|
|
<flux:badge color="{{ $consultation->consultation_type === \App\Enums\ConsultationType::Paid ? 'indigo' : 'zinc' }}" size="sm">
|
|
{{ $consultation->consultation_type->label() }}
|
|
</flux:badge>
|
|
|
|
@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
|
|
<flux:badge color="{{ $paymentColor }}" size="sm">
|
|
{{ $consultation->payment_status->label() }}
|
|
</flux:badge>
|
|
@endif
|
|
</div>
|
|
|
|
@if($consultation->problem_summary)
|
|
<p class="mt-2 text-sm text-zinc-600 line-clamp-2">
|
|
{{ Str::limit($consultation->problem_summary, 150) }}
|
|
</p>
|
|
@endif
|
|
</div>
|
|
|
|
<flux:button
|
|
href="{{ route('admin.consultations.show', $consultation) }}"
|
|
variant="outline"
|
|
size="sm"
|
|
wire:navigate
|
|
>
|
|
{{ __('common.edit') }}
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="text-center py-12 text-zinc-500 bg-white rounded-lg border border-zinc-200">
|
|
<flux:icon name="inbox" class="w-12 h-12 mx-auto mb-4" />
|
|
<p>{{ __('admin.no_consultations') }}</p>
|
|
</div>
|
|
@endforelse
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
{{ $consultations->links() }}
|
|
</div>
|
|
</div>
|