chore: new design for invitations accept

This commit is contained in:
fsylvain committed 2026-09-29 08:41:54 +02:00
1 parent 6afffc1984
commit 310cfd528e
8 files changed
+148 -34

No files matched your search

+12 -5
View File
@@ -79,13 +79,14 @@ class Component extends DCLogic {
{ t: 'Foundations', d: 'Tokens, contrast, type, motion, icons', href: 'RenewCMS Foundations.dc.html' },
{ t: 'Primitives', d: 'Themed Nuxt UI components', href: 'RenewCMS Components Primitives.dc.html' },
{ t: 'Product components', d: '17 RenewCMS components', href: 'RenewCMS Components Product.dc.html' },
{ t: 'Auth screens', d: 'Six public routes, every state', href: 'RenewCMS Screens Auth.dc.html' },
{ t: 'Auth screens', d: 'Seven public routes, every state', href: 'RenewCMS Screens Auth.dc.html' },
{ t: 'Back-office screens', d: 'Verified routes and global states', href: 'RenewCMS Screens Back-office.dc.html' },
{ t: 'Emails', d: 'Previews of both templates', href: 'RenewCMS Emails.dc.html' },
{ t: 'Emails', d: 'Previews of the three templates', href: 'RenewCMS Emails.dc.html' },
{ t: 'tokens/renewcms.css', d: '@theme, :root, .dark, .article-content', href: 'tokens/renewcms.css' },
{ t: 'tokens/ui.config.ts', d: 'Nuxt UI colors, icons, overrides', href: 'tokens/ui.config.ts' },
{ t: 'tokens/vite.config.ts', d: 'Vite plugin setup', href: 'tokens/vite.config.ts' },
{ t: 'emails/verification.html', d: 'Go html/template', href: 'emails/verification.html' },
{ t: 'emails/invitation.html', d: 'Go html/template', href: 'emails/invitation.html' },
{ t: 'emails/password-reset.html', d: 'Go html/template', href: 'emails/password-reset.html' },
{ t: 'brand/favicon.svg', d: '16 px grid mark, dark-aware', href: 'brand/favicon.svg' }
]
@@ -95,6 +96,7 @@ class Component extends DCLogic {
['/register', 'AuthShell', 'public', 'RegisterPage', 'POST /v1/auth/register'],
['/register/pending', 'AuthShell', 'session', 'PendingPage', 'DELETE /v1/auth/register · POST /v1/auth/logout'],
['/register/validate', 'AuthShell', 'public', 'VerifyPage', 'POST /v1/auth/verify (+ POST /login inline on 401)'],
['/invite/accept', 'AuthShell', 'public', 'AcceptInvitePage', 'GET /v1/auth/invite?c=* · POST /v1/auth/invite/accept*'],
['/register/reset/request', 'AuthShell', 'public', 'ResetRequestPage', 'POST /v1/auth/password-reset'],
['/register/reset/validate', 'AuthShell', 'public', 'ResetConfirmPage', 'POST /v1/auth/password-reset/confirm'],
['/home', 'DashboardShell', 'verified', 'HomePage', 'GET /v1/article/'],
@@ -120,9 +122,9 @@ class Component extends DCLogic {
['SaveStatus', 'custom (span + UButton)', "state: 'clean'|'dirty'|'saving'|'saved'|'error'|'offline', savedAt?: Date", 'retry', 'none', 'Editor'],
['PublishControl', 'UButton', 'online: boolean, dirty: boolean, pending?: string, disabled?', 'publish, unpublish', 'none', 'Editor'],
['ArticleDetails', 'UCard (desktop) / USlideover (mobile)', 'article: Article', 'copy-url', 'none', 'Editor'],
['CharacterCounter', 'custom', 'value: number, max: number, min?: number, warnAt?: number', 'none', 'none', 'NewArticleModal, Editor, Register'],
['PasswordStrengthHint', 'custom (in UFormField #help)', 'rules: { label, met }[], showErrors: boolean', 'none', 'none', 'Register, Reset'],
['ResultPanel', 'custom + UButton', "tone: 'success'|'error'|'info', icon, title, description, actions: ButtonProps[]", 'none', 'default', 'Pending, Verify, Reset request, Reset, Register (403)'],
['CharacterCounter', 'custom', 'value: number, max: number, min?: number, warnAt?: number', 'none', 'none', 'NewArticleModal, Editor, Register, Accept invite'],
['PasswordStrengthHint', 'custom (in UFormField #help)', 'rules: { label, met }[], showErrors: boolean', 'none', 'none', 'Register, Reset, Accept invite'],
['ResultPanel', 'custom + UButton', "tone: 'success'|'error'|'info', icon, title, description, actions: ButtonProps[]", 'none', 'default', 'Pending, Verify, Reset request, Reset, Accept invite, Register (403)'],
['CodeBlock', 'custom (shiki) + UButton', 'code: string, lang: string, label?', 'none', 'none', 'Integration'],
['EndpointCard', 'UCard, UBadge, UTabs', "method: 'GET', path, description, examples: { fetch, curl, response }", 'none', 'none', 'Integration'],
['ErrorView', 'custom + UButton', "kind: 'not-found'|'error'", 'retry', 'none', 'Not found, error boundary'],
@@ -136,6 +138,7 @@ class Component extends DCLogic {
M('Register', '/register', [['Default', 'Open instance'], ['Validation errors', 'Client rules fail'], ['Submitting', 'In flight'], ['Registration closed', '403'], ['Server error', '500 or network']]),
M('Pending', '/register/pending', [['Default', 'After registering (email known)'], ['Email unknown', 'After logging in unverified'], ['Confirm cancel', 'Cancel registration clicked'], ['Cancelling', 'DELETE in flight'], ['Cancelled', '200: /register with toast'], ['Already verified', '403: /home with toast']]),
M('Verify', '/register/validate?c=', [['Verifying', 'On load'], ['Success', '200: /home with toast'], ['Invalid or expired', '403'], ['No session', '401: inline log in, then retry'], ['Missing code', 'No c parameter']]),
M('Accept invite', '/invite/accept?c=', [['Checking the link', 'On load: GET invite*'], ['Default', 'Valid, unused code; email read-only'], ['Validation errors', 'Register rules fail'], ['Submitting', 'In flight'], ['Username taken', '409'], ['Invalid or used', '404 or no c parameter'], ['Expired', '410: ask the person who invited you'], ['Server error', '500 or network'], ['Success', '200: logged in, /home with toast']]),
M('Forgot password', '/register/reset/request', [['Default', 'Page load'], ['Validation', 'Invalid email'], ['Submitting', 'In flight'], ['Sent', 'Any 200 (neutral copy)'], ['Too many attempts', '429*'], ['Server error', '500 or network']]),
M('Reset password', '/register/reset/validate', [['Default', 'c and email present'], ['Too short', 'Under 8 characters'], ['Mismatch', 'Confirm field differs'], ['Submitting', 'In flight'], ['Success', '200: /login?reason=password-changed'], ['Invalid or expired', '403'], ['Missing parameters', 'No c or no email']]),
M('Home', '/home', [['Loading', 'List in flight (after 150 ms)'], ['Default', 'List loaded'], ['Empty', 'Zero articles'], ['Error', '500 or network']]),
@@ -153,6 +156,9 @@ class Component extends DCLogic {
['403', 'Any back-office call', 'Unverified: goes to /register/pending', 'Redirect'],
['403', 'Verify', '"This verification link doesn\'t work." Offers Cancel registration and start over', 'ResultPanel'],
['403', 'Cancel registration', '"Your account is already verified." Goes to /home', 'Toast'],
['404', 'Accept invite', '"This invite link doesn\'t work." Offers Go to log in', 'ResultPanel'],
['409', 'Accept invite', '"That username is taken. Try another."', 'Field'],
['410', 'Accept invite', '"This invite has expired. Ask the person who invited you to send a new one."', 'ResultPanel'],
['403', 'Reset confirm', '"This reset link has expired." Offers Request a new link', 'ResultPanel'],
['404', 'Editor load', '"This article doesn\'t exist." Offers All articles', 'ErrorView'],
['404', 'Row or editor action', '"That article no longer exists." The row is removed', 'Toast'],
@@ -167,6 +173,7 @@ class Component extends DCLogic {
const pending = [
{ a: 'GET /v1/auth/me → User | 401', d: 'The session check at boot. The HttpOnly cookie can\'t be read from JS. Until this exists, the guard can call GET /v1/article/ and infer: 401 means logged out, but verified and unverified users can\'t be told apart.' },
{ a: 'GET /v1/auth/registration → { open }', d: 'Shows "Create the owner account" on /login. Without it, the link is hidden and /register is reachable by URL only.' },
{ a: 'GET /v1/auth/invite?c=CODE → { email } | 404 | 410', d: 'Looks up the invite on load so the email can be shown and dead links are caught before the form. POST /v1/auth/invite/accept { code, username, password } returns 200 with the session cookie, 409 for a taken username, 404 or 410 as above. Neither exists yet.' },
{ a: '429 + Retry-After on /login, /password-reset', d: 'Drives the countdown state. The UI falls back to 60 s if the header is missing.' },
{ a: 'Serving /static/uploadedImages/*', d: 'The editor and preview are designed as if images load. Until they do, img tags show a broken image.' },
{ a: 'Not supported (disabled or omitted)', d: 'Renaming a title (shown read-only, with an explanation in Details), resending the verification email (the pending page explains how to start over), changing the password while logged in, editing the profile or email, listing or deleting individual images, multiple users.' }