Files
ladill-care/resources/views/care/nursing/roster.blade.php
T
isaaccladandCursor b2cebe2908
Deploy Ladill Care / deploy (push) Successful in 1m0s
Add shift templates, unit duty roster grid, and Nursing Services hub.
Phase 3 staff management: real shift entities, week roster linked to temporary assignments, and a nursing ops module surface (registry, today’s allocation, unit shortcuts).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:40:25 +00:00

125 lines
8.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-app-layout title="Roster · {{ $unit->name }}">
<div class="space-y-6">
<div class="flex flex-wrap items-start justify-between gap-4">
<div>
<p class="text-sm text-slate-500">
<a href="{{ route('care.care-units.show', $unit) }}" class="text-indigo-600 hover:text-indigo-800">{{ $unit->name }}</a>
<span class="text-slate-300">/</span>
Duty roster
</p>
<h1 class="mt-1 text-2xl font-semibold text-slate-900">Week roster</h1>
<p class="mt-1 text-sm text-slate-500">
{{ $weekStart->format('d M Y') }} {{ $weekStart->copy()->addDays(6)->format('d M Y') }}
· {{ $unit->department?->name }}
</p>
</div>
<div class="flex flex-wrap items-center gap-2">
<a href="{{ route('care.care-units.roster', ['careUnit' => $unit, 'week' => $prevWeek]) }}" class="btn-secondary">Previous</a>
<a href="{{ route('care.care-units.roster', ['careUnit' => $unit, 'week' => now()->startOfWeek(\Carbon\Carbon::MONDAY)->toDateString()]) }}" class="btn-secondary">This week</a>
<a href="{{ route('care.care-units.roster', ['careUnit' => $unit, 'week' => $nextWeek]) }}" class="btn-secondary">Next</a>
@if ($canManage)
<a href="{{ route('care.shifts.index') }}" class="btn-secondary">Shift templates</a>
@endif
</div>
</div>
<div class="overflow-x-auto rounded-2xl border border-slate-200 bg-white">
<table class="min-w-full text-sm">
<thead class="bg-slate-50 text-left text-xs uppercase text-slate-500">
<tr>
<th class="sticky left-0 z-10 bg-slate-50 px-3 py-3">Shift</th>
@foreach ($days as $day)
<th class="min-w-[9rem] px-3 py-3 {{ $day->isToday() ? 'bg-indigo-50 text-indigo-700' : '' }}">
<div>{{ $day->format('D') }}</div>
<div class="font-normal normal-case text-slate-400">{{ $day->format('d M') }}</div>
</th>
@endforeach
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
@foreach ($shifts as $shift)
<tr>
<td class="sticky left-0 z-10 bg-white px-3 py-3 align-top">
<div class="flex items-center gap-2 font-medium text-slate-900">
<span class="inline-block h-2.5 w-2.5 rounded-full" style="background: {{ $shift->color ?? '#64748b' }}"></span>
{{ $shift->label }}
</div>
<div class="mt-0.5 text-xs text-slate-400">{{ $shift->timeLabel() }}</div>
</td>
@foreach ($days as $day)
@php
$key = $day->toDateString().'|'.$shift->id;
$entries = $cells[$key] ?? [];
@endphp
<td class="px-2 py-2 align-top {{ $day->isToday() ? 'bg-indigo-50/40' : '' }}">
<div class="space-y-1.5">
@forelse ($entries as $entry)
<div class="rounded-lg border border-slate-100 bg-slate-50 px-2 py-1.5">
<div class="text-xs font-medium text-slate-800">
{{ $memberLabels[$entry->member_id] ?? ($entry->member?->user_ref ?? 'Staff') }}
</div>
@if ($canManage)
<form method="POST" action="{{ route('care.care-units.roster.destroy', [$unit, $entry]) }}" class="mt-1" onsubmit="return confirm('Remove from roster?')">
@csrf
@method('DELETE')
<button type="submit" class="text-[11px] text-red-600 hover:text-red-800">Remove</button>
</form>
@endif
</div>
@empty
<p class="px-1 text-[11px] text-slate-300"></p>
@endforelse
</div>
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
</div>
@if ($canManage)
<div class="rounded-2xl border border-slate-200 bg-white p-6">
<h2 class="text-base font-semibold text-slate-900">Add to roster</h2>
<p class="mt-1 text-sm text-slate-500">Creates a temporary staff assignment for that duty date.</p>
<form method="POST" action="{{ route('care.care-units.roster.store', $unit) }}" class="mt-4 grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
@csrf
<div>
<label class="block text-xs font-medium uppercase text-slate-500">Date</label>
<input type="date" name="duty_date" value="{{ old('duty_date', now()->toDateString()) }}" required class="mt-1 w-full rounded-lg border-slate-300 text-sm">
@error('duty_date')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
</div>
<div>
<label class="block text-xs font-medium uppercase text-slate-500">Shift</label>
<select name="shift_id" required class="mt-1 w-full rounded-lg border-slate-300 text-sm">
@foreach ($shifts as $shift)
<option value="{{ $shift->id }}" @selected(old('shift_id') == $shift->id)>{{ $shift->label }} ({{ $shift->timeLabel() }})</option>
@endforeach
</select>
@error('shift_id')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
</div>
<div class="lg:col-span-2">
<label class="block text-xs font-medium uppercase text-slate-500">Staff</label>
<select name="member_id" required class="mt-1 w-full rounded-lg border-slate-300 text-sm">
<option value="">Select…</option>
@foreach ($members as $member)
<option value="{{ $member->id }}" @selected(old('member_id') == $member->id)>
{{ $memberLabels[$member->id] ?? $member->user_ref }}
</option>
@endforeach
</select>
@error('member_id')<p class="mt-1 text-xs text-red-600">{{ $message }}</p>@enderror
</div>
<div class="flex items-end">
<button type="submit" class="btn-primary w-full">Assign</button>
</div>
<div class="sm:col-span-2 lg:col-span-5">
<label class="block text-xs font-medium uppercase text-slate-500">Notes</label>
<input type="text" name="notes" value="{{ old('notes') }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm" placeholder="Optional">
</div>
</form>
</div>
@endif
</div>
</x-app-layout>