+
+
+ `;
+
+ //Todas las comandas
+ TS_IndexElement(
+ "supercafe",
+ [
+ {
+ key: "Persona",
+ type: "persona",
+ default: "",
+ label: "Persona",
+ },
+ {
+ key: "Estado",
+ type: "comanda-status",
+ default: "",
+ label: "Estado",
+ },
+ {
+ key: "Comanda",
+ type: "comanda",
+ default: "",
+ label: "Comanda",
+ },
+ ],
+ gun.get(TABLE).get("supercafe"),
+ document.querySelector("#cont1"),
+ (data, new_tr) => {
+ // new_tr.style.backgroundColor = "#FFCCCB";
+
+ if (data.Estado == "Pedido") {
+ new_tr.style.backgroundColor = "#FFFFFF";
+ }
+ if (data.Estado == "En preparación") {
+ new_tr.style.backgroundColor = "#FFCCCB";
+ }
+ if (data.Estado == "Listo") {
+ new_tr.style.backgroundColor = "gold";
+ }
+ if (data.Estado == "Entregado") {
+ new_tr.style.backgroundColor = "lightgreen";
+ }
+ if (data.Estado == "Deuda") {
+ new_tr.style.backgroundColor = "#f5d3ff";
+ }
+ },
+ (data) => {
+ if (data.Estado == "Deuda") {
+ return true;
+ }
+ var key = data._key;
+ if (old[key] == undefined) {
+ old[key] = "";
+ }
+ if (old[key] != data.Estado) {
+ if (tts && document.getElementById(tts_check).checked) {
+ var msg = `Comanda de ${SC_Personas[data.Persona].Region}. - ${
+ JSON.parse(data.Comanda)["Selección"]
+ }. - ${SC_Personas[data.Persona].Nombre}. - ${data.Estado}`;
+ console.log("TTS: " + msg);
+ let utterance = new SpeechSynthesisUtterance(msg);
+ utterance.rate = 0.9;
+ // utterance.voice = speechSynthesis.getVoices()[7]
+ speechSynthesis.speak(utterance);
+ }
+ }
+ old[key] = data.Estado;
+ }
+ );
+
+ //Deudas
+ TS_IndexElement(
+ "supercafe",
+ [
+ {
+ key: "Persona",
+ type: "persona",
+ default: "",
+ label: "Persona",
+ },
+ {
+ key: "Estado",
+ type: "comanda-status",
+ default: "",
+ label: "Estado",
+ },
+ {
+ key: "Comanda",
+ type: "comanda",
+ default: "",
+ label: "Comanda",
+ },
+ ],
+ gun.get(TABLE).get("supercafe"),
+ document.querySelector("#cont2"),
+ (data, new_tr) => {
+ // new_tr.style.backgroundColor = "#FFCCCB";
+
+ if (data.Estado == "Pedido") {
+ new_tr.style.backgroundColor = "#FFFFFF";
+ }
+ if (data.Estado == "En preparación") {
+ new_tr.style.backgroundColor = "#FFCCCB";
+ }
+ if (data.Estado == "Listo") {
+ new_tr.style.backgroundColor = "gold";
+ }
+ if (data.Estado == "Entregado") {
+ new_tr.style.backgroundColor = "lightgreen";
+ }
+ if (data.Estado == "Deuda") {
+ new_tr.style.backgroundColor = "#f5d3ff";
+ }
+ },
+ (data) => {
+ if (data.Estado != "Deuda") {
+ return true;
+ }
+ var key = data._key;
+ if (old[key] == undefined) {
+ old[key] = "";
+ }
+ if (old[key] != data.Estado) {
+ if (tts && document.getElementById(tts_check).checked) {
+ var msg = `Comanda de ${SC_Personas[data.Persona].Region}. - ${
+ JSON.parse(data.Comanda)["Selección"]
+ }. - ${SC_Personas[data.Persona].Nombre}. - ${data.Estado}`;
+ console.log("TTS: " + msg);
+ let utterance = new SpeechSynthesisUtterance(msg);
+ utterance.rate = 0.9;
+ // utterance.voice = speechSynthesis.getVoices()[7]
+ speechSynthesis.speak(utterance);
+ }
+ }
+ old[key] = data.Estado;
+ }
+ );
+
+ document.getElementById(btn_new).onclick = () => {
+ setUrlHash("supercafe," + safeuuid(""));
+ };
+ },
+ }
\ No newline at end of file
diff --git a/dist/pwa.js b/dist/pwa.js
new file mode 100644
index 0000000..6a97603
--- /dev/null
+++ b/dist/pwa.js
@@ -0,0 +1,43 @@
+let newWorker;
+
+function showUpdateBar() {
+ let snackbar = document.getElementById("snackbar");
+ snackbar.className = "show";
+}
+
+// The click event on the pop up notification
+document.getElementById("reload").addEventListener("click", function () {
+ setTimeout(() => {
+ removeCache();
+ }, 1000);
+ newWorker.postMessage({ action: "skipWaiting" });
+});
+
+if ("serviceWorker" in navigator) {
+ navigator.serviceWorker.register("/sw.js").then((reg) => {
+ reg.addEventListener("updatefound", () => {
+ // A wild service worker has appeared in reg.installing!
+ newWorker = reg.installing;
+
+ newWorker.addEventListener("statechange", () => {
+ // Has network.state changed?
+ switch (newWorker.state) {
+ case "installed":
+ if (navigator.serviceWorker.controller) {
+ // new update available
+ showUpdateBar();
+ }
+ // No update available
+ break;
+ }
+ });
+ });
+ });
+
+ let refreshing;
+ navigator.serviceWorker.addEventListener("controllerchange", function () {
+ if (refreshing) return;
+ window.location.reload();
+ refreshing = true;
+ });
+}
diff --git a/src/app_logic.js b/src/app_logic.js
new file mode 100644
index 0000000..39b692f
--- /dev/null
+++ b/src/app_logic.js
@@ -0,0 +1,160 @@
+function tableScroll(query) {
+ $(query).doubleScroll();
+}
+//var secretTokenEl = document.getElementById("secretToken");
+var groupIdEl = document.getElementById("groupId");
+var container = document.getElementById("container");
+function LinkAccount(LinkAccount_group, LinkAccount_secret, refresh = false) {
+ GROUPID = LinkAccount_group.toUpperCase();
+ SECRET = LinkAccount_secret.toUpperCase();
+
+ localStorage.setItem("TELESEC_AUTO", "YES");
+ localStorage.setItem("TELESEC_groupid", GROUPID);
+ localStorage.setItem("TELESEC_secret", SECRET);
+
+ TABLE = GROUPID + ":telesec.tech.eus";
+ //secretTokenEl.innerText = SECRET;
+ groupIdEl.innerText = GROUPID;
+ document.getElementById("LinkAccount_details").open = false;
+ if (refresh == true) {
+ location.reload();
+ }
+}
+if (localStorage.getItem("TELESEC_AUTO") == "YES") {
+ LinkAccount(
+ localStorage.getItem("TELESEC_groupid"),
+ localStorage.getItem("TELESEC_secret")
+ );
+}
+if (urlParams.get("login") != null) {
+ LinkAccount(
+ urlParams.get("login").split(":")[0],
+ urlParams.get("login").split(":")[1]
+ );
+ //location.search = "";
+}
+function open_page(params) {
+ if (params == "") {
+ params = "index";
+ }
+ var path = params.split(",");
+ var app = path[0];
+ if (path[1] == undefined) {
+ PAGES[app].index();
+ return;
+ }
+ PAGES[app].edit(path[1]);
+}
+function setUrlHash(hash) {
+ location.hash = "#" + hash;
+}
+window.onhashchange = () => {
+ try {
+ if (EVENTLISTENER != null) {
+ try {
+ EVENTLISTENER.off();
+ EVENTLISTENER = null;
+ EVENTLISTENER2.off();
+ EVENTLISTENER2 = null;
+ // TypeError: Cannot read properties of null (reading 'off')
+ } catch (error) {
+ if (!error.name == "TypeError") {
+ console.debug("EVENTLISTENER error", error);
+ }
+ }
+ }
+ } catch (e) {
+ console.debug("EVENTLISTENER onhashchange", e);
+ }
+
+ open_page(location.hash.replace("#", ""));
+};
+function download(filename, text) {
+ var element = document.createElement("a");
+ element.setAttribute(
+ "href",
+ "data:application/octet-stream;charset=utf-8," + encodeURIComponent(text)
+ );
+ element.setAttribute("download", filename);
+
+ element.style.display = "none";
+ document.body.appendChild(element);
+
+ element.click();
+
+ document.body.removeChild(element);
+}
+function resizeInputImage(
+ file,
+ callback,
+ targetHeight = 256,
+ targetQuality = 0.75
+) {
+ const reader = new FileReader();
+
+ reader.onload = function (event) {
+ const img = new Image();
+ img.onload = function () {
+ const aspectRatio = img.width / img.height;
+ const targetWidth = targetHeight * aspectRatio;
+
+ const canvas = document.createElement("canvas");
+ canvas.width = targetWidth;
+ canvas.height = targetHeight;
+
+ const ctx = canvas.getContext("2d");
+
+ ctx.fillStyle = "#ffffff";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+ ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
+
+ // Get resized image as Blob
+ const dataURL = canvas.toDataURL("image/jpeg", targetQuality);
+ callback(dataURL);
+ };
+ img.src = event.target.result;
+ };
+
+ reader.readAsDataURL(file);
+}
+function CurrentISODate() {
+ return new Date().toISOString().split("T")[0].replace("T", " ");
+}
+function CurrentISOTime() {
+ return new Date().toISOString();
+}
+function fixGunLocalStorage() {
+ localStorage.removeItem("radata");
+ removeCache();
+ location.reload();
+}
+function betterGunPut(ref, data) {
+ ref.put(data, (ack) => {
+ if (ack.err) {
+ toastr.error(
+ ack.err + "
Pulsa aqui para reiniciar la app",
+ "Error al guardar",
+ { onclick: () => fixGunLocalStorage() }
+ );
+ } else {
+ console.debug("Guardado correctamente");
+ }
+ });
+ setTimeout(() => {
+ ref.put(data);
+ }, 250);
+ setTimeout(() => {
+ ref.put(data);
+ }, 500);
+}
+setInterval(() => {
+ betterGunPut(
+ gun.get(TABLE).get("heartbeat"),
+ "heartbeat-" + CurrentISOTime()
+ );
+ gun.get(TABLE).get("heartbeat").load(console.debug);
+}, 5000);
+gun.get(TABLE).on((data) => {
+ var e = true;
+});
diff --git a/src/app_modules.js b/src/app_modules.js
new file mode 100644
index 0000000..3035e2f
--- /dev/null
+++ b/src/app_modules.js
@@ -0,0 +1,872 @@
+try {
+ navigator.wakeLock.request("screen");
+} catch {
+ console.log("ScreenLock Failed");
+}
+const debounce = (callback, wait) => {
+ let isLocked = false;
+ let lastArgs = null;
+ let timeoutId = null;
+
+ return (...args) => {
+ if (!isLocked) {
+ // First call: run immediately
+ callback(...args);
+ isLocked = true;
+
+ // Start lock period
+ timeoutId = setTimeout(() => {
+ isLocked = false;
+ if (lastArgs) {
+ callback(...lastArgs);
+ lastArgs = null;
+ }
+ }, wait);
+ } else {
+ // During lock: save latest args
+ lastArgs = args;
+ }
+ };
+};
+
+String.prototype.toHex = function () {
+ var s = this + "0123456789";
+ var colors = [
+ "#ff0000",
+ "#ff00ff",
+ "#00ff00",
+ "#0000ff",
+ "#00ffff",
+ "#000000",
+ ];
+ var color =
+ (((((s.charCodeAt(1) * s.charCodeAt(2)) / s.charCodeAt(s.length - 1)) *
+ s.charCodeAt(s.length - 2)) /
+ s.charCodeAt(s.length - 2)) *
+ s.charCodeAt(s.length - 3)) /
+ s.charCodeAt(s.length - 3);
+ var cid = colors[Math.round(color) % colors.length];
+ console.log(color, cid, colors);
+ return cid;
+};
+function stringToColour(str) {
+ return str.toHex();
+}
+function colorIsDarkAdvanced(bgColor) {
+ let color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
+ let r = parseInt(color.substring(0, 2), 16); // hexToR
+ let g = parseInt(color.substring(2, 4), 16); // hexToG
+ let b = parseInt(color.substring(4, 6), 16); // hexToB
+ let uicolors = [r / 255, g / 255, b / 255];
+ let c = uicolors.map((col) => {
+ if (col <= 0.03928) {
+ return col / 12.92;
+ }
+ return Math.pow((col + 0.055) / 1.055, 2.4);
+ });
+ let L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
+ return L <= 0.179 ? "#FFFFFF" : "#000000";
+}
+function setLayeredImages(comanda, key) {
+ // Base paths for each layer type (adjust paths as needed)
+ const basePaths = {
+ Selección: "static/ico/layered1/",
+ Café: "static/ico/layered1/",
+ Endulzante: "static/ico/layered1/",
+ Cafeina: "static/ico/layered1/",
+ Leche: "static/ico/layered1/",
+ };
+
+ // Map for Selección to filenames
+ const selectionMap = {
+ "ColaCao con leche": "Selección-ColaCao.png",
+ Infusión: "Selección-Infusion.png",
+ "Café con leche": "Selección-CaféLeche.png",
+ "Solo Leche": "Selección-Leche.png",
+ "Solo café (sin leche)": "Selección-CaféSolo.png",
+ };
+
+ // Start div with relative positioning for layering
+ let html = `
`;
+
+ // Layer 1: Selección image
+ const selection = comanda["Selección"];
+ if (selectionMap[selection]) {
+ html += `

