Patients can be admitted, transferred, and discharged from unit/bed stays with occupancy sync, so MAR and ward boards have inpatient context. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -18,11 +18,106 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<a href="{{ route('care.care-units.edit', $unit) }}" class="btn-secondary">Edit</a>
|
||||
<a href="{{ route('care.staff-assignments.create', ['care_unit_id' => $unit->id]) }}" class="btn-primary">Assign staff</a>
|
||||
@php
|
||||
$member = auth()->user()
|
||||
? app(\App\Services\Care\OrganizationResolver::class)->memberFor(auth()->user())
|
||||
: null;
|
||||
$permissions = app(\App\Services\Care\CarePermissions::class);
|
||||
$canManageUnit = $permissions->can($member, 'admin.departments.manage');
|
||||
@endphp
|
||||
@if ($canManageUnit)
|
||||
<a href="{{ route('care.care-units.edit', $unit) }}" class="btn-secondary">Edit unit</a>
|
||||
<a href="{{ route('care.staff-assignments.create', ['care_unit_id' => $unit->id]) }}" class="btn-secondary">Assign staff</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Current patients --}}
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-6">
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<h2 class="text-base font-semibold text-slate-900">Patients on this unit</h2>
|
||||
<p class="text-sm text-slate-500">Active visit placements — foundation for MAR and ward boards.</p>
|
||||
</div>
|
||||
<p class="text-sm font-medium text-slate-700">{{ $placedVisits->count() }} placed</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<table class="min-w-full text-sm">
|
||||
<thead class="text-left text-xs uppercase text-slate-500">
|
||||
<tr>
|
||||
<th class="pb-2 pr-4">Patient</th>
|
||||
<th class="pb-2 pr-4">Bed</th>
|
||||
<th class="pb-2 pr-4">Placed</th>
|
||||
<th class="pb-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100">
|
||||
@forelse ($placedVisits as $visit)
|
||||
<tr>
|
||||
<td class="py-3 pr-4 font-medium">
|
||||
{{ $visit->patient?->fullName() ?? '—' }}
|
||||
@if ($visit->patient?->patient_number)
|
||||
<span class="text-xs text-slate-400">{{ $visit->patient->patient_number }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-3 pr-4">{{ $visit->bed?->label ?? '—' }}</td>
|
||||
<td class="py-3 pr-4 whitespace-nowrap">{{ $visit->placed_at?->format('d M Y H:i') ?? '—' }}</td>
|
||||
<td class="py-3 text-right whitespace-nowrap">
|
||||
@if ($canPlace)
|
||||
<form method="POST" action="{{ route('care.visits.placement.destroy', $visit) }}" class="inline" onsubmit="return confirm('Discharge placement and free the bed?')">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="text-red-600 hover:text-red-800">Discharge bed</button>
|
||||
</form>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="py-4 text-slate-500">No patients placed on this unit.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if ($canPlace && $unit->kind !== 'float_pool')
|
||||
<form method="POST" action="{{ route('care.care-units.placements.store', $unit) }}" class="mt-6 grid gap-3 border-t border-slate-100 pt-5 sm:grid-cols-4">
|
||||
@csrf
|
||||
<div class="sm:col-span-2">
|
||||
<label class="block text-xs font-medium uppercase text-slate-500">Open visit</label>
|
||||
<select name="visit_id" required class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
<option value="">Select patient visit…</option>
|
||||
@foreach ($placeableVisits as $visit)
|
||||
<option value="{{ $visit->id }}">
|
||||
{{ $visit->patient?->fullName() ?? 'Patient' }}
|
||||
· {{ $visit->checked_in_at?->format('d M H:i') ?? $visit->status }}
|
||||
@if ($visit->careUnit) (now: {{ $visit->careUnit->name ?? 'placed' }}) @endif
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('visit_id')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
|
||||
@error('care_unit_id')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
|
||||
@error('bed_id')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
|
||||
</div>
|
||||
@if ($unit->supportsBeds())
|
||||
<div>
|
||||
<label class="block text-xs font-medium uppercase text-slate-500">Bed</label>
|
||||
<select name="bed_id" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
<option value="">No bed yet</option>
|
||||
@foreach ($availableBeds as $bed)
|
||||
<option value="{{ $bed->id }}">{{ $bed->label }}@if ($bed->room) ({{ $bed->room }}) @endif</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@else
|
||||
<div></div>
|
||||
@endif
|
||||
<div class="flex items-end">
|
||||
<button type="submit" class="btn-primary w-full">Place on unit</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($unit->supportsBeds())
|
||||
<div class="rounded-2xl border border-slate-200 bg-white p-6">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
@@ -32,17 +127,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('care.care-units.beds.store', $unit) }}" class="mt-4 grid gap-3 sm:grid-cols-4">
|
||||
@csrf
|
||||
<input type="text" name="label" required placeholder="Bed label" class="rounded-lg border-slate-300 text-sm" value="{{ old('label') }}">
|
||||
<input type="text" name="room" placeholder="Room" class="rounded-lg border-slate-300 text-sm" value="{{ old('room') }}">
|
||||
<select name="status" class="rounded-lg border-slate-300 text-sm">
|
||||
@foreach ($bedStatuses as $value => $label)
|
||||
<option value="{{ $value }}" @selected(old('status', 'available') === $value)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<button type="submit" class="btn-primary">Add bed</button>
|
||||
</form>
|
||||
@if ($canManageUnit ?? false)
|
||||
<form method="POST" action="{{ route('care.care-units.beds.store', $unit) }}" class="mt-4 grid gap-3 sm:grid-cols-4">
|
||||
@csrf
|
||||
<input type="text" name="label" required placeholder="Bed label" class="rounded-lg border-slate-300 text-sm" value="{{ old('label') }}">
|
||||
<input type="text" name="room" placeholder="Room" class="rounded-lg border-slate-300 text-sm" value="{{ old('room') }}">
|
||||
<select name="status" class="rounded-lg border-slate-300 text-sm">
|
||||
@foreach ($bedStatuses as $value => $label)
|
||||
<option value="{{ $value }}" @selected(old('status', 'available') === $value)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<button type="submit" class="btn-primary">Add bed</button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
<div class="mt-4 overflow-x-auto">
|
||||
<table class="min-w-full text-sm">
|
||||
@@ -51,24 +148,31 @@
|
||||
<th class="pb-2 pr-4">Label</th>
|
||||
<th class="pb-2 pr-4">Room</th>
|
||||
<th class="pb-2 pr-4">Status</th>
|
||||
<th class="pb-2 pr-4">Occupant</th>
|
||||
<th class="pb-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100">
|
||||
@forelse ($unit->beds as $bed)
|
||||
@php
|
||||
$occupant = $placedVisits->firstWhere('bed_id', $bed->id);
|
||||
@endphp
|
||||
<tr class="{{ $bed->is_active ? '' : 'opacity-50' }}">
|
||||
<td class="py-3 pr-4 font-medium">{{ $bed->label }}</td>
|
||||
<td class="py-3 pr-4">{{ $bed->room ?: '—' }}</td>
|
||||
<td class="py-3 pr-4">{{ $bedStatuses[$bed->status] ?? $bed->status }}</td>
|
||||
<td class="py-3 pr-4">{{ $occupant?->patient?->fullName() ?? '—' }}</td>
|
||||
<td class="py-3 text-right">
|
||||
<form method="POST" action="{{ route('care.care-units.beds.destroy', [$unit, $bed]) }}" class="inline" onsubmit="return confirm('Remove this bed?')">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="text-red-600 hover:text-red-800">Remove</button>
|
||||
</form>
|
||||
@if ($canManageUnit ?? false)
|
||||
<form method="POST" action="{{ route('care.care-units.beds.destroy', [$unit, $bed]) }}" class="inline" onsubmit="return confirm('Remove this bed?')">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="text-red-600 hover:text-red-800">Remove</button>
|
||||
</form>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="py-4 text-slate-500">No beds yet.</td></tr>
|
||||
<tr><td colspan="5" class="py-4 text-slate-500">No beds yet.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -77,6 +181,9 @@
|
||||
@else
|
||||
<div class="rounded-2xl border border-dashed border-slate-200 bg-slate-50 px-6 py-5 text-sm text-slate-600">
|
||||
This unit kind does not use beds. Outpatient clinics, service units, and float pools assign staff without bed inventory.
|
||||
@if ($unit->kind === 'float_pool')
|
||||
Patients cannot be placed on a float pool.
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@@ -93,6 +93,9 @@
|
||||
{{ $visit->checked_in_at?->format('d M Y H:i') ?? '—' }}
|
||||
· {{ config('care.visit_statuses')[$visit->status] ?? $visit->status }}
|
||||
@if ($visit->branch) · {{ $visit->branch->name }} @endif
|
||||
@if ($visit->careUnit)
|
||||
· {{ $visit->careUnit->name }}@if ($visit->bed) / {{ $visit->bed->label }}@endif
|
||||
@endif
|
||||
</p>
|
||||
@empty
|
||||
<p class="mt-1 text-slate-400">No visits yet</p>
|
||||
|
||||
@@ -114,6 +114,8 @@
|
||||
if ($permissions->can($member, 'admin.departments.view')) {
|
||||
$adminNav[] = ['name' => 'Departments', 'route' => route('care.departments.index'), 'active' => request()->routeIs('care.departments.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 0 1 6 3.75h2.25A2.25 2.25 0 0 1 10.5 6v2.25a2.25 2.25 0 0 1-2.25 2.25H6a2.25 2.25 0 0 1-2.25-2.25V6ZM3.75 15.75A2.25 2.25 0 0 1 6 13.5h2.25a2.25 2.25 0 0 1 2.25 2.25V18a2.25 2.25 0 0 1-2.25 2.25H6A2.25 2.25 0 0 1 3.75 18v-2.25ZM13.5 6a2.25 2.25 0 0 1 2.25-2.25H18A2.25 2.25 0 0 1 20.25 6v2.25A2.25 2.25 0 0 1 18 10.5h-2.25a2.25 2.25 0 0 1-2.25-2.25V6ZM13.5 15.75a2.25 2.25 0 0 1 2.25-2.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-2.25A2.25 2.25 0 0 1 13.5 18v-2.25Z" />'];
|
||||
}
|
||||
if ($permissions->can($member, 'admin.departments.view') || $permissions->can($member, 'inpatient.placement.view')) {
|
||||
$adminNav[] = ['name' => 'Care units', 'route' => route('care.care-units.index'), 'active' => request()->routeIs('care.care-units.*'),
|
||||
'icon' => '<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Z" />'];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user