Consolidate consultation and specialty actions into a sticky panel.
Deploy Ladill Care / deploy (push) Successful in 35s
Deploy Ladill Care / deploy (push) Successful in 35s
Desktop uses a right sticky Actions column; mobile uses a FAB above the nav that opens a bottomsheet. Request investigations moves into a modal/sheet, and Call next is available on the consultation panel. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,8 +10,11 @@ use App\Models\Consultation;
|
||||
use App\Models\InvestigationType;
|
||||
use App\Models\Practitioner;
|
||||
use App\Services\Care\AssessmentService;
|
||||
use App\Services\Care\BranchContext;
|
||||
use App\Services\Care\CareFeatures;
|
||||
use App\Services\Care\CarePermissions;
|
||||
use App\Services\Care\CareQueueBridge;
|
||||
use App\Services\Care\CareQueueContexts;
|
||||
use App\Services\Care\ConsultationReturnContext;
|
||||
use App\Services\Care\ConsultationService;
|
||||
use App\Services\Care\OrganizationResolver;
|
||||
@@ -170,6 +173,24 @@ class ConsultationController extends Controller
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
$queueIntegration = ['enabled' => false];
|
||||
$queueBranchId = null;
|
||||
$queueBridge = app(CareQueueBridge::class);
|
||||
if ($permissions->handlesFloorCare($member) && $queueBridge->isEnabled($organization)) {
|
||||
$queueBranchId = app(BranchContext::class)->resolve($request, $organization, $member)
|
||||
?: (int) ($consultation->practitioner?->branch_id
|
||||
?: $consultation->visit?->branch_id
|
||||
?: $consultation->appointment?->branch_id
|
||||
?: 0);
|
||||
if ($queueBranchId > 0) {
|
||||
$queueIntegration = $queueBridge->listMeta(
|
||||
$organization,
|
||||
CareQueueContexts::CONSULTATION,
|
||||
$queueBranchId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return view('care.consultations.show', [
|
||||
'consultation' => $consultation,
|
||||
'practitioners' => $practitioners,
|
||||
@@ -193,6 +214,8 @@ class ConsultationController extends Controller
|
||||
'pathwaySuggestions' => $pathwaySuggestions,
|
||||
'activePathways' => $activePathways,
|
||||
'pathwayInstruments' => $pathwayInstruments ?? collect(),
|
||||
'queueIntegration' => $queueIntegration,
|
||||
'queueBranchId' => $queueBranchId,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -308,6 +308,27 @@ html.qr-mobile-page body {
|
||||
.btn-fab:hover {
|
||||
filter: brightness(0.92);
|
||||
}
|
||||
|
||||
/* Consultation / specialty action FAB — sits above mobile bottom nav */
|
||||
.clinical-actions-fab {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: calc(4rem + env(safe-area-inset-bottom, 0px) + 0.75rem);
|
||||
z-index: 45;
|
||||
display: inline-flex;
|
||||
height: 3.25rem;
|
||||
width: 3.25rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 9999px;
|
||||
background-image: linear-gradient(to right, rgb(79 70 229), rgb(124 58 237));
|
||||
color: #fff;
|
||||
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.15), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
.clinical-actions-fab:hover {
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
{{-- Action buttons for consultation show (desktop sticky + mobile sheet). --}}
|
||||
@php
|
||||
$canEdit = ! $isCompleted && ($canManage || $canVitals);
|
||||
$btn = 'flex w-full items-center justify-center rounded-xl px-3 py-2.5 text-sm font-semibold transition';
|
||||
$btnPrimary = $btn.' bg-indigo-600 text-white hover:bg-indigo-700';
|
||||
$btnSecondary = $btn.' border border-slate-200 bg-white text-slate-800 hover:bg-slate-50';
|
||||
$btnAccent = $btn.' border border-sky-200 bg-sky-50 text-sky-900 hover:bg-sky-100';
|
||||
@endphp
|
||||
|
||||
@include('care.partials.queue-ops', [
|
||||
'queueIntegration' => $queueIntegration ?? null,
|
||||
'queueCallNextRoute' => 'care.queue.call-next',
|
||||
'queueCallNextParams' => [],
|
||||
'branchId' => $queueBranchId ?? null,
|
||||
])
|
||||
|
||||
@if ($canManage && ! $isCompleted)
|
||||
<button
|
||||
type="button"
|
||||
class="{{ $btnPrimary }}"
|
||||
@click.stop="$dispatch('open-modal', {{ \Illuminate\Support\Js::from('complete-consultation-'.$consultation->id) }})"
|
||||
>
|
||||
Complete consultation
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if ($canEdit)
|
||||
<button type="submit" form="consultation-form" class="{{ $btnPrimary }}">Save</button>
|
||||
@if ($canManage && ($canViewAssessments ?? false))
|
||||
<button type="submit" form="consultation-form" name="suggest_pathways" value="1" class="{{ $btnAccent }}">
|
||||
Show condition suggestions
|
||||
</button>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if ($canPrescribe)
|
||||
<a href="{{ route('care.prescriptions.create', [$consultation, 'from_consultation' => $consultation->uuid]) }}" class="{{ $btnSecondary }}">
|
||||
Prescribe
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($canRequestInvestigations && $investigationTypes->isNotEmpty() && ! $isCompleted)
|
||||
<button
|
||||
type="button"
|
||||
class="{{ $btnSecondary }}"
|
||||
@click.stop="$dispatch('open-modal', {{ \Illuminate\Support\Js::from('request-investigations-'.$consultation->id) }})"
|
||||
>
|
||||
Request investigations
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if ($canGenerateBill && $isCompleted && $consultation->visit)
|
||||
<form method="POST" action="{{ route('care.bills.generate', $consultation->visit) }}" class="w-full" @click.stop>
|
||||
@csrf
|
||||
<input type="hidden" name="from_consultation" value="{{ $consultation->uuid }}">
|
||||
<button type="submit" class="{{ $btn }} w-full bg-slate-800 text-white hover:bg-slate-900">Generate bill</button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
<a href="{{ route('care.queue.index') }}" class="{{ $btnSecondary }}">Back to queue</a>
|
||||
@@ -1,4 +1,6 @@
|
||||
<x-app-layout :title="'Consultation · '.$consultation->patient->fullName()">
|
||||
<div class="lg:grid lg:grid-cols-[minmax(0,1fr)_16rem] lg:items-start lg:gap-6">
|
||||
<div class="min-w-0">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div>
|
||||
<p class="text-xs font-medium uppercase tracking-wide {{ $isCompleted ? 'text-emerald-600' : 'text-amber-600' }}">
|
||||
@@ -10,65 +12,19 @@
|
||||
@if ($consultation->practitioner) · {{ $consultation->practitioner->name }} @endif
|
||||
</p>
|
||||
</div>
|
||||
@if ($canManage && ! $isCompleted)
|
||||
<x-confirm-dialog
|
||||
:name="'complete-consultation-'.$consultation->id"
|
||||
title="Complete this consultation?"
|
||||
message="Mark the consultation as finished. You can still prescribe or generate a bill afterward."
|
||||
:action="route('care.consultations.complete', $consultation)"
|
||||
confirm-label="Complete consultation"
|
||||
variant="primary"
|
||||
>
|
||||
<x-slot:trigger>
|
||||
<button type="button" class="btn-primary">Complete consultation</button>
|
||||
</x-slot:trigger>
|
||||
</x-confirm-dialog>
|
||||
@endif
|
||||
@if ($canPrescribe)
|
||||
<a href="{{ route('care.prescriptions.create', [$consultation, 'from_consultation' => $consultation->uuid]) }}" class="rounded-lg border border-slate-200 bg-white px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Prescribe</a>
|
||||
@endif
|
||||
@if ($canGenerateBill && $isCompleted && $consultation->visit)
|
||||
<form method="POST" action="{{ route('care.bills.generate', $consultation->visit) }}">
|
||||
@csrf
|
||||
<input type="hidden" name="from_consultation" value="{{ $consultation->uuid }}">
|
||||
<button type="submit" class="rounded-lg bg-slate-800 px-4 py-2 text-sm font-medium text-white hover:bg-slate-900">Generate bill</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($canRequestInvestigations && $investigationTypes->isNotEmpty())
|
||||
@if ($canRequestInvestigations && $consultation->investigationRequests->isNotEmpty())
|
||||
<section class="mt-6 rounded-2xl border border-slate-200 bg-white p-6">
|
||||
<h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500">Request investigations</h2>
|
||||
<form method="POST" action="{{ route('care.lab.requests.store', $consultation) }}" class="mt-4 space-y-4">
|
||||
@csrf
|
||||
<div class="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
||||
@foreach ($investigationTypes as $type)
|
||||
<label class="flex items-center gap-2 rounded-lg border border-slate-100 bg-slate-50 px-3 py-2 text-sm">
|
||||
<input type="checkbox" name="investigation_type_ids[]" value="{{ $type->id }}" class="rounded border-slate-300">
|
||||
<span>{{ $type->name }} <span class="text-slate-400">({{ config('care.investigation_categories')[$type->category] ?? $type->category }})</span></span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<input type="text" name="clinical_notes" placeholder="Clinical notes for lab" class="rounded-lg border-slate-300 text-sm">
|
||||
<select name="priority" class="rounded-lg border-slate-300 text-sm">
|
||||
<option value="routine">Routine</option>
|
||||
<option value="urgent">Urgent</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn-primary">Submit requests</button>
|
||||
</form>
|
||||
@if ($consultation->investigationRequests->isNotEmpty())
|
||||
<div class="mt-4 border-t border-slate-100 pt-4 text-sm">
|
||||
<p class="font-medium text-slate-700">Requested tests</p>
|
||||
@foreach ($consultation->investigationRequests as $req)
|
||||
<p class="mt-1">
|
||||
<a href="{{ route('care.lab.requests.show', [$req, 'from_consultation' => $consultation->uuid]) }}" class="text-sky-600">{{ $req->investigationType->name }}</a>
|
||||
· {{ config('care.investigation_statuses')[$req->status] ?? $req->status }}
|
||||
</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<h2 class="text-sm font-semibold uppercase tracking-wide text-slate-500">Requested tests</h2>
|
||||
<div class="mt-3 space-y-1 text-sm">
|
||||
@foreach ($consultation->investigationRequests as $req)
|
||||
<p>
|
||||
<a href="{{ route('care.lab.requests.show', [$req, 'from_consultation' => $consultation->uuid]) }}" class="text-sky-600">{{ $req->investigationType->name }}</a>
|
||||
· {{ config('care.investigation_statuses')[$req->status] ?? $req->status }}
|
||||
</p>
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
@@ -284,7 +240,7 @@
|
||||
@endif
|
||||
|
||||
@if (! $isCompleted && ($canManage || $canVitals))
|
||||
<form method="POST" action="{{ route('care.consultations.update', $consultation) }}" enctype="multipart/form-data" class="mt-6 space-y-6">
|
||||
<form id="consultation-form" method="POST" action="{{ route('care.consultations.update', $consultation) }}" enctype="multipart/form-data" class="mt-6 space-y-6">
|
||||
@csrf @method('PUT')
|
||||
|
||||
@if ($canVitals)
|
||||
@@ -400,16 +356,6 @@
|
||||
<input type="file" name="documents[]" multiple accept=".pdf,.jpg,.jpeg,.png,.webp" class="mt-4 block w-full text-sm text-slate-500">
|
||||
</section>
|
||||
@endif
|
||||
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button type="submit" class="btn-primary">Save</button>
|
||||
@if ($canManage && ($canViewAssessments ?? false))
|
||||
<button type="submit" name="suggest_pathways" value="1" class="rounded-lg border border-sky-200 bg-sky-50 px-4 py-2 text-sm font-medium text-sky-800 hover:bg-sky-100">
|
||||
Save diagnoses & show condition suggestions
|
||||
</button>
|
||||
@endif
|
||||
<a href="{{ route('care.queue.index') }}" class="rounded-lg border border-slate-200 px-4 py-2 text-sm text-slate-600">Back to queue</a>
|
||||
</div>
|
||||
</form>
|
||||
@else
|
||||
<div class="mt-6 space-y-6">
|
||||
@@ -484,4 +430,60 @@
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>{{-- end main column --}}
|
||||
|
||||
@include('care.partials.clinical-actions-panel', [
|
||||
'actionsView' => 'care.consultations.partials.actions-menu',
|
||||
'title' => 'Actions',
|
||||
])
|
||||
</div>{{-- end grid --}}
|
||||
|
||||
@include('care.partials.clinical-actions-mobile', [
|
||||
'actionsView' => 'care.consultations.partials.actions-menu',
|
||||
'title' => 'Actions',
|
||||
])
|
||||
|
||||
@if ($canManage && ! $isCompleted)
|
||||
<x-confirm-dialog
|
||||
:name="'complete-consultation-'.$consultation->id"
|
||||
title="Complete this consultation?"
|
||||
message="Mark the consultation as finished. You can still prescribe or generate a bill afterward."
|
||||
:action="route('care.consultations.complete', $consultation)"
|
||||
confirm-label="Complete consultation"
|
||||
variant="primary"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($canRequestInvestigations && $investigationTypes->isNotEmpty() && ! $isCompleted)
|
||||
<x-modal :name="'request-investigations-'.$consultation->id" maxWidth="2xl">
|
||||
<div class="px-5 pb-6 pt-2 sm:px-6 sm:pb-6 sm:pt-4">
|
||||
<h2 class="pr-8 text-lg font-semibold text-slate-900">Request investigations</h2>
|
||||
<p class="mt-1 text-sm text-slate-500">Select tests to send to the lab for this visit.</p>
|
||||
<form method="POST" action="{{ route('care.lab.requests.store', $consultation) }}" class="mt-4 space-y-4">
|
||||
@csrf
|
||||
<div class="grid max-h-[40vh] gap-2 overflow-y-auto sm:grid-cols-2">
|
||||
@foreach ($investigationTypes as $type)
|
||||
<label class="flex items-center gap-2 rounded-lg border border-slate-100 bg-slate-50 px-3 py-2 text-sm">
|
||||
<input type="checkbox" name="investigation_type_ids[]" value="{{ $type->id }}" class="rounded border-slate-300">
|
||||
<span>{{ $type->name }} <span class="text-slate-400">({{ config('care.investigation_categories')[$type->category] ?? $type->category }})</span></span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<input type="text" name="clinical_notes" placeholder="Clinical notes for lab" class="rounded-lg border-slate-300 text-sm">
|
||||
<select name="priority" class="rounded-lg border-slate-300 text-sm">
|
||||
<option value="routine">Routine</option>
|
||||
<option value="urgent">Urgent</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
|
||||
<button type="button" class="rounded-xl border border-slate-200 px-4 py-2.5 text-sm font-semibold text-slate-700 hover:bg-slate-50" @click="$dispatch('close-modal', {{ \Illuminate\Support\Js::from('request-investigations-'.$consultation->id) }})">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn-primary">Submit requests</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</x-modal>
|
||||
@endif
|
||||
</x-app-layout>
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
{{-- Mobile FAB + bottomsheet Actions. Place outside the page grid. --}}
|
||||
@php
|
||||
$actionsView = $actionsView ?? null;
|
||||
$title = $title ?? 'Actions';
|
||||
@endphp
|
||||
@if ($actionsView)
|
||||
<div
|
||||
x-data="{ open: false }"
|
||||
@keydown.escape.window="open = false"
|
||||
class="lg:hidden"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="clinical-actions-fab"
|
||||
@click="open = ! open"
|
||||
:aria-expanded="open.toString()"
|
||||
aria-label="Open actions"
|
||||
>
|
||||
<svg x-show="! open" class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>
|
||||
</svg>
|
||||
<svg x-show="open" x-cloak class="h-6 w-6" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<template x-teleport="body">
|
||||
<div
|
||||
x-show="open"
|
||||
x-cloak
|
||||
class="fixed inset-0 z-[60] lg:hidden"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="{{ $title }}"
|
||||
>
|
||||
<div
|
||||
class="absolute inset-0 bg-slate-900/40 backdrop-blur-[2px]"
|
||||
@click="open = false"
|
||||
x-show="open"
|
||||
x-transition:enter="ease-out duration-200"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="ease-in duration-150"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="absolute inset-x-0 bottom-0 max-h-[85vh] overflow-y-auto rounded-t-3xl bg-white shadow-2xl"
|
||||
style="padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px))"
|
||||
@click.stop
|
||||
x-show="open"
|
||||
x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="translate-y-full"
|
||||
x-transition:enter-end="translate-y-0"
|
||||
x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="translate-y-0"
|
||||
x-transition:leave-end="translate-y-full"
|
||||
>
|
||||
<div class="flex justify-center pb-1 pt-3">
|
||||
<div class="h-1 w-10 rounded-full bg-slate-200"></div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between px-5 pb-2">
|
||||
<h2 class="text-base font-semibold text-slate-900">{{ $title }}</h2>
|
||||
<button type="button" class="rounded-full p-2 text-slate-400 hover:bg-slate-100 hover:text-slate-600" @click="open = false" aria-label="Close">
|
||||
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="space-y-2 px-4 pb-4">
|
||||
@include($actionsView)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@endif
|
||||
@@ -0,0 +1,13 @@
|
||||
{{-- Desktop sticky Actions column. Pair with clinical-actions-mobile outside the grid. --}}
|
||||
@php
|
||||
$actionsView = $actionsView ?? null;
|
||||
$title = $title ?? 'Actions';
|
||||
@endphp
|
||||
@if ($actionsView)
|
||||
<aside class="hidden rounded-2xl border border-slate-200 bg-white p-4 lg:sticky lg:top-4 lg:block lg:self-start">
|
||||
<h2 class="text-sm font-semibold text-slate-900">{{ $title }}</h2>
|
||||
<div class="mt-3 space-y-2">
|
||||
@include($actionsView)
|
||||
</div>
|
||||
</aside>
|
||||
@endif
|
||||
@@ -0,0 +1,69 @@
|
||||
{{-- Specialty shell action buttons (desktop sticky + mobile sheet). --}}
|
||||
@php
|
||||
$btn = 'flex w-full items-center justify-center rounded-xl px-3 py-2.5 text-sm font-semibold transition';
|
||||
$btnPrimary = $btn.' bg-indigo-600 text-white hover:bg-indigo-700';
|
||||
$btnSecondary = $btn.' border border-slate-200 bg-white text-slate-800 hover:bg-slate-50';
|
||||
$btnAccent = $btn.' border border-indigo-200 bg-indigo-50 text-indigo-900 hover:bg-indigo-100';
|
||||
@endphp
|
||||
|
||||
@include('care.partials.queue-ops', [
|
||||
'queueIntegration' => $queueIntegration ?? null,
|
||||
'queueCallNextRoute' => 'care.specialty.call-next',
|
||||
'queueCallNextParams' => ['module' => $moduleKey],
|
||||
'branchId' => $branchId ?? null,
|
||||
])
|
||||
|
||||
@if ($workspaceVisit)
|
||||
@php
|
||||
$appointment = $workspaceVisit->appointment;
|
||||
$openConsultation = $appointment?->consultation;
|
||||
$canStartConsultation = $appointment && in_array($appointment->status, [
|
||||
\App\Models\Appointment::STATUS_WAITING,
|
||||
\App\Models\Appointment::STATUS_CHECKED_IN,
|
||||
], true);
|
||||
$consultationInProgress = $appointment
|
||||
&& (
|
||||
$appointment->status === \App\Models\Appointment::STATUS_IN_CONSULTATION
|
||||
|| ($openConsultation && $openConsultation->status !== \App\Models\Consultation::STATUS_COMPLETED)
|
||||
);
|
||||
$chartTab = collect($workspaceTabs ?? [])
|
||||
->keys()
|
||||
->first(fn ($key) => ! in_array($key, ['overview', 'orders', 'billing', 'documents'], true))
|
||||
?: 'clinical_notes';
|
||||
@endphp
|
||||
@if ($consultationInProgress)
|
||||
<a href="{{ route('care.specialty.workspace', ['module' => $moduleKey, 'visit' => $workspaceVisit, 'tab' => $chartTab]) }}"
|
||||
class="{{ $btnPrimary }}">
|
||||
Open specialty chart
|
||||
</a>
|
||||
@elseif ($canStartConsultation)
|
||||
<form method="POST" action="{{ route('care.specialty.consultation.start', ['module' => $moduleKey, 'visit' => $workspaceVisit]) }}" class="w-full" @click.stop>
|
||||
@csrf
|
||||
<button type="submit" class="{{ $btnPrimary }}">
|
||||
{{ $actions['start'] ?? 'Start specialty encounter' }}
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
<a href="{{ route('care.specialty.workspace', ['module' => $moduleKey, 'visit' => $workspaceVisit]) }}"
|
||||
class="{{ $btnSecondary }}">
|
||||
Specialty workspace
|
||||
</a>
|
||||
@if ($workspaceVisit->patient)
|
||||
<a href="{{ route('care.patients.show', $workspaceVisit->patient) }}" class="{{ $btnSecondary }}">
|
||||
Patient chart
|
||||
</a>
|
||||
@endif
|
||||
@if ($workspaceVisit->appointment)
|
||||
<a href="{{ route('care.appointments.show', $workspaceVisit->appointment) }}" class="{{ $btnSecondary }}">
|
||||
Appointment
|
||||
</a>
|
||||
@endif
|
||||
@else
|
||||
<a href="{{ route('care.specialty.workspace', ['module' => $moduleKey]) }}" class="{{ $btnPrimary }}">
|
||||
Open workspace
|
||||
</a>
|
||||
@endif
|
||||
|
||||
<a href="{{ route('care.appointments.create') }}" class="{{ $btnAccent }}">
|
||||
Register / book
|
||||
</a>
|
||||
@@ -9,7 +9,7 @@
|
||||
<a href="{{ route('care.settings.modules') }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800">Manage modules</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 lg:grid-cols-[220px_minmax(0,1fr)_240px]">
|
||||
<div class="grid gap-4 lg:grid-cols-[220px_minmax(0,1fr)_16rem]">
|
||||
{{-- Left navigation --}}
|
||||
<nav class="rounded-2xl border border-slate-200 bg-white p-3 lg:sticky lg:top-4 lg:self-start">
|
||||
<p class="px-2 pb-2 text-[10px] font-semibold uppercase tracking-wider text-slate-400">Navigate</p>
|
||||
@@ -63,77 +63,15 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Action panel --}}
|
||||
<aside class="rounded-2xl border border-slate-200 bg-white p-4 lg:sticky lg:top-4 lg:self-start">
|
||||
<h2 class="text-sm font-semibold text-slate-900">Actions</h2>
|
||||
<div class="mt-3 space-y-2">
|
||||
@include('care.partials.queue-ops', [
|
||||
'queueIntegration' => $queueIntegration ?? null,
|
||||
'queueCallNextRoute' => 'care.specialty.call-next',
|
||||
'queueCallNextParams' => ['module' => $moduleKey],
|
||||
'branchId' => $branchId ?? null,
|
||||
])
|
||||
|
||||
@if ($workspaceVisit)
|
||||
@php
|
||||
$appointment = $workspaceVisit->appointment;
|
||||
$openConsultation = $appointment?->consultation;
|
||||
$canStartConsultation = $appointment && in_array($appointment->status, [
|
||||
\App\Models\Appointment::STATUS_WAITING,
|
||||
\App\Models\Appointment::STATUS_CHECKED_IN,
|
||||
], true);
|
||||
$consultationInProgress = $appointment
|
||||
&& (
|
||||
$appointment->status === \App\Models\Appointment::STATUS_IN_CONSULTATION
|
||||
|| ($openConsultation && $openConsultation->status !== \App\Models\Consultation::STATUS_COMPLETED)
|
||||
);
|
||||
$chartTab = collect($workspaceTabs ?? [])
|
||||
->keys()
|
||||
->first(fn ($key) => ! in_array($key, ['overview', 'orders', 'billing', 'documents'], true))
|
||||
?: 'clinical_notes';
|
||||
@endphp
|
||||
@if ($consultationInProgress)
|
||||
<a href="{{ route('care.specialty.workspace', ['module' => $moduleKey, 'visit' => $workspaceVisit, 'tab' => $chartTab]) }}"
|
||||
class="flex w-full items-center justify-center rounded-xl bg-indigo-600 px-3 py-2 text-sm font-semibold text-white hover:bg-indigo-700">
|
||||
Open specialty chart
|
||||
</a>
|
||||
@elseif ($canStartConsultation)
|
||||
<form method="POST" action="{{ route('care.specialty.consultation.start', ['module' => $moduleKey, 'visit' => $workspaceVisit]) }}">
|
||||
@csrf
|
||||
<button type="submit" class="flex w-full items-center justify-center rounded-xl bg-indigo-600 px-3 py-2 text-sm font-semibold text-white hover:bg-indigo-700">
|
||||
{{ $actions['start'] ?? 'Start specialty encounter' }}
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
<a href="{{ route('care.specialty.workspace', ['module' => $moduleKey, 'visit' => $workspaceVisit]) }}"
|
||||
class="flex w-full items-center justify-center rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-sm font-medium text-slate-800 hover:bg-slate-100">
|
||||
Specialty workspace
|
||||
</a>
|
||||
@if ($workspaceVisit->patient)
|
||||
<a href="{{ route('care.patients.show', $workspaceVisit->patient) }}"
|
||||
class="flex w-full items-center justify-center rounded-xl border border-slate-200 px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">
|
||||
Patient chart
|
||||
</a>
|
||||
@endif
|
||||
@if ($workspaceVisit->appointment)
|
||||
<a href="{{ route('care.appointments.show', $workspaceVisit->appointment) }}"
|
||||
class="flex w-full items-center justify-center rounded-xl border border-slate-200 px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">
|
||||
Appointment
|
||||
</a>
|
||||
@endif
|
||||
@else
|
||||
<a href="{{ route('care.specialty.workspace', ['module' => $moduleKey]) }}"
|
||||
class="flex w-full items-center justify-center rounded-xl bg-indigo-600 px-3 py-2 text-sm font-semibold text-white hover:bg-indigo-700">
|
||||
Open workspace
|
||||
</a>
|
||||
@endif
|
||||
|
||||
<a href="{{ route('care.appointments.create') }}"
|
||||
class="flex w-full items-center justify-center rounded-xl border border-indigo-200 bg-indigo-50 px-3 py-2 text-sm font-medium text-indigo-800 hover:bg-indigo-100">
|
||||
Register / book
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
@include('care.partials.clinical-actions-panel', [
|
||||
'actionsView' => 'care.specialty.partials.actions-menu',
|
||||
'title' => 'Actions',
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('care.partials.clinical-actions-mobile', [
|
||||
'actionsView' => 'care.specialty.partials.actions-menu',
|
||||
'title' => 'Actions',
|
||||
])
|
||||
</x-app-layout>
|
||||
|
||||
Reference in New Issue
Block a user