
Status-page incident report with a Resolved badge, duration and affected services in the header, then four updates newest first, from Resolved back to Investigating, each with a time and note.
blocks/timeline/incident-timeline/index.tsx
import {
Timeline,
TimelineContent,
TimelineDescription,
TimelineIndicator,
TimelineItem,
TimelineLabel,
TimelineTitle,
} from "@/components/editorial/timeline"
import { Badge } from "@/components/ui/badge"
// The copy: change text here, not in the markup.
const COPY = {
eyebrow: "Incident",
title: "Elevated error rates on the registry API",
resolved: "Resolved",
duration: "Duration 1h 48m",
affected: "Affected: registry downloads, MCP search",
} as const
const UPDATES = [
{
status: "Resolved",
time: "16:03 UTC",
body: "Error rates have been normal for 30 minutes. The faulty node is out of rotation and will be rebuilt.",
},
{
status: "Monitoring",
time: "15:33 UTC",
body: "A fix is deployed. We are watching error rates before closing.",
},
{
status: "Identified",
time: "14:51 UTC",
body: "One cache node is returning stale certificates. Traffic is being drained from it.",
},
{
status: "Investigating",
time: "14:15 UTC",
body: "We are looking into a rise in 5xx responses from the registry API in eu-west.",
},
] as const
// The newest update leads and carries the ring; older ones are plain dots.
export default function IncidentTimeline() {
return (
<article className="mx-auto w-full max-w-xl">
<header className="mb-8 border-b border-border pb-6">
<p className="text-xs font-medium tracking-wide text-muted-foreground uppercase">
{COPY.eyebrow}
</p>
<h2 className="mt-2 text-xl font-semibold tracking-tight">
{COPY.title}
</h2>
<div className="mt-3 flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
<Badge>{COPY.resolved}</Badge>
<span>{COPY.duration}</span>
<span aria-hidden>·</span>
<span>{COPY.affected}</span>
</div>
</header>
<Timeline className="[--timeline-lh:1.25rem]">
{UPDATES.map((u, i) => (
<TimelineItem key={u.time}>
<TimelineIndicator
className={
i > 0
? "border-0 [&_[data-slot=timeline-dot]]:bg-muted-foreground/60"
: undefined
}
/>
<TimelineContent>
<div className="flex flex-wrap items-baseline gap-x-3">
<TimelineTitle className="text-sm/5">{u.status}</TimelineTitle>
<TimelineLabel className="text-sm/5 tabular-nums">
{u.time}
</TimelineLabel>
</div>
<TimelineDescription className="max-w-prose">
{u.body}
</TimelineDescription>
</TimelineContent>
</TimelineItem>
))}
</Timeline>
</article>
)
}