import { useMemo, useState } from "react"; import { pb } from "../lib/pocketbase"; import { DAYS_OF_WEEK, formatUtcOffset, getLocalOnCallSchedule, listTimeZones, localScheduleToUtc, } from "../lib/oncallTime"; export default function OnCallSchedule({ record, onUpdate }) { const [editing, setEditing] = useState(false); const [timeZone, setTimeZone] = useState(null); const [schedule, setSchedule] = useState({}); const [saving, setSaving] = useState(false); const [status, setStatus] = useState({ text: "", error: false }); const display = useMemo(() => getLocalOnCallSchedule(record), [record]); const zones = useMemo(() => listTimeZones(), []); function startEdit() { const { timeZone: tz, schedule: sched } = getLocalOnCallSchedule(record); setTimeZone(tz); setSchedule(sched); setEditing(true); setStatus({ text: "", error: false }); } function cancelEdit() { setEditing(false); } function toggleDay(day, available) { setSchedule((prev) => { const next = { ...prev }; if (available) { next[day] = { available: true, start: prev[day]?.start ?? "", end: prev[day]?.end ?? "", }; } else { delete next[day]; } return next; }); } function setDayTime(day, key, value) { setSchedule((prev) => ({ ...prev, [day]: { ...prev[day], [key]: value }, })); } async function save() { setSaving(true); try { const utcSchedule = localScheduleToUtc(schedule, timeZone); const payload = { timezone: timeZone, ...utcSchedule }; const updated = await pb.collection("members").update(record.id, { onCallSchedule: payload, }); onUpdate(updated); setEditing(false); setStatus({ text: "", error: false }); } catch (err) { const msg = err?.response ? JSON.stringify(err.response) : (err?.message ?? String(err)); setStatus({ text: `Save failed: ${msg}`, error: true }); } finally { setSaving(false); } } const shownTz = editing ? timeZone : display.timeZone; const shownSchedule = editing ? schedule : display.schedule; const tzOptions = zones.includes(shownTz) ? zones : [shownTz, ...zones]; return (
Let the group know which days and hours you're usually free to join operations.
| Day | Free | From | To |
|---|---|---|---|
| {day} | {editing ? ( toggleDay(day, e.target.checked)} /> ) : entry.available ? ( "✅" ) : ( "❌" )} | {editing ? ( setDayTime(day, "start", e.target.value)} /> ) : entry.available && entry.start ? ( entry.start ) : ( "—" )} | {editing ? ( setDayTime(day, "end", e.target.value)} /> ) : entry.available && entry.end ? ( entry.end ) : ( "—" )} |
{status.text}