diff --git a/_assets.json b/_assets.json index 023f02a..915acb6 100644 --- a/_assets.json +++ b/_assets.json @@ -1,86 +1,85 @@ [ - "icon512_maskable.png", - "icon512_rounded.png", - "index.html", - "manifest.json", - "static/axe.js", - "static/doublescroll.js", - "static/gun.js", - "static/jquery.js", - "static/load.js", - "static/open.js", - "static/path.js", - "static/radisk.js", - "static/radix.js", - "static/rindexed.js", - "static/sea.js", - "static/showdown.min.js", - "static/simplemde.min.css", - "static/simplemde.min.js", - "static/store.js", - "static/synchronous.js", - "static/TeleSec.jpg", - "static/toastr.min.css", - "static/toastr.min.js", - "static/webrtc.js", - "static/yson.js", - "static/ico/add.png", - "static/ico/azucar-moreno.png", - "static/ico/azucar-blanco.jpg", - "static/ico/stevia.jpg", - "static/ico/stevia-gotas.webp", - "static/ico/sacarina.jpg", - "static/ico/arrow_down_blue.png", - "static/ico/arrow_left_green.png", - "static/ico/arrow_up_red.png", - "static/ico/camera2.png", - "static/ico/cereales.png", - "static/ico/checkbox.png", - "static/ico/checkbox_unchecked.png", - "static/ico/connect_ok.svg", - "static/ico/connect_ko.svg", - "static/ico/coffee_bean.png", - "static/ico/colacao.jpg", - "static/ico/cookies.png", - "static/ico/cow.png", - "static/ico/delete.png", - "static/ico/fire.png", - "static/ico/keyboard_key_g.png", - "static/ico/keyboard_key_p.png", - "static/ico/lollipop.png", - "static/ico/milk.png", - "static/ico/preferences.png", - "static/ico/sizes.png", - "static/ico/statusok.png", - "static/ico/snowflake.png", - "static/ico/tea_bag.png", - "static/ico/thermometer2.png", - "static/ico/user.png", - "static/ico/user_generic.png", - "static/ico/water_tap.png", - "static/ico/wheat.png", - "static/ico/layered1/Azucar-Az. Blanco.png", - "static/ico/layered1/Azucar-Az. Moreno.png", - "static/ico/layered1/Azucar-Edulcorante.png", - "static/ico/layered1/Azucar-Sacarina.png", - "static/ico/layered1/Azucar-Sin.png", - "static/ico/layered1/Azucar-Stevia (Gotas).png", - "static/ico/layered1/Azucar-Stevia (Pastillas).png", - "static/ico/layered1/Background.png", - "static/ico/layered1/Cafeina-Con.png", - "static/ico/layered1/Cafeina-Sin.png", - "static/ico/layered1/Leche-Agua.png", - "static/ico/layered1/Leche-Sin lactosa.png", - "static/ico/layered1/Leche-Vegetal.png", - "static/ico/layered1/Leche-de Vaca.png", - "static/ico/layered1/Selección-CafeSolo.png", - "static/ico/layered1/Selección-CaféLeche.png", - "static/ico/layered1/Selección-ColaCao.png", - "static/ico/layered1/Selección-Infusion.png", - "static/ico/layered1/Selección-Leche.png", - "static/ico/layered1/Tamaño-Grande.png", - "static/ico/layered1/Tamaño-Pequeño.png", - "static/ico/layered1/Temperatura-Caliente.png", - "static/ico/layered1/Temperatura-Frio.png", - "static/ico/layered1/Temperatura-Templado.png" -] \ No newline at end of file + "icon512_maskable.png", + "icon512_rounded.png", + "manifest.json", + "static/axe.js", + "static/doublescroll.js", + "static/gun.js", + "static/jquery.js", + "static/load.js", + "static/open.js", + "static/path.js", + "static/radisk.js", + "static/radix.js", + "static/rindexed.js", + "static/sea.js", + "static/showdown.min.js", + "static/simplemde.min.css", + "static/simplemde.min.js", + "static/store.js", + "static/synchronous.js", + "static/TeleSec.jpg", + "static/toastr.min.css", + "static/toastr.min.js", + "static/webrtc.js", + "static/yson.js", + "static/ico/add.png", + "static/ico/azucar-moreno.png", + "static/ico/azucar-blanco.jpg", + "static/ico/stevia.jpg", + "static/ico/stevia-gotas.webp", + "static/ico/sacarina.jpg", + "static/ico/arrow_down_blue.png", + "static/ico/arrow_left_green.png", + "static/ico/arrow_up_red.png", + "static/ico/camera2.png", + "static/ico/cereales.png", + "static/ico/checkbox.png", + "static/ico/checkbox_unchecked.png", + "static/ico/connect_ok.svg", + "static/ico/connect_ko.svg", + "static/ico/coffee_bean.png", + "static/ico/colacao.jpg", + "static/ico/cookies.png", + "static/ico/cow.png", + "static/ico/delete.png", + "static/ico/fire.png", + "static/ico/keyboard_key_g.png", + "static/ico/keyboard_key_p.png", + "static/ico/lollipop.png", + "static/ico/milk.png", + "static/ico/preferences.png", + "static/ico/sizes.png", + "static/ico/statusok.png", + "static/ico/snowflake.png", + "static/ico/tea_bag.png", + "static/ico/thermometer2.png", + "static/ico/user.png", + "static/ico/user_generic.png", + "static/ico/water_tap.png", + "static/ico/wheat.png", + "static/ico/layered1/Azucar-Az. Blanco.png", + "static/ico/layered1/Azucar-Az. Moreno.png", + "static/ico/layered1/Azucar-Edulcorante.png", + "static/ico/layered1/Azucar-Sacarina.png", + "static/ico/layered1/Azucar-Sin.png", + "static/ico/layered1/Azucar-Stevia (Gotas).png", + "static/ico/layered1/Azucar-Stevia (Pastillas).png", + "static/ico/layered1/Background.png", + "static/ico/layered1/Cafeina-Con.png", + "static/ico/layered1/Cafeina-Sin.png", + "static/ico/layered1/Leche-Agua.png", + "static/ico/layered1/Leche-Sin lactosa.png", + "static/ico/layered1/Leche-Vegetal.png", + "static/ico/layered1/Leche-de Vaca.png", + "static/ico/layered1/Selección-CafeSolo.png", + "static/ico/layered1/Selección-CaféLeche.png", + "static/ico/layered1/Selección-ColaCao.png", + "static/ico/layered1/Selección-Infusion.png", + "static/ico/layered1/Selección-Leche.png", + "static/ico/layered1/Tamaño-Grande.png", + "static/ico/layered1/Tamaño-Pequeño.png", + "static/ico/layered1/Temperatura-Caliente.png", + "static/ico/layered1/Temperatura-Frio.png", + "static/ico/layered1/Temperatura-Templado.png" +] diff --git a/build.py b/build.py index d428634..9d6e447 100644 --- a/build.py +++ b/build.py @@ -1,10 +1,14 @@ import json -ASSETS = json.load(open("_assets.json", "r")) +import os + PREFETCH = "" -VERSIONCO = "2025-07-18_2" -HANDLEPARSE = ["index.html", "sw.js"] +VERSIONCO = "2025-07-30_1" +HANDLEPARSE = os.listdir("src/") +ASSETS = json.load(open("_assets.json", "r")) + HANDLEPARSE for asset in ASSETS: - PREFETCH += f'\n' + if asset != "sw.js": + PREFETCH += f'\n' + def replace_handles(string): string = string.replace("%%PREFETCH%%", PREFETCH) @@ -12,8 +16,8 @@ def replace_handles(string): string = string.replace("%%ASSETSJSON%%", json.dumps(ASSETS, ensure_ascii=False)) return string -for file in HANDLEPARSE: +for file in HANDLEPARSE: with open("src/" + file, "r") as f: out = replace_handles(f.read()) with open("dist/" + file, "w") as f: diff --git a/dist/app_logic.js b/dist/app_logic.js new file mode 100644 index 0000000..39b692f --- /dev/null +++ b/dist/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/dist/app_modules.js b/dist/app_modules.js new file mode 100644 index 0000000..3035e2f --- /dev/null +++ b/dist/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/dist/config.js b/dist/config.js new file mode 100644 index 0000000..f6cc044 --- /dev/null +++ b/dist/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/dist/gun_init.js b/dist/gun_init.js new file mode 100644 index 0000000..cb2b3bc --- /dev/null +++ b/dist/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/dist/page__exportar.js b/dist/page__exportar.js new file mode 100644 index 0000000..9b8e895 --- /dev/null +++ b/dist/page__exportar.js @@ -0,0 +1,89 @@ +PAGES.exportar = { + navcss: "btn1", + Title: "Exportar", + index: function () { + var select_type = safeuuid(); + var textarea_content = safeuuid(); + var button_export_local = safeuuid(); + var button_export_safe = safeuuid(); + var button_export_safe_cloud = safeuuid(); + var button_clear = safeuuid(); + container.innerHTML = ` +

Exportar Datos

+
+ Exportar datos + Al pulsar, Espera hasta que salga una notificacion verde. +
+
+ + + + +
+ `; + document.getElementById(button_export_local).onclick = () => { + var data_export = {}; + var output = { + materiales: {}, + personas: {}, + }; + var download_data = (DATA) => { + Object.keys(DATA).forEach((modul) => { + Object.entries(DATA[modul] || {}).forEach((entry) => { + var key = entry[0]; + var value = entry[1]; + if (value != null) { + if (typeof value == "string") { + SEA.decrypt(value, SECRET, (data) => { + output[modul][key] = data; + }); + } else { + output[modul][key] = value; + } + } + }); + toastr.success("Exportado todo, descargando!"); + console.error(output); + download( + `Export TeleSec ${GROUPID}.json.txt`, + JSON.stringify(output) + ); + //setUrlHash(sel); + }, 2500); + }; + gun.get(TABLE).load(download_data); + }; + document.getElementById(button_export_safe).onclick = () => { + var download_data = (DATA) => { + toastr.success("Exportado todo, descargado!"); + console.error(DATA); + download( + `Export TeleSec Encriptado ${GROUPID}.json.txt`, + JSON.stringify(DATA) + ); + //setUrlHash(sel); + }; + gun.get(TABLE).load(download_data); + }; + document.getElementById(button_export_safe_cloud).onclick = () => { + var download_data = (DATA) => { + toastr.info("Exportado todo, subiendo!"); + console.error(DATA); + fetch( + "https://telesec-sync.tech.eus/upload_backup.php?table=" + GROUPID, + { + method: "POST", + body: JSON.stringify(DATA), + } + ) + .then(() => { + toastr.success("Subido correctamente!"); + }) + .catch(() => { + toastr.error("Ha ocurrido un error en la subida."); + }); + }; + gun.get(TABLE).load(download_data); + }; + }, +}; diff --git a/dist/page__importar.js b/dist/page__importar.js new file mode 100644 index 0000000..4d3c8a0 --- /dev/null +++ b/dist/page__importar.js @@ -0,0 +1,54 @@ +PAGES.importar = { + navcss: "btn1", + Title: "Importar", + index: function () { + var select_type = safeuuid(); + var textarea_content = safeuuid(); + var button_import = safeuuid(); + var button_clear = safeuuid(); + container.innerHTML = ` +

Importar Datos

+
+ Importar datos + Espera hasta que se vacien todas las notificaciones. + + + + +
+ `; + document.getElementById(button_import).onclick = () => { + toastr.info("Importando datos..."); + var val = document.getElementById(textarea_content).value; + var sel = document.getElementById(select_type).value; + if (sel == "%telesec") { + gun.get(TABLE).put(JSON.parse(val), (ack) => { + toastr.info("Importado " + entry[0] + "."); + }); + } else { + Object.entries(JSON.parse(val)["data"]).forEach((entry) => { + var enc = SEA.encrypt(entry[1], SECRET, (encrypted) => { + betterGunPut(gun.get(TABLE).get(sel).get(entry[0]), encrypted); + }); + }); + } + setTimeout(() => { + toastr.info("Importado todo!"); + + if (sel == "%telesec") { + setUrlHash("inicio"); + } else { + setUrlHash(sel); + } + }, 5000); + }; + }, +}; diff --git a/dist/page__index.js b/dist/page__index.js new file mode 100644 index 0000000..145327d --- /dev/null +++ b/dist/page__index.js @@ -0,0 +1,11 @@ +PAGES.index = { + //navcss: "btn1", + Title: "Inicio", + index: function () { + container.innerHTML = ` +

Inicio

+ Utiliza el menú superior para abrir un modulo +

+ `; + }, +}; diff --git a/dist/page__materiales.js b/dist/page__materiales.js new file mode 100644 index 0000000..9a2cc83 --- /dev/null +++ b/dist/page__materiales.js @@ -0,0 +1,194 @@ +PAGES.materiales = { + navcss: "btn2", + Title: "Materiales", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_nombre = safeuuid(); + var field_cantidad = safeuuid(); + var field_unidad = safeuuid(); + var field_cantidad_min = safeuuid(); + var field_abierto = safeuuid(); + var field_ubicacion = safeuuid(); + var field_referencia = safeuuid(); + var field_notas = safeuuid(); + var btn_guardar = safeuuid(); + var btn_borrar = safeuuid(); + container.innerHTML = ` +

Material

+
+ + + + + + +
+ + +
+ `; + gun + .get(TABLE) + .get("materiales") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_nombre).value = data["Nombre"] || ""; + document.getElementById(field_unidad).value = data["Unidad"] || ""; + document.getElementById(field_cantidad).value = + data["Cantidad"] || ""; + document.getElementById(field_cantidad_min).value = + data["Cantidad_Minima"] || ""; + document.getElementById(field_ubicacion).value = + data["Ubicacion"] || "-"; + document.getElementById(field_referencia).value = + data["Referencia"] || "?"; + document.getElementById(field_notas).value = data["Notas"] || ""; + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document.getElementById(btn_guardar).onclick = () => { + var data = { + Nombre: document.getElementById(field_nombre).value, + Unidad: document.getElementById(field_unidad).value, + Cantidad: document.getElementById(field_cantidad).value, + Cantidad_Minima: document.getElementById(field_cantidad_min).value, + Ubicacion: document.getElementById(field_ubicacion).value, + Referencia: document.getElementById(field_referencia).value, + Notas: document.getElementById(field_notas).value, + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut(gun.get(TABLE).get("materiales").get(mid), encrypted); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("materiales"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if (confirm("¿Quieres borrar este material?") == true) { + betterGunPut(gun.get(TABLE).get("materiales").get(mid), null); + toastr.error("Borrado!"); + setTimeout(() => { + setUrlHash("materiales"); + }, 1500); + } + }; + }, + index: function () { + const tablebody = safeuuid(); + var btn_new = safeuuid(); + container.innerHTML = ` +

Materiales

+ +
+ + + + + + + + + + + +
ReferenciaNombreUbicaciónCantidadNotas
+ `; + tableScroll("#scrolltable"); + var tablebody_EL = document.getElementById(tablebody); + var rows = {}; + function render() { + function sorter(a, b) { + if (a.Nombre < b.Nombre) { + return -1; + } + if (a.Nombre > b.Nombre) { + 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"); + new_tr.innerHTML = ` + ${data.Referencia || "?"} + ${data.Nombre || "?"} + ${data.Ubicacion || "?"} + ${data.Cantidad || "?"} ${data.Unidad || "?"} + ${data.Notas || "?"} + `; + var min = parseFloat(data.Cantidad_Minima); + var act = parseFloat(data.Cantidad); + if (act < min) { + new_tr.style.backgroundColor = "lightcoral"; + } + new_tr.onclick = () => { + setUrlHash("materiales," + data._key); + }; + tablebody_EL.append(new_tr); + }); + } + gun + .get(TABLE) + .get("materiales") + .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); + } + } + }); + document.getElementById(btn_new).onclick = () => { + setUrlHash("materiales," + safeuuid("")); + }; + }, + } \ No newline at end of file diff --git a/dist/page__notificaciones.js b/dist/page__notificaciones.js new file mode 100644 index 0000000..78114a2 --- /dev/null +++ b/dist/page__notificaciones.js @@ -0,0 +1,217 @@ +PAGES.notificaciones = { + navcss: "btn6", + Title: "Notificaciones", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_fecha = safeuuid(); + var field_asunto = safeuuid(); + var field_origen = safeuuid(); + var field_destino = safeuuid(); + var field_estado = safeuuid(); + var field_mensaje = safeuuid(); + var field_respuesta = safeuuid(); + var btn_leer = safeuuid(); + var btn_desleer = safeuuid(); + var btn_guardar = safeuuid(); + var btn_borrar = safeuuid(); + var div_actions = safeuuid(); + container.innerHTML = ` +

Notificación

+
+ Valores + + + + +
+ + +
+ + +
+ `; + document.getElementById(btn_leer).onclick = () => { + document.getElementById(field_estado).value = "leido"; + }; + document.getElementById(btn_desleer).onclick = () => { + document.getElementById(field_estado).value = "por_leer"; + }; + var divact = document.getElementById(div_actions); + addCategory_Personas( + divact, + SC_Personas, + "", + (value) => { + document.getElementById(field_origen).value = value; + }, + "Origen" + ); + addCategory_Personas( + divact, + SC_Personas, + "", + (value) => { + document.getElementById(field_destino).value = value; + }, + "Destino" + ); + gun + .get(TABLE) + .get("notificaciones") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_fecha).value = data["Fecha"]; + document.getElementById(field_asunto).value = data["Asunto"] || ""; + document.getElementById(field_mensaje).value = + data["Mensaje"] || ""; + document.getElementById(field_origen).value = data["Origen"] || ""; + document.getElementById(field_destino).value = + data["Destino"] || ""; + document.getElementById(field_estado).value = data["Estado"] || ""; + document.getElementById(field_respuesta).value = + data["Respuesta"] || ""; + + // Persona select + divact.innerHTML = ""; + addCategory_Personas( + divact, + SC_Personas, + data["Origen"] || "", + (value) => { + document.getElementById(field_origen).value = value; + }, + "Origen" + ); + addCategory_Personas( + divact, + SC_Personas, + data["Destino"] || "", + (value) => { + document.getElementById(field_destino).value = value; + }, + "Destino" + ); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document.getElementById(btn_guardar).onclick = () => { + if (document.getElementById(field_origen).value == "") { + alert("¡Hay que elegir una persona de origen!"); + return; + } + if (document.getElementById(field_destino).value == "") { + alert("¡Hay que elegir una persona de origen!"); + return; + } + var data = { + Fecha: document.getElementById(field_fecha).value, + Origen: document.getElementById(field_origen).value, + Destino: document.getElementById(field_destino).value, + Mensaje: document.getElementById(field_mensaje).value, + Respuesta: document.getElementById(field_respuesta).value, + Asunto: document.getElementById(field_asunto).value, + Estado: document + .getElementById(field_estado) + .value.replace("%%", "por_leer"), + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut( + gun.get(TABLE).get("notificaciones").get(mid), + encrypted + ); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("notificaciones"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if (confirm("¿Quieres borrar esta notificación?") == true) { + betterGunPut(gun.get(TABLE).get("notificaciones").get(mid), null); + toastr.error("Borrado!"); + setTimeout(() => { + setUrlHash("notificaciones"); + }, 1500); + } + }; + }, + index: function () { + const tablebody = safeuuid(); + var btn_new = safeuuid(); + container.innerHTML = ` +

Notificaciones

+ +
+ `; + TS_IndexElement( + "notificaciones", + [ + { + key: "Origen", + type: "persona", + default: "", + label: "Origen", + }, + { + key: "Destino", + type: "persona", + default: "", + label: "Destino", + }, + { + key: "Asunto", + type: "raw", + default: "", + label: "Asunto", + }, + { + key: "Estado", + type: "raw", + default: "", + label: "Estado", + }, + ], + gun.get(TABLE).get("notificaciones"), + document.querySelector("#cont"), + (data, new_tr) => { + new_tr.style.backgroundColor = "#FFCCCB"; + if (data.Estado == "leido") { + new_tr.style.backgroundColor = "lightgreen"; + } + } + ); + document.getElementById(btn_new).onclick = () => { + setUrlHash("notificaciones," + safeuuid("")); + }; + }, + } \ No newline at end of file diff --git a/dist/page__personas.js b/dist/page__personas.js new file mode 100644 index 0000000..4ec3529 --- /dev/null +++ b/dist/page__personas.js @@ -0,0 +1,224 @@ +PAGES.personas = { + navcss: "btn4", + Title: "Personas", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_nombre = safeuuid(); + var field_zona = safeuuid(); + var field_roles = safeuuid(); + var field_puntos = safeuuid(); + var field_notas = safeuuid(); + var field_anilla = safeuuid(); + var field_foto = safeuuid(); + var render_foto = safeuuid(); + var btn_guardar = safeuuid(); + var btn_borrar = safeuuid(); + container.innerHTML = ` +

Persona

+
+ + + + + + + + +
+ + +
+ `; + var resized = ""; + gun + .get(TABLE) + .get("personas") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_nombre).value = data["Nombre"] || ""; + document.getElementById(field_zona).value = data["Region"] || ""; + document.getElementById(field_roles).value = data["Roles"] || ""; + document.getElementById(field_puntos).value = data["Puntos"] || 0; + document.getElementById(field_anilla).value = data["SC_Anilla"] || ""; + // document.getElementById(field_foto).value = ""; + document.getElementById(render_foto).src = + data["Foto"] || "static/ico/user_generic.png"; + resized = data["Foto"] || "static/ico/user_generic.png"; + document.getElementById(field_notas).value = data["markdown"] || ""; + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document + .getElementById(field_foto) + .addEventListener("change", function (e) { + const file = e.target.files[0]; + if (!file) return; + + resizeInputImage( + file, + function (url) { + document.getElementById(render_foto).src = url; + resized = url; + }, + 125, + 0.7 + ); + }); + document.getElementById(btn_guardar).onclick = () => { + var data = { + Nombre: document.getElementById(field_nombre).value, + Region: document.getElementById(field_zona).value, + Roles: document.getElementById(field_roles).value, + Puntos: document.getElementById(field_puntos).value, + SC_Anilla: document.getElementById(field_anilla).value, + Foto: resized, + markdown: document.getElementById(field_notas).value, + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut(gun.get(TABLE).get("personas").get(mid), encrypted); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("personas"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if (confirm("¿Quieres borrar esta persona?") == true) { + betterGunPut(gun.get(TABLE).get("personas").get(mid), null); + toastr.error("Borrado!"); + setTimeout(() => { + setUrlHash("personas"); + }, 1500); + } + }; + }, + index: function () { + const tablebody = safeuuid(); + var btn_new = safeuuid(); + container.innerHTML = ` +

Personas

+ +
+ + + + + + + + + + +
NombreZonaPuntosPermisos
+ `; + tableScroll("#scrolltable"); // id="scrolltable" + var tablebody_EL = document.getElementById(tablebody); + var rows = {}; + function render() { + function sorter(a, b) { + if (a.Region.toUpperCase() < b.Region.toUpperCase()) { + return -1; + } + if (a.Region.toUpperCase() > b.Region.toUpperCase()) { + return 1; + } + return 0; + } + var tablebody_EL = document.getElementById(tablebody); + tablebody_EL.innerHTML = ""; + // SC_Personas = rows + Object.values(rows) + .sort(sorter) + .forEach((data) => { + var btn_comanda = safeuuid(); + var new_tr = document.createElement("tr"); + new_tr.innerHTML = ` +
${data.Nombre || ""} + ${data.Region || "?"} + ${data.Puntos || 0} + ${data.Roles || ""} + `; + + // + var act = parseFloat(data.Puntos); + if (act >= 10) { + new_tr.style.backgroundColor = "gold"; + } + new_tr.onclick = () => { + setUrlHash("personas," + data._key); + }; + tablebody_EL.append(new_tr); + // document.getElementById(btn_comanda).onclick = (e) => { + // setUrlHash("ventas," + data._key); + // if (!e) var e = window.event; + // e.cancelBubble = true; + // if (e.stopPropagation) e.stopPropagation(); + // }; + }); + } + gun + .get(TABLE) + .get("personas") + .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); + } + } + }); + document.getElementById(btn_new).onclick = () => { + setUrlHash("personas," + safeuuid("")); + }; + }, +}; diff --git a/dist/page__resumen_diario.js b/dist/page__resumen_diario.js new file mode 100644 index 0000000..d63fdb6 --- /dev/null +++ b/dist/page__resumen_diario.js @@ -0,0 +1,146 @@ +PAGES.resumen_diario = { + navcss: "btn3", + Title: "Resumen Semanal", + index: function () { + var table_materialesLow = safeuuid(); + var table_personasHigh = safeuuid(); + container.innerHTML = ` +

Resumen Semanal

+

Personas con café gratis (para el Viernes)

+
+

Materiales faltantes (o por llegar)

+
+ `; + var materiales_low = {}; + var personas_high = {}; + function render_materialesLow() { + function sorter(a, b) { + if (a.Nombre < b.Nombre) { + return -1; + } + if (a.Nombre > b.Nombre) { + return 1; + } + return 0; + } + var tablebody_EL = document.getElementById(table_materialesLow); + tablebody_EL.innerHTML = ""; + Object.values(materiales_low) + .sort(sorter) + .forEach((data) => { + var min = parseFloat(data.Cantidad_Minima); + var act = parseFloat(data.Cantidad); + var falta = min - act; + if (act < min) { + var new_tr = document.createElement("span"); + new_tr.innerHTML = `${data.Nombre || "?"}
Faltan ${ + falta || "?" + } ${data.Unidad || "?"}
${ + data.Ubicacion || "?" + }`; + new_tr.className = PAGES["materiales"].navcss; + new_tr.style.display = "inline-block"; + new_tr.style.margin = "5px"; + new_tr.style.padding = "5px"; + new_tr.style.borderRadius = "5px"; + new_tr.style.border = "2px solid black"; + new_tr.style.cursor = "pointer"; + new_tr.onclick = () => { + setUrlHash("materiales," + data._key); + }; + tablebody_EL.append(new_tr); + } + }); + } + gun + .get(TABLE) + .get("materiales") + .map() + .on((data, key, _msg, _ev) => { + EVENTLISTENER2 = _ev; + if (data != null) { + function add_row(data, key) { + if (data != null) { + data["_key"] = key; + materiales_low[key] = data; + } else { + delete materiales_low[key]; + } + render_materialesLow(); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + add_row(data, key); + }); + } else { + add_row(data, key); + } + } + }); + function render_personasHigh() { + function sorter(a, b) { + if (a.Nombre < b.Nombre) { + return -1; + } + if (a.Nombre > b.Nombre) { + return 1; + } + return 0; + } + var tablebody_EL = document.getElementById(table_personasHigh); + tablebody_EL.innerHTML = ""; + Object.values(personas_high) + .sort(sorter) + .forEach((data) => { + if (data.Puntos >= 10) { + var new_tr = document.createElement("span"); + new_tr.innerHTML = `${ + data.Nombre || "?" + }
Tiene ${ + data.Puntos || "?" + } puntos
${data.Region || "?"}`; + new_tr.className = PAGES["personas"].navcss; + new_tr.style.display = "inline-block"; + new_tr.style.margin = "5px"; + new_tr.style.padding = "5px"; + new_tr.style.borderRadius = "5px"; + new_tr.style.border = "2px solid black"; + new_tr.style.cursor = "pointer"; + new_tr.style.width = "200px"; + + new_tr.onclick = () => { + setUrlHash("personas," + data._key); + }; + tablebody_EL.append(new_tr); + } + }); + } + gun + .get(TABLE) + .get("personas") + .map() + .on((data, key, _msg, _ev) => { + EVENTLISTENER = _ev; + if (data != null) { + function add_row(data, key) { + if (data != null) { + data["_key"] = key; + personas_high[key] = data; + } else { + delete personas_high[key]; + } + render_personasHigh(); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + add_row(data, key); + }); + } else { + add_row(data, key); + } + } + }); + }, +}; diff --git a/dist/page__supercafe.js b/dist/page__supercafe.js new file mode 100644 index 0000000..b553ad5 --- /dev/null +++ b/dist/page__supercafe.js @@ -0,0 +1,315 @@ +PAGES.supercafe = { + navcss: "btn5", + Title: "SuperCafé", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_fecha = safeuuid(); + var field_persona = safeuuid(); + var field_comanda = safeuuid(); + var field_notas = safeuuid(); + var field_estado = safeuuid(); + var div_actions = safeuuid(); + var btn_pagos = safeuuid(); + var btn_cocina = safeuuid(); + var btn_guardar = safeuuid(); + var btn_guardar2 = safeuuid(); + var btn_borrar = safeuuid(); + container.innerHTML = ` +

Comanda

+ +
+ Rellenar comanda + + + +
+ +
+ + + + +
+ `; + var currentData = {}; + var currentPersonaID = ""; + var divact = document.getElementById(div_actions); + + function loadActions() { + divact.innerHTML = ""; + addCategory_Personas(divact, SC_Personas, currentPersonaID, (value) => { + document.getElementById(field_persona).value = value; + }); + Object.entries(SC_actions).forEach((category) => { + addCategory( + divact, + category[0], + SC_actions_icons[category[0]], + category[1], + currentData, + (values) => { + document.getElementById(field_comanda).value = SC_parse(values); + } + ); + }); + } + loadActions(); + gun + .get(TABLE) + .get("supercafe") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_fecha).value = data["Fecha"]; + document.getElementById(field_persona).value = + data["Persona"] || ""; + currentPersonaID = data["Persona"] || ""; + document.getElementById(field_comanda).value = + SC_parse(JSON.parse(data["Comanda"] || "{}")) || ""; + document.getElementById(field_notas).value = data["Notas"] || ""; + document.getElementById(field_estado).value = data["Estado"] || ""; + currentData = JSON.parse(data["Comanda"] || "{}"); + + loadActions(); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document.getElementById(btn_guardar).onclick = () => { + if (document.getElementById(field_persona).value == "") { + alert("¡Hay que elegir una persona!"); + return; + } + var data = { + Fecha: document.getElementById(field_fecha).value, + Persona: document.getElementById(field_persona).value, + Comanda: JSON.stringify(currentData), + Notas: document.getElementById(field_notas).value, + Estado: document + .getElementById(field_estado) + .value.replace("%%", "Pedido"), + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut(gun.get(TABLE).get("supercafe").get(mid), encrypted); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("supercafe"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if ( + confirm( + "¿Quieres borrar esta comanda? - NO se actualizaran los puntos de la persona asignada." + ) == true + ) { + betterGunPut(gun.get(TABLE).get("supercafe").get(mid), null); + setTimeout(() => { + setUrlHash("supercafe"); + }, 1500); + } + }; + }, + index: function () { + var tts = false; + var sc_nobtn = ""; + if (urlParams.get("sc_nobtn") == "yes") { + sc_nobtn = "pointer-events: none; opacity: 0.5"; + } + setTimeout(() => { + tts = true; + console.log("TTS Enabled"); + toastr.info("Texto a voz disponible"); + }, 6500); + const tablebody = safeuuid(); + const tablebody2 = safeuuid(); + var btn_new = safeuuid(); + var tts_check = safeuuid(); + var old = {}; + container.innerHTML = ` +

SuperCafé

+ +
+ + +
+ Todas las comandas +
+
+
+
+ Deudas +
+
+
+ `; + + //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; " /> +
+ Hay una nueva versión de TeleSec.
Pulsa aqui para actualizar. +
@@ -131,2496 +136,18 @@ } getQuota(); -
- Hay una nueva versión de TeleSec.
Pulsa aqui para actualizar. -
- - - - - + + + + + + + + + + + + + diff --git a/src/page__exportar.js b/src/page__exportar.js new file mode 100644 index 0000000..9b8e895 --- /dev/null +++ b/src/page__exportar.js @@ -0,0 +1,89 @@ +PAGES.exportar = { + navcss: "btn1", + Title: "Exportar", + index: function () { + var select_type = safeuuid(); + var textarea_content = safeuuid(); + var button_export_local = safeuuid(); + var button_export_safe = safeuuid(); + var button_export_safe_cloud = safeuuid(); + var button_clear = safeuuid(); + container.innerHTML = ` +

Exportar Datos

+
+ Exportar datos + Al pulsar, Espera hasta que salga una notificacion verde. +
+
+ + + + +
+ `; + document.getElementById(button_export_local).onclick = () => { + var data_export = {}; + var output = { + materiales: {}, + personas: {}, + }; + var download_data = (DATA) => { + Object.keys(DATA).forEach((modul) => { + Object.entries(DATA[modul] || {}).forEach((entry) => { + var key = entry[0]; + var value = entry[1]; + if (value != null) { + if (typeof value == "string") { + SEA.decrypt(value, SECRET, (data) => { + output[modul][key] = data; + }); + } else { + output[modul][key] = value; + } + } + }); + toastr.success("Exportado todo, descargando!"); + console.error(output); + download( + `Export TeleSec ${GROUPID}.json.txt`, + JSON.stringify(output) + ); + //setUrlHash(sel); + }, 2500); + }; + gun.get(TABLE).load(download_data); + }; + document.getElementById(button_export_safe).onclick = () => { + var download_data = (DATA) => { + toastr.success("Exportado todo, descargado!"); + console.error(DATA); + download( + `Export TeleSec Encriptado ${GROUPID}.json.txt`, + JSON.stringify(DATA) + ); + //setUrlHash(sel); + }; + gun.get(TABLE).load(download_data); + }; + document.getElementById(button_export_safe_cloud).onclick = () => { + var download_data = (DATA) => { + toastr.info("Exportado todo, subiendo!"); + console.error(DATA); + fetch( + "https://telesec-sync.tech.eus/upload_backup.php?table=" + GROUPID, + { + method: "POST", + body: JSON.stringify(DATA), + } + ) + .then(() => { + toastr.success("Subido correctamente!"); + }) + .catch(() => { + toastr.error("Ha ocurrido un error en la subida."); + }); + }; + gun.get(TABLE).load(download_data); + }; + }, +}; diff --git a/src/page__importar.js b/src/page__importar.js new file mode 100644 index 0000000..4d3c8a0 --- /dev/null +++ b/src/page__importar.js @@ -0,0 +1,54 @@ +PAGES.importar = { + navcss: "btn1", + Title: "Importar", + index: function () { + var select_type = safeuuid(); + var textarea_content = safeuuid(); + var button_import = safeuuid(); + var button_clear = safeuuid(); + container.innerHTML = ` +

Importar Datos

+
+ Importar datos + Espera hasta que se vacien todas las notificaciones. + + + + +
+ `; + document.getElementById(button_import).onclick = () => { + toastr.info("Importando datos..."); + var val = document.getElementById(textarea_content).value; + var sel = document.getElementById(select_type).value; + if (sel == "%telesec") { + gun.get(TABLE).put(JSON.parse(val), (ack) => { + toastr.info("Importado " + entry[0] + "."); + }); + } else { + Object.entries(JSON.parse(val)["data"]).forEach((entry) => { + var enc = SEA.encrypt(entry[1], SECRET, (encrypted) => { + betterGunPut(gun.get(TABLE).get(sel).get(entry[0]), encrypted); + }); + }); + } + setTimeout(() => { + toastr.info("Importado todo!"); + + if (sel == "%telesec") { + setUrlHash("inicio"); + } else { + setUrlHash(sel); + } + }, 5000); + }; + }, +}; diff --git a/src/page__index.js b/src/page__index.js new file mode 100644 index 0000000..145327d --- /dev/null +++ b/src/page__index.js @@ -0,0 +1,11 @@ +PAGES.index = { + //navcss: "btn1", + Title: "Inicio", + index: function () { + container.innerHTML = ` +

Inicio

+ Utiliza el menú superior para abrir un modulo +

+ `; + }, +}; diff --git a/src/page__materiales.js b/src/page__materiales.js new file mode 100644 index 0000000..9a2cc83 --- /dev/null +++ b/src/page__materiales.js @@ -0,0 +1,194 @@ +PAGES.materiales = { + navcss: "btn2", + Title: "Materiales", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_nombre = safeuuid(); + var field_cantidad = safeuuid(); + var field_unidad = safeuuid(); + var field_cantidad_min = safeuuid(); + var field_abierto = safeuuid(); + var field_ubicacion = safeuuid(); + var field_referencia = safeuuid(); + var field_notas = safeuuid(); + var btn_guardar = safeuuid(); + var btn_borrar = safeuuid(); + container.innerHTML = ` +

Material

+
+ + + + + + +
+ + +
+ `; + gun + .get(TABLE) + .get("materiales") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_nombre).value = data["Nombre"] || ""; + document.getElementById(field_unidad).value = data["Unidad"] || ""; + document.getElementById(field_cantidad).value = + data["Cantidad"] || ""; + document.getElementById(field_cantidad_min).value = + data["Cantidad_Minima"] || ""; + document.getElementById(field_ubicacion).value = + data["Ubicacion"] || "-"; + document.getElementById(field_referencia).value = + data["Referencia"] || "?"; + document.getElementById(field_notas).value = data["Notas"] || ""; + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document.getElementById(btn_guardar).onclick = () => { + var data = { + Nombre: document.getElementById(field_nombre).value, + Unidad: document.getElementById(field_unidad).value, + Cantidad: document.getElementById(field_cantidad).value, + Cantidad_Minima: document.getElementById(field_cantidad_min).value, + Ubicacion: document.getElementById(field_ubicacion).value, + Referencia: document.getElementById(field_referencia).value, + Notas: document.getElementById(field_notas).value, + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut(gun.get(TABLE).get("materiales").get(mid), encrypted); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("materiales"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if (confirm("¿Quieres borrar este material?") == true) { + betterGunPut(gun.get(TABLE).get("materiales").get(mid), null); + toastr.error("Borrado!"); + setTimeout(() => { + setUrlHash("materiales"); + }, 1500); + } + }; + }, + index: function () { + const tablebody = safeuuid(); + var btn_new = safeuuid(); + container.innerHTML = ` +

Materiales

+ +
+ + + + + + + + + + + +
ReferenciaNombreUbicaciónCantidadNotas
+ `; + tableScroll("#scrolltable"); + var tablebody_EL = document.getElementById(tablebody); + var rows = {}; + function render() { + function sorter(a, b) { + if (a.Nombre < b.Nombre) { + return -1; + } + if (a.Nombre > b.Nombre) { + 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"); + new_tr.innerHTML = ` + ${data.Referencia || "?"} + ${data.Nombre || "?"} + ${data.Ubicacion || "?"} + ${data.Cantidad || "?"} ${data.Unidad || "?"} + ${data.Notas || "?"} + `; + var min = parseFloat(data.Cantidad_Minima); + var act = parseFloat(data.Cantidad); + if (act < min) { + new_tr.style.backgroundColor = "lightcoral"; + } + new_tr.onclick = () => { + setUrlHash("materiales," + data._key); + }; + tablebody_EL.append(new_tr); + }); + } + gun + .get(TABLE) + .get("materiales") + .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); + } + } + }); + document.getElementById(btn_new).onclick = () => { + setUrlHash("materiales," + safeuuid("")); + }; + }, + } \ No newline at end of file diff --git a/src/page__notificaciones.js b/src/page__notificaciones.js new file mode 100644 index 0000000..78114a2 --- /dev/null +++ b/src/page__notificaciones.js @@ -0,0 +1,217 @@ +PAGES.notificaciones = { + navcss: "btn6", + Title: "Notificaciones", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_fecha = safeuuid(); + var field_asunto = safeuuid(); + var field_origen = safeuuid(); + var field_destino = safeuuid(); + var field_estado = safeuuid(); + var field_mensaje = safeuuid(); + var field_respuesta = safeuuid(); + var btn_leer = safeuuid(); + var btn_desleer = safeuuid(); + var btn_guardar = safeuuid(); + var btn_borrar = safeuuid(); + var div_actions = safeuuid(); + container.innerHTML = ` +

Notificación

+
+ Valores + + + + +
+ + +
+ + +
+ `; + document.getElementById(btn_leer).onclick = () => { + document.getElementById(field_estado).value = "leido"; + }; + document.getElementById(btn_desleer).onclick = () => { + document.getElementById(field_estado).value = "por_leer"; + }; + var divact = document.getElementById(div_actions); + addCategory_Personas( + divact, + SC_Personas, + "", + (value) => { + document.getElementById(field_origen).value = value; + }, + "Origen" + ); + addCategory_Personas( + divact, + SC_Personas, + "", + (value) => { + document.getElementById(field_destino).value = value; + }, + "Destino" + ); + gun + .get(TABLE) + .get("notificaciones") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_fecha).value = data["Fecha"]; + document.getElementById(field_asunto).value = data["Asunto"] || ""; + document.getElementById(field_mensaje).value = + data["Mensaje"] || ""; + document.getElementById(field_origen).value = data["Origen"] || ""; + document.getElementById(field_destino).value = + data["Destino"] || ""; + document.getElementById(field_estado).value = data["Estado"] || ""; + document.getElementById(field_respuesta).value = + data["Respuesta"] || ""; + + // Persona select + divact.innerHTML = ""; + addCategory_Personas( + divact, + SC_Personas, + data["Origen"] || "", + (value) => { + document.getElementById(field_origen).value = value; + }, + "Origen" + ); + addCategory_Personas( + divact, + SC_Personas, + data["Destino"] || "", + (value) => { + document.getElementById(field_destino).value = value; + }, + "Destino" + ); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document.getElementById(btn_guardar).onclick = () => { + if (document.getElementById(field_origen).value == "") { + alert("¡Hay que elegir una persona de origen!"); + return; + } + if (document.getElementById(field_destino).value == "") { + alert("¡Hay que elegir una persona de origen!"); + return; + } + var data = { + Fecha: document.getElementById(field_fecha).value, + Origen: document.getElementById(field_origen).value, + Destino: document.getElementById(field_destino).value, + Mensaje: document.getElementById(field_mensaje).value, + Respuesta: document.getElementById(field_respuesta).value, + Asunto: document.getElementById(field_asunto).value, + Estado: document + .getElementById(field_estado) + .value.replace("%%", "por_leer"), + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut( + gun.get(TABLE).get("notificaciones").get(mid), + encrypted + ); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("notificaciones"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if (confirm("¿Quieres borrar esta notificación?") == true) { + betterGunPut(gun.get(TABLE).get("notificaciones").get(mid), null); + toastr.error("Borrado!"); + setTimeout(() => { + setUrlHash("notificaciones"); + }, 1500); + } + }; + }, + index: function () { + const tablebody = safeuuid(); + var btn_new = safeuuid(); + container.innerHTML = ` +

Notificaciones

+ +
+ `; + TS_IndexElement( + "notificaciones", + [ + { + key: "Origen", + type: "persona", + default: "", + label: "Origen", + }, + { + key: "Destino", + type: "persona", + default: "", + label: "Destino", + }, + { + key: "Asunto", + type: "raw", + default: "", + label: "Asunto", + }, + { + key: "Estado", + type: "raw", + default: "", + label: "Estado", + }, + ], + gun.get(TABLE).get("notificaciones"), + document.querySelector("#cont"), + (data, new_tr) => { + new_tr.style.backgroundColor = "#FFCCCB"; + if (data.Estado == "leido") { + new_tr.style.backgroundColor = "lightgreen"; + } + } + ); + document.getElementById(btn_new).onclick = () => { + setUrlHash("notificaciones," + safeuuid("")); + }; + }, + } \ No newline at end of file diff --git a/src/page__personas.js b/src/page__personas.js new file mode 100644 index 0000000..4ec3529 --- /dev/null +++ b/src/page__personas.js @@ -0,0 +1,224 @@ +PAGES.personas = { + navcss: "btn4", + Title: "Personas", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_nombre = safeuuid(); + var field_zona = safeuuid(); + var field_roles = safeuuid(); + var field_puntos = safeuuid(); + var field_notas = safeuuid(); + var field_anilla = safeuuid(); + var field_foto = safeuuid(); + var render_foto = safeuuid(); + var btn_guardar = safeuuid(); + var btn_borrar = safeuuid(); + container.innerHTML = ` +

Persona

+
+ + + + + + + + +
+ + +
+ `; + var resized = ""; + gun + .get(TABLE) + .get("personas") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_nombre).value = data["Nombre"] || ""; + document.getElementById(field_zona).value = data["Region"] || ""; + document.getElementById(field_roles).value = data["Roles"] || ""; + document.getElementById(field_puntos).value = data["Puntos"] || 0; + document.getElementById(field_anilla).value = data["SC_Anilla"] || ""; + // document.getElementById(field_foto).value = ""; + document.getElementById(render_foto).src = + data["Foto"] || "static/ico/user_generic.png"; + resized = data["Foto"] || "static/ico/user_generic.png"; + document.getElementById(field_notas).value = data["markdown"] || ""; + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document + .getElementById(field_foto) + .addEventListener("change", function (e) { + const file = e.target.files[0]; + if (!file) return; + + resizeInputImage( + file, + function (url) { + document.getElementById(render_foto).src = url; + resized = url; + }, + 125, + 0.7 + ); + }); + document.getElementById(btn_guardar).onclick = () => { + var data = { + Nombre: document.getElementById(field_nombre).value, + Region: document.getElementById(field_zona).value, + Roles: document.getElementById(field_roles).value, + Puntos: document.getElementById(field_puntos).value, + SC_Anilla: document.getElementById(field_anilla).value, + Foto: resized, + markdown: document.getElementById(field_notas).value, + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut(gun.get(TABLE).get("personas").get(mid), encrypted); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("personas"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if (confirm("¿Quieres borrar esta persona?") == true) { + betterGunPut(gun.get(TABLE).get("personas").get(mid), null); + toastr.error("Borrado!"); + setTimeout(() => { + setUrlHash("personas"); + }, 1500); + } + }; + }, + index: function () { + const tablebody = safeuuid(); + var btn_new = safeuuid(); + container.innerHTML = ` +

Personas

+ +
+ + + + + + + + + + +
NombreZonaPuntosPermisos
+ `; + tableScroll("#scrolltable"); // id="scrolltable" + var tablebody_EL = document.getElementById(tablebody); + var rows = {}; + function render() { + function sorter(a, b) { + if (a.Region.toUpperCase() < b.Region.toUpperCase()) { + return -1; + } + if (a.Region.toUpperCase() > b.Region.toUpperCase()) { + return 1; + } + return 0; + } + var tablebody_EL = document.getElementById(tablebody); + tablebody_EL.innerHTML = ""; + // SC_Personas = rows + Object.values(rows) + .sort(sorter) + .forEach((data) => { + var btn_comanda = safeuuid(); + var new_tr = document.createElement("tr"); + new_tr.innerHTML = ` +
${data.Nombre || ""} + ${data.Region || "?"} + ${data.Puntos || 0} + ${data.Roles || ""} + `; + + // + var act = parseFloat(data.Puntos); + if (act >= 10) { + new_tr.style.backgroundColor = "gold"; + } + new_tr.onclick = () => { + setUrlHash("personas," + data._key); + }; + tablebody_EL.append(new_tr); + // document.getElementById(btn_comanda).onclick = (e) => { + // setUrlHash("ventas," + data._key); + // if (!e) var e = window.event; + // e.cancelBubble = true; + // if (e.stopPropagation) e.stopPropagation(); + // }; + }); + } + gun + .get(TABLE) + .get("personas") + .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); + } + } + }); + document.getElementById(btn_new).onclick = () => { + setUrlHash("personas," + safeuuid("")); + }; + }, +}; diff --git a/src/page__resumen_diario.js b/src/page__resumen_diario.js new file mode 100644 index 0000000..d63fdb6 --- /dev/null +++ b/src/page__resumen_diario.js @@ -0,0 +1,146 @@ +PAGES.resumen_diario = { + navcss: "btn3", + Title: "Resumen Semanal", + index: function () { + var table_materialesLow = safeuuid(); + var table_personasHigh = safeuuid(); + container.innerHTML = ` +

Resumen Semanal

+

Personas con café gratis (para el Viernes)

+
+

Materiales faltantes (o por llegar)

+
+ `; + var materiales_low = {}; + var personas_high = {}; + function render_materialesLow() { + function sorter(a, b) { + if (a.Nombre < b.Nombre) { + return -1; + } + if (a.Nombre > b.Nombre) { + return 1; + } + return 0; + } + var tablebody_EL = document.getElementById(table_materialesLow); + tablebody_EL.innerHTML = ""; + Object.values(materiales_low) + .sort(sorter) + .forEach((data) => { + var min = parseFloat(data.Cantidad_Minima); + var act = parseFloat(data.Cantidad); + var falta = min - act; + if (act < min) { + var new_tr = document.createElement("span"); + new_tr.innerHTML = `${data.Nombre || "?"}
Faltan ${ + falta || "?" + } ${data.Unidad || "?"}
${ + data.Ubicacion || "?" + }`; + new_tr.className = PAGES["materiales"].navcss; + new_tr.style.display = "inline-block"; + new_tr.style.margin = "5px"; + new_tr.style.padding = "5px"; + new_tr.style.borderRadius = "5px"; + new_tr.style.border = "2px solid black"; + new_tr.style.cursor = "pointer"; + new_tr.onclick = () => { + setUrlHash("materiales," + data._key); + }; + tablebody_EL.append(new_tr); + } + }); + } + gun + .get(TABLE) + .get("materiales") + .map() + .on((data, key, _msg, _ev) => { + EVENTLISTENER2 = _ev; + if (data != null) { + function add_row(data, key) { + if (data != null) { + data["_key"] = key; + materiales_low[key] = data; + } else { + delete materiales_low[key]; + } + render_materialesLow(); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + add_row(data, key); + }); + } else { + add_row(data, key); + } + } + }); + function render_personasHigh() { + function sorter(a, b) { + if (a.Nombre < b.Nombre) { + return -1; + } + if (a.Nombre > b.Nombre) { + return 1; + } + return 0; + } + var tablebody_EL = document.getElementById(table_personasHigh); + tablebody_EL.innerHTML = ""; + Object.values(personas_high) + .sort(sorter) + .forEach((data) => { + if (data.Puntos >= 10) { + var new_tr = document.createElement("span"); + new_tr.innerHTML = `${ + data.Nombre || "?" + }
Tiene ${ + data.Puntos || "?" + } puntos
${data.Region || "?"}`; + new_tr.className = PAGES["personas"].navcss; + new_tr.style.display = "inline-block"; + new_tr.style.margin = "5px"; + new_tr.style.padding = "5px"; + new_tr.style.borderRadius = "5px"; + new_tr.style.border = "2px solid black"; + new_tr.style.cursor = "pointer"; + new_tr.style.width = "200px"; + + new_tr.onclick = () => { + setUrlHash("personas," + data._key); + }; + tablebody_EL.append(new_tr); + } + }); + } + gun + .get(TABLE) + .get("personas") + .map() + .on((data, key, _msg, _ev) => { + EVENTLISTENER = _ev; + if (data != null) { + function add_row(data, key) { + if (data != null) { + data["_key"] = key; + personas_high[key] = data; + } else { + delete personas_high[key]; + } + render_personasHigh(); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + add_row(data, key); + }); + } else { + add_row(data, key); + } + } + }); + }, +}; diff --git a/src/page__supercafe.js b/src/page__supercafe.js new file mode 100644 index 0000000..b553ad5 --- /dev/null +++ b/src/page__supercafe.js @@ -0,0 +1,315 @@ +PAGES.supercafe = { + navcss: "btn5", + Title: "SuperCafé", + edit: function (mid) { + var nameh1 = safeuuid(); + var field_fecha = safeuuid(); + var field_persona = safeuuid(); + var field_comanda = safeuuid(); + var field_notas = safeuuid(); + var field_estado = safeuuid(); + var div_actions = safeuuid(); + var btn_pagos = safeuuid(); + var btn_cocina = safeuuid(); + var btn_guardar = safeuuid(); + var btn_guardar2 = safeuuid(); + var btn_borrar = safeuuid(); + container.innerHTML = ` +

Comanda

+ +
+ Rellenar comanda + + + +
+ +
+ + + + +
+ `; + var currentData = {}; + var currentPersonaID = ""; + var divact = document.getElementById(div_actions); + + function loadActions() { + divact.innerHTML = ""; + addCategory_Personas(divact, SC_Personas, currentPersonaID, (value) => { + document.getElementById(field_persona).value = value; + }); + Object.entries(SC_actions).forEach((category) => { + addCategory( + divact, + category[0], + SC_actions_icons[category[0]], + category[1], + currentData, + (values) => { + document.getElementById(field_comanda).value = SC_parse(values); + } + ); + }); + } + loadActions(); + gun + .get(TABLE) + .get("supercafe") + .get(mid) + .once((data, key) => { + function load_data(data, ENC = "") { + document.getElementById(nameh1).innerText = key; + document.getElementById(field_fecha).value = data["Fecha"]; + document.getElementById(field_persona).value = + data["Persona"] || ""; + currentPersonaID = data["Persona"] || ""; + document.getElementById(field_comanda).value = + SC_parse(JSON.parse(data["Comanda"] || "{}")) || ""; + document.getElementById(field_notas).value = data["Notas"] || ""; + document.getElementById(field_estado).value = data["Estado"] || ""; + currentData = JSON.parse(data["Comanda"] || "{}"); + + loadActions(); + } + if (typeof data == "string") { + SEA.decrypt(data, SECRET, (data) => { + load_data(data, "%E"); + }); + } else { + load_data(data); + } + }); + document.getElementById(btn_guardar).onclick = () => { + if (document.getElementById(field_persona).value == "") { + alert("¡Hay que elegir una persona!"); + return; + } + var data = { + Fecha: document.getElementById(field_fecha).value, + Persona: document.getElementById(field_persona).value, + Comanda: JSON.stringify(currentData), + Notas: document.getElementById(field_notas).value, + Estado: document + .getElementById(field_estado) + .value.replace("%%", "Pedido"), + }; + var enc = SEA.encrypt(data, SECRET, (encrypted) => { + document.getElementById("actionStatus").style.display = "block"; + betterGunPut(gun.get(TABLE).get("supercafe").get(mid), encrypted); + toastr.success("Guardado!"); + setTimeout(() => { + document.getElementById("actionStatus").style.display = "none"; + setUrlHash("supercafe"); + }, 1500); + }); + }; + document.getElementById(btn_borrar).onclick = () => { + if ( + confirm( + "¿Quieres borrar esta comanda? - NO se actualizaran los puntos de la persona asignada." + ) == true + ) { + betterGunPut(gun.get(TABLE).get("supercafe").get(mid), null); + setTimeout(() => { + setUrlHash("supercafe"); + }, 1500); + } + }; + }, + index: function () { + var tts = false; + var sc_nobtn = ""; + if (urlParams.get("sc_nobtn") == "yes") { + sc_nobtn = "pointer-events: none; opacity: 0.5"; + } + setTimeout(() => { + tts = true; + console.log("TTS Enabled"); + toastr.info("Texto a voz disponible"); + }, 6500); + const tablebody = safeuuid(); + const tablebody2 = safeuuid(); + var btn_new = safeuuid(); + var tts_check = safeuuid(); + var old = {}; + container.innerHTML = ` +

SuperCafé

+ +
+ + +
+ Todas las comandas +
+
+
+
+ Deudas +
+
+
+ `; + + //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/src/pwa.js b/src/pwa.js new file mode 100644 index 0000000..6a97603 --- /dev/null +++ b/src/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/sw.js b/src/sw.js index d2412c1..e6bece0 100644 --- a/src/sw.js +++ b/src/sw.js @@ -1,5 +1,6 @@ var cacheName = 'telesec_%%VERSIONCO%%'; + self.addEventListener('install', event => { event.waitUntil( caches.open(cacheName)