feat(frontend): Light-i18n + Org-Sprache durch /auth/me

Backend:
- UserMeResponse um output_language (de | en) erweitert.
- /auth/me liefert die Org-Sprache aus organization_settings.

Frontend:
- Neu: static/js/i18n.js mit T(key)-Helper, I18N.load(lang) und
  applyDom() ueber data-i18n + data-i18n-attr.
- Neu: static/i18n/de.json + en.json (sichtbare Bereiche: Sidebar,
  Header, Modal-Titel, Faktencheck-Status, Refresh-Hinweise).
- dashboard.html: i18n.js Script-Tag vor api.js, data-i18n auf den
  prominenten Strings (Abmelden, + Neuer Fall, Alle/Eigene, Sidebar-
  Sektionen, Bericht exportieren, Faktencheck-Tab, Lage anlegen).
  Tutorial.init() entfernt aus DOMContentLoaded.
- components.js: factCheckLabels/Tooltips/ChipLabels als Getter ueber
  T() mit DE-Fallbacks.
- app.js: vor Setup wird I18N.load(user.output_language) aufgerufen und
  applyDom() ausgefuehrt. Tutorial.init() laeuft nur bei lang === de.

Phase 6 von 8 (eng_demo / Org-Sprache).
Dieser Commit ist enthalten in:
Claude Code
2026-05-13 21:14:56 +00:00
Ursprung 4e51834163
Commit 3f0e680446
8 geänderte Dateien mit 271 neuen und 17 gelöschten Zeilen

Datei anzeigen

@@ -76,7 +76,10 @@ const UI = {
/**
* Faktencheck-Eintrag rendern.
*/
factCheckLabels: {
// Faktencheck-Status-Labels (org-sprach-relativ via T()).
// Die DE-Fallbacks sind die historische Quelle der Wahrheit; bei
// englischer Org liefert T() den EN-Text aus i18n/en.json.
_fcLabelDefaultsDE: {
confirmed: 'Bestätigt durch mehrere Quellen',
unconfirmed: 'Nicht unabhängig bestätigt',
contradicted: 'Widerlegt',
@@ -85,8 +88,7 @@ const UI = {
disputed: 'Umstrittener Sachverhalt',
unverified: 'Nicht unabhängig verifizierbar',
},
factCheckTooltips: {
_fcTooltipDefaultsDE: {
confirmed: 'Bestätigt: Mindestens zwei unabhängige, seriöse Quellen stützen diese Aussage übereinstimmend.',
established: 'Gesichert: Drei oder mehr unabhängige Quellen bestätigen den Sachverhalt. Hohe Verlässlichkeit.',
developing: 'Unklar: Die Faktenlage ist noch im Fluss. Neue Informationen können das Bild verändern.',
@@ -95,8 +97,7 @@ const UI = {
disputed: 'Umstritten: Quellen widersprechen sich. Es gibt sowohl stützende als auch widersprechende Belege.',
contradicted: 'Widerlegt: Zuverlässige Quellen widersprechen dieser Aussage. Wahrscheinlich falsch.',
},
factCheckChipLabels: {
_fcChipDefaultsDE: {
confirmed: 'Bestätigt',
unconfirmed: 'Unbestätigt',
contradicted: 'Widerlegt',
@@ -106,6 +107,34 @@ const UI = {
unverified: 'Ungeprüft',
},
get factCheckLabels() {
const out = {};
for (const k of Object.keys(this._fcLabelDefaultsDE)) {
out[k] = (typeof T === 'function')
? T('fc.label.' + k, this._fcLabelDefaultsDE[k])
: this._fcLabelDefaultsDE[k];
}
return out;
},
get factCheckTooltips() {
const out = {};
for (const k of Object.keys(this._fcTooltipDefaultsDE)) {
out[k] = (typeof T === 'function')
? T('fc.tooltip.' + k, this._fcTooltipDefaultsDE[k])
: this._fcTooltipDefaultsDE[k];
}
return out;
},
get factCheckChipLabels() {
const out = {};
for (const k of Object.keys(this._fcChipDefaultsDE)) {
out[k] = (typeof T === 'function')
? T('fc.chip.' + k, this._fcChipDefaultsDE[k])
: this._fcChipDefaultsDE[k];
}
return out;
},
factCheckIcons: {
confirmed: '✓',
unconfirmed: '?',