libra/resources/views/livewire/client/consultations/index.blade.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 rounded-lg p-3 sm:p-4 border border-zinc-200">
<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">
{{ $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">
{{ \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 rounded-lg">
<flux:icon name="calendar-days" class="empty-state-icon text-zinc-300" />
<flux:text class="text-zinc-500">{{ __('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 rounded-lg p-3 sm:p-4 border border-zinc-200">
<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">
{{ $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">
{{ \Carbon\Carbon::parse($consultation->booking_time)->format('g:i A') }}
</span>
</div>
<div class="text-sm text-zinc-500 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 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 rounded-lg">
<flux:icon name="inbox" class="empty-state-icon text-zinc-300" />
<flux:text class="text-zinc-500">{{ __('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 rounded-lg p-3 sm:p-4 border border-zinc-200">
<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">
{{ $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">
{{ \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 rounded-lg">
<flux:icon name="archive-box" class="empty-state-icon text-zinc-300" />
<flux:text class="text-zinc-500">{{ __('booking.no_past_consultations') }}</flux:text>
</div>
@endif
</section>
</div>