Phase 5: Translate Auth Pages - login and signup

- Create auth.json translation files for es, en, ca
- Translate login page: title, subtitle, form labels, buttons, footer
- Translate signup page: invite code step and account creation step
- Translate signup/[code] redirect page
- Update IntlProvider to load auth namespace
- Update test expectations to match Spanish translations (default language)
- All frontend and e2e tests passing
This commit is contained in:
counterweight 2025-12-25 22:14:04 +01:00
parent a5a1a2c1ad
commit 7dd13292a0
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
9 changed files with 188 additions and 47 deletions

View file

@ -5,6 +5,7 @@ import { useRouter } from "next/navigation";
import { useAuth } from "../auth-context";
import { authFormStyles as styles } from "../styles/auth-form";
import { LanguageSelector } from "../components/LanguageSelector";
import { useTranslation } from "../hooks/useTranslation";
export default function LoginPage() {
const [email, setEmail] = useState("");
@ -13,6 +14,7 @@ export default function LoginPage() {
const [isSubmitting, setIsSubmitting] = useState(false);
const { login } = useAuth();
const router = useRouter();
const t = useTranslation("auth");
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
@ -23,7 +25,7 @@ export default function LoginPage() {
await login(email, password);
router.push("/");
} catch (err) {
setError(err instanceof Error ? err.message : "Login failed");
setError(err instanceof Error ? err.message : t("login.loginFailed"));
} finally {
setIsSubmitting(false);
}
@ -37,8 +39,8 @@ export default function LoginPage() {
<div style={styles.container}>
<div style={styles.card}>
<div style={styles.header}>
<h1 style={styles.title}>Welcome back</h1>
<p style={styles.subtitle}>Sign in to your account</p>
<h1 style={styles.title}>{t("login.title")}</h1>
<p style={styles.subtitle}>{t("login.subtitle")}</p>
</div>
<form onSubmit={handleSubmit} style={styles.form}>
@ -46,7 +48,7 @@ export default function LoginPage() {
<div style={styles.field}>
<label htmlFor="email" style={styles.label}>
Email
{t("login.email")}
</label>
<input
id="email"
@ -54,14 +56,14 @@ export default function LoginPage() {
value={email}
onChange={(e) => setEmail(e.target.value)}
style={styles.input}
placeholder="you@example.com"
placeholder={t("login.emailPlaceholder")}
required
/>
</div>
<div style={styles.field}>
<label htmlFor="password" style={styles.label}>
Password
{t("login.password")}
</label>
<input
id="password"
@ -69,7 +71,7 @@ export default function LoginPage() {
value={password}
onChange={(e) => setPassword(e.target.value)}
style={styles.input}
placeholder="••••••••"
placeholder={t("login.passwordPlaceholder")}
required
/>
</div>
@ -82,14 +84,14 @@ export default function LoginPage() {
}}
disabled={isSubmitting}
>
{isSubmitting ? "Signing in..." : "Sign in"}
{isSubmitting ? t("login.signingIn") : t("login.signIn")}
</button>
</form>
<p style={styles.footer}>
Don&apos;t have an account?{" "}
{t("login.noAccount")}{" "}
<a href="/signup" style={styles.link}>
Sign up
{t("login.signUp")}
</a>
</p>
</div>