feat: i18n system - French/English internationalization
Core: i18n.js module with t(), setLocale(), initI18n() - Flat key→string JSON locale files (fr.json + en.json, 165 keys) - data-i18n / data-i18n-placeholder / data-i18n-attr DOM attributes - Live locale switch via setLocale() - no page reload - Language detection: localStorage > navigator.language > 'fr' - Fallback: missing key → French → raw key Wired into: - app.js: await initI18n() early in init() - config.js: profile save → await setLocale(), toasts + confirm via t() - auth.js: network error toast via t() - index.html: data-i18n on login form, profile section, search placeholder
This commit is contained in:
+16
-15
@@ -184,11 +184,11 @@
|
||||
<span class="login-logo-icon">📖</span>
|
||||
<span class="login-logo-text">ObsiGate</span>
|
||||
</div>
|
||||
<p class="login-subtitle">Accès sécurisé à vos vaults</p>
|
||||
<p class="login-subtitle" data-i18n="auth.login_title">Accès sécurisé à vos vaults</p>
|
||||
</div>
|
||||
<form id="login-form" class="login-form" autocomplete="on">
|
||||
<div class="form-group">
|
||||
<label for="login-username">Nom d'utilisateur</label>
|
||||
<label for="login-username" data-i18n="auth.username">Nom d'utilisateur</label>
|
||||
<input
|
||||
type="text"
|
||||
id="login-username"
|
||||
@@ -200,7 +200,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="login-password">Mot de passe</label>
|
||||
<label for="login-password" data-i18n="auth.password">Mot de passe</label>
|
||||
<div class="password-input-wrapper">
|
||||
<input
|
||||
type="password"
|
||||
@@ -227,12 +227,12 @@
|
||||
id="remember-me"
|
||||
name="remember_me"
|
||||
/>
|
||||
<span>Se souvenir de moi (30 jours)</span>
|
||||
<span data-i18n="auth.remember_me">Se souvenir de moi (30 jours)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="login-error" class="login-error hidden"></div>
|
||||
<button type="submit" id="login-btn" class="btn-login">
|
||||
<span class="btn-text">Se connecter</span>
|
||||
<span class="btn-text" data-i18n="auth.login_button">Se connecter</span>
|
||||
<span class="btn-spinner hidden">⏳</span>
|
||||
</button>
|
||||
</form>
|
||||
@@ -290,6 +290,7 @@
|
||||
<input
|
||||
type="text"
|
||||
id="search-input"
|
||||
data-i18n-placeholder="header.search_placeholder"
|
||||
placeholder="Rechercher ..."
|
||||
autocomplete="off"
|
||||
/>
|
||||
@@ -2021,29 +2022,29 @@
|
||||
class="config-section help-section"
|
||||
id="cfg-profile"
|
||||
>
|
||||
<h2>👤 Profil utilisateur</h2>
|
||||
<p class="config-description">
|
||||
Preferences personnelles pour personnaliser
|
||||
l'experience ObsiGate.
|
||||
<h2 data-i18n="config.profile">👤 Profil utilisateur</h2>
|
||||
<p class="config-description" data-i18n="config.profile_desc">
|
||||
Préférences personnelles pour personnaliser
|
||||
l'expérience ObsiGate.
|
||||
</p>
|
||||
<div class="profile-form" id="profile-form">
|
||||
<div class="profile-field">
|
||||
<label for="profile-lang">Langue preferee</label>
|
||||
<label for="profile-lang" data-i18n="config.lang_label">Langue préférée</label>
|
||||
<select id="profile-lang" class="config-select">
|
||||
<option value="fr">Francais</option>
|
||||
<option value="en">English</option>
|
||||
<option value="es">Espanol</option>
|
||||
<option value="de">Deutsch</option>
|
||||
</select>
|
||||
<span class="profile-hint">Utilisee par l'autocompletion et le ghost text.</span>
|
||||
<span class="profile-hint" data-i18n="config.lang_hint">Utilisée par l'autocomplétion et le ghost text.</span>
|
||||
</div>
|
||||
<div class="profile-field">
|
||||
<label for="profile-name">Nom d'affichage</label>
|
||||
<label for="profile-name" data-i18n="config.display_name">Nom d'affichage</label>
|
||||
<input type="text" id="profile-name" class="config-input" placeholder="Votre nom" maxlength="60">
|
||||
</div>
|
||||
<button class="config-save-btn" id="profile-save">Enregistrer</button>
|
||||
<button class="config-save-btn" id="profile-logout" style="background:var(--danger-bg);color:var(--danger);border-color:var(--danger);margin-left:8px">Deconnexion</button>
|
||||
<span class="profile-saved" id="profile-saved" style="display:none">✓ Sauvegarde</span>
|
||||
<button class="config-save-btn" id="profile-save" data-i18n="config.save">Enregistrer</button>
|
||||
<button class="config-save-btn" id="profile-logout" style="background:var(--danger-bg);color:var(--danger);border-color:var(--danger);margin-left:8px" data-i18n="config.logout">Déconnexion</button>
|
||||
<span class="profile-saved" id="profile-saved" style="display:none" data-i18n="config.saved">✓ Sauvegardé</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user