Finish setting up Northwind
Most teams finish in about 20 minutes.
Setup progress3 of 6 tasks
setup-checklist.tsx
"use client";
import { useState } from "react";
import { LuBookOpen, LuListChecks, LuMessageCircle } from "react-icons/lu";
import { Card, CheckboxField, ProgressBar } from "@nexera-ui/react";
const TASKS = [
{
id: "company",
label: "Add company details",
description: "Name, address and registration number for payslips.",
},
{
id: "policy",
label: "Set your leave policy",
description: "25 days a year, carry-over and public holidays.",
},
{
id: "people",
label: "Import your people",
description: "Upload a spreadsheet or add employees one by one.",
},
{
id: "approvers",
label: "Choose approvers",
description: "Who signs off leave and expenses in each team.",
},
{
id: "payroll",
label: "Connect payroll",
description: "Link your bank so October payroll runs on the 28th.",
},
{
id: "invite",
label: "Invite your team",
description: "Everyone gets an email with a link to sign in.",
},
];
/** Setup checklist: the tasks left to finish, with overall progress. */
export default function SetupChecklist() {
const [done, setDone] = useState<Set<string>>(new Set(["company", "policy", "people"]));
const toggle = (id: string, isSelected: boolean) => {
setDone((previous) => {
const next = new Set(previous);
if (isSelected) next.add(id);
else next.delete(id);
return next;
});
};
return (
<div className="@container min-h-[560px] bg-page px-4 py-8 @3xl:px-8">
<div className="mx-auto grid max-w-4xl gap-6 @3xl:grid-cols-[minmax(0,1fr)_16rem] @3xl:items-start">
<Card
icon={<LuListChecks />}
title="Finish setting up Northwind"
titleLevel={2}
body={
done.size === TASKS.length
? "All done. Your workspace is ready."
: "Most teams finish in about 20 minutes."
}
>
<div className="grid gap-5 pt-2">
<ProgressBar
label="Setup progress"
labelPosition="top"
size="md"
value={(done.size / TASKS.length) * 100}
valueLabel={`${done.size} of ${TASKS.length} tasks`}
tone={done.size === TASKS.length ? "success" : "brand"}
/>
<ul aria-label="Setup tasks" className="m-0 grid list-none gap-4 p-0">
{TASKS.map((task) => (
<li key={task.id}>
<CheckboxField
label={task.label}
description={task.description}
isSelected={done.has(task.id)}
onChange={(isSelected) => {
toggle(task.id, isSelected);
}}
/>
</li>
))}
</ul>
</div>
</Card>
<aside
aria-labelledby="help-heading"
className="grid gap-3 rounded-xl border border-default bg-surface p-4"
>
<h3 id="help-heading" className="text-heading-h4 text-primary">
Need a hand?
</h3>
<a
href="#setup-guide"
className="inline-flex items-center gap-2 text-body-small text-brand-text underline underline-offset-4"
>
<LuBookOpen aria-hidden="true" /> Read the setup guide
</a>
<a
href="#chat"
className="inline-flex items-center gap-2 text-body-small text-brand-text underline underline-offset-4"
>
<LuMessageCircle aria-hidden="true" /> Chat with onboarding support
</a>
<p className="text-body-small text-secondary">
Support is online Monday to Friday, 9:00–18:00 GMT.
</p>
</aside>
</div>
</div>
);
}