Add function Language
Some checks failed
Test / test (push) Has been cancelled

This commit is contained in:
2026-06-16 16:44:04 +07:00
parent 1156e1ab29
commit a2e87aeb29
11 changed files with 1790 additions and 474 deletions

View File

@@ -24,6 +24,8 @@
let pinDigits = [];
let pinSubmitting = false;
const t = (key, vars) => window.I18n?.t(key, vars) ?? key;
async function apiJson(path, opts = {}) {
const res = await fetch(path, {
credentials: "include",
@@ -82,9 +84,9 @@
} catch (e) {
const msg = String(e.message || "");
if (msg.includes("invalid pin") || msg.includes("401")) {
showError("Mã PIN không hợp lệ. Liên hệ quản trị viên.", "pin");
showError(t("login.error.invalidPin"), "pin");
} else {
showError(msg || "Mã PIN không hợp lệ", "pin");
showError(msg || t("login.error.invalidPinShort"), "pin");
}
resetPin();
setLoginLoading(false);
@@ -110,7 +112,7 @@
function setLoginLoading(loading) {
loginScreenEl?.classList.toggle("is-loading", loading);
document.querySelectorAll(".loginSubmitLabel").forEach((label) => {
label.textContent = loading ? "Đang đăng nhập…" : "Đăng nhập";
label.textContent = loading ? t("login.submitting") : t("login.submit");
});
}
@@ -153,12 +155,9 @@
}
function applyNavPermissions() {
document.querySelectorAll(".navItem[data-page]").forEach((a) => {
const page = a.dataset.page || "";
const allowed = canAccessPage(page);
a.hidden = !allowed;
a.style.display = allowed ? "" : "none";
});
if (window.NavApp?.applyPermissions) {
window.NavApp.applyPermissions();
}
document.body.classList.toggle("auth-readonly-config", !canWrite("config"));
document.body.classList.toggle("auth-readonly-missions", !canWrite("missions"));
document.body.classList.toggle("auth-readonly-integrations", !canWrite("integrations"));
@@ -263,7 +262,7 @@
async function saveProfile() {
const display_name = el("mirProfileDisplayName")?.value?.trim() || "";
if (!display_name) throw new Error("Tên hiển thị không được trống");
if (!display_name) throw new Error(t("auth.profile.displayNameRequired"));
const data = await apiJson("/api/auth/profile", {
method: "PUT",
body: JSON.stringify({ display_name }),
@@ -287,7 +286,7 @@
const username = el("loginUsername")?.value?.trim() || "";
const password = el("loginPasswordInput")?.value || "";
if (!username || !password) {
showError("Nhập tên đăng nhập và mật khẩu", "password");
showError(t("login.error.missingCredentials"), "password");
return;
}
setLoginLoading(true);
@@ -297,11 +296,11 @@
} catch (e) {
const msg = String(e.message || "");
if (msg.includes("credentials") || msg.includes("401")) {
showError("Sai tên đăng nhập hoặc mật khẩu. Thử Admin / admin", "password");
showError(t("login.error.badCredentials"), "password");
} else if (msg.includes("fetch") || msg.includes("Failed")) {
showError("Không kết nối được server. Kiểm tra http://localhost:8080", "password");
showError(t("login.error.serverUnreachable"), "password");
} else {
showError(msg || "Đăng nhập thất bại", "password");
showError(msg || t("login.error.failed"), "password");
}
setLoginLoading(false);
}
@@ -347,7 +346,7 @@
await saveProfile();
userMenuPanelEl?.setAttribute("hidden", "");
} catch (e) {
alert(e.message || "Lưu thông tin thất bại");
alert(e.message || t("auth.profile.saveFailed"));
}
});
@@ -357,7 +356,7 @@
const next = el("changePasswordNew")?.value || "";
const confirm = el("changePasswordConfirm")?.value || "";
if (next !== confirm) {
if (changePasswordErrorEl) changePasswordErrorEl.textContent = "Mật khẩu mới không khớp";
if (changePasswordErrorEl) changePasswordErrorEl.textContent = t("auth.changePassword.mismatch");
return;
}
try {
@@ -368,7 +367,7 @@
changePasswordDialogEl?.close();
changePasswordFormEl.reset();
} catch (e) {
if (changePasswordErrorEl) changePasswordErrorEl.textContent = e.message || "Đổi mật khẩu thất bại";
if (changePasswordErrorEl) changePasswordErrorEl.textContent = e.message || t("auth.changePassword.failed");
}
});
}
@@ -386,6 +385,10 @@
};
bindEvents();
window.addEventListener("lm:locale-change", () => {
const loading = loginScreenEl?.classList.contains("is-loading");
setLoginLoading(loading);
});
setLoginMode("password");
shellEl?.classList.add("auth-locked");
if (window.location.search) {