Poprawka botto bar i wersje językowe

This commit is contained in:
2026-09-25 17:39:44 +02:00
parent 3056eb6c3d
commit a381ad09d8
21 changed files with 770 additions and 428 deletions
+195 -183
View File
@@ -1,5 +1,5 @@
import { endpoints, geoBypassHosts } from "./config.js";
import { t } from "./i18n.js";
import { onLangChange, t } from "./i18n.js";
import { trackEvent } from "./analytics.js";
import {
runPendingProtectedAction,
@@ -20,95 +20,20 @@ import {
setPendingProtectedAction,
} from "./state.js";
// USER PROFILE LOGIC
const userProfileKey = "karczma_user_profile";
const USER_PROFILE_EXPIRE_MS = 180 * 24 * 60 * 60 * 1000; // ~6 months
/** @typedef {'consent'|'gate'|'blocked'|'checking'|'outside'|'https'|'unsupported'|'failed'} GeoUiMode */
export function initUserProfile() {
return; // Funkcja tymczasowo wyłączona
try {
const raw = localStorage.getItem(userProfileKey);
let profile = null;
if (raw) {
profile = JSON.parse(raw);
}
const now = Date.now();
// Check if profile exists and is valid
if (profile) {
if (profile.declined) {
// User declined in the past, don't ask again.
return;
}
// If expired, maybe we want to ask again or we could just keep it if they didn't decline.
// The user said: "trzymamy przez wiele miesięcy (odnawiamy datę przy każdej wizycie)"
if (now - profile.lastVisit > USER_PROFILE_EXPIRE_MS) {
// Profile expired. Ask again.
showNameDialog();
} else {
// Profile valid, renew date and show greeting
profile.lastVisit = now;
localStorage.setItem(userProfileKey, JSON.stringify(profile));
showGreeting(profile.name, profile.firstVisit || profile.lastVisit);
}
} else {
// No profile, ask for name
showNameDialog();
}
} catch (err) {
// If error parsing, ask again
showNameDialog();
}
}
function showNameDialog() {
const modal = document.getElementById("nameModal");
if (modal) {
modal.classList.add("active");
document.body.style.overflow = "hidden";
}
}
function hideNameDialog() {
const modal = document.getElementById("nameModal");
if (modal) {
modal.classList.remove("active");
document.body.style.overflow = "";
}
}
export function saveUserName() {
const input = document.getElementById("userNameInput").value.trim();
if (input) {
const now = Date.now();
const profile = { name: input, firstVisit: now, lastVisit: now, declined: false };
localStorage.setItem(userProfileKey, JSON.stringify(profile));
hideNameDialog();
showGreeting(profile.name, profile.firstVisit);
}
}
export function declineUserName() {
const profile = { name: null, firstVisit: Date.now(), lastVisit: Date.now(), declined: true };
localStorage.setItem(userProfileKey, JSON.stringify(profile));
hideNameDialog();
}
function showGreeting(name, firstVisitTime) {
const banner = document.getElementById("greetingBanner");
if (banner && name) {
const isToday = new Date(firstVisitTime).toDateString() === new Date().toDateString();
if (isToday) {
banner.innerHTML = `Cześć ${name}, życzymy pysznego posiłku!`;
} else {
banner.innerHTML = `Witaj ${name}, super że do nas wracasz!`;
}
banner.style.display = "block";
}
}
const geoUi = {
/** @type {GeoUiMode} */
mode: "consent",
pendingAction: null,
outsideDist: 0,
outsideAccuracy: 0,
actionBusy: false,
/** @type {'locate'|'check'|'retry'|'checking'} */
actionLabel: "locate",
/** @type {'menu_only'|'back_to_menu'} */
secondaryMode: "menu_only",
};
function GEO_GATE_LABELS() {
return {
@@ -118,8 +43,6 @@ function GEO_GATE_LABELS() {
};
}
const GEO_DEFAULT_LEAD = () => t("geo.lead");
function setGeoLead(html) {
const el = document.getElementById("geoLead");
if (el) el.innerHTML = html;
@@ -144,20 +67,6 @@ function hideGeoInstructions() {
showGeoInstructions("");
}
function setGeoActionBusy(busy) {
const btn = document.getElementById("geoActionBtn");
if (!btn) return;
btn.disabled = false;
btn.setAttribute("aria-busy", busy ? "true" : "false");
if (busy) {
setGeoActionLabel(t("geo.btn.checking"));
}
}
function isGeoPermissionDenied(error) {
return Number(error?.code) === 1;
}
function setGeoActionLabel(text) {
const btn = document.getElementById("geoActionBtn");
if (!btn) return;
@@ -166,14 +75,145 @@ function setGeoActionLabel(text) {
else btn.textContent = text;
}
function getGeoPermissionInstructions() {
return t("geo.hint.permission");
function applyGeoActionLabel() {
const keys = {
locate: "geo.btn.locate",
check: "geo.btn.check",
retry: "geo.btn.retry",
checking: "geo.btn.checking",
};
setGeoActionLabel(t(keys[geoUi.actionLabel] || keys.locate));
}
let geoMenuButtonMode = "menu_only";
function setGeoActionBusy(busy) {
const btn = document.getElementById("geoActionBtn");
if (!btn) return;
btn.disabled = false;
btn.setAttribute("aria-busy", busy ? "true" : "false");
geoUi.actionBusy = !!busy;
if (busy) {
geoUi.actionLabel = "checking";
}
applyGeoActionLabel();
}
function applyGeoSecondaryButton() {
const menuOnlyBtn = document.getElementById("geoMenuOnlyBtn");
if (!menuOnlyBtn) return;
const mainEl = menuOnlyBtn.querySelector(".geo-btn-main");
const subEl = menuOnlyBtn.querySelector(".geo-btn-sub");
menuOnlyBtn.style.display = "";
if (geoUi.secondaryMode === "back_to_menu") {
if (mainEl) mainEl.textContent = t("geo.btn.back_menu");
if (subEl) {
subEl.textContent = "";
subEl.style.display = "none";
}
return;
}
if (mainEl) mainEl.textContent = t("geo.btn.menu_main");
if (subEl) {
subEl.textContent = t("geo.btn.menu_sub");
subEl.style.display = "";
}
}
function refreshGeoCopy() {
const secondary =
getAppAccessLevel() === "menu" && geoUi.secondaryMode === "back_to_menu"
? "back_to_menu"
: geoUi.secondaryMode;
geoUi.secondaryMode = secondary;
switch (geoUi.mode) {
case "gate": {
const feature = GEO_GATE_LABELS()[geoUi.pendingAction] || t("geo.feature.other");
setGeoLead(t("geo.lead_action", { feature }));
break;
}
case "blocked":
setGeoLead(t("geo.lead"));
setGeoStatus(t("geo.status.blocked"), { error: true });
showGeoInstructions(t("geo.hint.permission"));
break;
case "checking":
setGeoLead(t("geo.lead"));
setGeoStatus(t("geo.status.checking"), { info: true });
hideGeoInstructions();
break;
case "outside":
setGeoLead(t("geo.lead"));
setGeoStatus(
t("geo.status.outside", {
dist: geoUi.outsideDist,
accuracy: geoUi.outsideAccuracy,
}),
{ error: true }
);
showGeoInstructions(t("geo.hint.outside"));
break;
case "https":
setGeoLead(t("geo.lead"));
setGeoStatus(t("geo.status.https"), { error: true });
showGeoInstructions(t("geo.hint.https"));
break;
case "unsupported":
setGeoLead(t("geo.lead"));
setGeoStatus(t("geo.status.unsupported"), { error: true });
hideGeoInstructions();
break;
case "failed":
setGeoLead(t("geo.lead"));
setGeoStatus(t("geo.status.failed"), { error: true });
showGeoInstructions(t("geo.hint.retry"));
break;
case "consent":
default:
setGeoLead(t("geo.lead"));
break;
}
applyGeoActionLabel();
applyGeoSecondaryButton();
}
onLangChange(() => {
refreshGeoCopy();
});
/* --- Disabled user profile (name modal) — kept for possible re-enable --- */
const userProfileKey = "karczma_user_profile";
const USER_PROFILE_EXPIRE_MS = 180 * 24 * 60 * 60 * 1000;
export function initUserProfile() {
return;
}
export function saveUserName() {
const input = document.getElementById("userNameInput");
if (!input) return;
const name = input.value.trim();
if (!name) return;
const now = Date.now();
localStorage.setItem(
userProfileKey,
JSON.stringify({ name, firstVisit: now, lastVisit: now, declined: false })
);
}
export function declineUserName() {
localStorage.setItem(
userProfileKey,
JSON.stringify({ name: null, firstVisit: Date.now(), lastVisit: Date.now(), declined: true })
);
}
export function handleGeoMenuClick() {
if (geoMenuButtonMode === "back_to_menu") {
if (geoUi.secondaryMode === "back_to_menu") {
document.getElementById("geoScreen")?.classList.add("hidden");
return;
}
@@ -204,49 +244,22 @@ export function bindGeoScreenButtons() {
});
}
function configureGeoSecondaryButton(mode) {
const menuOnlyBtn = document.getElementById("geoMenuOnlyBtn");
if (!menuOnlyBtn) return;
geoMenuButtonMode = mode;
const mainEl = menuOnlyBtn.querySelector(".geo-btn-main");
const subEl = menuOnlyBtn.querySelector(".geo-btn-sub");
if (mode === "back_to_menu") {
menuOnlyBtn.style.display = "";
if (mainEl) mainEl.textContent = t("geo.btn.back_menu");
if (subEl) {
subEl.textContent = "";
subEl.style.display = "none";
}
return;
}
menuOnlyBtn.style.display = "";
if (mainEl) mainEl.textContent = t("geo.btn.menu_main");
if (subEl) {
subEl.textContent = t("geo.btn.menu_sub");
subEl.style.display = "";
}
}
export function showGeoGateForAction(action) {
const geoScreen = document.getElementById("geoScreen");
const loadingScreen = document.getElementById("loadingScreen");
const geoActionBtn = document.getElementById("geoActionBtn");
if (loadingScreen) loadingScreen.classList.add("hidden");
if (geoScreen) geoScreen.classList.remove("hidden");
const feature = GEO_GATE_LABELS()[action] || t("geo.feature.other");
setGeoLead(t("geo.lead_action", { feature }));
geoUi.mode = "gate";
geoUi.pendingAction = action;
geoUi.actionBusy = false;
geoUi.actionLabel = "check";
geoUi.secondaryMode = getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only";
setGeoStatus("");
hideGeoInstructions();
if (geoActionBtn) {
setGeoActionBusy(false);
setGeoActionLabel(t("geo.btn.check"));
}
configureGeoSecondaryButton(getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only");
setGeoActionBusy(false);
refreshGeoCopy();
}
setGeoGateHandler(showGeoGateForAction);
@@ -400,31 +413,33 @@ export function startApp() {
}, 25000);
}
function isGeoPermissionDenied(error) {
return Number(error?.code) === 1;
}
function showGeoConsentScreen() {
const geoScreen = document.getElementById("geoScreen");
const loadingScreen = document.getElementById("loadingScreen");
const geoActionBtn = document.getElementById("geoActionBtn");
loadingScreen.classList.add("hidden");
geoScreen.classList.remove("hidden");
setGeoLead(GEO_DEFAULT_LEAD());
geoUi.mode = "consent";
geoUi.pendingAction = null;
geoUi.actionLabel = "locate";
geoUi.secondaryMode = "menu_only";
setGeoStatus("");
hideGeoInstructions();
if (geoActionBtn) {
setGeoActionBusy(false);
setGeoActionLabel(t("geo.btn.locate"));
}
configureGeoSecondaryButton("menu_only");
setGeoActionBusy(false);
refreshGeoCopy();
}
function showGeoPermissionBlockedState() {
setGeoStatus(t("geo.status.blocked"), { error: true });
showGeoInstructions(getGeoPermissionInstructions());
geoUi.mode = "blocked";
geoUi.actionLabel = "retry";
geoUi.secondaryMode = getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only";
setGeoActionBusy(false);
setGeoActionLabel(t("geo.btn.retry"));
configureGeoSecondaryButton(getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only");
refreshGeoCopy();
}
export function shouldBypassGeolocationHost() {
@@ -517,29 +532,27 @@ export async function initGeolocationAfterBypassChecks(options = {}) {
loadingScreen?.classList.add("hidden");
geoScreen?.classList.remove("hidden");
configureGeoSecondaryButton(getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only");
geoUi.secondaryMode = getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only";
if (!window.isSecureContext) {
setGeoLead(GEO_DEFAULT_LEAD());
setGeoStatus(t("geo.status.https"), { error: true });
showGeoInstructions(t("geo.hint.https"));
geoUi.mode = "https";
geoUi.actionLabel = "retry";
setGeoActionBusy(false);
setGeoActionLabel(t("geo.btn.retry"));
refreshGeoCopy();
return;
}
if (!navigator.geolocation) {
setGeoLead(GEO_DEFAULT_LEAD());
setGeoStatus(t("geo.status.unsupported"), { error: true });
hideGeoInstructions();
geoUi.mode = "unsupported";
geoUi.actionLabel = "retry";
setGeoActionBusy(false);
refreshGeoCopy();
return;
}
setGeoLead(GEO_DEFAULT_LEAD());
setGeoStatus(t("geo.status.checking"), { info: true });
hideGeoInstructions();
geoUi.mode = "checking";
setGeoActionBusy(true);
refreshGeoCopy();
const permissionState = await queryGeolocationPermissionState();
if (permissionState === "denied") {
@@ -573,36 +586,35 @@ export async function initGeolocationAfterBypassChecks(options = {}) {
distanceMeters: Math.round(dist),
accuracyMeters: Math.round(accuracy),
});
geoUi.mode = "outside";
geoUi.outsideDist = Math.round(dist);
geoUi.outsideAccuracy = Math.round(accuracy);
geoUi.actionLabel = "retry";
geoUi.secondaryMode = getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only";
setGeoActionBusy(false);
setGeoActionLabel(t("geo.btn.retry"));
configureGeoSecondaryButton(getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only");
setGeoStatus(
t("geo.status.outside", {
dist: Math.round(dist),
accuracy: Math.round(accuracy),
}),
{ error: true }
);
showGeoInstructions(t("geo.hint.outside"));
refreshGeoCopy();
} catch (error) {
trackEvent("geo_check_failed", {
reason: "browser_error",
code: error.code || null,
message: String(error.message || ""),
});
setGeoActionBusy(false);
setGeoActionLabel(t("geo.btn.retry"));
configureGeoSecondaryButton(getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only");
const deniedBecauseInsecure = /secure origins|only secure|https/i.test(String(error.message || ""));
if (deniedBecauseInsecure) {
setGeoStatus(t("geo.status.https_short"), { error: true });
showGeoInstructions(t("geo.hint.https"));
geoUi.mode = "https";
geoUi.actionLabel = "retry";
geoUi.secondaryMode = getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only";
setGeoActionBusy(false);
refreshGeoCopy();
} else if (isGeoPermissionDenied(error)) {
showGeoPermissionBlockedState();
} else {
setGeoStatus(t("geo.status.failed"), { error: true });
showGeoInstructions(t("geo.hint.retry"));
geoUi.mode = "failed";
geoUi.actionLabel = "retry";
geoUi.secondaryMode = getAppAccessLevel() === "menu" ? "back_to_menu" : "menu_only";
setGeoActionBusy(false);
refreshGeoCopy();
}
}
}