first commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# `<EmailVerificationPage>` — routing-aware verification page
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`<EmailVerificationPage>` is the routing-aware adapter that wraps the Wave 2 `<EmailVerificationView>` for the `?token=…`-bearing email-verification link sent by the server. It extracts the token from the URL search params, calls `useAuth().verifyEmail(token)` exactly once on mount, and renders one of four states via the underlying view component: `verifying` (default while the call is in flight), `success` (after a resolved call), `expired` (after a rejection whose message contains "expired" or "invalid"), or `error` (everything else).
|
||||
|
||||
Use this as the `Route element` for `/auth/verify-email`. The page never re-implements the four state cards — those live in the Wave 2 view.
|
||||
|
||||
## Features
|
||||
|
||||
- `useAuthGuard({ requireGuest: true })` so authenticated visitors are redirected away.
|
||||
- Single in-flight `verifyEmail(token)` call on mount; React's `useEffect` dep array is `[token, verifyEmail]` so re-renders don't fire spurious calls.
|
||||
- Error classifier: rejections whose `message` contains `expired` or `invalid` (case-insensitive) map to the `expired` state; all other failures map to `error`.
|
||||
- Three navigation callbacks wired into the view: `onContinueToLogin` → `/auth/login`, `onRegisterAgain` → `/auth/register`, `onTryAgain` reloads the page.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```tsx
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
import { EmailVerificationPage } from "@suaveplan/react-auth";
|
||||
|
||||
export function AuthRoutes() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path="/auth/verify-email"
|
||||
element={<EmailVerificationPage />}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
When sending the verification email, embed the token in the URL:
|
||||
|
||||
```ts
|
||||
const link = new URL("/auth/verify-email", site.origin);
|
||||
link.searchParams.set("token", verificationToken);
|
||||
await mailer.send({ to: user.email, subject, body: link.toString() });
|
||||
```
|
||||
|
||||
If you want a different post-verification destination, wrap the page in a custom layout that hooks into `useAuth()` to redirect on `user.emailVerified === true`.
|
||||
|
||||
## API Reference
|
||||
|
||||
`<EmailVerificationPage>` accepts no props.
|
||||
|
||||
### `EmailVerificationPageState`
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `status` | `EmailVerificationStatus` | One of `"verifying" \| "success" \| "error" \| "expired"`. |
|
||||
| `message` | `string` | Human-readable message displayed by the view. |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The reload-style `onTryAgain` handler intentionally short-circuits on SSR (`typeof window === "undefined"`). The page is browser-only in practice, but the guard keeps the code defensive.
|
||||
- The `verifyEmail` mount-time call is fired even if the token is malformed; the server's response carries the failure mode (404, expired, malformed) which the classifier maps to `expired` / `error`.
|
||||
- The page intentionally does NOT renavigate on success — the user clicks the visible CTA to continue to login, mirroring the upstream UX where some users may want to copy state from the verification screen first.
|
||||
Reference in New Issue
Block a user