Add full Blood Bank specialty suite on shared shell.
Deploy Ladill Care / deploy (push) Successful in 37s

Mirror Emergency: stage workflow, issue/transfusion records, analytics,
print, and action-menu stage flow without a parallel EHR.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-18 21:36:57 +00:00
co-authored by Cursor
parent 847d63c1c2
commit f688a48c37
19 changed files with 1590 additions and 30 deletions
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blood Bank summary · {{ $patient->fullName() }}</title>
<style>
body { font-family: system-ui, sans-serif; color: #0f172a; margin: 2rem; }
h1 { font-size: 1.25rem; margin: 0 0 .25rem; }
h2 { font-size: .95rem; margin: 1.25rem 0 .5rem; border-bottom: 1px solid #e2e8f0; padding-bottom: .25rem; }
.meta { color: #64748b; font-size: .875rem; }
dl { display: grid; grid-template-columns: 10rem 1fr; gap: .35rem .75rem; font-size: .875rem; }
dt { color: #64748b; }
dd { margin: 0; font-weight: 500; }
@media print { .no-print { display: none; } }
</style>
</head>
<body>
<p class="no-print"><a href="{{ route('care.specialty.workspace', ['module' => 'blood_bank', 'visit' => $visit]) }}">Back</a></p>
<h1>{{ $patient->fullName() }}</h1>
<p class="meta">
{{ $patient->patient_number }}
· Visit #{{ $visit->id }}
· Stage {{ $visit->specialty_stage ?? '—' }}
· {{ $visit->checked_in_at?->format('d M Y H:i') ?? '—' }}
</p>
<h2>Blood request</h2>
@if ($bloodRequest)
<dl>
<dt>Product</dt><dd>{{ $bloodRequest->payload['product'] ?? '—' }}</dd>
<dt>Units requested</dt><dd>{{ $bloodRequest->payload['units'] ?? '—' }}</dd>
<dt>Urgency</dt><dd>{{ $bloodRequest->payload['urgency'] ?? '—' }}</dd>
<dt>Blood group</dt><dd>{{ $bloodRequest->payload['patient_blood_group'] ?? '—' }}</dd>
<dt>Indication</dt><dd>{{ $bloodRequest->payload['indication'] ?? '—' }}</dd>
<dt>Cross-match</dt><dd>{{ $bloodRequest->payload['crossmatch_status'] ?? '—' }}</dd>
<dt>Issued units</dt><dd>{{ $bloodRequest->payload['issued_units'] ?? '—' }}</dd>
<dt>Notes</dt><dd>{{ $bloodRequest->payload['notes'] ?? '—' }}</dd>
</dl>
@else
<p class="meta">No blood request recorded.</p>
@endif
<h2>Issue</h2>
@if ($issueNote)
<dl>
<dt>Product</dt><dd>{{ $issueNote->payload['product'] ?? '—' }}</dd>
<dt>Units issued</dt><dd>{{ $issueNote->payload['units_issued'] ?? '—' }}</dd>
<dt>Bag numbers</dt><dd>{{ $issueNote->payload['bag_numbers'] ?? '—' }}</dd>
<dt>Issued to</dt><dd>{{ $issueNote->payload['issued_to'] ?? '—' }}</dd>
<dt>Issued at</dt><dd>{{ $issueNote->payload['issued_at'] ?? '—' }}</dd>
<dt>Notes</dt><dd>{{ $issueNote->payload['notes'] ?? '—' }}</dd>
</dl>
@else
<p class="meta">No issue recorded.</p>
@endif
<h2>Transfusion</h2>
@if ($transfusionNote)
<dl>
<dt>Started</dt><dd>{{ $transfusionNote->payload['started_at'] ?? '—' }}</dd>
<dt>Units transfused</dt><dd>{{ $transfusionNote->payload['units_transfused'] ?? '—' }}</dd>
<dt>Reaction</dt><dd>{{ $transfusionNote->payload['reaction'] ?? '—' }}</dd>
<dt>Outcome</dt><dd>{{ $transfusionNote->payload['outcome'] ?? '—' }}</dd>
<dt>Notes</dt><dd>{{ $transfusionNote->payload['notes'] ?? '—' }}</dd>
</dl>
@else
<p class="meta">No transfusion record.</p>
@endif
@if ($visit->bill)
<h2>Billing ({{ $visit->bill->invoice_number }})</h2>
<dl>
@foreach ($visit->bill->lineItems as $line)
<dt>{{ $line->description }}</dt>
<dd>{{ number_format($line->total_minor / 100, 2) }}</dd>
@endforeach
</dl>
@endif
<script>window.print();</script>
</body>
</html>
@@ -0,0 +1,86 @@
<x-app-layout title="Blood Bank reports">
<div class="space-y-6">
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<h1 class="text-xl font-semibold text-slate-900">Blood Bank reports</h1>
<p class="mt-1 text-sm text-slate-500">Requests, urgency mix, products issued, low stock, and bb.* revenue.</p>
</div>
<a href="{{ route('care.specialty.workspace', 'blood_bank') }}" class="text-sm font-medium text-indigo-600"> Specialty home</a>
</div>
<form method="GET" class="flex flex-wrap items-end gap-3 rounded-2xl border border-slate-200 bg-white p-4">
<div>
<label class="block text-xs font-medium text-slate-600">From</label>
<input type="date" name="from" value="{{ $report['from'] ?? '' }}" class="mt-1 rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<div>
<label class="block text-xs font-medium text-slate-600">To</label>
<input type="date" name="to" value="{{ $report['to'] ?? '' }}" class="mt-1 rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<button type="submit" class="rounded-xl bg-indigo-600 px-4 py-2 text-sm font-semibold text-white">Apply</button>
</form>
<div class="grid gap-4 sm:grid-cols-4">
<div class="rounded-2xl border border-slate-200 bg-white p-4">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Requests today</p>
<p class="mt-2 text-2xl font-semibold tabular-nums text-slate-900">{{ number_format($report['requests_today']) }}</p>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Completed today</p>
<p class="mt-2 text-2xl font-semibold tabular-nums text-slate-900">{{ number_format($report['completed_today']) }}</p>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">High-urgency open</p>
<p class="mt-2 text-2xl font-semibold tabular-nums text-rose-700">{{ number_format($report['high_urgency_open']) }}</p>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Low stock flags</p>
<p class="mt-2 text-2xl font-semibold tabular-nums text-amber-800">{{ number_format($report['low_stock_flags']) }}</p>
</div>
</div>
<div class="grid gap-4 lg:grid-cols-2">
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<h2 class="text-sm font-semibold text-slate-900">Urgency mix</h2>
<ul class="mt-3 space-y-2 text-sm">
@forelse ($report['urgency_mix'] as $row)
<li class="flex justify-between gap-3">
<span>{{ $row['urgency'] }}</span>
<span class="tabular-nums text-slate-600">{{ $row['total'] }}</span>
</li>
@empty
<li class="text-slate-500">No requests in range.</li>
@endforelse
</ul>
</section>
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<h2 class="text-sm font-semibold text-slate-900">Products issued</h2>
<ul class="mt-3 space-y-2 text-sm">
@forelse ($report['products_issued'] as $row)
<li class="flex justify-between gap-3">
<span>{{ $row['product'] }} <span class="text-slate-400">×{{ $row['issues'] }}</span></span>
<span class="tabular-nums text-slate-600">{{ $row['total'] }} units</span>
</li>
@empty
<li class="text-slate-500">No issues in range.</li>
@endforelse
</ul>
</section>
</div>
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<h2 class="text-sm font-semibold text-slate-900">Blood Bank service revenue</h2>
<ul class="mt-3 space-y-2 text-sm">
@forelse ($report['revenue_by_service'] as $row)
<li class="flex justify-between gap-3">
<span>{{ $row->description }} <span class="text-slate-400">×{{ $row->total }}</span></span>
<span class="tabular-nums">{{ $currency }} {{ number_format($row->amount_minor / 100, 2) }}</span>
</li>
@empty
<li class="text-slate-500">No Blood Bank bill lines in range.</li>
@endforelse
</ul>
</section>
</div>
</x-app-layout>
@@ -0,0 +1,100 @@
@php
$issue = $bloodBankIssue;
$payload = $issue?->payload ?? [];
$requestPayload = $bloodBankRequest?->payload ?? [];
$canManage = $canManageClinical ?? $canConsult ?? false;
$defaults = [
'product' => $payload['product'] ?? ($requestPayload['product'] ?? ''),
'units_issued' => $payload['units_issued'] ?? ($requestPayload['units'] ?? ''),
'bag_numbers' => $payload['bag_numbers'] ?? '',
'issued_to' => $payload['issued_to'] ?? '',
'issued_at' => $payload['issued_at'] ?? now()->format('Y-m-d H:i'),
'notes' => $payload['notes'] ?? '',
];
@endphp
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 class="text-sm font-semibold text-slate-900">Product issue</h3>
<p class="mt-0.5 text-xs text-slate-500">Confirm units issued and optionally bill Blood Bank catalog services.</p>
</div>
@if ($issue)
<span class="rounded-lg bg-emerald-50 px-2.5 py-1 text-xs font-semibold text-emerald-800">Issued recorded</span>
@endif
</div>
@if ($canManage)
<form method="POST" action="{{ route('care.specialty.blood-bank.issue', $workspaceVisit) }}" class="mt-4 space-y-4">
@csrf
<input type="hidden" name="tab" value="issue">
<div class="grid gap-3 sm:grid-cols-2">
<div>
<label class="block text-xs font-medium text-slate-600">Product</label>
<select name="payload[product]" required class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
<option value="">Select…</option>
@foreach (['Whole blood', 'Packed RBC', 'Platelets', 'FFP', 'Cryoprecipitate'] as $option)
<option value="{{ $option }}" @selected(old('payload.product', $defaults['product']) === $option)>{{ $option }}</option>
@endforeach
</select>
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Units issued</label>
<input type="number" name="payload[units_issued]" min="1" required value="{{ old('payload.units_issued', $defaults['units_issued']) }}" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Bag / unit numbers</label>
<input type="text" name="payload[bag_numbers]" value="{{ old('payload.bag_numbers', $defaults['bag_numbers']) }}" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Issued to (ward / clinician)</label>
<input type="text" name="payload[issued_to]" value="{{ old('payload.issued_to', $defaults['issued_to']) }}" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Issued at</label>
<input type="text" name="payload[issued_at]" value="{{ old('payload.issued_at', $defaults['issued_at']) }}" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Notes</label>
<textarea name="payload[notes]" rows="2" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">{{ old('payload.notes', $defaults['notes']) }}</textarea>
</div>
<div class="flex flex-wrap gap-4 text-sm">
<label class="inline-flex items-center gap-2">
<input type="checkbox" name="bill_product" value="1" checked class="rounded border-slate-300">
Bill product units (bb.*)
</label>
<label class="inline-flex items-center gap-2">
<input type="checkbox" name="bill_crossmatch" value="1" class="rounded border-slate-300">
Bill cross-match
</label>
</div>
<button type="submit" class="btn-primary">Confirm issue</button>
</form>
@elseif ($issue)
<dl class="mt-4 grid gap-3 text-sm sm:grid-cols-2">
<div>
<dt class="text-slate-500">Product</dt>
<dd class="font-medium text-slate-900">{{ $payload['product'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Units issued</dt>
<dd class="font-medium text-slate-900">{{ $payload['units_issued'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Bag numbers</dt>
<dd class="font-medium text-slate-900">{{ $payload['bag_numbers'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Issued to</dt>
<dd class="font-medium text-slate-900">{{ $payload['issued_to'] ?? '—' }}</dd>
</div>
</dl>
@else
<p class="mt-3 text-sm text-slate-500">No issue recorded yet.</p>
@endif
</section>
@@ -0,0 +1,143 @@
@php
$requestRecord = $bloodBankRequest;
$payload = $requestRecord?->payload ?? [];
$issuePayload = $bloodBankIssue?->payload ?? [];
$inventoryPayload = $bloodBankInventory?->payload ?? [];
$currentStage = $workspaceVisit->specialty_stage;
$stageFlow = $bloodBankStageFlow ?? [];
$canManage = $canConsult ?? false;
$urgency = (string) ($payload['urgency'] ?? '');
$isHighUrgency = str_contains(strtolower($urgency), 'urgent')
|| str_contains(strtolower($urgency), 'emergency')
|| str_contains(strtolower($urgency), 'massive');
@endphp
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 class="text-sm font-semibold text-slate-900">Blood Bank overview</h3>
<p class="mt-0.5 text-xs text-slate-500">Open request, urgency, cross-match status, and visit stage.</p>
</div>
<div class="flex flex-wrap gap-3 text-sm">
<a href="{{ route('care.specialty.blood-bank.print', $workspaceVisit) }}" target="_blank" class="font-medium text-indigo-600">Print summary</a>
<a href="{{ route('care.specialty.blood-bank.reports') }}" class="font-medium text-indigo-600">BB reports</a>
</div>
</div>
<div class="mt-4 grid gap-3 sm:grid-cols-3">
<div class="rounded-xl border border-slate-100 bg-slate-50 px-3 py-3">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Request</p>
<p class="mt-1 text-sm font-semibold text-slate-900">{{ $payload['product'] ?? 'No request' }}</p>
<p class="mt-1 text-xs text-slate-500">
{{ isset($payload['units']) ? $payload['units'].' unit(s)' : '—' }}
· {{ $payload['patient_blood_group'] ?? 'Group —' }}
</p>
</div>
<div class="rounded-xl border border-slate-100 bg-slate-50 px-3 py-3">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Urgency / cross-match</p>
<p @class([
'mt-1 text-sm font-semibold',
'text-rose-700' => $isHighUrgency,
'text-slate-900' => ! $isHighUrgency,
])>
{{ $urgency !== '' ? $urgency : 'Not set' }}
</p>
<p class="mt-1 text-xs text-slate-500">{{ $payload['crossmatch_status'] ?? 'Cross-match not started' }}</p>
</div>
<div class="rounded-xl border border-slate-100 bg-slate-50 px-3 py-3">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Issued</p>
<p class="mt-1 text-sm font-semibold text-slate-900">
{{ $issuePayload['units_issued'] ?? $payload['issued_units'] ?? '0' }} unit(s)
</p>
<p class="mt-1 text-xs text-slate-500">
{{ $issuePayload['product'] ?? ($payload['product'] ?? '—') }}
</p>
</div>
</div>
<div class="mt-4 rounded-xl border border-slate-100 bg-slate-50 px-3 py-3">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Visit stage</p>
<p class="mt-1 text-sm font-medium text-slate-900">
{{ $currentStage ? ucfirst(str_replace('_', ' ', $currentStage)) : 'Not set' }}
</p>
<div class="mt-3 flex flex-wrap gap-2">
@foreach (($bloodBankStageCodes ?: ['request', 'crossmatch', 'issue', 'transfusion', 'completed']) as $stageCode)
@if ($canManage)
<form method="POST" action="{{ route('care.specialty.blood-bank.stage', $workspaceVisit) }}">
@csrf
<input type="hidden" name="stage" value="{{ $stageCode }}">
<button type="submit"
@class([
'rounded-lg px-2.5 py-1 text-xs font-semibold',
'bg-indigo-600 text-white' => $currentStage === $stageCode,
'border border-slate-200 bg-white text-slate-700 hover:bg-slate-50' => $currentStage !== $stageCode,
])>
{{ ucfirst(str_replace('_', ' ', $stageCode)) }}
</button>
</form>
@else
<span
@class([
'rounded-lg px-2.5 py-1 text-xs font-semibold',
'bg-indigo-600 text-white' => $currentStage === $stageCode,
'border border-slate-200 bg-white text-slate-400' => $currentStage !== $stageCode,
])
@if ($currentStage !== $stageCode) aria-disabled="true" title="View-only access" @endif
>
{{ ucfirst(str_replace('_', ' ', $stageCode)) }}
</span>
@endif
@endforeach
@if ($canManage && $currentStage && isset($stageFlow[$currentStage]) && $stageFlow[$currentStage]['next'] !== $currentStage)
<form method="POST" action="{{ route('care.specialty.blood-bank.stage', $workspaceVisit) }}">
@csrf
<input type="hidden" name="stage" value="{{ $stageFlow[$currentStage]['next'] }}">
<button type="submit" class="rounded-lg bg-emerald-600 px-2.5 py-1 text-xs font-semibold text-white hover:bg-emerald-700">
{{ $stageFlow[$currentStage]['label'] }}
</button>
</form>
@endif
</div>
</div>
<dl class="mt-4 grid gap-3 text-sm sm:grid-cols-2">
<div>
<dt class="text-slate-500">Indication</dt>
<dd class="font-medium text-slate-900">{{ $payload['indication'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Inventory flag</dt>
<dd class="font-medium text-slate-900">
@if (! empty($inventoryPayload['low_stock_alert']))
<span class="text-amber-800">Low stock flagged</span>
@else
{{ isset($inventoryPayload['packed_rbc_units']) ? 'Stock noted' : '—' }}
@endif
</dd>
</div>
<div>
<dt class="text-slate-500">Queue</dt>
<dd class="font-medium text-slate-900">
{{ $workspaceVisit->appointment?->queue_ticket_number ?? '—' }}
@if ($workspaceVisit->appointment?->queue_ticket_status)
<span class="text-slate-500">({{ $workspaceVisit->appointment->queue_ticket_status }})</span>
@endif
</dd>
</div>
<div>
<dt class="text-slate-500">Checked in</dt>
<dd class="font-medium text-slate-900">{{ $workspaceVisit->checked_in_at?->format('d M Y H:i') ?? '—' }}</dd>
</div>
</dl>
@if (! empty($clinicalAlerts))
<div class="mt-4 space-y-1.5 border-t border-slate-100 pt-4">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Alerts</p>
@foreach ($clinicalAlerts as $alert)
<p class="text-sm {{ ($alert['severity'] ?? '') === 'critical' ? 'text-rose-700' : 'text-amber-800' }}">
{{ $alert['message'] ?? '' }}
</p>
@endforeach
</div>
@endif
</section>
@@ -0,0 +1,90 @@
@php
$transfusion = $bloodBankTransfusion;
$payload = $transfusion?->payload ?? [];
$canManage = $canManageClinical ?? $canConsult ?? false;
$defaults = [
'started_at' => $payload['started_at'] ?? now()->format('Y-m-d H:i'),
'units_transfused' => $payload['units_transfused'] ?? '',
'vitals_ok' => old('payload.vitals_ok', $payload['vitals_ok'] ?? true),
'reaction' => $payload['reaction'] ?? 'None',
'outcome' => $payload['outcome'] ?? '',
'notes' => $payload['notes'] ?? '',
];
@endphp
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 class="text-sm font-semibold text-slate-900">Transfusion</h3>
<p class="mt-0.5 text-xs text-slate-500">Document transfusion progress, reactions, and outcome.</p>
</div>
</div>
@if ($canManage)
<form method="POST" action="{{ route('care.specialty.blood-bank.transfusion', $workspaceVisit) }}" class="mt-4 space-y-4">
@csrf
<input type="hidden" name="tab" value="transfusion">
<div class="grid gap-3 sm:grid-cols-2">
<div>
<label class="block text-xs font-medium text-slate-600">Started at</label>
<input type="text" name="payload[started_at]" value="{{ old('payload.started_at', $defaults['started_at']) }}" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Units transfused</label>
<input type="number" name="payload[units_transfused]" min="0" value="{{ old('payload.units_transfused', $defaults['units_transfused']) }}" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Reaction</label>
<select name="payload[reaction]" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
@foreach (['None', 'Mild (fever / itch)', 'Moderate', 'Severe / stop transfusion'] as $option)
<option value="{{ $option }}" @selected(old('payload.reaction', $defaults['reaction']) === $option)>{{ $option }}</option>
@endforeach
</select>
</div>
<div>
<label class="block text-xs font-medium text-slate-600">Outcome</label>
<select name="payload[outcome]" required class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">
<option value="">Select…</option>
@foreach (['In progress', 'Completed uneventfully', 'Stopped — reaction', 'Stopped — other'] as $option)
<option value="{{ $option }}" @selected(old('payload.outcome', $defaults['outcome']) === $option)>{{ $option }}</option>
@endforeach
</select>
</div>
</div>
<label class="inline-flex items-center gap-2 text-sm">
<input type="checkbox" name="payload[vitals_ok]" value="1" @checked(old('payload.vitals_ok', $defaults['vitals_ok'])) class="rounded border-slate-300">
Pre-/intra-transfusion vitals acceptable
</label>
<div>
<label class="block text-xs font-medium text-slate-600">Notes</label>
<textarea name="payload[notes]" rows="3" class="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 text-sm">{{ old('payload.notes', $defaults['notes']) }}</textarea>
</div>
<button type="submit" class="btn-primary">Save transfusion</button>
</form>
@elseif ($transfusion)
<dl class="mt-4 grid gap-3 text-sm sm:grid-cols-2">
<div>
<dt class="text-slate-500">Outcome</dt>
<dd class="font-medium text-slate-900">{{ $payload['outcome'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Reaction</dt>
<dd class="font-medium text-slate-900">{{ $payload['reaction'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Units transfused</dt>
<dd class="font-medium text-slate-900">{{ $payload['units_transfused'] ?? '—' }}</dd>
</div>
<div>
<dt class="text-slate-500">Notes</dt>
<dd class="font-medium text-slate-900">{{ $payload['notes'] ?? '—' }}</dd>
</div>
</dl>
@else
<p class="mt-3 text-sm text-slate-500">No transfusion record yet.</p>
@endif
</section>
@@ -30,21 +30,51 @@
&& $openConsultation->status !== \App\Models\Consultation::STATUS_COMPLETED;
$chartTab = collect($workspaceTabs ?? [])
->keys()
->first(fn ($key) => ! in_array($key, ['overview', 'timeline', 'plan', 'treat', 'notes', 'imaging', 'orders', 'billing', 'documents', 'perio', 'lab', 'recalls', 'vitals', 'disposition', 'observation'], true))
?: ($moduleKey === 'emergency' ? 'triage' : 'odontogram');
$stageFlow = $moduleKey === 'emergency'
? ($emergencyStageFlow ?? [
->first(fn ($key) => ! in_array($key, ['overview', 'timeline', 'plan', 'treat', 'notes', 'imaging', 'orders', 'billing', 'documents', 'perio', 'lab', 'recalls', 'vitals', 'disposition', 'observation', 'issue', 'transfusion', 'inventory'], true))
?: match ($moduleKey) {
'emergency' => 'triage',
'blood_bank' => 'requests',
default => 'odontogram',
};
$stageRoute = match ($moduleKey) {
'dentistry' => 'care.specialty.dentistry.stage',
'emergency' => 'care.specialty.emergency.stage',
'blood_bank' => 'care.specialty.blood-bank.stage',
default => null,
};
$stageFlow = match ($moduleKey) {
'emergency' => ($emergencyStageFlow ?? [
'arrival' => ['next' => 'treatment', 'label' => 'Move to treatment'],
'resus' => ['next' => 'treatment', 'label' => 'Move to treatment bay'],
'treatment' => ['next' => 'observation', 'label' => 'Move to observation'],
'observation' => ['next' => 'disposition', 'label' => 'Ready for disposition'],
])
: [
]),
'blood_bank' => ($bloodBankStageFlow ?? [
'request' => ['next' => 'crossmatch', 'label' => 'Start cross-match'],
'crossmatch' => ['next' => 'issue', 'label' => 'Ready to issue'],
'issue' => ['next' => 'transfusion', 'label' => 'Start transfusion'],
'transfusion' => ['next' => 'completed', 'label' => 'Complete visit'],
]),
'dentistry' => [
'waiting' => ['next' => 'chair', 'label' => 'Seat at chair'],
'chair' => ['next' => 'procedure', 'label' => 'Start procedure'],
'procedure' => ['next' => 'recovery', 'label' => 'Move to recovery'],
'recovery' => ['next' => 'completed', 'label' => 'Complete visit'],
];
],
default => [],
};
$defaultStartStage = match ($moduleKey) {
'emergency' => 'arrival',
'blood_bank' => 'request',
'dentistry' => 'chair',
default => null,
};
$defaultStartLabel = match ($moduleKey) {
'emergency' => 'Start triage',
'blood_bank' => 'Start request',
'dentistry' => 'Seat at chair',
default => 'Start',
};
$currentStage = $workspaceVisit?->specialty_stage;
@endphp
@@ -67,29 +97,17 @@
@endif
@if ($workspaceVisit)
@if ($canAdvanceStage && $moduleKey === 'dentistry' && $currentStage && isset($stageFlow[$currentStage]))
<form method="POST" action="{{ route('care.specialty.dentistry.stage', $workspaceVisit) }}" class="w-full" @click.stop>
@if ($canAdvanceStage && $stageRoute && $currentStage && isset($stageFlow[$currentStage]) && ($stageFlow[$currentStage]['next'] ?? null) !== $currentStage)
<form method="POST" action="{{ route($stageRoute, $workspaceVisit) }}" class="w-full" @click.stop>
@csrf
<input type="hidden" name="stage" value="{{ $stageFlow[$currentStage]['next'] }}">
<button type="submit" class="{{ $btnAccent }}">{{ $stageFlow[$currentStage]['label'] }}</button>
</form>
@elseif ($canAdvanceStage && $moduleKey === 'dentistry' && ! $currentStage)
<form method="POST" action="{{ route('care.specialty.dentistry.stage', $workspaceVisit) }}" class="w-full" @click.stop>
@elseif ($canAdvanceStage && $stageRoute && ! $currentStage && $defaultStartStage)
<form method="POST" action="{{ route($stageRoute, $workspaceVisit) }}" class="w-full" @click.stop>
@csrf
<input type="hidden" name="stage" value="chair">
<button type="submit" class="{{ $btnAccent }}">Seat at chair</button>
</form>
@elseif ($canAdvanceStage && $moduleKey === 'emergency' && $currentStage && isset($stageFlow[$currentStage]) && ($stageFlow[$currentStage]['next'] ?? null) !== $currentStage)
<form method="POST" action="{{ route('care.specialty.emergency.stage', $workspaceVisit) }}" class="w-full" @click.stop>
@csrf
<input type="hidden" name="stage" value="{{ $stageFlow[$currentStage]['next'] }}">
<button type="submit" class="{{ $btnAccent }}">{{ $stageFlow[$currentStage]['label'] }}</button>
</form>
@elseif ($canAdvanceStage && $moduleKey === 'emergency' && ! $currentStage)
<form method="POST" action="{{ route('care.specialty.emergency.stage', $workspaceVisit) }}" class="w-full" @click.stop>
@csrf
<input type="hidden" name="stage" value="arrival">
<button type="submit" class="{{ $btnAccent }}">Start triage</button>
<input type="hidden" name="stage" value="{{ $defaultStartStage }}">
<button type="submit" class="{{ $btnAccent }}">{{ $defaultStartLabel }}</button>
</form>
@endif
@@ -48,6 +48,8 @@
@include('care.specialty.dentistry.workspace-'.$activeTab)
@elseif ($moduleKey === 'emergency' && in_array($activeTab, ['overview', 'vitals', 'disposition'], true))
@include('care.specialty.emergency.workspace-'.$activeTab)
@elseif ($moduleKey === 'blood_bank' && in_array($activeTab, ['overview', 'issue', 'transfusion'], true))
@include('care.specialty.blood-bank.workspace-'.$activeTab)
@elseif ($activeTab === 'billing')
<section class="rounded-2xl border border-slate-200 bg-white p-5">
<h3 class="text-sm font-semibold text-slate-900">
@@ -23,6 +23,9 @@
@if ($moduleKey === 'emergency')
<a href="{{ route('care.specialty.emergency.reports') }}" class="text-slate-600 hover:text-slate-900">Reports</a>
@endif
@if ($moduleKey === 'blood_bank')
<a href="{{ route('care.specialty.blood-bank.reports') }}" class="text-slate-600 hover:text-slate-900">Reports</a>
@endif
<a href="{{ route('care.specialty.history', $moduleKey) }}" class="text-slate-600 hover:text-slate-900">History</a>
@if ($canManageClinical ?? $canManageSpecialty ?? true)
<a href="{{ route('care.specialty.billing', $moduleKey) }}" class="text-slate-600 hover:text-slate-900">Billing</a>