React On-Call Schedule Board

The board that answers “who do I wake at 3am”, and the escalation panel that answers “and who after them”. Built so a swap someone arranged last week reads differently from the published rota — because at 3am, that difference is the whole point.

On-call rotation

Week of 20 Jul
MonTueWedThuFriSatSun
Primary
MOM.
MOM.
ALA.
JRJ.
JRJ.
JRJ.
JRJ.
Secondary
SKS.
SKS.
SKS.
SKS.
SKS.
ALA.
ALA.
1 override this week — A. (Okafor at supplier audit).

Escalation policy

  1. +5m Secondary
  2. +15m Shift lead
  3. +30m Eng. manager

Installation

npx shadcn@latest add "https://kelvinui.com/registry/on-call-board.json"

Props

PropTypeDescription
peopleOnCallPerson[]{ id, name, initials }
shiftsShift[]{ personId, day, tier } — day 0–6, Mon-first
overridesOverride[]{ personId, day, tier, reason }
escalationEscalationRule[]{ afterMinutes, target }
todaynumber0–6, highlights the current column

An override is not a schedule edit

When someone covers a shift, the board keeps the original rotation underneath and draws the override on top — amber, with the reason on hover — rather than silently replacing the name. This is deliberate. A page that goes to the wrong person because a swap was quietly merged into the rota is a page that gets missed, and the operator staring at the board needs to see that today is not the normal pattern. A running count of overrides sits below the grid so nobody is surprised by a busy week.

The current day is highlighted top-to-bottom so your eye lands on the right column immediately, and the tier column is sticky so the Primary/Secondary labels stay put as the week scrolls on a narrow screen.

The escalation path is on the same screen

Knowing who is primary is half the answer; the other half is what happens when they don't pick up. The escalation policy renders as an explicit chain — Secondary at +5m, shift lead at +15m, manager at +30m — next to the roster, so the full answer to "who handles this" lives in one place instead of in a runbook nobody opens mid-incident.

New components every week

Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.