Maintenance and offline
Tell people about downtime or lost connection.
Built with
Warning: Northwind is down for planned maintenance on Saturday 11 October, 22:00 to 23:30 UTC. Save your work before then.Status page
My timesheet
Week of 6 October · 18 h 15 m logged
| Day | Project | Time |
|---|---|---|
| Mon 6 Oct | Client onboarding · Acme Retail | 7 h 30 m |
| Tue 7 Oct | Payroll integration QA | 6 h 45 m |
| Wed 8 Oct | Sprint planning and reviews | 4 h 00 m |
maintenance-and-offline.tsx
"use client";
import { useState } from "react";
import { Alert, Banner, Button, SwitchField } from "@nexera-ui/react";
const ENTRIES = [
["Mon 6 Oct", "Client onboarding · Acme Retail", "7 h 30 m"],
["Tue 7 Oct", "Payroll integration QA", "6 h 45 m"],
["Wed 8 Oct", "Sprint planning and reviews", "4 h 00 m"],
] as const;
/** Maintenance and offline: a page-wide banner for planned downtime, and an inline alert when the connection drops. */
export default function MaintenanceAndOffline() {
const [showBanner, setShowBanner] = useState(true);
const [offline, setOffline] = useState(false);
return (
<div className="@container bg-page px-4 py-8 @3xl:px-8">
<div className="mx-auto grid max-w-4xl overflow-hidden rounded-xl border border-default bg-surface shadow-sm">
{showBanner ? (
<Banner
tone="warning"
message="Northwind is down for planned maintenance on Saturday 11 October, 22:00 to 23:30 UTC. Save your work before then."
action={<a href="#status">Status page</a>}
onDismiss={() => {
setShowBanner(false);
}}
/>
) : null}
<div className="grid gap-5 p-4 @3xl:p-6">
<header className="flex flex-wrap items-end justify-between gap-3">
<div className="grid gap-1">
<h2 className="text-heading-h2 text-primary">My timesheet</h2>
<p className="text-body-default text-secondary">
Week of 6 October · 18 h 15 m logged
</p>
</div>
<SwitchField
label="Simulate lost connection"
isSelected={offline}
onChange={setOffline}
/>
</header>
{offline ? (
<Alert
tone="warning"
title="You're offline"
description="We'll keep your changes on this device and sync them when you reconnect. Submitting is paused until then."
actions={
<Button
size="sm"
variant="secondary"
onPress={() => {
setOffline(false);
}}
>
Try to reconnect
</Button>
}
/>
) : null}
<div className="overflow-x-auto rounded-lg border border-default">
<table className="w-full border-collapse text-start">
<caption className="sr-only">Time logged this week</caption>
<thead className="bg-sunken text-body-small text-secondary">
<tr>
<th scope="col" className="px-4 py-2 text-start font-medium">
Day
</th>
<th scope="col" className="px-4 py-2 text-start font-medium">
Project
</th>
<th scope="col" className="px-4 py-2 text-end font-medium">
Time
</th>
</tr>
</thead>
<tbody className="text-body-default text-primary">
{ENTRIES.map(([day, project, time]) => (
<tr key={day} className="border-t border-subtle">
<td className="px-4 py-3">{day}</td>
<td className="px-4 py-3">{project}</td>
<td className="px-4 py-3 text-end tabular-nums">{time}</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="flex flex-wrap justify-end gap-2">
<Button variant="secondary" size="md">
Add time
</Button>
<Button size="md" isDisabled={offline}>
Submit timesheet
</Button>
</div>
</div>
</div>
</div>
);
}
More states and system messages blocks
- Empty statesFirst use, no results and all done.
- Loading skeletonsPage and panel placeholders while data loads.
- Error pagesNot found, no access and something went wrong.
- Success confirmationA modal that confirms a finished task.
- ToastsShort confirmations with undo.
- Confirm a destructive actionName what will be deleted before deleting it.
- Long-running jobProgress for exports, imports and uploads.