`;
+ }
+
+ // Layer 2: Café
+ if (comanda.Café) {
+ html += `

`;
+ }
+
+ // Layer 3: Endulzante
+ if (comanda.Endulzante) {
+ html += `

`;
+ }
+
+ // Layer 4: Cafeina
+ if (comanda.Cafeina) {
+ html += `

`;
+ }
+ // Layer 5: Leche
+ if (comanda.Leche) {
+ html += `

`;
+ }
+ // Layer 6: Temperatura
+ if (comanda.Temperatura) {
+ html += `

`;
+ }
+ // Layer 7: Tamaño
+ if (comanda.Tamaño) {
+ html += `

`;
+ }
+
+ // Close div
+ html += "
";
+
+ return html;
+}
+function addCategory(
+ parent,
+ name,
+ icon,
+ options,
+ values,
+ change_cb = () => {}
+) {
+ var details_0 = document.createElement("details"); // children: img_0, summary_0
+ //details_0.open = true;
+ var img_0 = document.createElement("img");
+ img_0.src = "static/ico/checkbox_unchecked.png";
+ img_0.style.height = "30px";
+ if (values[name] != undefined) {
+ //details_0.open = true;
+ img_0.src = "static/ico/checkbox.png";
+ }
+ var summary_0 = document.createElement("summary");
+ var span_0 = document.createElement("span");
+ span_0.style.float = "right";
+ span_0.append(values[name] || "", " ", img_0);
+ summary_0.append(name, span_0);
+ details_0.append(summary_0, document.createElement("br"));
+ details_0.style.textAlign = "center";
+ details_0.style.margin = "5px";
+ details_0.style.padding = "5px";
+ details_0.style.border = "2px solid black";
+ details_0.style.borderRadius = "5px";
+ details_0.style.backgroundColor = "white";
+ details_0.style.cursor = "pointer";
+ details_0.style.width = "calc(100% - 25px)";
+ details_0.style.display = "inline-block";
+ summary_0.style.padding = "10px";
+ // background image at the start of summary_0:
+ summary_0.style.backgroundImage = "url('" + icon + "')";
+ summary_0.style.backgroundSize = "contain";
+ summary_0.style.backgroundPosition = "left";
+ summary_0.style.backgroundRepeat = "no-repeat";
+ summary_0.style.textAlign = "left";
+ summary_0.style.paddingLeft = "55px";
+ parent.append(details_0);
+
+ options.forEach((option) => {
+ var btn = document.createElement("button");
+ var br1 = document.createElement("br");
+ //btn.innerText = option.key + ": " + option.value
+ btn.append(option.value);
+ // for each image in option.img:
+
+ if (option.img) {
+ var br2 = document.createElement("br");
+ btn.append(br2);
+ option.img.forEach((imgsrc) => {
+ var img = document.createElement("img");
+ img.src = imgsrc;
+ img.style.height = "50px";
+ img.style.padding = "5px";
+ img.style.backgroundColor = "white";
+ btn.append(img, " ");
+ });
+ }
+ btn.className = option.className;
+ if (values[option.key] == option.value) {
+ btn.classList.add("activeSCButton");
+ }
+ btn.onclick = (event) => {
+ var items = details_0.getElementsByClassName("activeSCButton");
+ for (var i = 0; i < items.length; i++) {
+ items[i].classList.remove("activeSCButton");
+ }
+ btn.classList.add("activeSCButton");
+ values[option.key] = option.value;
+ span_0.innerText = option.value;
+ change_cb(values);
+ img_0.src = "static/ico/checkbox.png";
+ };
+ btn.style.borderRadius = "20px";
+ //btn.style.fontSize="17.5px"
+ details_0.append(btn);
+ });
+}
+function addCategory_Personas(
+ parent,
+ options,
+ defaultval,
+ change_cb = () => {},
+ label = "Persona"
+) {
+ var details_0 = document.createElement("details"); // children: img_0, summary_0
+ //details_0.open = true;
+ var img_0 = document.createElement("img");
+ img_0.src = "static/ico/checkbox_unchecked.png";
+ img_0.style.height = "30px";
+ if (defaultval != "") {
+ details_0.open = false;
+ img_0.src = "static/ico/checkbox.png";
+ }
+ var summary_0 = document.createElement("summary");
+ var span_0 = document.createElement("span");
+ span_0.style.float = "right";
+ var p = SC_Personas[defaultval] || {};
+ span_0.append(p.Nombre || "", " ", img_0);
+ summary_0.append(label, span_0);
+ details_0.append(summary_0, document.createElement("br"));
+ details_0.style.textAlign = "center";
+ details_0.style.margin = "5px";
+ details_0.style.padding = "5px";
+ details_0.style.border = "2px solid black";
+ details_0.style.borderRadius = "5px";
+ details_0.style.backgroundColor = "white";
+ details_0.style.cursor = "pointer";
+ details_0.style.width = "calc(100% - 25px)";
+ details_0.style.display = "inline-block";
+ summary_0.style.padding = "10px";
+ // background image at the start of summary_0:
+ summary_0.style.backgroundImage = "url('static/ico/user.png')";
+ summary_0.style.backgroundSize = "contain";
+ summary_0.style.backgroundPosition = "left";
+ summary_0.style.backgroundRepeat = "no-repeat";
+ summary_0.style.textAlign = "left";
+ summary_0.style.paddingLeft = "55px";
+ parent.append(details_0);
+ var lastreg = "";
+ Object.entries(options)
+ .sort(PERSONAS_Sorter)
+ .map((entry) => {
+ var key = entry[0];
+ var value = entry[1];
+ if (lastreg != value.Region.toUpperCase()) {
+ lastreg = value.Region.toUpperCase();
+ var h3_0 = document.createElement("h2");
+ h3_0.style.margin = "0";
+ h3_0.style.marginTop = "15px";
+ h3_0.innerText = lastreg;
+ details_0.append(h3_0);
+ }
+ var option = value.Nombre;
+ var btn = document.createElement("button");
+ var br1 = document.createElement("br");
+ //btn.innerText = option.key + ": " + option.value
+ btn.append(option);
+
+ var br2 = document.createElement("br");
+ btn.append(br2);
+ var img = document.createElement("img");
+ img.src = value.Foto;
+ img.style.height = "60px";
+ img.style.padding = "5px";
+ img.style.backgroundColor = "white";
+ btn.append(img, " ");
+
+ if (defaultval == key) {
+ btn.classList.add("activeSCButton");
+ }
+ btn.onclick = (event) => {
+ var items = details_0.getElementsByClassName("activeSCButton");
+ for (var i = 0; i < items.length; i++) {
+ items[i].classList.remove("activeSCButton");
+ }
+ btn.classList.add("activeSCButton");
+ defaultval = key;
+ span_0.innerText = "";
+ var img_5 = document.createElement("img");
+ img_5.src = value.Foto;
+ img_5.style.height = "30px";
+ span_0.append(img_5, value.Nombre);
+ change_cb(defaultval);
+ img_0.src = "static/ico/checkbox.png";
+ };
+ btn.style.borderRadius = "20px";
+ //btn.style.fontSize="17.5px"
+ details_0.append(btn);
+ });
+}
+const SC_actions_icons = {
+ Tamaño: "static/ico/sizes.png",
+ Temperatura: "static/ico/thermometer2.png",
+ Leche: "static/ico/milk.png",
+ Selección: "static/ico/preferences.png",
+ Cafeina: "static/ico/coffee_bean.png",
+ Endulzante: "static/ico/lollipop.png",
+ Receta: "static/ico/cookies.png",
+};
+const SC_actions = {
+ Selección: [
+ {
+ value: "Solo Leche",
+ key: "Selección",
+ className: "btn4",
+ img: ["static/ico/milk.png"],
+ },
+ {
+ value: "Solo café (sin leche)",
+ key: "Selección",
+ className: "btn4",
+ img: ["static/ico/coffee_bean.png"],
+ },
+ {
+ value: "Café con leche",
+ key: "Selección",
+ className: "btn4",
+ img: ["static/ico/coffee_bean.png", "static/ico/milk.png"],
+ },
+ {
+ value: "ColaCao con leche",
+ key: "Selección",
+ className: "btn4",
+ img: ["static/ico/colacao.jpg", "static/ico/milk.png"],
+ },
+ {
+ value: "Leche con cereales",
+ key: "Selección",
+ className: "btn4",
+ img: ["static/ico/cereales.png", "static/ico/milk.png"],
+ },
+ {
+ value: "Infusión",
+ key: "Selección",
+ className: "btn4",
+ img: ["static/ico/tea_bag.png"],
+ },
+ ],
+ Tamaño: [
+ {
+ value: "Grande",
+ key: "Tamaño",
+ className: "btn1",
+ img: ["static/ico/keyboard_key_g.png"],
+ },
+ {
+ value: "Pequeño",
+ key: "Tamaño",
+ className: "btn1",
+ img: ["static/ico/keyboard_key_p.png"],
+ },
+ ],
+ Temperatura: [
+ {
+ value: "Caliente",
+ key: "Temperatura",
+ className: "btn2",
+ img: [
+ "static/ico/thermometer2.png",
+ "static/ico/arrow_up_red.png",
+ "static/ico/fire.png",
+ ],
+ },
+ {
+ value: "Templado",
+ key: "Temperatura",
+ className: "btn2",
+ img: ["static/ico/thermometer2.png", "static/ico/arrow_left_green.png"],
+ },
+ {
+ value: "Frio",
+ key: "Temperatura",
+ className: "btn2",
+ img: [
+ "static/ico/thermometer2.png",
+ "static/ico/arrow_down_blue.png",
+ "static/ico/snowflake.png",
+ ],
+ },
+ ],
+ Leche: [
+ {
+ value: "de Vaca",
+ key: "Leche",
+ className: "btn3",
+ img: ["static/ico/cow.png", "static/ico/add.png"],
+ },
+ {
+ value: "Sin lactosa",
+ key: "Leche",
+ className: "btn3",
+ img: ["static/ico/cow.png", "static/ico/delete.png"],
+ },
+ {
+ value: "Vegetal",
+ key: "Leche",
+ className: "btn3",
+ img: ["static/ico/milk.png", "static/ico/wheat.png"],
+ },
+ {
+ value: "Agua",
+ key: "Leche",
+ className: "btn3",
+ img: ["static/ico/water_tap.png"],
+ },
+ ],
+ Cafeina: [
+ {
+ value: "Con",
+ key: "Cafeina",
+ className: "btn5",
+ img: ["static/ico/coffee_bean.png", "static/ico/add.png"],
+ },
+ {
+ value: "Sin",
+ key: "Cafeina",
+ className: "btn5",
+ img: ["static/ico/coffee_bean.png", "static/ico/delete.png"],
+ },
+ ],
+ Endulzante: [
+ {
+ value: "Az. Blanco",
+ key: "Endulzante",
+ className: "btn6",
+ img: ["static/ico/azucar-blanco.jpg"],
+ },
+ {
+ value: "Az. Moreno",
+ key: "Endulzante",
+ className: "btn6",
+ img: ["static/ico/azucar-moreno.png"],
+ },
+ {
+ value: "Sacarina",
+ key: "Endulzante",
+ className: "btn6",
+ img: ["static/ico/sacarina.jpg"],
+ },
+ {
+ value: "Stevia (Pastillas)",
+ key: "Endulzante",
+ className: "btn6",
+ img: ["static/ico/stevia.jpg"],
+ },
+ {
+ value: "Stevia (Gotas)",
+ key: "Endulzante",
+ className: "btn6",
+ img: ["static/ico/stevia-gotas.webp"],
+ },
+ {
+ value: "Sin",
+ key: "Endulzante",
+ className: "btn6",
+ img: ["static/ico/delete.png"],
+ },
+ ],
+ Receta: [
+ {
+ value: "Si",
+ key: "Receta",
+ className: "btn7",
+ img: ["static/ico/add.png"],
+ },
+ {
+ value: "No",
+ key: "Receta",
+ className: "btn7",
+ img: ["static/ico/delete.png"],
+ },
+ ],
+};
+var SC_Personas = {};
+// Listado precargado de personas:
+gun
+ .get(TABLE)
+ .get("personas")
+ .map()
+ .on((data, key, _msg, _ev) => {
+ if (data != null) {
+ function add_row(data, key) {
+ if (data != null) {
+ data["_key"] = key;
+ SC_Personas[key] = data;
+ } else {
+ delete SC_Personas[key];
+ }
+ }
+ if (typeof data == "string") {
+ SEA.decrypt(data, SECRET, (data) => {
+ add_row(data, key);
+ });
+ } else {
+ add_row(data, key);
+ }
+ }
+ });
+
+function SC_parse(json) {
+ var out = "";
+ Object.entries(json).forEach((entry) => {
+ out += entry[0] + ": " + entry[1] + "\n";
+ });
+ return out;
+}
+function SC_parse_short(json) {
+ var valores = "
Servicio base (10c)\n";
+
+ Object.entries(json).forEach((entry) => {
+ valores +=
+ "
" +
+ entry[0] +
+ ": " +
+ entry[1] +
+ " ";
+ var combo = entry[0] + ";" + entry[1];
+ switch (entry[0]) {
+ case "Leche":
+ // Leche pequeña = 10c
+ if (
+ json["Tamaño"] == "Pequeño" &&
+ ["de Vaca", "Sin lactosa", "Vegetal"].includes(json["Leche"])
+ ) {
+ valores += "
(P = 10c)";
+ }
+ // Leche grande = 20c
+ if (
+ json["Tamaño"] == "Grande" &&
+ ["de Vaca", "Sin lactosa", "Vegetal"].includes(json["Leche"])
+ ) {
+ valores += "
(G = 20c)";
+ }
+ break;
+ case "Selección":
+ // Café = 20c
+ if (
+ ["Café con leche", "Solo café (sin leche)"].includes(
+ json["Selección"]
+ )
+ ) {
+ valores += "
(20c)";
+ }
+ // ColaCao = 20c
+ if (json["Selección"] == "ColaCao con leche") {
+ valores += "
(20c)";
+ }
+ default:
+ break;
+ }
+
+ valores += "\n";
+ });
+ return valores;
+}
+function SC_priceCalc(json) {
+ var precio = 0;
+ var valores = "";
+ // Servicio base = 10c
+ precio += 10;
+ valores += "Servicio base = 10c\n";
+ // Leche pequeña = 10c
+ if (
+ json["Tamaño"] == "Pequeño" &&
+ ["de Vaca", "Sin lactosa", "Vegetal"].includes(json["Leche"])
+ ) {
+ precio += 10;
+ valores += "Leche pequeña = 10c\n";
+ }
+ // Leche grande = 20c
+ if (
+ json["Tamaño"] == "Grande" &&
+ ["de Vaca", "Sin lactosa", "Vegetal"].includes(json["Leche"])
+ ) {
+ precio += 20;
+ valores += "Leche grande = 20c\n";
+ }
+ // Café = 20c
+ if (["Café con leche", "Solo café (sin leche)"].includes(json["Selección"])) {
+ precio += 20;
+ valores += "Café = 20c\n";
+ }
+ // ColaCao = 20c
+ if (json["Selección"] == "ColaCao con leche") {
+ precio += 20;
+ valores += "ColaCao = 20c\n";
+ }
+ valores += "
Total: " + precio + "c\n";
+ return [precio, valores];
+}
+function PERSONAS_Sorter(a, b) {
+ if (a[1].Region < b[1].Region) {
+ return -1;
+ }
+ if (a[1].Region > b[1].Region) {
+ return 1;
+ }
+ return 0;
+}
+
+function TS_IndexElement(
+ pageco,
+ config,
+ ref,
+ container,
+ rowCallback = undefined,
+ canAddCallback = undefined
+) {
+ // Every item in config should have:
+ // key: string
+ // type: string
+ // default: string
+ // label: string
+ var tablebody = safeuuid();
+ var tablehead = safeuuid();
+ container.innerHTML = `
+
+ `;
+ tableScroll("#scrolltable"); // id="scrolltable"
+ var tablehead_EL = document.getElementById(tablehead);
+ var tablebody_EL = document.getElementById(tablebody);
+ var rows = {};
+ config.forEach((key) => {
+ tablehead_EL.innerHTML += `
${key.label} | `;
+ });
+ function render() {
+ function sorter(a, b) {
+ if (a.Fecha < b.Fecha) {
+ return -1;
+ }
+ if (a.Fecha > b.Fecha) {
+ return 1;
+ }
+ return 0;
+ }
+ var tablebody_EL = document.getElementById(tablebody);
+ tablebody_EL.innerHTML = "";
+ Object.values(rows)
+ .sort(sorter)
+ .forEach((data) => {
+ var new_tr = document.createElement("tr");
+
+ if (canAddCallback != undefined) {
+ if (canAddCallback(data) == true) {
+ return;
+ }
+ }
+ tablebody_EL.append(new_tr);
+ if (rowCallback != undefined) {
+ rowCallback(data, new_tr);
+ }
+ config.forEach((key) => {
+ switch (key.type) {
+ case "raw":
+ const tdRaw = document.createElement('td');
+ tdRaw.textContent = data[key.key] || key.default;
+ new_tr.appendChild(tdRaw);
+ break;
+ case "comanda":
+ const tdComanda = document.createElement('td');
+ const parsedComanda = JSON.parse(data.Comanda);
+ const precio = SC_priceCalc(parsedComanda)[0];
+
+ // Create a temporary div to parse the HTML from setLayeredImages
+ const tempDiv = document.createElement('div');
+ tempDiv.innerHTML = setLayeredImages(parsedComanda, data._key);
+ tdComanda.appendChild(tempDiv.firstChild);
+
+ const pre = document.createElement('pre');
+ pre.style.fontSize = '15px';
+ pre.style.display = 'inline-block';
+
+ const spanPrecio = document.createElement('span');
+ spanPrecio.style.fontSize = '20px';
+ spanPrecio.innerHTML = SC_Personas[data.Persona].Puntos >= 10 ?
+ `Total: Gratis!(${precio}c)` :
+ `Total: ${precio}c`;
+
+ pre.appendChild(spanPrecio);
+ pre.appendChild(document.createTextNode('\n'));
+ pre.innerHTML += SC_parse_short(parsedComanda) + "
" + data.Notas;
+
+ tdComanda.appendChild(pre);
+ new_tr.appendChild(tdComanda);
+ break;
+ case "comanda-status":
+ var sc_nobtn = "";
+ if (urlParams.get("sc_nobtn") == "yes") {
+ sc_nobtn = "pointer-events: none; opacity: 0.5";
+ }
+ const td = document.createElement('td');
+ td.style.fontSize = '17px';
+ if (sc_nobtn) {
+ td.style.pointerEvents = 'none';
+ td.style.opacity = '0.5';
+ }
+
+ // Create buttons
+ const createButton = (text, state) => {
+ const button = document.createElement('button');
+ button.textContent = text;
+ if (data.Estado === state) {
+ button.className = 'rojo';
+ }
+ button.onclick = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ data.Estado = state;
+ var enc = SEA.encrypt(data, SECRET, (encrypted) => {
+ betterGunPut(ref.get(data._key), encrypted);
+ toastr.success("Guardado!");
+ });
+ return false;
+ };
+ return button;
+ };
+
+ // Create all buttons
+ const buttons = [
+ createButton('Pedido', 'Pedido'),
+ createButton('En preparación', 'En preparación'),
+ createButton('Listo', 'Listo'),
+ createButton('Entregado', 'Entregado'),
+ createButton('Deuda', 'Deuda')
+ ];
+
+ // Create paid button separately due to different behavior
+ const paidButton = document.createElement('button');
+ paidButton.textContent = 'Pagado';
+ paidButton.onclick = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!confirm("¿Quieres marcar como pagado? - Se borrara la comanda y se actualizarán los puntos.")) {
+ return false;
+ }
+ data.Estado = "Pagado";
+ betterGunPut(ref.get(data._key), null);
+ toastr.success("Guardado!");
+ if (SC_Personas[data.Persona].Puntos >= 10) {
+ SC_Personas[data.Persona].Puntos -= 10;
+ toastr.success("¡Comada gratis para " + SC_Personas[data.Persona].Nombre + "!");
+ toastr.success("¡Comada gratis para " + SC_Personas[data.Persona].Nombre + "!");
+ } else {
+ SC_Personas[data.Persona].Puntos += 1;
+ toastr.success("¡Comada DE PAGO!");
+ }
+ SEA.encrypt(SC_Personas[data.Persona], SECRET, (encrypted) => {
+ betterGunPut(gun.get(TABLE).get("personas").get(data.Persona), encrypted);
+ });
+ return false;
+ };
+
+ // Add all buttons to td with line breaks between
+ buttons.forEach(button => {
+ td.appendChild(button);
+ td.appendChild(document.createElement('br'));
+ });
+ td.appendChild(paidButton);
+ new_tr.appendChild(td);
+
+ // Event handlers are now attached during button creation
+ break;
+ case "persona":
+ const persona = SC_Personas[data[key.key]];
+ const regco = stringToColour((persona.Region || "?").toLowerCase());
+
+ const tdPersona = document.createElement('td');
+ tdPersona.style.textAlign = 'center';
+ tdPersona.style.fontSize = '20px';
+ tdPersona.style.backgroundColor = regco;
+ tdPersona.style.color = colorIsDarkAdvanced(regco);
+
+ const regionSpan = document.createElement('span');
+ regionSpan.style.fontSize = '40px';
+ regionSpan.style.textTransform = 'capitalize';
+ regionSpan.textContent = (persona.Region || "?").toLowerCase();
+ tdPersona.appendChild(regionSpan);
+
+ tdPersona.appendChild(document.createElement('br'));
+
+ const infoSpan = document.createElement('span');
+ infoSpan.style.backgroundColor = 'white';
+ infoSpan.style.border = '2px solid black';
+ infoSpan.style.borderRadius = '5px';
+ infoSpan.style.display = 'inline-block';
+ infoSpan.style.padding = '5px';
+ infoSpan.style.color = 'black';
+
+ const img = document.createElement('img');
+ img.src = persona.Foto || "static/ico/user_generic.png";
+ img.height = 70;
+ infoSpan.appendChild(img);
+
+ infoSpan.appendChild(document.createElement('br'));
+ infoSpan.appendChild(document.createTextNode(persona.Nombre || ""));
+
+ infoSpan.appendChild(document.createElement('br'));
+ const pointsSpan = document.createElement('span');
+ pointsSpan.style.fontSize = '17px';
+ pointsSpan.textContent = (persona.Puntos || "0") + " puntos.";
+ infoSpan.appendChild(pointsSpan);
+
+ tdPersona.appendChild(infoSpan);
+ new_tr.appendChild(tdPersona);
+ break;
+
+ default:
+ break;
+ }
+ });
+ new_tr.onclick = (event) => {
+ setUrlHash(pageco + "," + data._key);
+ };
+ });
+ }
+ ref.map().on((data, key, _msg, _ev) => {
+ EVENTLISTENER = _ev;
+ if (data != null) {
+ function add_row(data, key) {
+ if (data != null) {
+ data["_key"] = key;
+ rows[key] = data;
+ } else {
+ delete rows[key];
+ }
+ render();
+ }
+ if (typeof data == "string") {
+ SEA.decrypt(data, SECRET, (data) => {
+ add_row(data, key);
+ });
+ } else {
+ add_row(data, key);
+ }
+ }
+ });
+}
+
+const PAGES = {};
+document.addEventListener("DOMContentLoaded", () => {
+ Object.keys(PAGES).forEach((key) => {
+ var a = document.createElement("a");
+ a.className = "button " + PAGES[key].navcss;
+ a.href = "#" + key;
+ a.innerText = PAGES[key].Title;
+ document.getElementById("appendApps").append(a);
+ });
+ open_page(location.hash.replace("#", ""));
+});
diff --git a/src/config.js b/src/config.js
new file mode 100644
index 0000000..f6cc044
--- /dev/null
+++ b/src/config.js
@@ -0,0 +1,22 @@
+var EVENTLISTENER = null;
+var EVENTLISTENER2 = null;
+var urlParams = new URLSearchParams(location.search);
+if (urlParams.get("hidenav") == "yes") {
+ document.getElementById("header_hide_query").style.display = "none";
+}
+var GROUPID = "";
+// const PUBLIC_KEY = "~cppGiuA4UFUPGTDoC-4r2izVC3F7MfpaCmF3iZdESN4.vntmjgbAVUpF_zfinYY6EKVFuuTYxh5xOrL4KmtdTmc"
+var TABLE = GROUPID + ":telesec.tech.eus";
+const RELAYS = [
+ "https://gun-es01.tech.eus/gun",
+ "https://gun-es02.tech.eus/gun",
+ "https://gun-es03.tech.eus/gun",
+ "https://gun-es04.tech.eus/gun",
+ "https://gun-es05.tech.eus/gun",
+ "https://gun-es06.tech.eus/gun",
+ // "https://gun-es07.tech.eus/gun", // No he podido instalar el nodo.
+ "https://gun-manhattan.herokuapp.com/gun",
+ "https://peer.wallie.io/gun",
+ "https://gun.defucc.me/gun",
+];
+var SECRET = "";
diff --git a/src/gun_init.js b/src/gun_init.js
new file mode 100644
index 0000000..cb2b3bc
--- /dev/null
+++ b/src/gun_init.js
@@ -0,0 +1,61 @@
+window.rtcRoom = "telesec.tech.eus";
+var gun = Gun(RELAYS, {
+ axe: false,
+ localStorage: true,
+ // radisk: true,
+});
+var SEA = Gun.SEA;
+var user = gun.user();
+function removeCache() {
+ caches.keys().then(function (names) {
+ for (let name of names) caches.delete(name);
+ console.log("Removing cache " + name);
+ console.log("OK");
+ location.reload(true);
+ });
+}
+function getPeers() {
+ var peerCount = 0;
+ var peerCountEl = document.getElementById("peerCount");
+ var peerListEl = document.getElementById("peerList");
+ var list = document.createElement("ul");
+ document.getElementById("peerPID").innerText = "PID " + gun.back("opt.pid");
+ Object.values(gun.back("opt.peers")).forEach((peer) => {
+ if (
+ peer.wire != undefined &&
+ (peer.wire.readyState == 1 || peer.wire.readyState == "open")
+ ) {
+ peerCount += 1;
+ var wireType = peer.wire.constructor.name;
+ var wireHType = peer.wire.constructor.name;
+ var wireID = peer.id;
+ switch (wireType) {
+ case "WebSocket":
+ wireHType = "Web";
+ wireID = wireID.split("/")[2];
+ break;
+ case "RTCDataChannel":
+ wireHType = "Mesh";
+ wireID = peer.id;
+ }
+ var el = document.createElement("li");
+ el.innerText = `Nodo ${wireHType}: ${wireID}`;
+ list.append(el);
+ }
+ });
+ peerListEl.innerHTML = list.innerHTML;
+ peerCountEl.innerText = peerCount;
+ if (peerCount < 3) {
+ document.getElementById("connectStatus").src = "static/ico/connect_ko.svg";
+ gun.opt({ peers: RELAYS });
+ } else {
+ document.getElementById("connectStatus").src = "static/ico/connect_ok.svg";
+ }
+}
+getPeers();
+setInterval(() => {
+ getPeers();
+}, 2500);
+function safeuuid(prefix = "AXLUID_") {
+ return prefix + crypto.randomUUID().split("-")[4];
+}
diff --git a/src/index.html b/src/index.html
index ee33bef..e59c91a 100644
--- a/src/index.html
+++ b/src/index.html
@@ -96,6 +96,11 @@
display: none;
"
/>
+
@@ -131,2496 +136,18 @@
}
getQuota();
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+