236 lines
12 KiB
PHP
236 lines
12 KiB
PHP
<?php
|
|
|
|
use App\Enums\ConsultationStatus;
|
|
use App\Enums\ConsultationType;
|
|
use App\Enums\PaymentStatus;
|
|
use Livewire\Volt\Component;
|
|
use Livewire\WithPagination;
|
|
|
|
new class extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
public function with(): array
|
|
{
|
|
$user = auth()->user();
|
|
|
|
return [
|
|
'upcoming' => $user->consultations()
|
|
->approved()
|
|
->where('booking_date', '>=', today())
|
|
->orderBy('booking_date')
|
|
->orderBy('booking_time')
|
|
->get(),
|
|
'pending' => $user->consultations()
|
|
->pending()
|
|
->latest()
|
|
->get(),
|
|
'past' => $user->consultations()
|
|
->where(function ($query) use ($user) {
|
|
$query->whereIn('status', [
|
|
ConsultationStatus::Completed,
|
|
ConsultationStatus::Cancelled,
|
|
ConsultationStatus::NoShow,
|
|
])
|
|
->orWhere(function ($q) {
|
|
$q->where('status', ConsultationStatus::Approved)
|
|
->where('booking_date', '<', today());
|
|
});
|
|
})
|
|
->orderBy('booking_date', 'desc')
|
|
->paginate(10),
|
|
];
|
|
}
|
|
}; ?>
|
|
|
|
<div class="space-y-6 sm:space-y-8">
|
|
{{-- Header --}}
|
|
<div class="page-header">
|
|
<flux:heading size="xl" class="text-xl sm:text-2xl">{{ __('booking.my_consultations') }}</flux:heading>
|
|
<flux:button href="{{ route('client.consultations.book') }}" variant="primary" wire:navigate class="w-full sm:w-auto justify-center">
|
|
{{ __('booking.request_consultation') }}
|
|
</flux:button>
|
|
</div>
|
|
|
|
@if(session('success'))
|
|
<flux:callout variant="success">
|
|
{{ session('success') }}
|
|
</flux:callout>
|
|
@endif
|
|
|
|
{{-- Upcoming Consultations Section --}}
|
|
<section>
|
|
<flux:heading size="lg" class="mb-4 text-base sm:text-lg">{{ __('booking.upcoming_consultations') }}</flux:heading>
|
|
|
|
@if($upcoming->isNotEmpty())
|
|
<div class="space-y-3 sm:space-y-4">
|
|
@foreach($upcoming as $consultation)
|
|
<div wire:key="upcoming-{{ $consultation->id }}" class="bg-white dark:bg-zinc-800 rounded-lg p-3 sm:p-4 border border-zinc-200 dark:border-zinc-700">
|
|
<div class="flex flex-col sm:flex-row justify-between items-start gap-4">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<flux:icon name="calendar" class="w-5 h-5 text-zinc-500" />
|
|
<span class="font-semibold text-zinc-900 dark:text-zinc-100">
|
|
{{ $consultation->booking_date->translatedFormat(app()->getLocale() === 'ar' ? 'l، j F Y' : 'l, F j, Y') }}
|
|
</span>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-3">
|
|
<flux:icon name="clock" class="w-5 h-5 text-zinc-500" />
|
|
<span class="text-zinc-600 dark:text-zinc-400">
|
|
{{ \Carbon\Carbon::parse($consultation->booking_time)->format('g:i A') }}
|
|
</span>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
{{-- Consultation Type Badge --}}
|
|
@if($consultation->consultation_type === ConsultationType::Free)
|
|
<flux:badge color="sky">{{ __('booking.type_free') }}</flux:badge>
|
|
@else
|
|
<flux:badge color="amber">{{ __('booking.type_paid') }}</flux:badge>
|
|
@endif
|
|
|
|
{{-- Status Badge --}}
|
|
<flux:badge color="green">{{ $consultation->status->label() }}</flux:badge>
|
|
|
|
{{-- Payment Status (for paid consultations) --}}
|
|
@if($consultation->consultation_type === ConsultationType::Paid)
|
|
@if($consultation->payment_status === PaymentStatus::Received)
|
|
<flux:badge color="green">{{ __('booking.payment_received') }}</flux:badge>
|
|
@else
|
|
<flux:badge color="yellow">{{ __('booking.payment_pending') }}</flux:badge>
|
|
@endif
|
|
@endif
|
|
</div>
|
|
</div>
|
|
<div class="flex-shrink-0 w-full sm:w-auto">
|
|
<flux:button
|
|
size="sm"
|
|
href="{{ route('client.consultations.calendar', $consultation) }}"
|
|
icon="calendar-days"
|
|
class="w-full sm:w-auto justify-center"
|
|
>
|
|
{{ __('booking.add_to_calendar') }}
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@else
|
|
<div class="empty-state bg-zinc-50 dark:bg-zinc-800/50 rounded-lg">
|
|
<flux:icon name="calendar-days" class="empty-state-icon text-zinc-300 dark:text-zinc-600" />
|
|
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('booking.no_upcoming_consultations') }}</flux:text>
|
|
<div class="mt-4">
|
|
<flux:button href="{{ route('client.consultations.book') }}" variant="primary" size="sm" wire:navigate class="w-full sm:w-auto">
|
|
{{ __('booking.book_consultation') }}
|
|
</flux:button>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</section>
|
|
|
|
{{-- Pending Requests Section --}}
|
|
<section>
|
|
<flux:heading size="lg" class="mb-4 text-base sm:text-lg">{{ __('booking.pending_requests') }}</flux:heading>
|
|
|
|
@if($pending->isNotEmpty())
|
|
<div class="space-y-3 sm:space-y-4">
|
|
@foreach($pending as $consultation)
|
|
<div wire:key="pending-{{ $consultation->id }}" class="bg-white dark:bg-zinc-800 rounded-lg p-3 sm:p-4 border border-zinc-200 dark:border-zinc-700">
|
|
<div class="flex flex-col sm:flex-row justify-between items-start gap-4">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<flux:icon name="calendar" class="w-5 h-5 text-zinc-500" />
|
|
<span class="font-semibold text-zinc-900 dark:text-zinc-100">
|
|
{{ $consultation->booking_date->translatedFormat(app()->getLocale() === 'ar' ? 'l، j F Y' : 'l, F j, Y') }}
|
|
</span>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<flux:icon name="clock" class="w-5 h-5 text-zinc-500" />
|
|
<span class="text-zinc-600 dark:text-zinc-400">
|
|
{{ \Carbon\Carbon::parse($consultation->booking_time)->format('g:i A') }}
|
|
</span>
|
|
</div>
|
|
<div class="text-sm text-zinc-500 dark:text-zinc-400 mb-2">
|
|
{{ __('booking.submitted_on') }}: {{ $consultation->created_at->translatedFormat(app()->getLocale() === 'ar' ? 'j F Y' : 'F j, Y') }}
|
|
</div>
|
|
@if($consultation->problem_summary)
|
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 line-clamp-2">
|
|
{{ Str::limit($consultation->problem_summary, 150) }}
|
|
</p>
|
|
@endif
|
|
<div class="mt-3">
|
|
<flux:badge color="yellow">{{ __('booking.pending_review') }}</flux:badge>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@else
|
|
<div class="empty-state bg-zinc-50 dark:bg-zinc-800/50 rounded-lg">
|
|
<flux:icon name="inbox" class="empty-state-icon text-zinc-300 dark:text-zinc-600" />
|
|
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('booking.no_pending_requests') }}</flux:text>
|
|
</div>
|
|
@endif
|
|
</section>
|
|
|
|
{{-- Past Consultations Section --}}
|
|
<section>
|
|
<flux:heading size="lg" class="mb-4 text-base sm:text-lg">{{ __('booking.past_consultations') }}</flux:heading>
|
|
|
|
@if($past->isNotEmpty())
|
|
<div class="space-y-3 sm:space-y-4">
|
|
@foreach($past as $consultation)
|
|
<div wire:key="past-{{ $consultation->id }}" class="bg-white dark:bg-zinc-800 rounded-lg p-3 sm:p-4 border border-zinc-200 dark:border-zinc-700">
|
|
<div class="flex flex-col sm:flex-row justify-between items-start gap-4">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<flux:icon name="calendar" class="w-5 h-5 text-zinc-500" />
|
|
<span class="font-semibold text-zinc-900 dark:text-zinc-100">
|
|
{{ $consultation->booking_date->translatedFormat(app()->getLocale() === 'ar' ? 'l، j F Y' : 'l, F j, Y') }}
|
|
</span>
|
|
</div>
|
|
<div class="flex items-center gap-2 mb-3">
|
|
<flux:icon name="clock" class="w-5 h-5 text-zinc-500" />
|
|
<span class="text-zinc-600 dark:text-zinc-400">
|
|
{{ \Carbon\Carbon::parse($consultation->booking_time)->format('g:i A') }}
|
|
</span>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2">
|
|
{{-- Consultation Type Badge --}}
|
|
@if($consultation->consultation_type === ConsultationType::Free)
|
|
<flux:badge color="sky">{{ __('booking.type_free') }}</flux:badge>
|
|
@else
|
|
<flux:badge color="amber">{{ __('booking.type_paid') }}</flux:badge>
|
|
@endif
|
|
|
|
{{-- Status Badge --}}
|
|
@php
|
|
$statusColor = match($consultation->status) {
|
|
ConsultationStatus::Completed => 'zinc',
|
|
ConsultationStatus::Cancelled => 'red',
|
|
ConsultationStatus::NoShow => 'red',
|
|
ConsultationStatus::Approved => 'zinc',
|
|
default => 'zinc',
|
|
};
|
|
@endphp
|
|
<flux:badge :color="$statusColor">{{ $consultation->status->label() }}</flux:badge>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
{{ $past->links() }}
|
|
</div>
|
|
@else
|
|
<div class="empty-state bg-zinc-50 dark:bg-zinc-800/50 rounded-lg">
|
|
<flux:icon name="archive-box" class="empty-state-icon text-zinc-300 dark:text-zinc-600" />
|
|
<flux:text class="text-zinc-500 dark:text-zinc-400">{{ __('booking.no_past_consultations') }}</flux:text>
|
|
</div>
|
|
@endif
|
|
</section>
|
|
</div>
|