diff --git a/web-next/app/[locale]/activate-account/ActivateClient.tsx b/web-next/app/[locale]/activate-account/ActivateClient.tsx index 2a03a8b..098f4d8 100644 --- a/web-next/app/[locale]/activate-account/ActivateClient.tsx +++ b/web-next/app/[locale]/activate-account/ActivateClient.tsx @@ -2,17 +2,17 @@ import { useEffect, useRef, useState } from 'react' import { useTranslations } from 'next-intl' -import { Link } from '@/i18n/navigation' const ERROR_KEYS = ['invalidLink', 'expiredLink'] as const -export function ActivateClient({ hash }: { hash: string }) { +export function ActivateClient({ hash, realm }: { hash: string; realm: string }) { const t = useTranslations('Activate') // Sin hash el error se sabe YA, al renderizar (y 'invalidLink' es justo el // errorKey por defecto): se deriva del prop en vez de ponerlo con setState // dentro del efecto, que encadena un render de más. const [state, setState] = useState<'loading' | 'ok' | 'error'>(hash ? 'loading' : 'error') const [errorKey, setErrorKey] = useState('invalidLink') + const [email, setEmail] = useState('') const ran = useRef(false) useEffect(() => { @@ -24,9 +24,11 @@ export function ActivateClient({ hash }: { hash: string }) { body: JSON.stringify({ hash }), }) .then((r) => r.json()) - .then((d: { success?: boolean; error?: string }) => { - if (d.success) setState('ok') - else { + .then((d: { success?: boolean; error?: string; email?: string }) => { + if (d.success) { + setEmail(d.email ?? '') + setState('ok') + } else { setErrorKey((ERROR_KEYS as readonly string[]).includes(d.error ?? '') ? d.error! : 'invalidLink') setState('error') } @@ -34,18 +36,28 @@ export function ActivateClient({ hash }: { hash: string }) { .catch(() => setState('error')) }, [hash]) + // El envoltorio ya lo pone la página (`body-box-content centered`), así que aquí + // van los

sueltos: es la estructura que tenían las plantillas del tema. return ( -

+ <> {state === 'loading' &&

{t('activating')}

} {state === 'ok' && ( <> - {t('success')} -

- {t('goLogin')} -

+
+

{t('welcome', { realm })}

+

{t.rich('activated', { email, account: (c) => {c} })}

+
+

{t('canPlay')}

+
)} - {state === 'error' && {t(errorKey)}} -
+ {state === 'error' && ( + <> +

{t(errorKey)}

+
+

{t('needHelp', { realm })}

+ + )} + ) } diff --git a/web-next/app/[locale]/activate-account/page.tsx b/web-next/app/[locale]/activate-account/page.tsx index 761e4ef..69e706d 100644 --- a/web-next/app/[locale]/activate-account/page.tsx +++ b/web-next/app/[locale]/activate-account/page.tsx @@ -1,5 +1,6 @@ import { getTranslations, setRequestLocale } from 'next-intl/server' import { PageShell } from '@/components/PageShell' +import { getRealmName } from '@/lib/realm' import { ActivateClient } from './ActivateClient' export default async function ActivatePage({ @@ -13,12 +14,13 @@ export default async function ActivatePage({ setRequestLocale(locale) const { act } = await searchParams const t = await getTranslations('Activate') + const realm = await getRealmName() return (
- +
diff --git a/web-next/lib/register.ts b/web-next/lib/register.ts index 2b37230..6b96dae 100644 --- a/web-next/lib/register.ts +++ b/web-next/lib/register.ts @@ -18,6 +18,8 @@ export interface RegisterInput { export interface Result { success: boolean error?: string + /** Solo al activar: el correo de la cuenta, para poder decir cuál se activó. */ + email?: string } export async function registerAccount(input: RegisterInput): Promise { @@ -111,5 +113,7 @@ export async function activateAccount(hash: string, lastIp = '0.0.0.0'): Promise ) await db(DB.default).query('DELETE FROM accountactivation WHERE id = ?', [act.id]) - return { success: true } + // El correo tal cual se registró, no `emailNorm`: ese va en MAYÚSCULAS porque lo + // exige el SRP6 de Battle.net, y en pantalla quedaría como INNA@INNA.CL. + return { success: true, email: act.email } } diff --git a/web-next/messages/en.json b/web-next/messages/en.json index 3b78385..bbca6f9 100644 --- a/web-next/messages/en.json +++ b/web-next/messages/en.json @@ -201,10 +201,12 @@ }, "Activate": { "activating": "Activating your account…", - "success": "Account activated! You can now sign in.", - "invalidLink": "The link is invalid or has already been used.", - "expiredLink": "The link has expired. Please request a new one.", - "goLogin": "Go to sign in", + "welcome": "Welcome to {realm}!", + "activated": "The account {email} has been activated successfully.", + "canPlay": "You can now log in to the website or start enjoying the server.", + "invalidLink": "The activation link is invalid", + "expiredLink": "The activation link has expired", + "needHelp": "If you need help creating an account, you can contact the {realm} team.", "title": "Account activation" }, "Recover": { diff --git a/web-next/messages/es.json b/web-next/messages/es.json index 09505d0..415d355 100644 --- a/web-next/messages/es.json +++ b/web-next/messages/es.json @@ -201,10 +201,12 @@ }, "Activate": { "activating": "Activando tu cuenta…", - "success": "¡Cuenta activada! Ya puedes iniciar sesión.", - "invalidLink": "El enlace no es válido o ya se ha usado.", - "expiredLink": "El enlace ha caducado. Solicita uno nuevo.", - "goLogin": "Ir a iniciar sesión", + "welcome": "¡Bienvenido a {realm}!", + "activated": "La cuenta {email} ha sido activada exitosamente.", + "canPlay": "Ya puedes conectar a la página web o empezar a disfrutar del servidor.", + "invalidLink": "El enlace de activación es inválido", + "expiredLink": "El enlace de activación ha caducado", + "needHelp": "Si necesitas ayuda para crear una cuenta, puedes contactar con el equipo de {realm}.", "title": "Activación de cuenta" }, "Recover": {