feat: implement internationalization for duty calendar
All checks were successful
CI / lint-and-test (push) Successful in 14s

- Introduced a new `i18n.js` module for handling translations and language detection, supporting both Russian and English.
- Updated various components to utilize the new translation functions, enhancing user experience by providing localized messages for errors, hints, and UI elements.
- Refactored existing code in `api.js`, `calendar.js`, `dutyList.js`, `hints.js`, and `ui.js` to replace hardcoded strings with translated messages, improving maintainability and accessibility.
- Enhanced the initialization process in `main.js` to set the document language and update UI elements based on the user's language preference.
This commit is contained in:
2026-02-19 16:00:00 +03:00
parent a5f7a5a0ef
commit 4c2d95e776
9 changed files with 262 additions and 51 deletions

View File

@@ -3,6 +3,7 @@
*/
import { initTheme, applyTheme } from "./theme.js";
import { getLang, t, weekdayLabels } from "./i18n.js";
import { getInitData } from "./auth.js";
import { isLocalhost } from "./auth.js";
import { RETRY_DELAY_MS, RETRY_AFTER_ACCESS_DENIED_MS } from "./constants.js";
@@ -12,7 +13,8 @@ import {
prevBtn,
nextBtn,
loadingEl,
errorEl
errorEl,
weekdaysEl
} from "./dom.js";
import { showAccessDenied, hideAccessDenied, showError, setNavEnabled } from "./ui.js";
import { fetchDuties, fetchCalendarEvents } from "./api.js";
@@ -32,6 +34,20 @@ import {
initTheme();
state.lang = getLang();
document.documentElement.lang = state.lang;
document.title = t(state.lang, "app.title");
if (loadingEl) loadingEl.textContent = t(state.lang, "loading");
const dayLabels = weekdayLabels(state.lang);
if (weekdaysEl) {
const spans = weekdaysEl.querySelectorAll("span");
spans.forEach((span, i) => {
if (dayLabels[i]) span.textContent = dayLabels[i];
});
}
if (prevBtn) prevBtn.setAttribute("aria-label", t(state.lang, "nav.prev_month"));
if (nextBtn) nextBtn.setAttribute("aria-label", t(state.lang, "nav.next_month"));
/**
* Run callback when Telegram WebApp is ready (or immediately outside Telegram).
* Expands and applies theme when in TWA.
@@ -79,12 +95,12 @@ function requireTelegramOrLocalhost(onAllowed) {
onAllowed();
return;
}
showAccessDenied();
showAccessDenied(undefined);
if (loadingEl) loadingEl.classList.add("hidden");
}, RETRY_DELAY_MS);
return;
}
showAccessDenied();
showAccessDenied(undefined);
if (loadingEl) loadingEl.classList.add("hidden");
}
@@ -151,7 +167,7 @@ async function loadMonth() {
}
return;
}
showError(e.message || "Не удалось загрузить данные.");
showError(e.message || t(state.lang, "error_generic"));
setNavEnabled(true);
return;
}