feat(i18n): localize hardcoded headers and recovery fallback flows

This commit is contained in:
2026-05-28 16:47:30 +02:00
parent 387849a1c2
commit d8f9585ac8
4 changed files with 48 additions and 16 deletions
+12 -12
View File
@@ -79,10 +79,10 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
if (success) {
onAuthenticated()
} else {
setError('Incorrect recovery phrase. Decryption failed.')
setError(t('auth.error_incorrect_recovery'))
}
} catch (err: any) {
setError('Decryption failed. Please check your recovery phrase.')
setError(t('auth.error_decryption_failed'))
} finally {
setLoading(false)
}
@@ -121,7 +121,7 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
<div className="auth-actions">
<button className="btn secondary" onClick={copyToClipboard}>
{copied ? 'Copied!' : 'Copy Phrase'}
{copied ? t('auth.copied') : t('auth.copy_phrase')}
</button>
<button className="btn primary" onClick={onAuthenticated}>
{t('auth.confirm_recovery')}
@@ -137,16 +137,16 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
<div className="auth-card glass">
<div className="auth-header">
<KeyRound className="auth-icon accent" size={48} />
<h2>Enter Recovery Phrase</h2>
<h2>{t('auth.enter_recovery')}</h2>
</div>
<p className="recovery-warning">
Your Passkey authenticated successfully, but your device does not support hardware key derivation. Enter your 12-word recovery phrase to decrypt your logbook.
{t('auth.recovery_fallback_warning')}
</p>
<form onSubmit={handleRecoverySubmit} className="auth-form">
<textarea
className="input-textarea"
placeholder="Enter your 12-word recovery phrase separated by spaces..."
placeholder={t('auth.recovery_placeholder')}
value={recoveryInput}
onChange={(e) => setRecoveryInput(e.target.value)}
disabled={loading}
@@ -163,10 +163,10 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
onClick={() => setShowRecoveryFallback(false)}
disabled={loading}
>
Back
{t('auth.back')}
</button>
<button type="submit" className="btn primary" disabled={loading}>
{loading ? 'Decrypting...' : 'Decrypt Logbook'}
{loading ? t('auth.decrypting') : t('auth.decrypt_logbook')}
</button>
</div>
</form>
@@ -192,13 +192,13 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
disabled={loading}
style={{ width: '100%', padding: '16px' }}
>
{loading ? 'Processing...' : t('auth.login')}
{loading ? t('auth.processing') : t('auth.login')}
</button>
{/* Separator */}
<div style={{ display: 'flex', alignItems: 'center', margin: '10px 0', width: '100%' }}>
<div style={{ flex: 1, height: '1px', background: 'rgba(255,255,255,0.1)' }}></div>
<span style={{ padding: '0 10px', fontSize: '12px', color: '#64748b', textTransform: 'uppercase' }}>or register</span>
<span style={{ padding: '0 10px', fontSize: '12px', color: '#64748b', textTransform: 'uppercase' }}>{t('auth.or_register')}</span>
<div style={{ flex: 1, height: '1px', background: 'rgba(255,255,255,0.1)' }}></div>
</div>
@@ -208,7 +208,7 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
<input
type="text"
className="input-text"
placeholder="Username / Skipper Name"
placeholder={t('auth.username_placeholder')}
value={username}
onChange={(e) => setUsername(e.target.value)}
disabled={loading}
@@ -236,7 +236,7 @@ export default function AuthOnboarding({ onAuthenticated }: AuthOnboardingProps)
</button>
<a href="#help" className="btn-icon-text link-sec">
<HelpCircle size={18} />
Help
{t('auth.help')}
</a>
</div>
</div>
+2 -2
View File
@@ -704,7 +704,7 @@ export default function LogEntryEditor({ entryId, logbookId, onBack }: LogEntryE
<div className="form-card">
<div className="form-header">
<FileText size={20} className="form-icon" />
<h3>Travel Details</h3>
<h3>{t('logs.travel_details')}</h3>
</div>
<div className="form-grid">
<div className="input-group">
@@ -941,7 +941,7 @@ export default function LogEntryEditor({ entryId, logbookId, onBack }: LogEntryE
{/* Add New Event Form Sub-Card */}
<div className="member-editor-card glass">
<h4 style={{ margin: '0 0 16px 0', color: '#fbbf24' }}>Add Event Log Record</h4>
<h4 style={{ margin: '0 0 16px 0', color: '#fbbf24' }}>{t('logs.add_event')}</h4>
<div className="form-grid mb-4">
<div className="input-group">
+17 -1
View File
@@ -21,7 +21,21 @@
"recovery_warning": "WICHTIG: Schreiben Sie diese 12 Wörter auf. Wenn Sie Ihren Passkey und diese Wörter verlieren, können Ihre Daten nicht wiederhergestellt werden.",
"confirm_recovery": "Ich habe die Wörter aufgeschrieben",
"status_logged_in": "Angemeldet",
"status_logged_out": "Abgemeldet"
"status_logged_out": "Abgemeldet",
"copied": "Kopiert!",
"copy_phrase": "Schlüssel kopieren",
"enter_recovery": "Wiederherstellungsschlüssel eingeben",
"recovery_fallback_warning": "Ihr Passkey wurde erfolgreich authentifiziert, aber Ihr Gerät unterstützt keine hardwarebasierte Schlüsselableitung. Geben Sie Ihren 12-Wörter-Wiederherstellungsschlüssel ein, um Ihr Logbuch zu entschlüsseln.",
"recovery_placeholder": "Geben Sie Ihren aus 12 Wörtern bestehenden Wiederherstellungsschlüssel getrennt durch Leerzeichen ein...",
"back": "Zurück",
"decrypting": "Entschlüsselung...",
"decrypt_logbook": "Logbuch entschlüsseln",
"error_incorrect_recovery": "Falscher Wiederherstellungsschlüssel. Entschlüsselung fehlgeschlagen.",
"error_decryption_failed": "Entschlüsselung fehlgeschlagen. Bitte überprüfen Sie Ihren Wiederherstellungsschlüssel.",
"or_register": "oder Registrieren",
"username_placeholder": "Benutzername / Skippername",
"processing": "Verarbeitung...",
"help": "Hilfe"
},
"sync": {
"status_synced": "Synchronisiert",
@@ -54,6 +68,8 @@
"logs": {
"title": "Logbuch-Journal",
"new_entry": "Neuer Reisetag",
"travel_details": "Reisedetails",
"add_event": "Neuen Logbucheintrag hinzufügen",
"date": "Datum",
"day_of_travel": "Tag der Reise / Reisetag",
"departure": "Start-Hafen (Reise von)",
+17 -1
View File
@@ -21,7 +21,21 @@
"recovery_warning": "IMPORTANT: Write down these 12 words. If you lose your Passkey and these words, your data cannot be recovered.",
"confirm_recovery": "I have written down the recovery phrase",
"status_logged_in": "Logged in",
"status_logged_out": "Logged out"
"status_logged_out": "Logged out",
"copied": "Copied!",
"copy_phrase": "Copy Phrase",
"enter_recovery": "Enter Recovery Phrase",
"recovery_fallback_warning": "Your Passkey authenticated successfully, but your device does not support hardware key derivation. Enter your 12-word recovery phrase to decrypt your logbook.",
"recovery_placeholder": "Enter your 12-word recovery phrase separated by spaces...",
"back": "Back",
"decrypting": "Decrypting...",
"decrypt_logbook": "Decrypt Logbook",
"error_incorrect_recovery": "Incorrect recovery phrase. Decryption failed.",
"error_decryption_failed": "Decryption failed. Please check your recovery phrase.",
"or_register": "or register",
"username_placeholder": "Username / Skipper Name",
"processing": "Processing...",
"help": "Help"
},
"sync": {
"status_synced": "Synced",
@@ -54,6 +68,8 @@
"logs": {
"title": "Logbook Journal",
"new_entry": "New Travel Day",
"travel_details": "Travel Details",
"add_event": "Add Event Log Record",
"date": "Date",
"day_of_travel": "Day of Travel",
"departure": "Departure Port (von)",