Page header
Title, description, status badge and primary actions.
October 2026 payroll
Awaiting approvalMonthly run for Northwind Europe. Approve by Friday 24 October so payments reach accounts on the pay date.
Prepared by Sara Malik · last edited 6 Oct, 16:42
- Employees248
- Gross pay€1,284,560.00
- Pay date31 Oct 2026
page-header.tsx
"use client";
import { useState, type Key } from "react";
import {
LuCalendarDays,
LuDownload,
LuFileSpreadsheet,
LuFileText,
LuPencil,
LuUsers,
LuWallet,
} from "react-icons/lu";
import { Badge, Breadcrumb, BreadcrumbItem, Button, MenuItem, SplitButton } from "@nexera-ui/react";
const EXPORTS: Record<string, string> = {
pdf: "PDF summary",
xlsx: "Excel workbook",
csv: "CSV for your bank",
};
const SUMMARY = [
{ icon: <LuUsers />, label: "Employees", value: "248" },
{ icon: <LuWallet />, label: "Gross pay", value: "€1,284,560.00" },
{ icon: <LuCalendarDays />, label: "Pay date", value: "31 Oct 2026" },
] as const;
/** Page header: breadcrumbs, title, status badge, description and the page's primary actions. */
export default function PageHeader() {
const [exported, setExported] = useState<string | null>(null);
const exportAs = (key: Key) => {
setExported(EXPORTS[String(key)] ?? null);
};
return (
<div className="@container bg-page px-4 py-8 @3xl:px-8">
<div className="mx-auto grid max-w-5xl gap-6">
<header className="grid gap-4 border-b border-default pb-6">
<Breadcrumb>
<BreadcrumbItem type="home" label="Home" href="#home" />
<BreadcrumbItem label="Payroll" href="#payroll" />
<BreadcrumbItem label="October 2026" href="#payroll-october-2026" />
</Breadcrumb>
<div className="flex flex-col gap-4 @3xl:flex-row @3xl:items-start @3xl:justify-between">
<div className="grid max-w-2xl gap-2">
<div className="flex flex-wrap items-center gap-2">
<h2 className="text-heading-h2 text-primary">October 2026 payroll</h2>
<Badge tone="warning" label="Awaiting approval" size="md" />
</div>
<p className="text-body-default text-secondary">
Monthly run for Northwind Europe. Approve by Friday 24 October so payments reach
accounts on the pay date.
</p>
<p className="text-body-small text-muted">
Prepared by Sara Malik · last edited 6 Oct, 16:42
</p>
</div>
<div className="flex flex-wrap items-center gap-2">
<Button variant="ghost" size="md" leadingIcon={<LuPencil />}>
Edit run
</Button>
<SplitButton
variant="secondary"
label="Export"
icon={<LuDownload />}
menuTriggerLabel="More export options"
onPress={() => {
exportAs("pdf");
}}
onAction={exportAs}
>
<MenuItem id="pdf" label="Export as PDF" icon={<LuFileText />} />
<MenuItem id="xlsx" label="Export as Excel" icon={<LuFileSpreadsheet />} />
<MenuItem id="csv" label="Export as CSV" />
</SplitButton>
<Button size="md">Approve payroll</Button>
</div>
</div>
{exported ? (
<p role="status" className="text-body-small text-secondary">
Exported the {exported}. This is a demo, so nothing was downloaded.
</p>
) : null}
</header>
<ul className="m-0 grid list-none gap-4 p-0 @3xl:grid-cols-3">
{SUMMARY.map(({ icon, label, value }) => (
<li
key={label}
className="flex items-center gap-3 rounded-lg border border-default bg-surface p-4"
>
<span
aria-hidden="true"
className="grid size-10 place-items-center rounded-md bg-brand-subtle text-brand-text"
>
{icon}
</span>
<span className="grid">
<span className="text-body-small text-secondary">{label}</span>
<span className="text-body-strong text-primary">{value}</span>
</span>
</li>
))}
</ul>
</div>
</div>
);
}
More app shells and navigation blocks
- Sidebar app shellSidebar with sections, nested items, badges and a user card.
- Top bar with tabsPage title, breadcrumbs, actions and section tabs.
- Mobile app shellTop app bar and a bottom navigation bar.
- Settings layoutVertical tabs on the left, a form on the right.
- Command palette⌘K search for pages, people and actions.
- Workspace switcherSwitch organisation or create a new one.