Check your phone
To keep payroll and personal data safe, Northwind asks for a code when you sign in on a new device.
Info: New sign-in from Chrome on macOS
London, United Kingdom. If this wasn't you, change your password after verifying.
twostep-verification.tsx
"use client";
import { useState, type SyntheticEvent } from "react";
import { LuShieldCheck } from "react-icons/lu";
import { Alert, Button, OTPInput } from "@nexera-ui/react";
/** Two-step verification: enter the 6-digit code sent by SMS, with resend and other ways to verify. */
export default function TwoStepVerification() {
const [code, setCode] = useState("");
const [error, setError] = useState("");
const [verified, setVerified] = useState(false);
const [resent, setResent] = useState(false);
const verify = (value: string) => {
if (value.length < 6) {
setError("Enter all 6 digits of the code.");
return;
}
setError("");
setVerified(true); // replace with your verification request
};
const onSubmit = (event: SyntheticEvent<HTMLFormElement>) => {
event.preventDefault();
verify(code);
};
return (
<div className="@container grid min-h-[560px] place-items-center bg-page px-4 py-10">
<div className="grid w-full max-w-sm gap-6 rounded-xl border border-default bg-surface p-6 shadow-sm @sm:p-8">
<header className="grid gap-3">
<span
className="grid size-10 place-items-center rounded-lg bg-brand-subtle text-brand-text"
aria-hidden="true"
>
<LuShieldCheck className="size-5" />
</span>
<div className="grid gap-1">
<h2 className="text-heading-h3 text-primary">Check your phone</h2>
<p className="text-body-default text-secondary">
To keep payroll and personal data safe, Northwind asks for a code when you sign in on
a new device.
</p>
</div>
</header>
<Alert
tone="info"
title="New sign-in from Chrome on macOS"
description="London, United Kingdom. If this wasn't you, change your password after verifying."
/>
<form className="grid gap-4" onSubmit={onSubmit}>
<OTPInput
label="Verification code"
length={6}
name="code"
value={code}
onChange={(value) => {
setCode(value);
setError("");
}}
onComplete={verify}
description={
resent
? "We sent a new code to +44 •••• ••• 417."
: "Sent by SMS to +44 •••• ••• 417."
}
isInvalid={error !== ""}
errorMessage={error}
{...(verified ? { status: "success" as const } : {})}
statusMessage="Verified. Signing you in…"
resend="Resend code"
onResend={() => {
setResent(true);
}}
/>
<Button type="submit" size="lg" className="w-full" isDisabled={verified}>
Verify and continue
</Button>
</form>
<nav
aria-label="Other ways to verify"
className="grid gap-2 border-t border-subtle pt-4 text-body-small"
>
<a href="#authenticator" className="text-brand-text underline underline-offset-4">
Use your authenticator app instead
</a>
<a href="#backup-code" className="text-brand-text underline underline-offset-4">
Enter a backup code
</a>
<p className="text-secondary">
Lost your phone?{" "}
<a href="#it-help" className="text-brand-text underline underline-offset-4">
Contact Northwind IT
</a>
</p>
</nav>
</div>
</div>
);
}
More sign in and account blocks
- Sign inEmail and password with remember me and a link to reset.
- Create accountName, email and password with a live strength meter.
- Forgot passwordAsk for an email, then confirm the reset link was sent.
- Set a new passwordNew password with strength rules and confirmation.
- Check your emailMagic link sent, with resend and change email actions.
- Session expiredAsk the person to sign in again without losing their place.
- Choose a workspacePick one of several organisations after signing in.