UI Kit/System status

System status

Shows each service's state, its recent history and past incidents.

System Status

  • APIOperationalLast: 2024-05-01
  • DatabaseDegradedLast: 2024-04-28
  • AuthOperational
  • EmailDownLast: 2024-05-02

Incident History

  • Email - 2024-05-02

    Email delivery outage. Resolved in 2h.

  • Database - 2024-04-28

    Performance issues. Resolved in 1h.

  • API - 2024-05-01

    Minor outage. Resolved in 30m.

View code
import { SystemStatus } from "@/components/kit/system-status";

const days = (...downDays: number[]) => Array.from({ length: 30 }, (_, day) => !downDays.includes(day));

export function SystemStatusDemo() {
  return (
    <SystemStatus
      services={[
        { name: "API", state: "operational", lastIncident: "2024-05-01", history: days(27) },
        { name: "Database", state: "degraded", lastIncident: "2024-04-28", history: days(22, 23) },
        { name: "Auth", state: "operational", history: days() },
        { name: "Email", state: "down", lastIncident: "2024-05-02", history: days(21, 22, 23) },
      ]}
      incidents={[
        { service: "Email", date: "2024-05-02", summary: "Email delivery outage. Resolved in 2h." },
        { service: "Database", date: "2024-04-28", summary: "Performance issues. Resolved in 1h." },
        { service: "API", date: "2024-05-01", summary: "Minor outage. Resolved in 30m." },
      ]}
    />
  );
}

Pass your services and incidents as data, and it draws the rest. TypeScript checks the shape of that data, so a misspelled state is caught before it ships.

Installation

bunx --bun shadcn@latest add HarshitMahajan/UI/system-status

Copies the code to components/kit/system-status.tsx along with button, which it uses, installs its packages, and adds the tokens it needs to your globals.css. Your existing shadcn components aren't touched.

Usage

import { SystemStatus } from "@/components/kit/system-status"
<SystemStatus
  services={[
    { name: "API", state: "operational", lastIncident: "2024-05-01", history: [true, true, false, true] },
  ]}
  incidents={[
    { service: "API", date: "2024-05-01", summary: "Minor outage. Resolved in 30m." },
  ]}
/>

Composition

SystemStatus

Features

  • Three states: operational, degraded and down
  • One bar per day, for any number of days
  • Incident history that collapses with Base UI Collapsible
  • Exported SystemStatusProps, SystemStatusService and SystemStatusIncident types

Starts hidden

Set defaultOpen={false} to keep the incident history closed until someone asks for it.

System Status

  • APIOperationalLast: 2024-05-01
View code
import { SystemStatus } from "@/components/kit/system-status";

const days = (...downDays: number[]) => Array.from({ length: 30 }, (_, day) => !downDays.includes(day));

export function SystemStatusCollapsed() {
  return (
    <SystemStatus
      defaultOpen={false}
      services={[{ name: "API", state: "operational", lastIncident: "2024-05-01", history: days(27) }]}
      incidents={[{ service: "API", date: "2024-05-01", summary: "Minor outage. Resolved in 30m." }]}
    />
  );
}

No incidents

Leave out incidents, and the history and its Hide button don't appear.

All systems operational

  • APIOperational
  • AuthOperational
View code
import { SystemStatus } from "@/components/kit/system-status";

const allUp = Array.from({ length: 30 }, () => true);

export function SystemStatusAllClear() {
  return (
    <SystemStatus
      title="All systems operational"
      services={[
        { name: "API", state: "operational", history: allUp },
        { name: "Auth", state: "operational", history: allUp },
      ]}
    />
  );
}

Longer history

Pass as many days as you like. The bars narrow to fit.

Last 90 days

  • APIOperationalLast: 2024-05-01
  • EmailDegradedLast: 2024-05-02
View code
import { SystemStatus } from "@/components/kit/system-status";

const days = (...downDays: number[]) => Array.from({ length: 90 }, (_, day) => !downDays.includes(day));

export function SystemStatusLongHistory() {
  return (
    <SystemStatus
      title="Last 90 days"
      services={[
        { name: "API", state: "operational", lastIncident: "2024-05-01", history: days(12, 60, 61) },
        { name: "Email", state: "degraded", lastIncident: "2024-05-02", history: days(40, 41, 42, 88) },
      ]}
    />
  );
}

Accessibility

History as a summary

Each row of bars is announced as one sentence, such as: API, up 29 of the last 30 days.

Hidden means hidden

While collapsed, the incident list can't be reached by keyboard or screen readers.

API Reference

SystemStatus

The whole block.

PropTypeDefaultDescription
servicesSystemStatusService[]-The services to list.
incidentsSystemStatusIncident[][]Past incidents, in the order you pass them.
defaultOpenbooleantrueWhether the incident history starts open.
titlestring"System Status"The heading.
classNamestring-Additional classes for the block.

SystemStatusService

One entry in services.

PropTypeDefaultDescription
namestring-The service's name.
state"operational" | "degraded" | "down"-The current state.
lastIncidentstring-A date shown on the right.
historyboolean[]-One entry per day, oldest first. true means it was up.

SystemStatusIncident

One entry in incidents.

PropTypeDefaultDescription
servicestring-The affected service.
datestring-When it happened.
summarystring-What happened.