Zmiana aplikacji na wersje lang

This commit is contained in:
2026-09-25 16:59:37 +02:00
parent 9d25de0d89
commit 3056eb6c3d
24 changed files with 1308 additions and 1105 deletions
+43 -29
View File
@@ -1,4 +1,5 @@
import { endpoints, loaderMinMs } from "./config.js";
import { getLang, t } from "./i18n.js";
import { runPendingProtectedAction, updateNavAccessState } from "./access.js";
import {
refreshGuestPendingActions,
@@ -30,17 +31,29 @@ const SIX_MONTHS_MS = 180 * 24 * 60 * 60 * 1000;
const LOADER_MIN_MS = loaderMinMs;
const loadStartTime = Date.now();
const msgs = ["Rozgrzewamy piece...", "Szef kuchni sprawdza składniki...", "Łączenie z sercem restauracji...", "Prawie gotowe..."];
function getLoaderMsgs() {
return [t("loader.msg1"), t("loader.msg2"), t("loader.msg3"), t("loader.msg4")];
}
let msgIdx = 0;
const msgInterval = setInterval(() => {
const msgs = getLoaderMsgs();
msgIdx = (msgIdx + 1) % msgs.length;
if (loaderMsg) loaderMsg.textContent = msgs[msgIdx];
}, 4000);
function formatTableLabel(name) {
const raw = String(name || "").trim();
if (!raw) return t("table.label", { name: "" }).trim();
if (raw.toUpperCase().startsWith("STOLIK") || raw.toUpperCase().startsWith("TABLE") || raw.toUpperCase().startsWith("TISCH")) {
return raw;
}
return t("table.label", { name: raw });
}
// Initial State
if (getTableParam()) {
const tableParam = getTableParam();
tableLabel.textContent = tableParam.toUpperCase().startsWith("STOLIK") ? tableParam : `Stolik ${tableParam}`;
tableLabel.textContent = formatTableLabel(getTableParam());
}
/** Storage key must follow current hash (fallback: table), not a frozen empty tableParam at init. */
@@ -73,9 +86,7 @@ export async function resolveTableLabel() {
const response = await fetch(`${endpoints.kds}?h=${encodeURIComponent(hashParam)}`);
const result = await response.json();
if (result.status === "success" && result.tableName && result.tableName !== "") {
tableLabel.textContent = result.tableName.toUpperCase().startsWith("STOLIK")
? result.tableName
: `Stolik ${result.tableName}`;
tableLabel.textContent = formatTableLabel(result.tableName);
setTableParam(result.tableName);
}
} catch {
@@ -106,16 +117,16 @@ function showEmptyState() {
emptyState.classList.remove("hidden");
itemsList.innerHTML = "";
prepStatus.textContent = "Brak aktywnych zamówień";
prepStatus.textContent = t("status.none");
statusIcon.textContent = "🍃";
progressBar.style.width = "0%";
statusMeta.textContent = "Zapraszamy do sprawdzenia naszego menu.";
statusMeta.textContent = t("status.none_meta");
// Historia może istnieć nawet gdy brak bieżących pozycji
renderGlobalHistory();
}
function normalizeArticleName(rawName) {
const name = String(rawName || "Pozycja");
const name = String(rawName || t("orders.item_fallback"));
// Usuwa gramatury typu: "300G", "250 G", "500/200/150G".
const withoutWeight = name.replace(
@@ -126,7 +137,7 @@ function normalizeArticleName(rawName) {
return withoutWeight
.replace(/\s{2,}/g, " ")
.replace(/\s+([,.;:!?])/g, "$1")
.trim() || "Pozycja";
.trim() || t("orders.item_fallback");
}
function loadPersistedItems() {
@@ -202,6 +213,7 @@ function addItemsToGlobalHistory(items, sourceTable) {
export function renderGlobalHistory() {
const now = Date.now();
const lang = getLang();
const history = loadGlobalHistory()
.filter((e) => now - (e.archivedAt || 0) <= SIX_MONTHS_MS)
.sort((a, b) => (b.archivedAt || 0) - (a.archivedAt || 0));
@@ -224,7 +236,11 @@ export function renderGlobalHistory() {
div.innerHTML = `
<div class="item-info">
<span class="item-name">${entry.name}</span>
<span class="item-meta">Stolik ${entry.sourceTable || "?"} • ${dt.toLocaleDateString("pl-PL")} ${dt.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</span>
<span class="item-meta">${t("history.entry_meta", {
table: formatTableLabel(entry.sourceTable || "?"),
date: dt.toLocaleDateString(lang),
time: dt.toLocaleTimeString(lang, { hour: "2-digit", minute: "2-digit" }),
})}</span>
</div>
<div class="item-qty">x${entry.qty}</div>
`;
@@ -234,7 +250,7 @@ export function renderGlobalHistory() {
export function clearGlobalHistory(e) {
if (e) e.preventDefault();
if (confirm("Czy na pewno chcesz usunąć historię swoich poprzednich zamówień?")) {
if (confirm(t("history.clear_confirm"))) {
localStorage.removeItem(historyKey);
renderGlobalHistory();
}
@@ -282,7 +298,7 @@ function mergeWithPersistedItems(articles) {
// Aktywne na górze, gotowe (zniknięte) na dole
merged.sort((a, b) => {
if (a.present !== b.present) return a.present ? -1 : 1;
return a.name.localeCompare(b.name, "pl");
return a.name.localeCompare(b.name, getLang());
});
savePersistedItems(merged);
@@ -301,11 +317,11 @@ function renderItems(items) {
const div = document.createElement("div");
div.className = `item-card ${isReady ? "ready" : ""} ${item.present ? "" : "archived"}`;
let meta = "🔥 W przygotowaniu";
let meta = t("orders.item_preparing");
if (isReady && item.completedByDisappear) {
meta = "✅ Gotowe (zrealizowane)";
meta = t("orders.item_ready_done");
} else if (isReady) {
meta = "✅ Gotowe";
meta = t("orders.item_ready");
}
div.innerHTML = `
@@ -333,29 +349,29 @@ function updateStatus(bills, items) {
progressBar.style.width = `${pct}%`;
if (pct >= 100) {
prepStatus.textContent = "Gotowe do podania!";
prepStatus.textContent = t("status.ready");
statusIcon.innerHTML = "😋";
statusMeta.textContent = "Wszystkie Twoje dania opuściły już kuchnię.";
statusMeta.textContent = t("status.ready_meta");
} else if (pct > 0) {
prepStatus.textContent = "Częściowo gotowe";
prepStatus.textContent = t("status.partial");
statusIcon.innerHTML = "🍳";
statusMeta.textContent = "Pierwsze pyszności już na Ciebie czekają!";
statusMeta.textContent = t("status.partial_meta");
} else {
prepStatus.textContent = "W przygotowaniu";
prepStatus.textContent = t("status.preparing");
if (!window.selectedAnimationHtml) {
window.selectedAnimationHtml =
window.kitchenAnimations[Math.floor(Math.random() * window.kitchenAnimations.length)];
}
statusIcon.innerHTML = window.selectedAnimationHtml;
statusMeta.textContent = "Twoje zamówienie jest właśnie tworzone przez naszych kucharzy.";
statusMeta.textContent = t("status.preparing_meta");
}
// Footer meta
const newest = [...bills].sort((a, b) => new Date(b?.Date || 0) - new Date(a?.Date || 0))[0];
const time = newest?.Date
? new Date(newest.Date).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
? new Date(newest.Date).toLocaleTimeString(getLang(), { hour: "2-digit", minute: "2-digit" })
: "--:--";
metaFooter.textContent = `Zamówienie złożone o godzinie ${time} • Stolik ${getTableParam()}`;
metaFooter.textContent = t("status.footer", { time, table: getTableParam() });
}
export async function fetchOrders() {
@@ -371,9 +387,7 @@ export async function fetchOrders() {
if (result.status === "success") {
if (result.tableName && result.tableName !== "") {
tableLabel.textContent = result.tableName.toUpperCase().startsWith("STOLIK")
? result.tableName
: `Stolik ${result.tableName}`;
tableLabel.textContent = formatTableLabel(result.tableName);
setTableParam(result.tableName); // Aktualizacja do właściwej nazwy na poczet innych zapytań
refreshGuestPendingActions();
startGuestPendingPoll();
@@ -419,9 +433,9 @@ export async function fetchOrders() {
},
]);
} else {
loaderMsg.textContent = "Błąd API: " + result.message;
loaderMsg.textContent = t("loader.api_error", { message: result.message });
}
} catch (err) {
loaderMsg.textContent = "Problem z połączeniem. Próbujemy ponownie...";
loaderMsg.textContent = t("loader.connection");
}
}