@include('partials.paciente-header', ['title'=>'Mis citas y sesiones', 'subtitle'=>'Consulta tus próximas sesiones, solicitudes y el historial de atención.']) @include('partials.frontend-alerts') @php $statusLabels = [ 'pending_payment' => 'Pendiente de pago', 'pending' => 'Solicitada', 'accepted' => 'Confirmada', 'rescheduled' => 'Reagenda pendiente', 'rejected' => 'Rechazada', 'cancelled' => 'Cancelada', 'completed' => 'Completada', 'missed' => 'Perdida / sin entrar', ]; $paymentLabels = ['pending'=>'Pago pendiente','paid'=>'Pagada','refunded'=>'Reembolsada','waived'=>'Sin cobro']; $now = now(config('app.timezone')); $upcoming = $appointments->filter(fn($a) => $a->status === 'accepted' && ($a->is_pending_or_active_session ?? false))->sortBy('starts_at')->values(); $requests = $appointments->filter(fn($a) => in_array($a->status, ['pending_payment','pending','rescheduled'], true))->sortBy('starts_at')->values(); $history = $appointments->filter(fn($a) => in_array($a->effective_status, ['completed', 'missed'], true))->values(); $cancelled = $appointments->filter(fn($a) => in_array($a->status, ['cancelled','rejected'], true))->values(); $nextAppointment = $upcoming->sortBy('starts_at')->first(); $monthNames = ['01'=>'ENE','02'=>'FEB','03'=>'MAR','04'=>'ABR','05'=>'MAY','06'=>'JUN','07'=>'JUL','08'=>'AGO','09'=>'SEP','10'=>'OCT','11'=>'NOV','12'=>'DIC']; $tabs = ['proximas' => ['label' => 'Próximas', 'items' => $upcoming], 'solicitudes' => ['label' => 'Solicitudes', 'items' => $requests], 'historial' => ['label' => 'Historial', 'items' => $history], 'canceladas' => ['label' => 'Canceladas', 'items' => $cancelled]]; @endphp
Próxima cita{{ $nextAppointment?->starts_at?->format('d') ?? '—' }}{{ $nextAppointment?->starts_at?->format('d/m/Y H:i') ?? 'Sin cita confirmada' }}
Citas activas{{ $upcoming->count() }}Sesiones confirmadas
Solicitudes{{ $requests->count() }}Pago, revisión o reagenda
@foreach($tabs as $key => $tab) @endforeach
+
@foreach($tabs as $key => $tab)
@forelse($tab['items'] as $appointment) @php $profile = $appointment->professional?->professionalProfile; $startsAt = $appointment->starts_at; $month = $startsAt ? ($monthNames[$startsAt->format('m')] ?? strtoupper($startsAt->format('M'))) : '---'; $day = $startsAt?->format('d') ?? '--'; $year = $startsAt?->format('Y') ?? ''; $timeLabel = $startsAt?->format('H:i') ?? ($appointment->appointment_time ?: 'Por definir'); $effectiveStatus = $appointment->effective_status; $statusClass = match($effectiveStatus) { 'accepted' => 'confirmed', 'completed' => 'completed', 'missed', 'cancelled', 'rejected' => 'cancelled', default => 'pending' }; $displayFolio = 'ID '.$appointment->id; $professionalName = $appointment->professional?->nombre_completo ?? 'Especialista pendiente'; $specialty = $profile?->especialidad_principal ?? (($appointment->professional?->rol === 'psiquiatra') ? 'Psiquiatría' : 'Psicología'); $modality = ucfirst($appointment->modality ?? 'Modalidad'); $reason = $appointment->reason ?: 'Motivo pendiente'; $videoLink = $appointment->patient_video_url; $isSessionMoment = $appointment->is_video_session_available ?? false; $sessionAccessEnds = $appointment->session_access_ends_at; $hasPrimaryAction = false; $requestTitle = match($appointment->status) { 'pending_payment' => 'Pago pendiente de cita', 'pending' => 'Nueva cita solicitada', 'rescheduled' => 'Solicitud de reagenda', default => $professionalName, }; $requestDescription = match($appointment->status) { 'pending_payment' => 'Completa el pago para enviar la solicitud al especialista.', 'pending' => 'Pendiente de confirmación por el especialista.', 'rescheduled' => 'El especialista propuso un nuevo horario. Acepta la propuesta o cancela la cita.', default => $modality.' · '.$reason, }; $schedulePayload = $appointment->patient_booking_payload ?? ['days' => [], 'availability' => [], 'duration' => 50, 'blockedSlots' => []]; @endphp
{{ $month }} {{ $day }} {{ $year }}
{{ $statusLabels[$effectiveStatus] ?? ucfirst($effectiveStatus) }} {{ $timeLabel }} hrs {{ $displayFolio }}

{{ $key === 'solicitudes' ? $requestTitle : $professionalName }}

@if($key === 'solicitudes') {{ $professionalName }} · {{ $reason }} · {{ $modality }}

{{ $requestDescription }}

@else {{ $modality }} · {{ $reason }} @if($specialty){{ $specialty }}@endif @endif
@if($appointment->status === 'rescheduled')
Propuesta: {{ optional($appointment->reschedule_date)->format('d/m/Y') }} {{ $appointment->reschedule_time }} @if($appointment->reschedule_proposal) · {{ $appointment->reschedule_proposal }} @endif
@endif
Pago: {{ $paymentLabels[$appointment->payment_status] ?? ucfirst($appointment->payment_status) }} Total: ${{ number_format((float) $appointment->amount, 2) }} MXN
@if($key === 'proximas') @if($isSessionMoment && $videoLink) @php $hasPrimaryAction = true; @endphp Entrar a sesión @else {{ $startsAt && $startsAt->lte($now) ? 'Disponible hasta '.optional($sessionAccessEnds)->format('H:i').' hrs' : 'Disponible 2 min antes' }} @endif @elseif($key === 'solicitudes')
@if($appointment->status === 'pending_payment') Pagar @endif @if($appointment->status === 'rescheduled')
@csrf
@endif @if($appointment->status === 'pending' && $appointment->requested_by === 'profesional')
@csrf
@endif @if($appointment->status !== 'pending_payment') @endif @if(!in_array($effectiveStatus, ['completed','cancelled','rejected','missed'], true)) @endif
@endif
@empty
No hay registros en esta sección.
@endforelse
@endforeach
@include('partials.floating-auxilio')