Files
karczma-aplikacja-stoliki/public/assets/js/modules/analytics.js
T

94 lines
2.4 KiB
JavaScript

import { endpoints } from "./config.js";
import {
getAnalyticsSessionId,
getHashParam,
getIsStaffPreview,
getTableParam,
setAnalyticsSessionId,
} from "./state.js";
const analyticsSessionKey = "karczma_analytics_session_id";
function getOrCreateAnalyticsSessionId() {
let existing = localStorage.getItem(analyticsSessionKey);
if (existing) return existing;
let newId = "";
if (window.crypto && crypto.randomUUID) {
newId = crypto.randomUUID();
} else {
newId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
}
localStorage.setItem(analyticsSessionKey, newId);
return newId;
}
setAnalyticsSessionId(getOrCreateAnalyticsSessionId());
function detectDeviceType() {
const ua = navigator.userAgent || "";
if (/iPad|iPhone|iPod/.test(ua) || (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)) return "ios";
if (/Android/i.test(ua)) return "android";
return "other";
}
function detectBrowser() {
const ua = navigator.userAgent || "";
if (/Edg\//.test(ua)) return "edge";
if (/OPR\//.test(ua)) return "opera";
if (/Chrome\//.test(ua)) return "chrome";
if (/Safari\//.test(ua)) return "safari";
if (/Firefox\//.test(ua)) return "firefox";
return "other";
}
function deriveZoneFromTable(tableValue) {
const raw = String(tableValue || "").trim().toLowerCase();
if (!raw) return null;
if (raw.startsWith("t") || raw.includes("taras")) return "taras";
if (raw.startsWith("k") || raw.includes("karczma")) return "karczma";
return null;
}
export function trackEvent(eventName, payload = {}) {
if (getIsStaffPreview()) {
return;
}
const tableParam = getTableParam();
const hashParam = getHashParam();
const body = {
eventName,
sessionId: getAnalyticsSessionId(),
tableId: tableParam || null,
zone: deriveZoneFromTable(tableParam),
qrHash: hashParam || null,
deviceType: detectDeviceType(),
browser: detectBrowser(),
payload
};
const bodyString = JSON.stringify(body);
try {
if (navigator.sendBeacon) {
const blob = new Blob([bodyString], { type: "application/json" });
navigator.sendBeacon(endpoints.analytics, blob);
return;
}
} catch {
// fallback to fetch below
}
fetch(endpoints.analytics, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: bodyString,
keepalive: true
}).catch(() => {
// best effort - ignore analytics errors
});
}