Poprawka botto bar i wersje językowe
This commit is contained in:
+195
-183
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user