| Name | Type | Rotation | Status | Actions |
|---|---|---|---|---|
|
{{ nmAvI(staff.full_name) }}
{{ staff.full_name }}
Affiliated · {{ staff.primary_dept_name || 'External' }}
{{ staff.specialization }}
{{ staff.resident_category === 'external_resident' ? 'External' : 'Internal' }}
|
{{ formatStaffTypeShortFn(staff.staff_type) }} |
{{ getTrainingUnitName(getCurrentRotationForStaff(staff.id).training_unit_id) }}
{{ formatClinicalDuration(getCurrentRotationForStaff(staff.id).start_date, getCurrentRotationForStaff(staff.id).end_date) }}
—
|
{{ formatEmploymentStatus(staff.employment_status) }} | {}">
|
|
No medical staff found
No results match your filters — try clearing them
Add your first staff member to get started
|
||||
| Shift Period | Physician | Type | Status | Backup | Actions |
|---|
| Shift Period | Physician | Type | Status | Backup | Actions |
|---|---|---|---|---|---|
|
{{ formatDate(schedule.duty_date) }}
TODAY
+1d
{{ (schedule.start_time||'').slice(0,5) }}
→
{{ (schedule.end_time||'').slice(0,5) }}
{{ schedule.coverage_area?.name || coverageAreas.find(a=>a.id===schedule.coverage_area_id)?.name }}
|
{{ (getPhysicianName(schedule.primary_physician_id)||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ getPhysicianName(schedule.primary_physician_id) }}
On duty now
|
{{ {'primary_call':'Primary','backup_call':'Backup','weekend_coverage':'Weekend','float_physician':'Float'}[schedule.shift_type] || schedule.shift_type }} | {{ new Date(schedule.duty_date + 'T' + (schedule.start_time||'00:00')) > new Date() ? 'Upcoming' : isToday(schedule.duty_date) ? 'Live' : 'Done' }} | {{ getPhysicianName(schedule.backup_physician_id) }} — |
|
|
No schedules found
No results match your filters
No on-call shifts have been scheduled yet
|
|||||
| Physician | Called at | Type | Duration | Reason | |
|---|---|---|---|---|---|
|
{{ (c.staff?.full_name || c.staff_id || '??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ c.staff?.full_name || '—' }}
|
{{ c.called_at ? new Date(c.called_at).toLocaleDateString('es-ES',{day:'2-digit',month:'short',year:'numeric'}) : '—' }}
{{ c.called_at ? new Date(c.called_at).toLocaleTimeString('es-ES',{hour:'2-digit',minute:'2-digit'}) : '' }}
|
{{ calloutTimeTypes[c.time_type] || c.time_type }} | {{ Math.round((new Date(c.end_time) - new Date(c.called_at)) / 60000) }}m — |
{{ calloutReasonLabels[c.reason_category] || c.reason_category }}
{{ c.notes }}
|
|
| Physician | Scheduled on-call | Call-outs | Night | Weekend | Total | vs avg |
|---|---|---|---|---|---|---|
|
{{ (row.name||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ row.name }}
{{ formatStaffType(row.staffType) }}
|
{{ row.scheduled }} | {{ row.callouts }} | {{ row.night }} | {{ row.weekend }} | {{ row.total }} |
| Resident | Unit | Period | Days Left | Status | Actions |
|---|
| Resident | Unit | Period | Days Left | Status | Supervisor | Actions |
|---|---|---|---|---|---|---|
|
{{ (getResidentName(rotation.resident_id)||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ getResidentName(rotation.resident_id) }}
{{ rotation.resident.external_contact_name }}
{}" title="Email contact">
|
{{ getTrainingUnitName(rotation.training_unit_id) }}
{{ rotation.training_unit.dept.name }}
|
{{ formatDateShort(rotation.start_date) }}
→
{{ formatDateShort(rotation.end_date) }}
|
{{ getRotationProgress(rotation).pct }}% · {{ getRotationProgress(rotation).label }}
|
{{ formatRotationStatus(rotation.rotation_status) }} | {{ getSupervisorName(rotation.supervising_attending_id) }} — |
|
|
No rotations found
No results match your filters
No resident rotations have been assigned yet
|
||||||
| Staff member | Reason | Status | From | Until | Duration | Coverage |
|---|
| Staff member | Reason | Status | From | Until | Duration | Coverage | |
|---|---|---|---|---|---|---|---|
|
{{ (getStaffName(absence.staff_member_id)||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ getStaffName(absence.staff_member_id) }}
|
{{ absence.absence_reason ? absence.absence_reason.replace('_',' ') : '—' }} | Absent nowPlannedReturnedCancelled{{ absence.current_status }} | {{ formatDate(absence.start_date) }} | {{ formatDate(absence.end_date) }} | {{ calculateAbsenceDuration(absence.start_date, absence.end_date) }} days | {{ getStaffName(absence.covering_staff_id) }} Covered No coverage |
|
|
No absences found
No results match your filtersNo absence records have been logged yet
|
|||||||
{{ day.available }}/{{ day.available + day.absent }} available
No absences in this period
{{ absences.length === 0 ? 'No absence records have been created yet.' : 'All absences in this window are resolved. Navigate forward or switch to Planning mode.' }}
No staff found
No briefing posted yet today
Nothing posted yet. Be first to update the department.
Define the coverage areas for on-call assignments (e.g. ICU, Hospitalization, General). Each shift is assigned to one area, allowing multiple primaries per day — one per area.
coverage_areas SQL in Supabase before using this feature.