i18n: extract Authorization screens into a new auth namespace
Every user-facing string under src/views/Authorization/ moves to i18next.
English only — no translations in this PR, so it is language-agnostic and
reviewable as a pure refactor.
Covered:
- LoginView — primary/sub-account tabs, credential form, social and
Authentik buttons, welcome-back state, every auth error toast
- Signup — account creation form and each field-validation message
- ForgotPasswordView / UpdatePasswordView — reset flow and its toasts
- Authenticating — the OAuth landing screen, including its MFA branches
- MFAVerificationModal — code entry, backup codes, error states
- AuthFields / LoginSettings — shared field labels and server settings
`auth` is registered in src/i18n/config.js; public/locales/en/auth.json
holds the 103 keys. The Crowdin config picks up /public/locales/en/*.json
by glob, so the namespace flows into the pipeline with no change to
crowdin.yml.
No behaviour change: every t() value is the string that rendered before,
character for character — checked mechanically against this branch's base.
The e2e suite selects auth controls by visible text ('Create account',
'Username must be at least 4 characters'), so a green run is the proof.
Two fixes fell out of the extraction:
- AuthPasswordField had label='Password' as a prop default, so neither
LoginView nor Signup passed one. A default cannot be translated at module
scope, so the label moves to the call sites and both now pass it.
- AuthDivider defaulted children to 'or' for the same reason; it now falls
back to t('or').
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import MarkEmailReadOutlined from '@mui/icons-material/MarkEmailReadOutlined'
|
||||
import { Box, Button, Link, Typography } from '@mui/joy'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useNotification } from '../../service/NotificationProvider'
|
||||
import { ResetPassword } from '../../utils/Fetcher'
|
||||
@@ -12,6 +13,7 @@ const isInvalidEmail = email =>
|
||||
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(email)
|
||||
|
||||
const ForgotPasswordView = () => {
|
||||
const { t } = useTranslation('auth')
|
||||
const navigate = useNavigate()
|
||||
const [resetStatusOk, setResetStatusOk] = useState(null)
|
||||
const [email, setEmail] = useState('')
|
||||
@@ -40,21 +42,21 @@ const ForgotPasswordView = () => {
|
||||
setResetStatusOk(true)
|
||||
showNotification({
|
||||
type: 'success',
|
||||
title: 'Reset Email Sent',
|
||||
message: 'Check your email for password reset instructions',
|
||||
title: t('resetEmailSent'),
|
||||
message: t('resetEmailSentMsg'),
|
||||
})
|
||||
} else {
|
||||
setResetStatusOk(false)
|
||||
showError({
|
||||
title: 'Reset Failed',
|
||||
message: 'Failed to send reset email, please try again later',
|
||||
title: t('resetFailed'),
|
||||
message: t('resetFailedMsg'),
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
setResetStatusOk(false)
|
||||
showError({
|
||||
title: 'Reset Failed',
|
||||
message: 'Failed to send reset email, please try again later',
|
||||
title: t('resetFailed'),
|
||||
message: t('resetFailedMsg'),
|
||||
})
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
@@ -79,7 +81,7 @@ const ForgotPasswordView = () => {
|
||||
if (resetStatusOk !== null) {
|
||||
return (
|
||||
<AuthShell
|
||||
title='Check your email'
|
||||
title={t('checkYourEmail')}
|
||||
subtitle={`If an account exists for ${email}, we've sent instructions for resetting your password.`}
|
||||
footer={<LegalLinks />}
|
||||
logoSize={0}
|
||||
@@ -101,7 +103,7 @@ const ForgotPasswordView = () => {
|
||||
sx={authButtonSx}
|
||||
onClick={() => navigate('/login')}
|
||||
>
|
||||
Back to sign in
|
||||
{t('backToSignIn')}
|
||||
</Button>
|
||||
</Box>
|
||||
</AuthShell>
|
||||
@@ -110,7 +112,7 @@ const ForgotPasswordView = () => {
|
||||
|
||||
return (
|
||||
<AuthShell
|
||||
title='Reset your password'
|
||||
title={t('resetYourPassword')}
|
||||
subtitle="Enter your email and we'll send you a link to get back into your account."
|
||||
footer={<LegalLinks />}
|
||||
logoSize={0}
|
||||
@@ -126,7 +128,7 @@ const ForgotPasswordView = () => {
|
||||
name='email'
|
||||
type='email'
|
||||
autoComplete='email'
|
||||
placeholder='you@example.com'
|
||||
placeholder={t('emailPlaceholder')}
|
||||
autoFocus
|
||||
value={email}
|
||||
error={emailError}
|
||||
@@ -152,7 +154,7 @@ const ForgotPasswordView = () => {
|
||||
underline='hover'
|
||||
onClick={() => navigate('/login')}
|
||||
>
|
||||
Back to sign in
|
||||
{t('backToSignIn')}
|
||||
</Link>
|
||||
</Typography>
|
||||
</AuthShell>
|
||||
|
||||
Reference in New Issue
Block a user