@extends('layouts.app')
@section('title', $patient->fullName())
@php
use App\Modules\Patients\Enums\ClinicalRecordStatus;
$activeAllergies = $allergies->where('status', ClinicalRecordStatus::Active);
$activeConditions = $conditions->where('status', ClinicalRecordStatus::Active);
$activeMedications = $medications->where('status', ClinicalRecordStatus::Active);
$severeAllergy = $activeAllergies->first(fn ($a) => $a->severity->isHigh());
$address = collect([
$patient->address_line_1, $patient->address_line_2,
$patient->city, $patient->state, $patient->postal_code,
])->filter()->implode(', ');
/*
| The counts at the top.
|
| Every one is something this module owns and already has in memory, and
| every one links to the panel that explains it — a number nobody can act
| on is decoration. Appointments, invoices and an outstanding balance are
| deliberately absent: they belong to other modules, and a record screen
| that queried them directly would stop rendering on a clinic that has not
| installed them. They are reachable from Quick links instead.
*/
$summaryCards = [
[
'label' => __('patients::messages.clinical.allergies'),
'value' => $activeAllergies->count(),
'icon' => 'bi-shield-exclamation',
'tone' => $severeAllergy ? 'pink' : 'violet',
'note' => __('patients::messages.summary.allergies_note'),
'anchor' => '#allergies',
],
[
'label' => __('patients::messages.clinical.conditions'),
'value' => $activeConditions->count(),
'icon' => 'bi-clipboard2-pulse',
'tone' => 'amber',
'note' => __('patients::messages.summary.conditions_note'),
'anchor' => '#conditions',
],
[
'label' => __('patients::messages.clinical.medications'),
'value' => $activeMedications->count(),
'icon' => 'bi-capsule',
'tone' => 'green',
'note' => __('patients::messages.summary.medications_note'),
'anchor' => '#medications',
],
[
'label' => __('patients::messages.patients.documents'),
'value' => $documents->count(),
'icon' => 'bi-folder2-open',
'tone' => 'blue',
'note' => __('patients::messages.summary.documents_note'),
'anchor' => '#documents',
],
];
@endphp
@section('content')
{{-- ============================ IDENTITY ============================ --}}
{{-- One card: who they are, the counts, and what you can do next. Three
regions across a wide screen, stacked in the same order below it. --}}
{{ $patient->fullName() }}
{{-- Identity first, then the facts a clinician checks before
anything else. Blood group and date of birth sit here rather
than in the panel below because both are read at a glance:
one before a transfusion, the other because age drives every
reference range on the screen. --}}
{{-- An archived record is still readable, and must never be mistaken
for a live one. The active state is stated too rather than left
to be inferred from the absence of a warning. --}}
{{ $patient->is_active ? __('common.active') : __('common.inactive') }}
@if ($canSeeClinical)
{{-- The counts, in the header where the reference puts them. Each
one jumps to the panel that explains it. --}}
@foreach ($summaryCards as $card)
{{-- The qualifier rides on the link rather than under the
number: a tile this size has no room for a third line,
and "3 allergies" is ambiguous without knowing whether
that means ever or still active. --}}
{{ number_format($card['value']) }}{{ $card['label'] }}
@endforeach
@endif
{{--
Actions, each guarded by the route that serves it: a clinic without
the appointments or laboratory module gets a shorter row, not a
broken button. Ordered by how often reception reaches for them.
--}}
@if ($canSeeClinical)
{{-- The single most important thing on this screen, above everything
else it might compete with. --}}
@include('patients::partials.allergy-banner')
@endif
{{--
One flowing grid across the full width, not a main column and a sidebar.
Panels sit side by side as many as fit and reflow as the window narrows —
which is the only arrangement that can work here, because how many panels
there are depends on which modules the clinic installed. Laboratory adds
result trends; the upload portal adds another. This screen never learns
their names.
--}}
{{ $patient->date_of_birth?->format('d M Y') ?? '—' }}
@if ($patient->date_of_birth_estimated)
{{-- An estimated date drives age, and age drives lab
reference ranges. Marked, never hidden. --}}
~
@endif
{{ $patient->registered_at?->format('d M Y') ?? '—' }}
{{ $patient->registeredBy?->name }}
@if ($patient->notes)
{{ $patient->notes }}
@endif
{{--
Panel order is deliberate and reads across, then down:
Demographics · Allergies · Problem list · Go to
Medications · Documents · Reports · Contacts
Allergies sit next to the identity because they are the thing
that changes what may safely be prescribed. Contacts come last
of the eight: they are the only panel nobody reads unless
something has gone wrong.
It holds at the width that fits four across. Narrower, the grid
reflows to three, two or one and the pairing goes with it —
which is the trade for a layout that also works on a laptop.
--}}
@if ($canSeeClinical)
@include('patients::partials.clinical-allergies')
@include('patients::partials.clinical-conditions')
@else
{{-- Said plainly rather than shown as an empty screen: a blank
panel reads as "this patient has no history". --}}
@endif
{{--
Quick links, in the grid rather than in a column of their own.
This was a sidebar, which earned its quarter of the screen when
it also carried the patient's identity and the record history.
With only these links left the column was a band of empty
background down the whole page, so the links became another panel
and the record took the width back.
--}}
{{-- ── Second row ─────────────────────────────────────────────── --}}
@if ($canSeeClinical)
@include('patients::partials.clinical-medications')
@endif
@include('patients::partials.documents')
{{--
Contributed regions. The upload portal fills the administrative
one with its "send us your reports" panel; Laboratory fills the
clinical one with result trends. Patients learns about neither,
which is what lets this screen render unchanged on a clinic that
has installed neither.
Administrative sits here, in the second row. Clinical comes last
because result trends claims the whole width, and a full-width
panel in the middle would cut the eight cards in half.
--}}
@include('patients::partials.contacts')
{{-- Behind the same gate as the panels above: a trend line is
clinical information, and a receptionist who may not read the
problem list may not read it either. --}}
@if ($canSeeClinical)
@endif