Modularized, fixed SuperCafe's table
This commit is contained in:
169
_assets.json
169
_assets.json
@@ -1,86 +1,85 @@
|
|||||||
[
|
[
|
||||||
"icon512_maskable.png",
|
"icon512_maskable.png",
|
||||||
"icon512_rounded.png",
|
"icon512_rounded.png",
|
||||||
"index.html",
|
"manifest.json",
|
||||||
"manifest.json",
|
"static/axe.js",
|
||||||
"static/axe.js",
|
"static/doublescroll.js",
|
||||||
"static/doublescroll.js",
|
"static/gun.js",
|
||||||
"static/gun.js",
|
"static/jquery.js",
|
||||||
"static/jquery.js",
|
"static/load.js",
|
||||||
"static/load.js",
|
"static/open.js",
|
||||||
"static/open.js",
|
"static/path.js",
|
||||||
"static/path.js",
|
"static/radisk.js",
|
||||||
"static/radisk.js",
|
"static/radix.js",
|
||||||
"static/radix.js",
|
"static/rindexed.js",
|
||||||
"static/rindexed.js",
|
"static/sea.js",
|
||||||
"static/sea.js",
|
"static/showdown.min.js",
|
||||||
"static/showdown.min.js",
|
"static/simplemde.min.css",
|
||||||
"static/simplemde.min.css",
|
"static/simplemde.min.js",
|
||||||
"static/simplemde.min.js",
|
"static/store.js",
|
||||||
"static/store.js",
|
"static/synchronous.js",
|
||||||
"static/synchronous.js",
|
"static/TeleSec.jpg",
|
||||||
"static/TeleSec.jpg",
|
"static/toastr.min.css",
|
||||||
"static/toastr.min.css",
|
"static/toastr.min.js",
|
||||||
"static/toastr.min.js",
|
"static/webrtc.js",
|
||||||
"static/webrtc.js",
|
"static/yson.js",
|
||||||
"static/yson.js",
|
"static/ico/add.png",
|
||||||
"static/ico/add.png",
|
"static/ico/azucar-moreno.png",
|
||||||
"static/ico/azucar-moreno.png",
|
"static/ico/azucar-blanco.jpg",
|
||||||
"static/ico/azucar-blanco.jpg",
|
"static/ico/stevia.jpg",
|
||||||
"static/ico/stevia.jpg",
|
"static/ico/stevia-gotas.webp",
|
||||||
"static/ico/stevia-gotas.webp",
|
"static/ico/sacarina.jpg",
|
||||||
"static/ico/sacarina.jpg",
|
"static/ico/arrow_down_blue.png",
|
||||||
"static/ico/arrow_down_blue.png",
|
"static/ico/arrow_left_green.png",
|
||||||
"static/ico/arrow_left_green.png",
|
"static/ico/arrow_up_red.png",
|
||||||
"static/ico/arrow_up_red.png",
|
"static/ico/camera2.png",
|
||||||
"static/ico/camera2.png",
|
"static/ico/cereales.png",
|
||||||
"static/ico/cereales.png",
|
"static/ico/checkbox.png",
|
||||||
"static/ico/checkbox.png",
|
"static/ico/checkbox_unchecked.png",
|
||||||
"static/ico/checkbox_unchecked.png",
|
"static/ico/connect_ok.svg",
|
||||||
"static/ico/connect_ok.svg",
|
"static/ico/connect_ko.svg",
|
||||||
"static/ico/connect_ko.svg",
|
"static/ico/coffee_bean.png",
|
||||||
"static/ico/coffee_bean.png",
|
"static/ico/colacao.jpg",
|
||||||
"static/ico/colacao.jpg",
|
"static/ico/cookies.png",
|
||||||
"static/ico/cookies.png",
|
"static/ico/cow.png",
|
||||||
"static/ico/cow.png",
|
"static/ico/delete.png",
|
||||||
"static/ico/delete.png",
|
"static/ico/fire.png",
|
||||||
"static/ico/fire.png",
|
"static/ico/keyboard_key_g.png",
|
||||||
"static/ico/keyboard_key_g.png",
|
"static/ico/keyboard_key_p.png",
|
||||||
"static/ico/keyboard_key_p.png",
|
"static/ico/lollipop.png",
|
||||||
"static/ico/lollipop.png",
|
"static/ico/milk.png",
|
||||||
"static/ico/milk.png",
|
"static/ico/preferences.png",
|
||||||
"static/ico/preferences.png",
|
"static/ico/sizes.png",
|
||||||
"static/ico/sizes.png",
|
"static/ico/statusok.png",
|
||||||
"static/ico/statusok.png",
|
"static/ico/snowflake.png",
|
||||||
"static/ico/snowflake.png",
|
"static/ico/tea_bag.png",
|
||||||
"static/ico/tea_bag.png",
|
"static/ico/thermometer2.png",
|
||||||
"static/ico/thermometer2.png",
|
"static/ico/user.png",
|
||||||
"static/ico/user.png",
|
"static/ico/user_generic.png",
|
||||||
"static/ico/user_generic.png",
|
"static/ico/water_tap.png",
|
||||||
"static/ico/water_tap.png",
|
"static/ico/wheat.png",
|
||||||
"static/ico/wheat.png",
|
"static/ico/layered1/Azucar-Az. Blanco.png",
|
||||||
"static/ico/layered1/Azucar-Az. Blanco.png",
|
"static/ico/layered1/Azucar-Az. Moreno.png",
|
||||||
"static/ico/layered1/Azucar-Az. Moreno.png",
|
"static/ico/layered1/Azucar-Edulcorante.png",
|
||||||
"static/ico/layered1/Azucar-Edulcorante.png",
|
"static/ico/layered1/Azucar-Sacarina.png",
|
||||||
"static/ico/layered1/Azucar-Sacarina.png",
|
"static/ico/layered1/Azucar-Sin.png",
|
||||||
"static/ico/layered1/Azucar-Sin.png",
|
"static/ico/layered1/Azucar-Stevia (Gotas).png",
|
||||||
"static/ico/layered1/Azucar-Stevia (Gotas).png",
|
"static/ico/layered1/Azucar-Stevia (Pastillas).png",
|
||||||
"static/ico/layered1/Azucar-Stevia (Pastillas).png",
|
"static/ico/layered1/Background.png",
|
||||||
"static/ico/layered1/Background.png",
|
"static/ico/layered1/Cafeina-Con.png",
|
||||||
"static/ico/layered1/Cafeina-Con.png",
|
"static/ico/layered1/Cafeina-Sin.png",
|
||||||
"static/ico/layered1/Cafeina-Sin.png",
|
"static/ico/layered1/Leche-Agua.png",
|
||||||
"static/ico/layered1/Leche-Agua.png",
|
"static/ico/layered1/Leche-Sin lactosa.png",
|
||||||
"static/ico/layered1/Leche-Sin lactosa.png",
|
"static/ico/layered1/Leche-Vegetal.png",
|
||||||
"static/ico/layered1/Leche-Vegetal.png",
|
"static/ico/layered1/Leche-de Vaca.png",
|
||||||
"static/ico/layered1/Leche-de Vaca.png",
|
"static/ico/layered1/Selección-CafeSolo.png",
|
||||||
"static/ico/layered1/Selección-CafeSolo.png",
|
"static/ico/layered1/Selección-CaféLeche.png",
|
||||||
"static/ico/layered1/Selección-CaféLeche.png",
|
"static/ico/layered1/Selección-ColaCao.png",
|
||||||
"static/ico/layered1/Selección-ColaCao.png",
|
"static/ico/layered1/Selección-Infusion.png",
|
||||||
"static/ico/layered1/Selección-Infusion.png",
|
"static/ico/layered1/Selección-Leche.png",
|
||||||
"static/ico/layered1/Selección-Leche.png",
|
"static/ico/layered1/Tamaño-Grande.png",
|
||||||
"static/ico/layered1/Tamaño-Grande.png",
|
"static/ico/layered1/Tamaño-Pequeño.png",
|
||||||
"static/ico/layered1/Tamaño-Pequeño.png",
|
"static/ico/layered1/Temperatura-Caliente.png",
|
||||||
"static/ico/layered1/Temperatura-Caliente.png",
|
"static/ico/layered1/Temperatura-Frio.png",
|
||||||
"static/ico/layered1/Temperatura-Frio.png",
|
"static/ico/layered1/Temperatura-Templado.png"
|
||||||
"static/ico/layered1/Temperatura-Templado.png"
|
]
|
||||||
]
|
|
||||||
|
|||||||
14
build.py
14
build.py
@@ -1,10 +1,14 @@
|
|||||||
import json
|
import json
|
||||||
ASSETS = json.load(open("_assets.json", "r"))
|
import os
|
||||||
|
|
||||||
PREFETCH = ""
|
PREFETCH = ""
|
||||||
VERSIONCO = "2025-07-18_2"
|
VERSIONCO = "2025-07-30_1"
|
||||||
HANDLEPARSE = ["index.html", "sw.js"]
|
HANDLEPARSE = os.listdir("src/")
|
||||||
|
ASSETS = json.load(open("_assets.json", "r")) + HANDLEPARSE
|
||||||
for asset in ASSETS:
|
for asset in ASSETS:
|
||||||
PREFETCH += f'<link rel="prefetch" href="{asset}" />\n'
|
if asset != "sw.js":
|
||||||
|
PREFETCH += f'<link rel="prefetch" href="{asset}" />\n'
|
||||||
|
|
||||||
|
|
||||||
def replace_handles(string):
|
def replace_handles(string):
|
||||||
string = string.replace("%%PREFETCH%%", PREFETCH)
|
string = string.replace("%%PREFETCH%%", PREFETCH)
|
||||||
@@ -12,8 +16,8 @@ def replace_handles(string):
|
|||||||
string = string.replace("%%ASSETSJSON%%", json.dumps(ASSETS, ensure_ascii=False))
|
string = string.replace("%%ASSETSJSON%%", json.dumps(ASSETS, ensure_ascii=False))
|
||||||
return string
|
return string
|
||||||
|
|
||||||
for file in HANDLEPARSE:
|
|
||||||
|
|
||||||
|
for file in HANDLEPARSE:
|
||||||
with open("src/" + file, "r") as f:
|
with open("src/" + file, "r") as f:
|
||||||
out = replace_handles(f.read())
|
out = replace_handles(f.read())
|
||||||
with open("dist/" + file, "w") as f:
|
with open("dist/" + file, "w") as f:
|
||||||
|
|||||||
160
dist/app_logic.js
vendored
Normal file
160
dist/app_logic.js
vendored
Normal file
@@ -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 + "<br>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;
|
||||||
|
});
|
||||||
872
dist/app_modules.js
vendored
Normal file
872
dist/app_modules.js
vendored
Normal file
@@ -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 = `<div style="position: relative; width: 200px; height: 200px; background: white; display: inline-block; border: 1px dotted black;">`;
|
||||||
|
|
||||||
|
// Layer 1: Selección image
|
||||||
|
const selection = comanda["Selección"];
|
||||||
|
if (selectionMap[selection]) {
|
||||||
|
html += `<img id="img1-${key}" src="${
|
||||||
|
basePaths.Selección + selectionMap[selection]
|
||||||
|
}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 2: Café
|
||||||
|
if (comanda.Café) {
|
||||||
|
html += `<img id="img2-${key}" src="${basePaths.Café}Café-${comanda.Café}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 3: Endulzante
|
||||||
|
if (comanda.Endulzante) {
|
||||||
|
html += `<img id="img3-${key}" src="${basePaths.Endulzante}Azucar-${comanda.Endulzante}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 4: Cafeina
|
||||||
|
if (comanda.Cafeina) {
|
||||||
|
html += `<img id="img4-${key}" src="${basePaths.Cafeina}Cafeina-${comanda.Cafeina}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
// Layer 5: Leche
|
||||||
|
if (comanda.Leche) {
|
||||||
|
html += `<img id="img5-${key}" src="${basePaths.Leche}Leche-${comanda.Leche}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
// Layer 6: Temperatura
|
||||||
|
if (comanda.Temperatura) {
|
||||||
|
html += `<img id="img6-${key}" src="${basePaths.Leche}Temperatura-${comanda.Temperatura}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
// Layer 7: Tamaño
|
||||||
|
if (comanda.Tamaño) {
|
||||||
|
html += `<img id="img7-${key}" src="${basePaths.Leche}Tamaño-${comanda.Tamaño}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close div
|
||||||
|
html += "</div>";
|
||||||
|
|
||||||
|
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 = "<small style='font-size: 60%;'>Servicio base (10c)</small>\n";
|
||||||
|
|
||||||
|
Object.entries(json).forEach((entry) => {
|
||||||
|
valores +=
|
||||||
|
"<small style='font-size: 60%;'>" +
|
||||||
|
entry[0] +
|
||||||
|
":</small> " +
|
||||||
|
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 += "<small>(P = 10c)</small>";
|
||||||
|
}
|
||||||
|
// Leche grande = 20c
|
||||||
|
if (
|
||||||
|
json["Tamaño"] == "Grande" &&
|
||||||
|
["de Vaca", "Sin lactosa", "Vegetal"].includes(json["Leche"])
|
||||||
|
) {
|
||||||
|
valores += "<small>(G = 20c)</small>";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Selección":
|
||||||
|
// Café = 20c
|
||||||
|
if (
|
||||||
|
["Café con leche", "Solo café (sin leche)"].includes(
|
||||||
|
json["Selección"]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
valores += "<small>(20c)</small>";
|
||||||
|
}
|
||||||
|
// ColaCao = 20c
|
||||||
|
if (json["Selección"] == "ColaCao con leche") {
|
||||||
|
valores += "<small>(20c)</small>";
|
||||||
|
}
|
||||||
|
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 += "<hr>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 = `
|
||||||
|
<div id="scrolltable">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr id="${tablehead}"></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${tablebody}">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
tableScroll("#scrolltable"); // id="scrolltable"
|
||||||
|
var tablehead_EL = document.getElementById(tablehead);
|
||||||
|
var tablebody_EL = document.getElementById(tablebody);
|
||||||
|
var rows = {};
|
||||||
|
config.forEach((key) => {
|
||||||
|
tablehead_EL.innerHTML += `<th>${key.label}</th>`;
|
||||||
|
});
|
||||||
|
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) + "<hr>" + 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("#", ""));
|
||||||
|
});
|
||||||
22
dist/config.js
vendored
Normal file
22
dist/config.js
vendored
Normal file
@@ -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 = "";
|
||||||
61
dist/gun_init.js
vendored
Normal file
61
dist/gun_init.js
vendored
Normal file
@@ -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];
|
||||||
|
}
|
||||||
89
dist/page__exportar.js
vendored
Normal file
89
dist/page__exportar.js
vendored
Normal file
@@ -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 = `
|
||||||
|
<h1>Exportar Datos</h1>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Exportar datos</legend>
|
||||||
|
<em>Al pulsar, Espera hasta que salga una notificacion verde.</em>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<button id="${button_export_local}" type="button">Exportar sin cifrar</button>
|
||||||
|
<button id="${button_export_safe}" type="button">Exportar con cifrado</button>
|
||||||
|
<button id="${button_export_safe_cloud}" style="display: none;" type="button">Exportar a EuskadiTech - cifrado</button>
|
||||||
|
<!--<br><br><em>Para descargar envia un correo a telesec@tech.eus con el asunto "TSBK %${GROUPID}".</em>-->
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
54
dist/page__importar.js
vendored
Normal file
54
dist/page__importar.js
vendored
Normal file
@@ -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 = `
|
||||||
|
<h1>Importar Datos</h1>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Importar datos</legend>
|
||||||
|
<em>Espera hasta que se vacien todas las notificaciones.</em>
|
||||||
|
<select id="${select_type}">
|
||||||
|
<option value="" disabled selected>Tipo de archivo...</option>
|
||||||
|
<option value="comedor">Galileo - db.comedor.axd</option>
|
||||||
|
<option value="recetas">Galileo - db.recetas.axd</option>
|
||||||
|
<option value="materiales">Galileo - db.materiales.axd</option>
|
||||||
|
<option value="personas">Galileo - db.personas.axd</option>
|
||||||
|
<option value="comandas">Galileo - db.cafe.comandas.axd</option>
|
||||||
|
<option value="%telesec">TeleSec Exportado (encriptado o no)</option>
|
||||||
|
</select>
|
||||||
|
<textarea id="${textarea_content}" style="height: 100px;" placeholder="Introduce el contenido del archivo"></textarea>
|
||||||
|
<button id="${button_import}" type="button">Importar</button>
|
||||||
|
<button id="${button_clear}" type="button">Vaciar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
11
dist/page__index.js
vendored
Normal file
11
dist/page__index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
PAGES.index = {
|
||||||
|
//navcss: "btn1",
|
||||||
|
Title: "Inicio",
|
||||||
|
index: function () {
|
||||||
|
container.innerHTML = `
|
||||||
|
<h1>Inicio</h1>
|
||||||
|
<em>Utiliza el menú superior para abrir un modulo</em>
|
||||||
|
<br><br>
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
};
|
||||||
194
dist/page__materiales.js
vendored
Normal file
194
dist/page__materiales.js
vendored
Normal file
@@ -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 = `
|
||||||
|
<h1>Material <code id="${nameh1}"></code></h1>
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
Referencia<br>
|
||||||
|
<input type="text" id="${field_referencia}" value="?"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Nombre<br>
|
||||||
|
<input type="text" id="${field_nombre}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Unidad<br>
|
||||||
|
<input type="text" id="${field_unidad}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Cantidad Actual<br>
|
||||||
|
<input type="number" step="0.5" id="${field_cantidad}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Cantidad Minima<br>
|
||||||
|
<input type="number" step="0.5" id="${field_cantidad_min}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Ubicación<br>
|
||||||
|
<input type="text" id="${field_ubicacion}" value="-"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Notas<br>
|
||||||
|
<textarea id="${field_notas}"></textarea><br><br>
|
||||||
|
</label><hr>
|
||||||
|
<button class="btn5" id="${btn_guardar}">Guardar</button>
|
||||||
|
<button class="rojo" id="${btn_borrar}">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>Materiales</h1>
|
||||||
|
<button id="${btn_new}">Nuevo Material</button>
|
||||||
|
<div id="scrolltable"><table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Referencia</th>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Ubicación</th>
|
||||||
|
<th>Cantidad</th>
|
||||||
|
<th>Notas</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${tablebody}">
|
||||||
|
</tbody>
|
||||||
|
</table></div>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<td>${data.Referencia || "?"}</td>
|
||||||
|
<td>${data.Nombre || "?"}</td>
|
||||||
|
<td>${data.Ubicacion || "?"}</td>
|
||||||
|
<td>${data.Cantidad || "?"} ${data.Unidad || "?"}</td>
|
||||||
|
<td>${data.Notas || "?"}</td>
|
||||||
|
`;
|
||||||
|
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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
217
dist/page__notificaciones.js
vendored
Normal file
217
dist/page__notificaciones.js
vendored
Normal file
@@ -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 = `
|
||||||
|
<h1>Notificación <code id="${nameh1}"></code></h1>
|
||||||
|
<fieldset style="float: left;">
|
||||||
|
<legend>Valores</legend>
|
||||||
|
<label>
|
||||||
|
Fecha<br>
|
||||||
|
<input readonly disabled type="text" id="${field_fecha}" value="${CurrentISODate()}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Asunto<br>
|
||||||
|
<input type="text" id="${field_asunto}" value=""><br><br>
|
||||||
|
</label>
|
||||||
|
<input type="hidden" id="${field_origen}">
|
||||||
|
<input type="hidden" id="${field_destino}">
|
||||||
|
<div id="${div_actions}"></div>
|
||||||
|
<label>
|
||||||
|
Mensaje<br>
|
||||||
|
<textarea id="${field_mensaje}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Respuesta<br>
|
||||||
|
<textarea id="${field_respuesta}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Estado<br>
|
||||||
|
<input readonly disabled type="text" id="${field_estado}" value="%%">
|
||||||
|
<br>
|
||||||
|
<button id="${btn_leer}">Leido</button>
|
||||||
|
<button id="${btn_desleer}">No leido</button>
|
||||||
|
<br>
|
||||||
|
</label><hr>
|
||||||
|
<button class="btn5" id="${btn_guardar}">Guardar</button>
|
||||||
|
<button class="rojo" id="${btn_borrar}">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>Notificaciones</h1>
|
||||||
|
<button id="${btn_new}">Nueva notificación</button>
|
||||||
|
<div id="cont">
|
||||||
|
`;
|
||||||
|
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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
224
dist/page__personas.js
vendored
Normal file
224
dist/page__personas.js
vendored
Normal file
@@ -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 = `
|
||||||
|
<h1>Persona <code id="${nameh1}"></code></h1>
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
Nombre<br>
|
||||||
|
<input type="text" id="${field_nombre}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Zona<br>
|
||||||
|
<input type="text" id="${field_zona}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Permisos<br>
|
||||||
|
<input type="text" id="${field_roles}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Puntos<br>
|
||||||
|
<input type="number" id="${field_puntos}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Anilla<br>
|
||||||
|
<input type="color" id="${field_anilla}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Foto (PNG o JPG)<br>
|
||||||
|
<img id="${render_foto}" height="100px" style="border: 3px inset; min-width: 7px;" src="static/camera2.png">
|
||||||
|
<input type="file" accept="image/*" id="${field_foto}" style="display: none;"><br><br>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Notas<br>
|
||||||
|
<textarea id="${field_notas}"></textarea><br><br>
|
||||||
|
</label><hr>
|
||||||
|
<button class="btn5" id="${btn_guardar}">Guardar</button>
|
||||||
|
<button class="rojo" id="${btn_borrar}">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>Personas</h1>
|
||||||
|
<button id="${btn_new}">Nueva Persona</button>
|
||||||
|
<div id="scrolltable"><table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Zona</th>
|
||||||
|
<th>Puntos</th>
|
||||||
|
<th>Permisos</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${tablebody}">
|
||||||
|
</tbody>
|
||||||
|
</table></div>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<td class="TextBorder" style="background-color: ${
|
||||||
|
data.SC_Anilla
|
||||||
|
}; text-align: center"><img src="${
|
||||||
|
data.Foto || "static/ico/user_generic.png"
|
||||||
|
}" height="50"> <br> ${data.Nombre || ""}</td>
|
||||||
|
<td>${data.Region || "?"}</td>
|
||||||
|
<td>${data.Puntos || 0}</td>
|
||||||
|
<td>${data.Roles || ""}</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// <button id="${btn_comanda}" class="${PAGES.ventas.navcss}">Nueva venta</button>
|
||||||
|
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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
146
dist/page__resumen_diario.js
vendored
Normal file
146
dist/page__resumen_diario.js
vendored
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
PAGES.resumen_diario = {
|
||||||
|
navcss: "btn3",
|
||||||
|
Title: "Resumen Semanal",
|
||||||
|
index: function () {
|
||||||
|
var table_materialesLow = safeuuid();
|
||||||
|
var table_personasHigh = safeuuid();
|
||||||
|
container.innerHTML = `
|
||||||
|
<h1>Resumen Semanal</h1>
|
||||||
|
<h2>Personas con café gratis (para el Viernes)</h2>
|
||||||
|
<div id="${table_personasHigh}"></div>
|
||||||
|
<h2>Materiales faltantes (o por llegar)</h2>
|
||||||
|
<div id="${table_materialesLow}"></div>
|
||||||
|
`;
|
||||||
|
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 = `<b>${data.Nombre || "?"}</b><br>Faltan ${
|
||||||
|
falta || "?"
|
||||||
|
} ${data.Unidad || "?"} <br><i style="font-size: 75%">${
|
||||||
|
data.Ubicacion || "?"
|
||||||
|
}</i>`;
|
||||||
|
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 = `<img src="${
|
||||||
|
data.Foto || ""
|
||||||
|
}" alt="" height="55" style="float: left; margin-right: 5px;"><b>${
|
||||||
|
data.Nombre || "?"
|
||||||
|
}</b><br>Tiene ${
|
||||||
|
data.Puntos || "?"
|
||||||
|
} puntos <br><i style="font-size: 75%">${data.Region || "?"}</i>`;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
315
dist/page__supercafe.js
vendored
Normal file
315
dist/page__supercafe.js
vendored
Normal file
@@ -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 = `
|
||||||
|
<h1>Comanda <code id="${nameh1}"></code></h1>
|
||||||
|
<button onclick="setUrlHash('supercafe');">Salir</button>
|
||||||
|
<fieldset style="text-align: center;">
|
||||||
|
<legend>Rellenar comanda</legend>
|
||||||
|
<label style="display: none;">
|
||||||
|
Fecha<br>
|
||||||
|
<input readonly disabled type="text" id="${field_fecha}" value="${CurrentISODate()}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label style="display: none;">
|
||||||
|
Persona<br>
|
||||||
|
<input type="hidden" id="${field_persona}">
|
||||||
|
<br><br>
|
||||||
|
</label>
|
||||||
|
<label style="display: none;">
|
||||||
|
Comanda (utiliza el panel de relleno)<br>
|
||||||
|
<textarea readonly disabled id="${field_comanda}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<div id="${div_actions}" open>
|
||||||
|
<!--<summary>Mostrar botones de relleno</summary>-->
|
||||||
|
</div>
|
||||||
|
<label>
|
||||||
|
Notas<br>
|
||||||
|
<textarea id="${field_notas}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<label style="display: none;">
|
||||||
|
Estado<br>
|
||||||
|
<input readonly disabled type="text" id="${field_estado}" value="%%">
|
||||||
|
<br>Modificar en el listado de comandas<br>
|
||||||
|
</label>
|
||||||
|
<button id=${btn_guardar} class="btn5">Guardar</button>
|
||||||
|
<button id=${btn_borrar} class="rojo">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>SuperCafé</h1>
|
||||||
|
<button id="${btn_new}" style="${sc_nobtn};">Nueva comanda</button>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<b>Habilitar avisos:</b>
|
||||||
|
<input type="checkbox" id="${tts_check}" style="height: 25px;width: 25px;">
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<details style="background: beige; padding: 15px; border-radius: 15px; border: 2px solid black" open>
|
||||||
|
<summary>Todas las comandas</summary>
|
||||||
|
<div id="cont1"></div>
|
||||||
|
</details>
|
||||||
|
<br>
|
||||||
|
<details style="background: lightpink; padding: 15px; border-radius: 15px; border: 2px solid black" open>
|
||||||
|
<summary>Deudas</summary>
|
||||||
|
<div id="scrolltable2">
|
||||||
|
<div id="cont2"></div>
|
||||||
|
</details>
|
||||||
|
`;
|
||||||
|
|
||||||
|
//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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
43
dist/pwa.js
vendored
Normal file
43
dist/pwa.js
vendored
Normal file
@@ -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;
|
||||||
|
});
|
||||||
|
}
|
||||||
160
src/app_logic.js
Normal file
160
src/app_logic.js
Normal file
@@ -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 + "<br>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;
|
||||||
|
});
|
||||||
872
src/app_modules.js
Normal file
872
src/app_modules.js
Normal file
@@ -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 = `<div style="position: relative; width: 200px; height: 200px; background: white; display: inline-block; border: 1px dotted black;">`;
|
||||||
|
|
||||||
|
// Layer 1: Selección image
|
||||||
|
const selection = comanda["Selección"];
|
||||||
|
if (selectionMap[selection]) {
|
||||||
|
html += `<img id="img1-${key}" src="${
|
||||||
|
basePaths.Selección + selectionMap[selection]
|
||||||
|
}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 2: Café
|
||||||
|
if (comanda.Café) {
|
||||||
|
html += `<img id="img2-${key}" src="${basePaths.Café}Café-${comanda.Café}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 3: Endulzante
|
||||||
|
if (comanda.Endulzante) {
|
||||||
|
html += `<img id="img3-${key}" src="${basePaths.Endulzante}Azucar-${comanda.Endulzante}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 4: Cafeina
|
||||||
|
if (comanda.Cafeina) {
|
||||||
|
html += `<img id="img4-${key}" src="${basePaths.Cafeina}Cafeina-${comanda.Cafeina}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
// Layer 5: Leche
|
||||||
|
if (comanda.Leche) {
|
||||||
|
html += `<img id="img5-${key}" src="${basePaths.Leche}Leche-${comanda.Leche}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
// Layer 6: Temperatura
|
||||||
|
if (comanda.Temperatura) {
|
||||||
|
html += `<img id="img6-${key}" src="${basePaths.Leche}Temperatura-${comanda.Temperatura}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
// Layer 7: Tamaño
|
||||||
|
if (comanda.Tamaño) {
|
||||||
|
html += `<img id="img7-${key}" src="${basePaths.Leche}Tamaño-${comanda.Tamaño}.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close div
|
||||||
|
html += "</div>";
|
||||||
|
|
||||||
|
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 = "<small style='font-size: 60%;'>Servicio base (10c)</small>\n";
|
||||||
|
|
||||||
|
Object.entries(json).forEach((entry) => {
|
||||||
|
valores +=
|
||||||
|
"<small style='font-size: 60%;'>" +
|
||||||
|
entry[0] +
|
||||||
|
":</small> " +
|
||||||
|
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 += "<small>(P = 10c)</small>";
|
||||||
|
}
|
||||||
|
// Leche grande = 20c
|
||||||
|
if (
|
||||||
|
json["Tamaño"] == "Grande" &&
|
||||||
|
["de Vaca", "Sin lactosa", "Vegetal"].includes(json["Leche"])
|
||||||
|
) {
|
||||||
|
valores += "<small>(G = 20c)</small>";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Selección":
|
||||||
|
// Café = 20c
|
||||||
|
if (
|
||||||
|
["Café con leche", "Solo café (sin leche)"].includes(
|
||||||
|
json["Selección"]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
valores += "<small>(20c)</small>";
|
||||||
|
}
|
||||||
|
// ColaCao = 20c
|
||||||
|
if (json["Selección"] == "ColaCao con leche") {
|
||||||
|
valores += "<small>(20c)</small>";
|
||||||
|
}
|
||||||
|
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 += "<hr>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 = `
|
||||||
|
<div id="scrolltable">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr id="${tablehead}"></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${tablebody}">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
tableScroll("#scrolltable"); // id="scrolltable"
|
||||||
|
var tablehead_EL = document.getElementById(tablehead);
|
||||||
|
var tablebody_EL = document.getElementById(tablebody);
|
||||||
|
var rows = {};
|
||||||
|
config.forEach((key) => {
|
||||||
|
tablehead_EL.innerHTML += `<th>${key.label}</th>`;
|
||||||
|
});
|
||||||
|
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) + "<hr>" + 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("#", ""));
|
||||||
|
});
|
||||||
22
src/config.js
Normal file
22
src/config.js
Normal file
@@ -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 = "";
|
||||||
61
src/gun_init.js
Normal file
61
src/gun_init.js
Normal file
@@ -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];
|
||||||
|
}
|
||||||
2509
src/index.html
2509
src/index.html
File diff suppressed because it is too large
Load Diff
89
src/page__exportar.js
Normal file
89
src/page__exportar.js
Normal file
@@ -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 = `
|
||||||
|
<h1>Exportar Datos</h1>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Exportar datos</legend>
|
||||||
|
<em>Al pulsar, Espera hasta que salga una notificacion verde.</em>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<button id="${button_export_local}" type="button">Exportar sin cifrar</button>
|
||||||
|
<button id="${button_export_safe}" type="button">Exportar con cifrado</button>
|
||||||
|
<button id="${button_export_safe_cloud}" style="display: none;" type="button">Exportar a EuskadiTech - cifrado</button>
|
||||||
|
<!--<br><br><em>Para descargar envia un correo a telesec@tech.eus con el asunto "TSBK %${GROUPID}".</em>-->
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
54
src/page__importar.js
Normal file
54
src/page__importar.js
Normal file
@@ -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 = `
|
||||||
|
<h1>Importar Datos</h1>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Importar datos</legend>
|
||||||
|
<em>Espera hasta que se vacien todas las notificaciones.</em>
|
||||||
|
<select id="${select_type}">
|
||||||
|
<option value="" disabled selected>Tipo de archivo...</option>
|
||||||
|
<option value="comedor">Galileo - db.comedor.axd</option>
|
||||||
|
<option value="recetas">Galileo - db.recetas.axd</option>
|
||||||
|
<option value="materiales">Galileo - db.materiales.axd</option>
|
||||||
|
<option value="personas">Galileo - db.personas.axd</option>
|
||||||
|
<option value="comandas">Galileo - db.cafe.comandas.axd</option>
|
||||||
|
<option value="%telesec">TeleSec Exportado (encriptado o no)</option>
|
||||||
|
</select>
|
||||||
|
<textarea id="${textarea_content}" style="height: 100px;" placeholder="Introduce el contenido del archivo"></textarea>
|
||||||
|
<button id="${button_import}" type="button">Importar</button>
|
||||||
|
<button id="${button_clear}" type="button">Vaciar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
11
src/page__index.js
Normal file
11
src/page__index.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
PAGES.index = {
|
||||||
|
//navcss: "btn1",
|
||||||
|
Title: "Inicio",
|
||||||
|
index: function () {
|
||||||
|
container.innerHTML = `
|
||||||
|
<h1>Inicio</h1>
|
||||||
|
<em>Utiliza el menú superior para abrir un modulo</em>
|
||||||
|
<br><br>
|
||||||
|
`;
|
||||||
|
},
|
||||||
|
};
|
||||||
194
src/page__materiales.js
Normal file
194
src/page__materiales.js
Normal file
@@ -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 = `
|
||||||
|
<h1>Material <code id="${nameh1}"></code></h1>
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
Referencia<br>
|
||||||
|
<input type="text" id="${field_referencia}" value="?"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Nombre<br>
|
||||||
|
<input type="text" id="${field_nombre}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Unidad<br>
|
||||||
|
<input type="text" id="${field_unidad}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Cantidad Actual<br>
|
||||||
|
<input type="number" step="0.5" id="${field_cantidad}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Cantidad Minima<br>
|
||||||
|
<input type="number" step="0.5" id="${field_cantidad_min}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Ubicación<br>
|
||||||
|
<input type="text" id="${field_ubicacion}" value="-"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Notas<br>
|
||||||
|
<textarea id="${field_notas}"></textarea><br><br>
|
||||||
|
</label><hr>
|
||||||
|
<button class="btn5" id="${btn_guardar}">Guardar</button>
|
||||||
|
<button class="rojo" id="${btn_borrar}">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>Materiales</h1>
|
||||||
|
<button id="${btn_new}">Nuevo Material</button>
|
||||||
|
<div id="scrolltable"><table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Referencia</th>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Ubicación</th>
|
||||||
|
<th>Cantidad</th>
|
||||||
|
<th>Notas</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${tablebody}">
|
||||||
|
</tbody>
|
||||||
|
</table></div>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<td>${data.Referencia || "?"}</td>
|
||||||
|
<td>${data.Nombre || "?"}</td>
|
||||||
|
<td>${data.Ubicacion || "?"}</td>
|
||||||
|
<td>${data.Cantidad || "?"} ${data.Unidad || "?"}</td>
|
||||||
|
<td>${data.Notas || "?"}</td>
|
||||||
|
`;
|
||||||
|
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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
217
src/page__notificaciones.js
Normal file
217
src/page__notificaciones.js
Normal file
@@ -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 = `
|
||||||
|
<h1>Notificación <code id="${nameh1}"></code></h1>
|
||||||
|
<fieldset style="float: left;">
|
||||||
|
<legend>Valores</legend>
|
||||||
|
<label>
|
||||||
|
Fecha<br>
|
||||||
|
<input readonly disabled type="text" id="${field_fecha}" value="${CurrentISODate()}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Asunto<br>
|
||||||
|
<input type="text" id="${field_asunto}" value=""><br><br>
|
||||||
|
</label>
|
||||||
|
<input type="hidden" id="${field_origen}">
|
||||||
|
<input type="hidden" id="${field_destino}">
|
||||||
|
<div id="${div_actions}"></div>
|
||||||
|
<label>
|
||||||
|
Mensaje<br>
|
||||||
|
<textarea id="${field_mensaje}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Respuesta<br>
|
||||||
|
<textarea id="${field_respuesta}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Estado<br>
|
||||||
|
<input readonly disabled type="text" id="${field_estado}" value="%%">
|
||||||
|
<br>
|
||||||
|
<button id="${btn_leer}">Leido</button>
|
||||||
|
<button id="${btn_desleer}">No leido</button>
|
||||||
|
<br>
|
||||||
|
</label><hr>
|
||||||
|
<button class="btn5" id="${btn_guardar}">Guardar</button>
|
||||||
|
<button class="rojo" id="${btn_borrar}">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>Notificaciones</h1>
|
||||||
|
<button id="${btn_new}">Nueva notificación</button>
|
||||||
|
<div id="cont">
|
||||||
|
`;
|
||||||
|
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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
224
src/page__personas.js
Normal file
224
src/page__personas.js
Normal file
@@ -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 = `
|
||||||
|
<h1>Persona <code id="${nameh1}"></code></h1>
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
Nombre<br>
|
||||||
|
<input type="text" id="${field_nombre}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Zona<br>
|
||||||
|
<input type="text" id="${field_zona}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Permisos<br>
|
||||||
|
<input type="text" id="${field_roles}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Puntos<br>
|
||||||
|
<input type="number" id="${field_puntos}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Anilla<br>
|
||||||
|
<input type="color" id="${field_anilla}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Foto (PNG o JPG)<br>
|
||||||
|
<img id="${render_foto}" height="100px" style="border: 3px inset; min-width: 7px;" src="static/camera2.png">
|
||||||
|
<input type="file" accept="image/*" id="${field_foto}" style="display: none;"><br><br>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Notas<br>
|
||||||
|
<textarea id="${field_notas}"></textarea><br><br>
|
||||||
|
</label><hr>
|
||||||
|
<button class="btn5" id="${btn_guardar}">Guardar</button>
|
||||||
|
<button class="rojo" id="${btn_borrar}">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>Personas</h1>
|
||||||
|
<button id="${btn_new}">Nueva Persona</button>
|
||||||
|
<div id="scrolltable"><table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Zona</th>
|
||||||
|
<th>Puntos</th>
|
||||||
|
<th>Permisos</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="${tablebody}">
|
||||||
|
</tbody>
|
||||||
|
</table></div>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<td class="TextBorder" style="background-color: ${
|
||||||
|
data.SC_Anilla
|
||||||
|
}; text-align: center"><img src="${
|
||||||
|
data.Foto || "static/ico/user_generic.png"
|
||||||
|
}" height="50"> <br> ${data.Nombre || ""}</td>
|
||||||
|
<td>${data.Region || "?"}</td>
|
||||||
|
<td>${data.Puntos || 0}</td>
|
||||||
|
<td>${data.Roles || ""}</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// <button id="${btn_comanda}" class="${PAGES.ventas.navcss}">Nueva venta</button>
|
||||||
|
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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
146
src/page__resumen_diario.js
Normal file
146
src/page__resumen_diario.js
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
PAGES.resumen_diario = {
|
||||||
|
navcss: "btn3",
|
||||||
|
Title: "Resumen Semanal",
|
||||||
|
index: function () {
|
||||||
|
var table_materialesLow = safeuuid();
|
||||||
|
var table_personasHigh = safeuuid();
|
||||||
|
container.innerHTML = `
|
||||||
|
<h1>Resumen Semanal</h1>
|
||||||
|
<h2>Personas con café gratis (para el Viernes)</h2>
|
||||||
|
<div id="${table_personasHigh}"></div>
|
||||||
|
<h2>Materiales faltantes (o por llegar)</h2>
|
||||||
|
<div id="${table_materialesLow}"></div>
|
||||||
|
`;
|
||||||
|
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 = `<b>${data.Nombre || "?"}</b><br>Faltan ${
|
||||||
|
falta || "?"
|
||||||
|
} ${data.Unidad || "?"} <br><i style="font-size: 75%">${
|
||||||
|
data.Ubicacion || "?"
|
||||||
|
}</i>`;
|
||||||
|
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 = `<img src="${
|
||||||
|
data.Foto || ""
|
||||||
|
}" alt="" height="55" style="float: left; margin-right: 5px;"><b>${
|
||||||
|
data.Nombre || "?"
|
||||||
|
}</b><br>Tiene ${
|
||||||
|
data.Puntos || "?"
|
||||||
|
} puntos <br><i style="font-size: 75%">${data.Region || "?"}</i>`;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
315
src/page__supercafe.js
Normal file
315
src/page__supercafe.js
Normal file
@@ -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 = `
|
||||||
|
<h1>Comanda <code id="${nameh1}"></code></h1>
|
||||||
|
<button onclick="setUrlHash('supercafe');">Salir</button>
|
||||||
|
<fieldset style="text-align: center;">
|
||||||
|
<legend>Rellenar comanda</legend>
|
||||||
|
<label style="display: none;">
|
||||||
|
Fecha<br>
|
||||||
|
<input readonly disabled type="text" id="${field_fecha}" value="${CurrentISODate()}"><br><br>
|
||||||
|
</label>
|
||||||
|
<label style="display: none;">
|
||||||
|
Persona<br>
|
||||||
|
<input type="hidden" id="${field_persona}">
|
||||||
|
<br><br>
|
||||||
|
</label>
|
||||||
|
<label style="display: none;">
|
||||||
|
Comanda (utiliza el panel de relleno)<br>
|
||||||
|
<textarea readonly disabled id="${field_comanda}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<div id="${div_actions}" open>
|
||||||
|
<!--<summary>Mostrar botones de relleno</summary>-->
|
||||||
|
</div>
|
||||||
|
<label>
|
||||||
|
Notas<br>
|
||||||
|
<textarea id="${field_notas}"></textarea><br><br>
|
||||||
|
</label>
|
||||||
|
<label style="display: none;">
|
||||||
|
Estado<br>
|
||||||
|
<input readonly disabled type="text" id="${field_estado}" value="%%">
|
||||||
|
<br>Modificar en el listado de comandas<br>
|
||||||
|
</label>
|
||||||
|
<button id=${btn_guardar} class="btn5">Guardar</button>
|
||||||
|
<button id=${btn_borrar} class="rojo">Borrar</button>
|
||||||
|
</fieldset>
|
||||||
|
`;
|
||||||
|
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 = `
|
||||||
|
<h1>SuperCafé</h1>
|
||||||
|
<button id="${btn_new}" style="${sc_nobtn};">Nueva comanda</button>
|
||||||
|
<br>
|
||||||
|
<label>
|
||||||
|
<b>Habilitar avisos:</b>
|
||||||
|
<input type="checkbox" id="${tts_check}" style="height: 25px;width: 25px;">
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<details style="background: beige; padding: 15px; border-radius: 15px; border: 2px solid black" open>
|
||||||
|
<summary>Todas las comandas</summary>
|
||||||
|
<div id="cont1"></div>
|
||||||
|
</details>
|
||||||
|
<br>
|
||||||
|
<details style="background: lightpink; padding: 15px; border-radius: 15px; border: 2px solid black" open>
|
||||||
|
<summary>Deudas</summary>
|
||||||
|
<div id="scrolltable2">
|
||||||
|
<div id="cont2"></div>
|
||||||
|
</details>
|
||||||
|
`;
|
||||||
|
|
||||||
|
//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(""));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
43
src/pwa.js
Normal file
43
src/pwa.js
Normal file
@@ -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;
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user