# EmailVerificationView _(no submodules)_ ## Purpose `` is the pure-UI surface that renders the four states of an email-verification flow — `verifying`, `success`, `expired`, `error` — with the right icon, copy, and CTA per state. It is a status view rather than a form: there are no inputs, no validation, just a deterministic switch from `status` to one of four cards. The page-level host owns the token-extraction, the API call against `useAuth().verifyEmail`, and the status transitions; the view is a dumb renderer that can also be reused inside admin re-verification flows or as a notification banner. ## Features - Four discrete render branches keyed off the `status` prop, each with its own icon (`Loader2` / `CheckCircle2` / `AlertTriangle` / `XCircle`). - Each branch ships a CTA wired to one of `onContinueToLogin` / `onRegisterAgain` / `onTryAgain` callbacks supplied by the host. - The `error` branch additionally renders a destructive `` with the same message for screen-reader prominence. - The `error` retry CTA shows a spinner and is disabled while `isLoading` is true. - Optional `message` prop overrides the default per-status description copy. - `translations?: Partial` for full Welsh / zh-CN coverage via Wave 1's translation packs. - Always renders a "back to login" link except in the `verifying` state (where no action is meaningful yet). ## Usage: Basic ```tsx import { EmailVerificationView } from "@suaveplan/react-auth"; import { BrowserRouter } from "react-router-dom"; export function VerifyEmailPage() { return ( ); } ``` ## Usage: Advanced Drive every transition from URL state + `useAuth().verifyEmail`: ```tsx import { EmailVerificationView, useAuth, } from "@suaveplan/react-auth"; import { useEffect, useState, } from "react"; import { useNavigate, useSearchParams } from "react-router-dom"; export function VerifyEmail() { const { verifyEmail } = useAuth(); const navigate = useNavigate(); const [params] = useSearchParams(); const token = params.get("token"); const [status, setStatus] = useState< "verifying" | "success" | "error" | "expired" >("verifying"); const [message, setMessage] = useState(""); useEffect(() => { if (token === null) { setStatus("expired"); return; } verifyEmail({ token }) .then(() => setStatus("success")) .catch((err: unknown) => { setStatus("error"); setMessage( err instanceof Error ? err.message : String(err) ); }); }, [token, verifyEmail]); return ( navigate("/auth/login")} onRegisterAgain={() => navigate("/auth/register")} onTryAgain={() => setStatus("verifying")} /> ); } ``` ## API Reference ### `EmailVerificationView(props: EmailVerificationViewProps): ReactElement` | Prop | Type | Default | Description | |---|---|---|---| | `status` | `"verifying" \| "success" \| "error" \| "expired"` | — required | Which card to render. | | `message` | `string` | `""` | Override for the default description copy. | | `onContinueToLogin` | `() => void` | — | Fired by the success-status CTA. | | `onRegisterAgain` | `() => void` | — | Fired by the expired-status CTA. | | `onTryAgain` | `() => void` | — | Fired by the error-status retry CTA. | | `isLoading` | `boolean` | `false` | Disables the error-status retry CTA. | | `translations` | `Partial` | `enGb.auth.emailVerification` | Override any subset of the 8 copy keys. | ### `EmailVerificationStatus` ```ts type EmailVerificationStatus = | "verifying" | "success" | "error" | "expired"; ``` ## Implementation Notes - Each card is implemented as a small internal component (`VerifyingCard`, `SuccessCard`, `ExpiredCard`, `ErrorCard`) and dispatched through a `switch`-style helper to keep the public file under the 300-line cap. - The component intentionally does NOT consume `useTranslation` — Wave 1 dropped the `@suaveplan/react-translate` dependency, and Wave 2 follows that precedent. Translations are injected via the `translations` prop instead. - The `verifying` card carries `role="status"` on the spinner wrapper for assistive-tech announcements. - The error card duplicates the message in a destructive `` so the failure is announced even when the CTA is off-screen on narrow viewports. - No OTel instruments emitted from the view; metrics live on the Wave 1 `verifyEmail` action.