"use client"; import { useActionState, type ReactNode } from "react"; import { cancelTwoFactorSetupAction, disableTwoFactorAction, enableTwoFactorAction, regenerateRecoveryCodesAction, } from "@/app/actions/settings"; import { DownloadIcon } from "@/components/icons"; import { CopyIconButton, TextField } from "@/components/settings-fields"; import { PlateBody, PlateFooter } from "@/components/settings-plate"; import { Alert, Button } from "@/components/ui"; function CodeField({ label = "Authentication code", description }: { label?: string; description?: ReactNode }) { return ( ); } /** Recovery codes, shown once: copy, download, then Done reloads the page. */ function RecoveryCodes({ codes, notice }: { codes: string[]; notice: string }) { const text = codes.join("\n"); const download = () => { const url = URL.createObjectURL(new Blob([`${text}\n`], { type: "text/plain" })); const a = Object.assign(document.createElement("a"), { href: url, download: "recovery-codes.txt" }); a.click(); URL.revokeObjectURL(url); }; return ( <> {notice}

Save these recovery codes somewhere safe, like a password manager. If you lose your device, each one signs you in once. You won’t be able to see them again.

    {codes.map((code) => (
  • {code}
  • ))}
); } export function EnableTwoFactorForm({ qr, secret }: { qr: ReactNode; secret: string }) { const [state, action, pending] = useActionState(enableTwoFactorAction, undefined); if (state?.codes) return ; return (
{qr}

1. Scan the QR code

Use an authenticator app like 1Password, Google Authenticator, Microsoft Authenticator, Authy or Bitwarden.

Can’t scan it? Enter this setup key instead:

{secret}

2. Enter the 6-digit code from the app

{state?.error && {state.error}}
); } export function RegenerateRecoveryCodesForm() { const [state, action, pending] = useActionState(regenerateRecoveryCodesAction, undefined); if (state?.codes) return ; return (
{state?.error && {state.error}}
); } export function DisableTwoFactorForm() { const [state, action, pending] = useActionState(disableTwoFactorAction, undefined); return (
{state?.error && {state.error}}
); }