@extends('layouts.app') @section('title', 'Queue Board') @php if (!function_exists('queueOpenUrl')) { function queueOpenUrl($visit) { if ($visit->visit_type === 'anc' && $visit->patient_id) { $ancReg = \App\Models\AncRegistration::where('patient_id', $visit->patient_id)->where('status', 'active')->first(); if ($ancReg) return route('maternity.anc.show', $ancReg); } return route('visits.show', $visit); } } $queueReadOnly = auth()->user()->hasAnyRole('Lab User', 'Imaging User') && !auth()->user()->hasAnyRole('Super Admin', 'Hospital Admin'); // Merge all active visits into one collection with stage labels for // the row-based table view. Done visits are NOT merged in — the // queue board is for active patients only; completed encounters // belong in OPD Visits → Completed, not on the live floor view. // (May 24 2026 cleanup: the Done tab was removed from this page.) $allQueue = collect(); foreach ($waiting as $v) { $v->_stage = 'waiting'; $allQueue->push($v); } foreach ($inTriage as $v) { $v->_stage = 'triage'; $allQueue->push($v); } foreach ($inConsultation as $v) { $v->_stage = 'consulting'; $allQueue->push($v); } foreach ($atLab as $v) { $v->_stage = 'lab'; $allQueue->push($v); } foreach ($atRadiology as $v) { $v->_stage = 'imaging'; $allQueue->push($v); } @endphp @section('styles') @endsection @section('content') {{-- Page header and action row removed per UI cleanup. Department filtering and refresh are out; the queue auto-shows all departments, and a manual refresh isn't needed (the page is mostly real-time-ish). If you need the completed-visits view back, it's still at route('visits.opd.completed'). --}} {{-- Carryover banner removed May 14 2026: the per-card wait-time display and the >30-min hot-card highlighting already surface stuck visits more usefully than a banner could. The banner was also confusing to staff who read it as an error message. --}} {{-- Quick Action Button — May 24 2026: Consolidated to ONE "Start New Visit" button. The receptionist picks the department inside the modal and the system decides which encounter to open from that choice: Laboratory → direct_lab encounter, Radiology → direct_radiology encounter, everything else (Outpatient, Inpatient, Maternity, Dental, MCH/FP, Specialized Clinics + sub-clinics) opens a standard OPD encounter. Replaces the four separate buttons we had before (OPD / Dental / Direct Lab / Direct Radiology), which forced the receptionist to know the visit_type before knowing the department — backwards from how reception actually works. --}} @if(!$queueReadOnly)
| # | Patient | Type | Stage | Check-In | Wait Time | Department | Clinician |
|---|---|---|---|---|---|---|---|
| {{ $rowNum }} |
@if($v->status === 'urgent')URG@endif
{{-- Name + phone two-line layout (25 May 2026):
name is the primary scan-target at the row's
base font size; phone sits underneath one step
smaller as metadata. MRN was removed from this
cell — it stays visible inside the encounter
and on invoices for staff who need it. --}}
{{ $v->patient->full_name ?? '' }} {{ $v->patient->phone ?? '' }} |
@if($v->visit_type === 'anc')ANC @elseif($v->visit_type === 'direct_lab')Direct Lab @elseif($v->visit_type === 'direct_radiology')Direct Radiology @else{{ str_replace('_', ' ', $v->visit_type ?? 'OPD') }} @endif | @switch($v->_stage) @case('waiting')Waiting@break @case('triage'){{ $v->status === 'triaged' ? 'Triaged' : 'In Triage' }}@break @case('consulting')Consulting@break @case('lab')At Lab@break @case('imaging')At Imaging@break @endswitch | {{ $v->check_in_at ? $v->check_in_at->format('H:i') : '-' }} | {{ $v->check_in_at ? $v->check_in_at->diffForHumans(null, true, false, 2) : '-' }} | {{ $v->department->name ?? '-' }} | {{ $v->clinician->name ?? '-' }} |
| No active visits. | |||||||