Multilanguage: Deutsch / English, umschaltbar in Einstellungen

- i18n.js: Übersetzungsmodul mit t(), setLang(), applyLang() + vollst. DE/EN Wörterbuch
- Backend: language-Feld in UserSettings, Migration, Settings-API
- calendar.js: alle deutschen Strings auf t()-Aufrufe umgestellt, setLang() beim Start
- app.js, api.js, color-picker.js, views/*.js: alle UI-Strings übersetzt
- Sprach-Dropdown in Einstellungen > Darstellung, data-i18n-Attribute in index.html
This commit is contained in:
2026-03-27 15:15:07 +01:00
parent e4a14e6927
commit cd5d866cb1
12 changed files with 544 additions and 129 deletions

View File

@@ -58,6 +58,11 @@ def _migrate():
conn.commit()
except Exception:
pass
try:
conn.execute(text("ALTER TABLE user_settings ADD COLUMN language VARCHAR(5) DEFAULT 'de'"))
conn.commit()
except Exception:
pass
_migrate()

View File

@@ -78,6 +78,7 @@ class UserSettings(Base):
text_contrast = Column(Integer, default=3)
line_contrast = Column(Integer, default=3)
hour_height = Column(Integer, default=60)
language = Column(String(5), default="de")
user = relationship("User", back_populates="settings")

View File

@@ -21,6 +21,7 @@ class SettingsUpdate(BaseModel):
text_contrast: Optional[int] = None
line_contrast: Optional[int] = None
hour_height: Optional[int] = None
language: Optional[str] = None
def _settings_dict(s: models.UserSettings) -> dict:
@@ -34,6 +35,7 @@ def _settings_dict(s: models.UserSettings) -> dict:
"text_contrast": s.text_contrast or 3,
"line_contrast": s.line_contrast or 3,
"hour_height": s.hour_height or 60,
"language": s.language or "de",
}