Policies to accept
Accept these before you can book your first remote day.
Remote work policy
Version 3.2 · updated 1 September 2026
terms-and-consent.tsx
"use client";
import { useState } from "react";
import { LuFileText, LuHouse } from "react-icons/lu";
import { Badge, Button, CheckboxField, Modal } from "@nexera-ui/react";
const SECTIONS = [
{
title: "1. Who this policy covers",
text: "Every Northwind employee on a permanent or fixed-term contract who works from home for at least one day a week. Contractors follow the terms in their own agreement.",
},
{
title: "2. Your workspace",
text: "You agree to work from a safe, quiet space with a stable internet connection. Northwind pays up to £400 once for a desk, chair or monitor, claimed through Expenses within 90 days of your start date.",
},
{
title: "3. Working hours",
text: "Core hours are 10:00 to 16:00 in your local time zone. Outside core hours you plan your own time, as long as your team knows when to reach you.",
},
{
title: "4. Equipment and security",
text: "Company laptops stay encrypted and locked when unattended. Do not let family or friends use them, and connect only through the Northwind VPN on public networks.",
},
{
title: "5. Health and safety",
text: "Complete the home workstation check in your first month. Report any work-related injury to People Ops within 48 hours, exactly as you would in the office.",
},
{
title: "6. Changes to this policy",
text: "We review the policy every January. You will be asked to accept it again whenever it changes in a way that affects you.",
},
];
/** Terms and consent: a policy in a modal, with scrollable text and a required checkbox before you can accept. */
export default function TermsAndConsent() {
const [open, setOpen] = useState(false);
const [agreed, setAgreed] = useState(false);
const [accepted, setAccepted] = useState(false);
return (
<div className="@container bg-page px-4 py-8 @3xl:px-8">
<section
aria-labelledby="policies-title"
className="mx-auto grid max-w-2xl gap-5 rounded-xl border border-default bg-surface p-5 shadow-sm @3xl:p-8"
>
<header className="grid gap-1">
<h2 id="policies-title" className="text-heading-h3 text-primary">
Policies to accept
</h2>
<p className="text-body-default text-secondary">
Accept these before you can book your first remote day.
</p>
</header>
<div className="flex flex-wrap items-center gap-4 rounded-lg border border-subtle p-4">
<span className="grid size-10 shrink-0 place-items-center rounded-md bg-brand-subtle text-brand-text">
<LuHouse aria-hidden />
</span>
<div className="grid min-w-0 flex-1 gap-0.5">
<h3 className="text-body-strong text-primary">Remote work policy</h3>
<p className="text-body-small text-secondary">Version 3.2 · updated 1 September 2026</p>
</div>
{accepted ? (
<Badge label="Accepted" tone="success" />
) : (
<Button
variant="secondary"
size="md"
leadingIcon={<LuFileText />}
onPress={() => {
setAgreed(false);
setOpen(true);
}}
>
Review and accept
</Button>
)}
</div>
</section>
<Modal
title="Remote work policy"
subtitle="Read the policy, then confirm you agree."
size="md"
isOpen={open}
onOpenChange={setOpen}
secondaryAction={
<Button variant="secondary" size="md" slot="close">
Not now
</Button>
}
primaryAction={
<Button
size="md"
isDisabled={!agreed}
onPress={() => {
setAccepted(true);
setOpen(false);
}}
>
Accept policy
</Button>
}
>
<div className="grid gap-4">
<div
role="region"
aria-label="Policy text"
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- a scrollable region must be reachable by keyboard (WCAG 2.1.1); it is labelled
tabIndex={0}
className="grid max-h-64 gap-4 overflow-y-auto rounded-lg border border-subtle bg-sunken p-4 focus-visible:outline-2 focus-visible:outline-offset-2"
>
{SECTIONS.map((section) => (
<section key={section.title} className="grid gap-1">
<h3 className="text-body-strong text-primary">{section.title}</h3>
<p className="text-body-small text-secondary">{section.text}</p>
</section>
))}
</div>
<CheckboxField
label="I have read the remote work policy and agree to follow it"
name="consent"
isSelected={agreed}
onChange={setAgreed}
isRequired
description="Your acceptance is saved with the date and policy version."
/>
</div>
</Modal>
</div>
);
}
More forms and data entry blocks
- Contact formName, email, topic and message with validation.
- Add a personCreate a record in a modal.
- Multi-step formLong forms split into steps you can go back to.
- Address and phoneCountry, address lookup and phone with dialling code.
- File uploadDrag files in and watch each one upload.
- Date range pickerChoose a start and end date on a calendar.
- Search with suggestionsType ahead and pick from matching results.
- Choose an optionPick one option from a short list in a dialog.
- Pick a colourBrand or label colour from swatches or a picker.