diff --git a/app/Http/Controllers/Care/DashboardController.php b/app/Http/Controllers/Care/DashboardController.php index ad8dbd5..7e8d788 100644 --- a/app/Http/Controllers/Care/DashboardController.php +++ b/app/Http/Controllers/Care/DashboardController.php @@ -4,12 +4,16 @@ namespace App\Http\Controllers\Care; use App\Http\Controllers\Controller; use App\Http\Controllers\Care\Concerns\ScopesToAccount; +use App\Models\Appointment; use App\Models\Branch; use App\Models\Member; +use App\Models\Practitioner; +use App\Services\Care\AppointmentService; use App\Services\Care\CarePermissions; use App\Services\Care\OrganizationResolver; use App\Services\Care\ReportService; use Illuminate\Http\Request; +use Illuminate\Support\Collection; use Illuminate\View\View; class DashboardController extends Controller @@ -19,6 +23,7 @@ class DashboardController extends Controller public function __construct( protected ReportService $reports, protected CarePermissions $permissions, + protected AppointmentService $appointments, ) {} public function index(Request $request): View @@ -33,6 +38,8 @@ class DashboardController extends Controller $canDepartments = $this->permissions->can($member, 'admin.departments.view'); $canBills = $this->permissions->can($member, 'bills.view'); $canFinance = $this->permissions->can($member, 'reports.finance.view'); + $canConsult = $this->permissions->can($member, 'consultations.manage'); + $showPatientQueue = $this->permissions->can($member, 'appointments.view') && ! $canBranches; $branchQuery = Branch::owned($owner)->where('organization_id', $organization->id); $this->scopeToBranch($request, $branchQuery); @@ -65,6 +72,10 @@ class DashboardController extends Controller includeBilling: $canBills || $canFinance, ); + [$queue, $inConsultation, $practitionerId] = $showPatientQueue + ? $this->patientQueueForMember($request, $organization->id, $owner, $member, $branchScope) + : [collect(), collect(), null]; + return view('care.dashboard', [ 'organization' => $organization, 'member' => $member, @@ -77,6 +88,61 @@ class DashboardController extends Controller 'canDepartments' => $canDepartments, 'canBills' => $canBills, 'canFinance' => $canFinance, + 'canConsult' => $canConsult, + 'showPatientQueue' => $showPatientQueue, + 'patientQueue' => $queue, + 'inConsultation' => $inConsultation, + 'practitionerId' => $practitionerId, ]); } + + /** + * @return array{0: Collection, 1: Collection, 2: ?int} + */ + protected function patientQueueForMember( + Request $request, + int $organizationId, + string $owner, + ?Member $member, + ?int $branchScope, + ): array { + $practitioner = null; + if ($member) { + $practitioner = Practitioner::owned($owner) + ->where('organization_id', $organizationId) + ->where('is_active', true) + ->where(function ($query) use ($member) { + $query->where('member_id', $member->id) + ->orWhere('user_ref', $member->user_ref); + }) + ->first(); + } + + $practitionerId = $practitioner?->id; + $branchId = $branchScope + ?? $practitioner?->branch_id + ?? Branch::owned($owner) + ->where('organization_id', $organizationId) + ->where('is_active', true) + ->orderBy('name') + ->value('id'); + + if (! $branchId) { + return [collect(), collect(), $practitionerId]; + } + + $queue = $this->appointments->queue($owner, (int) $branchId, $practitionerId); + + $inConsultation = Appointment::owned($owner) + ->where('organization_id', $organizationId) + ->where('status', Appointment::STATUS_IN_CONSULTATION) + ->where('branch_id', $branchId) + ->when($practitionerId, fn ($q) => $q->where('practitioner_id', $practitionerId)) + ->with(['patient', 'practitioner', 'consultation']) + ->orderBy('started_at') + ->limit(20) + ->get(); + + return [$queue, $inConsultation, $practitionerId]; + } } diff --git a/resources/views/care/dashboard.blade.php b/resources/views/care/dashboard.blade.php index cd5d9b9..ad0ab6d 100644 --- a/resources/views/care/dashboard.blade.php +++ b/resources/views/care/dashboard.blade.php @@ -129,6 +129,69 @@ @endif + @if (! empty($showPatientQueue)) +
+
+
+

Patients in queue

+

+ {{ $patientQueue->count() }} waiting + · {{ $inConsultation->count() }} in consultation +

+
+ Open full queue +
+ +
+
+

Waiting

+
+ @forelse ($patientQueue->take(8) as $appointment) +
+
+

+ @if ($appointment->queue_position) + {{ $appointment->queue_position }} + @endif + {{ $appointment->patient?->fullName() ?? 'Patient' }} +

+

{{ $appointment->patient?->patient_number }} · {{ $appointment->reason ?? 'No reason noted' }}

+
+ @if (! empty($canConsult)) +
+ @csrf + +
+ @endif +
+ @empty +

No patients waiting right now.

+ @endforelse +
+
+ +
+

In consultation

+
+ @forelse ($inConsultation->take(8) as $appointment) +
+
+

{{ $appointment->patient?->fullName() ?? 'Patient' }}

+

{{ $appointment->practitioner?->name ?? 'Unassigned' }}

+
+ @if ($appointment->consultation) + Open + @endif +
+ @empty +

No active consultations.

+ @endforelse +
+
+
+
+ @endif + @if (count($organizationCards) > 0) @php $orgCols = match (count($organizationCards)) { diff --git a/tests/Feature/CareWebTest.php b/tests/Feature/CareWebTest.php index c03c28d..2bc1503 100644 --- a/tests/Feature/CareWebTest.php +++ b/tests/Feature/CareWebTest.php @@ -95,6 +95,8 @@ class CareWebTest extends TestCase ->assertOk() ->assertSee('Patients today') ->assertSee('Appointments today') + ->assertSee('Patients in queue') + ->assertSee('No patients waiting right now.') ->assertDontSee('Revenue today') ->assertDontSee('Open bills') ->assertDontSee('Team members')