Compare commits
8 Commits
v2025-07-3
...
v2025-07-3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e35428f3ee | ||
|
|
def79a2015 | ||
|
|
64d11fe224 | ||
|
|
a016e06557 | ||
|
|
a274de3c4d | ||
|
|
0f2b2df969 | ||
|
|
8052d21fcc | ||
|
|
03c132a6bd |
85
_assets.json
85
_assets.json
@@ -1,85 +0,0 @@
|
||||
[
|
||||
"icon512_maskable.png",
|
||||
"icon512_rounded.png",
|
||||
"manifest.json",
|
||||
"static/axe.js",
|
||||
"static/doublescroll.js",
|
||||
"static/gun.js",
|
||||
"static/jquery.js",
|
||||
"static/load.js",
|
||||
"static/open.js",
|
||||
"static/path.js",
|
||||
"static/radisk.js",
|
||||
"static/radix.js",
|
||||
"static/rindexed.js",
|
||||
"static/sea.js",
|
||||
"static/showdown.min.js",
|
||||
"static/simplemde.min.css",
|
||||
"static/simplemde.min.js",
|
||||
"static/store.js",
|
||||
"static/synchronous.js",
|
||||
"static/TeleSec.jpg",
|
||||
"static/toastr.min.css",
|
||||
"static/toastr.min.js",
|
||||
"static/webrtc.js",
|
||||
"static/yson.js",
|
||||
"static/ico/add.png",
|
||||
"static/ico/azucar-moreno.png",
|
||||
"static/ico/azucar-blanco.jpg",
|
||||
"static/ico/stevia.jpg",
|
||||
"static/ico/stevia-gotas.webp",
|
||||
"static/ico/sacarina.jpg",
|
||||
"static/ico/arrow_down_blue.png",
|
||||
"static/ico/arrow_left_green.png",
|
||||
"static/ico/arrow_up_red.png",
|
||||
"static/ico/camera2.png",
|
||||
"static/ico/cereales.png",
|
||||
"static/ico/checkbox.png",
|
||||
"static/ico/checkbox_unchecked.png",
|
||||
"static/ico/connect_ok.svg",
|
||||
"static/ico/connect_ko.svg",
|
||||
"static/ico/coffee_bean.png",
|
||||
"static/ico/colacao.jpg",
|
||||
"static/ico/cookies.png",
|
||||
"static/ico/cow.png",
|
||||
"static/ico/delete.png",
|
||||
"static/ico/fire.png",
|
||||
"static/ico/keyboard_key_g.png",
|
||||
"static/ico/keyboard_key_p.png",
|
||||
"static/ico/lollipop.png",
|
||||
"static/ico/milk.png",
|
||||
"static/ico/preferences.png",
|
||||
"static/ico/sizes.png",
|
||||
"static/ico/statusok.png",
|
||||
"static/ico/snowflake.png",
|
||||
"static/ico/tea_bag.png",
|
||||
"static/ico/thermometer2.png",
|
||||
"static/ico/user.png",
|
||||
"static/ico/user_generic.png",
|
||||
"static/ico/water_tap.png",
|
||||
"static/ico/wheat.png",
|
||||
"static/ico/layered1/Azucar-Az. Blanco.png",
|
||||
"static/ico/layered1/Azucar-Az. Moreno.png",
|
||||
"static/ico/layered1/Azucar-Edulcorante.png",
|
||||
"static/ico/layered1/Azucar-Sacarina.png",
|
||||
"static/ico/layered1/Azucar-Sin.png",
|
||||
"static/ico/layered1/Azucar-Stevia (Gotas).png",
|
||||
"static/ico/layered1/Azucar-Stevia (Pastillas).png",
|
||||
"static/ico/layered1/Background.png",
|
||||
"static/ico/layered1/Cafeina-Con.png",
|
||||
"static/ico/layered1/Cafeina-Sin.png",
|
||||
"static/ico/layered1/Leche-Agua.png",
|
||||
"static/ico/layered1/Leche-Sin lactosa.png",
|
||||
"static/ico/layered1/Leche-Vegetal.png",
|
||||
"static/ico/layered1/Leche-de Vaca.png",
|
||||
"static/ico/layered1/Selección-CafeSolo.png",
|
||||
"static/ico/layered1/Selección-CaféLeche.png",
|
||||
"static/ico/layered1/Selección-ColaCao.png",
|
||||
"static/ico/layered1/Selección-Infusion.png",
|
||||
"static/ico/layered1/Selección-Leche.png",
|
||||
"static/ico/layered1/Tamaño-Grande.png",
|
||||
"static/ico/layered1/Tamaño-Pequeño.png",
|
||||
"static/ico/layered1/Temperatura-Caliente.png",
|
||||
"static/ico/layered1/Temperatura-Frio.png",
|
||||
"static/ico/layered1/Temperatura-Templado.png"
|
||||
]
|
||||
0
assets/page/.placeholder
Normal file
0
assets/page/.placeholder
Normal file
28
build.py
28
build.py
@@ -1,10 +1,23 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
def get_all_files(directory):
|
||||
files = []
|
||||
for root, _, filenames in os.walk(directory):
|
||||
for filename in filenames:
|
||||
path = os.path.join(root, filename)
|
||||
# Convert to relative path and normalize separators
|
||||
rel_path = os.path.relpath(path, directory)
|
||||
files.append(rel_path.replace('\\', '/'))
|
||||
return files
|
||||
|
||||
PREFETCH = ""
|
||||
VERSIONCO = "2025-07-30_3"
|
||||
HANDLEPARSE = os.listdir("src/")
|
||||
ASSETS = json.load(open("_assets.json", "r")) + HANDLEPARSE
|
||||
VERSIONCO = "2025-07-31_2"
|
||||
HANDLEPARSE = get_all_files("src")
|
||||
|
||||
# Combine assets from JSON and recursively found files
|
||||
ASSETS = get_all_files("assets")
|
||||
|
||||
for asset in ASSETS:
|
||||
if asset != "sw.js":
|
||||
PREFETCH += f'<link rel="prefetch" href="{asset}" />\n'
|
||||
@@ -18,7 +31,8 @@ def replace_handles(string):
|
||||
|
||||
|
||||
for file in HANDLEPARSE:
|
||||
with open("src/" + file, "r") as f:
|
||||
out = replace_handles(f.read())
|
||||
with open("dist/" + file, "w") as f:
|
||||
f.write(out)
|
||||
print(file)
|
||||
with open("src/" + file, "r") as f1:
|
||||
out = replace_handles(f1.read())
|
||||
with open("dist/" + file, "w") as f2:
|
||||
f2.write(out)
|
||||
|
||||
@@ -34,6 +34,10 @@ if (urlParams.get("login") != null) {
|
||||
//location.search = "";
|
||||
}
|
||||
function open_page(params) {
|
||||
if (SUB_LOGGED_IN != true) {
|
||||
PAGES["login"].index();
|
||||
return;
|
||||
}
|
||||
if (params == "") {
|
||||
params = "index";
|
||||
}
|
||||
|
||||
@@ -215,7 +215,9 @@ function addCategory_Personas(
|
||||
options,
|
||||
defaultval,
|
||||
change_cb = () => {},
|
||||
label = "Persona"
|
||||
label = "Persona",
|
||||
open_default = false,
|
||||
default_empty_text = "- Lista Vacia -"
|
||||
) {
|
||||
var details_0 = document.createElement("details"); // children: img_0, summary_0
|
||||
//details_0.open = true;
|
||||
@@ -233,6 +235,9 @@ function addCategory_Personas(
|
||||
span_0.append(p.Nombre || "", " ", img_0);
|
||||
summary_0.append(label, span_0);
|
||||
details_0.append(summary_0, document.createElement("br"));
|
||||
if (open_default == true) {
|
||||
details_0.open = true;
|
||||
}
|
||||
details_0.style.textAlign = "center";
|
||||
details_0.style.margin = "5px";
|
||||
details_0.style.padding = "5px";
|
||||
@@ -302,6 +307,11 @@ function addCategory_Personas(
|
||||
//btn.style.fontSize="17.5px"
|
||||
details_0.append(btn);
|
||||
});
|
||||
if (Object.entries(options).length == 0) {
|
||||
var btn = document.createElement("b");
|
||||
btn.append(default_empty_text);
|
||||
details_0.append(btn);
|
||||
}
|
||||
}
|
||||
const SC_actions_icons = {
|
||||
Tamaño: "static/ico/sizes.png",
|
||||
@@ -493,23 +503,21 @@ gun
|
||||
.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);
|
||||
});
|
||||
function add_row(data, key) {
|
||||
if (data != null) {
|
||||
data["_key"] = key;
|
||||
SC_Personas[key] = data;
|
||||
} else {
|
||||
add_row(data, key);
|
||||
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) {
|
||||
@@ -619,7 +627,8 @@ function TS_IndexElement(
|
||||
ref,
|
||||
container,
|
||||
rowCallback = undefined,
|
||||
canAddCallback = undefined
|
||||
canAddCallback = undefined,
|
||||
globalSearchBar = true,
|
||||
) {
|
||||
// Every item in config should have:
|
||||
// key: string
|
||||
@@ -628,24 +637,74 @@ function TS_IndexElement(
|
||||
// label: string
|
||||
var tablebody = safeuuid();
|
||||
var tablehead = safeuuid();
|
||||
var scrolltable = safeuuid();
|
||||
var searchKeyInput = safeuuid();
|
||||
|
||||
// Create the container with search bar and table
|
||||
container.innerHTML = `
|
||||
<div id="scrolltable">
|
||||
<table>
|
||||
<thead>
|
||||
<tr id="${tablehead}"></tr>
|
||||
</thead>
|
||||
<tbody id="${tablebody}">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="${scrolltable}">
|
||||
<input type="text" id="${searchKeyInput}" placeholder="🔍 Buscar..." style="width: 100%; max-width: 20rem; padding: 8px; border: 1px solid #ccc; border-radius: 4px; background-color: rebeccapurple; color: white;">
|
||||
<table>
|
||||
<thead>
|
||||
<tr id="${tablehead}"></tr>
|
||||
</thead>
|
||||
<tbody id="${tablebody}">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
tableScroll("#scrolltable"); // id="scrolltable"
|
||||
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>`;
|
||||
});
|
||||
// Add search functionality
|
||||
const searchKeyEl = document.getElementById(searchKeyInput);
|
||||
searchKeyEl.addEventListener('input', debounce(() => render(), 300));
|
||||
|
||||
function searchInData(data, searchValue, config) {
|
||||
if (!searchValue) return true;
|
||||
|
||||
// Search in ID
|
||||
if (data._key.toLowerCase().includes(searchValue)) return true;
|
||||
|
||||
// Search in configured fields
|
||||
for (const field of config) {
|
||||
const value = data[field.key];
|
||||
if (!value) continue;
|
||||
|
||||
// Handle different field types
|
||||
switch (field.type) {
|
||||
case "comanda":
|
||||
try {
|
||||
const comandaData = JSON.parse(data.Comanda);
|
||||
// Search in all comanda fields
|
||||
if (Object.values(comandaData).some(v =>
|
||||
String(v).toLowerCase().includes(searchValue)
|
||||
)) return true;
|
||||
} catch (e) {
|
||||
// If JSON parse fails, search in raw string
|
||||
if (data.Comanda.toLowerCase().includes(searchValue)) return true;
|
||||
}
|
||||
break;
|
||||
case "persona":
|
||||
const persona = SC_Personas[value];
|
||||
if (persona) {
|
||||
// Search in persona fields
|
||||
if (persona.Nombre?.toLowerCase().includes(searchValue)) return true;
|
||||
if (persona.Region?.toLowerCase().includes(searchValue)) return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// For raw and other types, search in the direct value
|
||||
if (String(value).toLowerCase().includes(searchValue)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function render() {
|
||||
function sorter(a, b) {
|
||||
if (a.Fecha < b.Fecha) {
|
||||
@@ -656,9 +715,12 @@ function TS_IndexElement(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
var tablebody_EL = document.getElementById(tablebody);
|
||||
|
||||
const searchValue = searchKeyEl.value.toLowerCase().trim();
|
||||
tablebody_EL.innerHTML = "";
|
||||
Object.values(rows)
|
||||
Object.entries(rows)
|
||||
.filter(([_, data]) => searchInData(data, searchValue, config))
|
||||
.map(([_, data]) => data)
|
||||
.sort(sorter)
|
||||
.forEach((data) => {
|
||||
var new_tr = document.createElement("tr");
|
||||
@@ -675,34 +737,39 @@ function TS_IndexElement(
|
||||
config.forEach((key) => {
|
||||
switch (key.type) {
|
||||
case "raw":
|
||||
const tdRaw = document.createElement('td');
|
||||
const rawContent = (data[key.key] || key.default || "").replace(/\n/g, '<br>');
|
||||
const tdRaw = document.createElement("td");
|
||||
const rawContent = (data[key.key] || key.default || "").replace(
|
||||
/\n/g,
|
||||
"<br>"
|
||||
);
|
||||
tdRaw.innerHTML = rawContent;
|
||||
new_tr.appendChild(tdRaw);
|
||||
break;
|
||||
case "comanda":
|
||||
const tdComanda = document.createElement('td');
|
||||
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');
|
||||
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 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`;
|
||||
|
||||
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;
|
||||
pre.appendChild(document.createTextNode("\n"));
|
||||
pre.innerHTML +=
|
||||
SC_parse_short(parsedComanda) + "<hr>" + data.Notas;
|
||||
|
||||
tdComanda.appendChild(pre);
|
||||
new_tr.appendChild(tdComanda);
|
||||
@@ -712,19 +779,19 @@ function TS_IndexElement(
|
||||
if (urlParams.get("sc_nobtn") == "yes") {
|
||||
sc_nobtn = "pointer-events: none; opacity: 0.5";
|
||||
}
|
||||
const td = document.createElement('td');
|
||||
td.style.fontSize = '17px';
|
||||
const td = document.createElement("td");
|
||||
td.style.fontSize = "17px";
|
||||
if (sc_nobtn) {
|
||||
td.style.pointerEvents = 'none';
|
||||
td.style.opacity = '0.5';
|
||||
td.style.pointerEvents = "none";
|
||||
td.style.opacity = "0.5";
|
||||
}
|
||||
|
||||
// Create buttons
|
||||
const createButton = (text, state) => {
|
||||
const button = document.createElement('button');
|
||||
const button = document.createElement("button");
|
||||
button.textContent = text;
|
||||
if (data.Estado === state) {
|
||||
button.className = 'rojo';
|
||||
button.className = "rojo";
|
||||
}
|
||||
button.onclick = (event) => {
|
||||
event.preventDefault();
|
||||
@@ -741,20 +808,24 @@ function TS_IndexElement(
|
||||
|
||||
// Create all buttons
|
||||
const buttons = [
|
||||
createButton('Pedido', 'Pedido'),
|
||||
createButton('En preparación', 'En preparación'),
|
||||
createButton('Listo', 'Listo'),
|
||||
createButton('Entregado', 'Entregado'),
|
||||
createButton('Deuda', 'Deuda')
|
||||
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';
|
||||
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.")) {
|
||||
if (
|
||||
!confirm(
|
||||
"¿Quieres marcar como pagado? - Se borrara la comanda y se actualizarán los puntos."
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
data.Estado = "Pagado";
|
||||
@@ -762,22 +833,33 @@ function TS_IndexElement(
|
||||
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 + "!");
|
||||
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);
|
||||
betterGunPut(
|
||||
gun.get(TABLE).get("personas").get(data.Persona),
|
||||
encrypted
|
||||
);
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
// Add all buttons to td with line breaks between
|
||||
buttons.forEach(button => {
|
||||
buttons.forEach((button) => {
|
||||
td.appendChild(button);
|
||||
td.appendChild(document.createElement('br'));
|
||||
td.appendChild(document.createElement("br"));
|
||||
});
|
||||
td.appendChild(paidButton);
|
||||
new_tr.appendChild(td);
|
||||
@@ -786,41 +868,45 @@ function TS_IndexElement(
|
||||
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';
|
||||
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';
|
||||
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';
|
||||
tdPersona.appendChild(document.createElement("br"));
|
||||
|
||||
const img = document.createElement('img');
|
||||
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';
|
||||
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);
|
||||
|
||||
@@ -839,23 +925,21 @@ function TS_IndexElement(
|
||||
}
|
||||
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);
|
||||
});
|
||||
function add_row(data, key) {
|
||||
if (data != null) {
|
||||
data["_key"] = key;
|
||||
rows[key] = data;
|
||||
} else {
|
||||
add_row(data, key);
|
||||
delete rows[key];
|
||||
}
|
||||
render();
|
||||
}
|
||||
if (typeof data == "string") {
|
||||
SEA.decrypt(data, SECRET, (data) => {
|
||||
add_row(data, key);
|
||||
});
|
||||
} else {
|
||||
add_row(data, key);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -863,6 +947,9 @@ function TS_IndexElement(
|
||||
const PAGES = {};
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
Object.keys(PAGES).forEach((key) => {
|
||||
if (PAGES[key].Esconder == true) {
|
||||
return;
|
||||
}
|
||||
var a = document.createElement("a");
|
||||
a.className = "button " + PAGES[key].navcss;
|
||||
a.href = "#" + key;
|
||||
|
||||
@@ -20,3 +20,6 @@ const RELAYS = [
|
||||
"https://gun.defucc.me/gun",
|
||||
];
|
||||
var SECRET = "";
|
||||
var SUB_LOGGED_IN = false;
|
||||
var SUB_LOGGED_IN_DETAILS = false;
|
||||
var SUB_LOGGED_IN_ID = false;
|
||||
308
src/index.html
308
src/index.html
@@ -1,154 +1,154 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<title>TeleSec</title>
|
||||
<link rel="icon" type="image/png" href="static/TeleSec.jpg" />
|
||||
<link href="static/euskaditech-css/simple.css" rel="stylesheet" />
|
||||
<link href="static/toastr.min.css" rel="stylesheet" />
|
||||
|
||||
%%PREFETCH%%
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<details class="supermesh-indicator">
|
||||
<summary>
|
||||
<b>SuperMesh</b><br />
|
||||
<br /><small id="peerPID" style="font-family: monospace"
|
||||
>PID ??????????</small
|
||||
>
|
||||
</summary>
|
||||
<ul id="peerList"></ul>
|
||||
<i>Todos los datos están encriptados.</i>
|
||||
</details>
|
||||
<main>
|
||||
<header class="no_print" id="header_hide_query">
|
||||
<details id="LinkAccount_details" open>
|
||||
<summary>
|
||||
<b
|
||||
>TeleSec - <span id="groupId">???</span> - (<span id="peerCount"
|
||||
>?</span
|
||||
>
|
||||
nodos)</b
|
||||
>
|
||||
</summary>
|
||||
<fieldset id="auth_fieldSet">
|
||||
<legend>Credenciales</legend>
|
||||
<br />
|
||||
<label
|
||||
>Codigo de grupo:<br />
|
||||
<input type="text" id="LinkAccount_group"
|
||||
/></label>
|
||||
<br />
|
||||
<br />
|
||||
<label
|
||||
>Clave secreta:<br />
|
||||
<input type="text" id="LinkAccount_secret"
|
||||
/></label>
|
||||
<br /><br />
|
||||
<button
|
||||
type="button"
|
||||
onclick='LinkAccount(document.getElementById("LinkAccount_group").value, document.getElementById("LinkAccount_secret").value, true)'
|
||||
>
|
||||
Iniciar sesión
|
||||
</button>
|
||||
</fieldset>
|
||||
</details>
|
||||
<!-- <button onclick="displayPost('index')">Ir a la pagina de inicio</button> -->
|
||||
<div id="appendApps">
|
||||
<!--<a class="button nav-supercafe nav-disabled" disabled>SuperCafé</a>
|
||||
<a class="button nav-comedor nav-disabled" disabled>Menú Comedor</a>
|
||||
<a class="button nav-recetas nav-disabled" disabled>Recetas</a>-->
|
||||
</div>
|
||||
<hr />
|
||||
</header>
|
||||
<div id="container"></div>
|
||||
<!-- <br><br><br>
|
||||
<footer>
|
||||
<hr>
|
||||
<details>
|
||||
<summary><b>Apps SuperMesh</b></summary>
|
||||
<button type="button">
|
||||
<img src="static/TeleSec.jpg" alt="" width="100px">
|
||||
<br>TeleSec
|
||||
</button>
|
||||
</details>
|
||||
</footer> -->
|
||||
<img
|
||||
id="connectStatus"
|
||||
style="bottom: 15px; right: 15px; position: fixed; width: 50px"
|
||||
/>
|
||||
</main>
|
||||
<img
|
||||
id="actionStatus"
|
||||
src="static/ico/statusok.png"
|
||||
style="
|
||||
z-index: 2048;
|
||||
margin: 0px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: none;
|
||||
"
|
||||
/>
|
||||
<div id="snackbar">
|
||||
Hay una nueva versión de TeleSec.<br /><a id="reload"
|
||||
>Pulsa aqui para actualizar.</a
|
||||
>
|
||||
</div>
|
||||
<script src="static/showdown.min.js"></script>
|
||||
<script src="static/jquery.js"></script>
|
||||
<script src="static/gun.js"></script>
|
||||
<script src="static/webrtc.js"></script>
|
||||
<script src="static/sea.js"></script>
|
||||
<script src="static/yson.js"></script>
|
||||
<script src="static/radix.js"></script>
|
||||
<!-- <script src="static/radisk.js"></script> -->
|
||||
<!-- <script src="static/store.js"></script> -->
|
||||
<script src="static/rindexed.js"></script>
|
||||
<script src="static/path.js"></script>
|
||||
<script src="static/open.js"></script>
|
||||
<script src="static/load.js"></script>
|
||||
<!--<script src="static/synchronous.js"></script>-->
|
||||
<!--<script src="static/axe.js"></script>-->
|
||||
<script src="static/toastr.min.js"></script>
|
||||
<script src="static/doublescroll.js"></script>
|
||||
<!--<script src="static/simplemde.min.js"></script>-->
|
||||
<script async>
|
||||
async function getQuota(cb = () => {}) {
|
||||
if (navigator.storage && navigator.storage.estimate) {
|
||||
const quota = await navigator.storage.estimate();
|
||||
// quota.usage -> Number of bytes used.
|
||||
// quota.quota -> Maximum number of bytes available.
|
||||
const percentageUsed = (quota.usage / quota.quota) * 100;
|
||||
console.log(
|
||||
`You've used ${percentageUsed}% of the available storage.`
|
||||
);
|
||||
const remaining = quota.quota - quota.usage;
|
||||
cb(percentageUsed, remaining);
|
||||
console.log(`You can write up to ${remaining} more bytes.`);
|
||||
}
|
||||
}
|
||||
getQuota();
|
||||
</script>
|
||||
<script src="pwa.js"></script>
|
||||
<script src="config.js"></script>
|
||||
<script src="gun_init.js"></script>
|
||||
<script src="app_logic.js"></script>
|
||||
<script src="app_modules.js"></script>
|
||||
<script src="page__index.js"></script>
|
||||
<script src="page__importar.js"></script>
|
||||
<script src="page__exportar.js"></script>
|
||||
<script src="page__materiales.js"></script>
|
||||
<script src="page__resumen_diario.js"></script>
|
||||
<script src="page__personas.js"></script>
|
||||
<script src="page__supercafe.js"></script>
|
||||
<script src="page__notificaciones.js"></script>
|
||||
<script src="page__comedor.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<title>TeleSec</title>
|
||||
<link rel="icon" type="image/png" href="static/TeleSec.jpg" />
|
||||
<link href="static/euskaditech-css/simple.css" rel="stylesheet" />
|
||||
<link href="static/toastr.min.css" rel="stylesheet" />
|
||||
%%PREFETCH%%
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<details class="supermesh-indicator">
|
||||
<summary>
|
||||
<b>SuperMesh</b><br />
|
||||
<br /><small id="peerPID" style="font-family: monospace"
|
||||
>PID ??????????</small
|
||||
>
|
||||
</summary>
|
||||
<ul id="peerList"></ul>
|
||||
<i>Todos los datos están encriptados.</i>
|
||||
</details>
|
||||
<main>
|
||||
<header class="no_print" id="header_hide_query">
|
||||
<details id="LinkAccount_details" open>
|
||||
<summary>
|
||||
<b
|
||||
>TeleSec - <span id="groupId">???</span> - (<span id="peerCount"
|
||||
>?</span
|
||||
>
|
||||
nodos)</b
|
||||
>
|
||||
</summary>
|
||||
<fieldset id="auth_fieldSet">
|
||||
<legend>Credenciales</legend>
|
||||
<br />
|
||||
<label
|
||||
>Codigo de grupo:<br />
|
||||
<input type="text" id="LinkAccount_group"
|
||||
/></label>
|
||||
<br />
|
||||
<br />
|
||||
<label
|
||||
>Clave secreta:<br />
|
||||
<input type="text" id="LinkAccount_secret"
|
||||
/></label>
|
||||
<br /><br />
|
||||
<button
|
||||
type="button"
|
||||
onclick='LinkAccount(document.getElementById("LinkAccount_group").value, document.getElementById("LinkAccount_secret").value, true)'
|
||||
>
|
||||
Iniciar sesión
|
||||
</button>
|
||||
</fieldset>
|
||||
</details>
|
||||
<!-- <button onclick="displayPost('index')">Ir a la pagina de inicio</button> -->
|
||||
<div id="appendApps">
|
||||
<!--<a class="button nav-supercafe nav-disabled" disabled>SuperCafé</a>
|
||||
<a class="button nav-comedor nav-disabled" disabled>Menú Comedor</a>
|
||||
<a class="button nav-recetas nav-disabled" disabled>Recetas</a>-->
|
||||
</div>
|
||||
<hr />
|
||||
</header>
|
||||
<div id="container"></div>
|
||||
<!-- <br><br><br>
|
||||
<footer>
|
||||
<hr>
|
||||
<details>
|
||||
<summary><b>Apps SuperMesh</b></summary>
|
||||
<button type="button">
|
||||
<img src="static/TeleSec.jpg" alt="" width="100px">
|
||||
<br>TeleSec
|
||||
</button>
|
||||
</details>
|
||||
</footer> -->
|
||||
<img
|
||||
id="connectStatus"
|
||||
style="bottom: 15px; right: 15px; position: fixed; width: 50px"
|
||||
/>
|
||||
</main>
|
||||
<img
|
||||
id="actionStatus"
|
||||
src="static/ico/statusok.png"
|
||||
style="
|
||||
z-index: 2048;
|
||||
margin: 0px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: none;
|
||||
"
|
||||
/>
|
||||
<div id="snackbar">
|
||||
Hay una nueva versión de TeleSec.<br /><a id="reload"
|
||||
>Pulsa aqui para actualizar.</a
|
||||
>
|
||||
</div>
|
||||
<script src="static/showdown.min.js"></script>
|
||||
<script src="static/jquery.js"></script>
|
||||
<script src="static/gun.js"></script>
|
||||
<script src="static/webrtc.js"></script>
|
||||
<script src="static/sea.js"></script>
|
||||
<script src="static/yson.js"></script>
|
||||
<script src="static/radix.js"></script>
|
||||
<!-- <script src="static/radisk.js"></script> -->
|
||||
<!-- <script src="static/store.js"></script> -->
|
||||
<script src="static/rindexed.js"></script>
|
||||
<script src="static/path.js"></script>
|
||||
<script src="static/open.js"></script>
|
||||
<script src="static/load.js"></script>
|
||||
<!--<script src="static/synchronous.js"></script>-->
|
||||
<!--<script src="static/axe.js"></script>-->
|
||||
<script src="static/toastr.min.js"></script>
|
||||
<script src="static/doublescroll.js"></script>
|
||||
<!--<script src="static/simplemde.min.js"></script>-->
|
||||
<script async>
|
||||
async function getQuota(cb = () => {}) {
|
||||
if (navigator.storage && navigator.storage.estimate) {
|
||||
const quota = await navigator.storage.estimate();
|
||||
// quota.usage -> Number of bytes used.
|
||||
// quota.quota -> Maximum number of bytes available.
|
||||
const percentageUsed = (quota.usage / quota.quota) * 100;
|
||||
console.log(
|
||||
`You've used ${percentageUsed}% of the available storage.`
|
||||
);
|
||||
const remaining = quota.quota - quota.usage;
|
||||
cb(percentageUsed, remaining);
|
||||
console.log(`You can write up to ${remaining} more bytes.`);
|
||||
}
|
||||
}
|
||||
getQuota();
|
||||
</script>
|
||||
<script src="pwa.js"></script>
|
||||
<script src="config.js"></script>
|
||||
<script src="gun_init.js"></script>
|
||||
<script src="app_logic.js"></script>
|
||||
<script src="app_modules.js"></script>
|
||||
<script src="page/login.js"></script>
|
||||
<script src="page/index.js"></script>
|
||||
<script src="page/importar.js"></script>
|
||||
<script src="page/exportar.js"></script>
|
||||
<script src="page/materiales.js"></script>
|
||||
<script src="page/resumen_diario.js"></script>
|
||||
<script src="page/personas.js"></script>
|
||||
<script src="page/supercafe.js"></script>
|
||||
<script src="page/notificaciones.js"></script>
|
||||
<script src="page/comedor.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,7 +8,7 @@ PAGES.comedor = {
|
||||
var btn_guardar = safeuuid();
|
||||
var btn_borrar = safeuuid();
|
||||
container.innerHTML = `
|
||||
<h1>Menú del Comedor <code id="${nameh1}"></code></h1>
|
||||
<h1>Entrada del menú <code id="${nameh1}"></code></h1>
|
||||
<fieldset style="float: left;">
|
||||
<legend>Valores</legend>
|
||||
<label>
|
||||
@@ -80,7 +80,7 @@ PAGES.comedor = {
|
||||
container.innerHTML = `
|
||||
<h1>Menú del comedor</h1>
|
||||
<button id="${btn_new}">Nueva entrada</button>
|
||||
<div id="cont">
|
||||
<div id="cont"></div>
|
||||
`;
|
||||
TS_IndexElement(
|
||||
"comedor",
|
||||
50
src/page/login.js
Normal file
50
src/page/login.js
Normal file
@@ -0,0 +1,50 @@
|
||||
PAGES.login = {
|
||||
Esconder: true,
|
||||
Title: "Login",
|
||||
index: function (mid) {
|
||||
var field_persona = safeuuid();
|
||||
var btn_guardar = safeuuid();
|
||||
var btn_reload = safeuuid();
|
||||
var div_actions = safeuuid();
|
||||
container.innerHTML = `
|
||||
<h1>Iniciar sesión</h1>
|
||||
<fieldset>
|
||||
<legend>Valores</legend>
|
||||
<input type="hidden" id="${field_persona}">
|
||||
<div id="${div_actions}"></div>
|
||||
<button class="btn5" id="${btn_guardar}">Acceder</button>
|
||||
<button class="btn1" id="${btn_reload}">Recargar lista</button>
|
||||
</fieldset>
|
||||
<a style="color: rgb(240,240,240)">Acceso sin cuenta</a>
|
||||
`;
|
||||
var divact = document.getElementById(div_actions);
|
||||
addCategory_Personas(
|
||||
divact,
|
||||
SC_Personas,
|
||||
"",
|
||||
(value) => {
|
||||
document.getElementById(field_persona).value = value;
|
||||
},
|
||||
"¿Quién eres?",
|
||||
true,
|
||||
"- Pulsa recargar -"
|
||||
);
|
||||
document.getElementById("appendApps").style.display = "none"
|
||||
document.getElementById(btn_guardar).onclick = () => {
|
||||
if (document.getElementById(field_persona).value == "") {
|
||||
alert("Tienes que elegir tu cuenta!");
|
||||
return;
|
||||
}
|
||||
SUB_LOGGED_IN_ID = document.getElementById(field_persona).value
|
||||
SUB_LOGGED_IN_DETAILS = SC_Personas[SUB_LOGGED_IN_ID]
|
||||
SUB_LOGGED_IN = true
|
||||
setUrlHash("index")
|
||||
document.getElementById("appendApps").style.display = "unset"
|
||||
};
|
||||
|
||||
document.getElementById(btn_reload).onclick = () => {
|
||||
setUrlHash("login," + safeuuid(""))
|
||||
};
|
||||
|
||||
},
|
||||
}
|
||||
192
src/page/materiales.js
Normal file
192
src/page/materiales.js
Normal file
@@ -0,0 +1,192 @@
|
||||
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;
|
||||
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(""));
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -171,7 +171,7 @@ PAGES.notificaciones = {
|
||||
container.innerHTML = `
|
||||
<h1>Notificaciones</h1>
|
||||
<button id="${btn_new}">Nueva notificación</button>
|
||||
<div id="cont">
|
||||
<div id="cont"></div>
|
||||
`;
|
||||
TS_IndexElement(
|
||||
"notificaciones",
|
||||
@@ -198,23 +198,21 @@ PAGES.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);
|
||||
});
|
||||
function add_row(data, key) {
|
||||
if (data != null) {
|
||||
data["_key"] = key;
|
||||
rows[key] = data;
|
||||
} else {
|
||||
add_row(data, key);
|
||||
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 = () => {
|
||||
@@ -1,11 +1,14 @@
|
||||
PAGES.resumen_diario = {
|
||||
navcss: "btn3",
|
||||
Title: "Resumen Semanal",
|
||||
Title: "Resumen Diario",
|
||||
index: function () {
|
||||
var table_materialesLow = safeuuid();
|
||||
var table_personasHigh = safeuuid();
|
||||
var table_comedor = safeuuid();
|
||||
container.innerHTML = `
|
||||
<h1>Resumen Semanal</h1>
|
||||
<h1>Resumen Diario</h1>
|
||||
<h2>Menú del comedor de hoy</h2>
|
||||
<span class="btn7" style="display: inline-block; margin: 5px; padding: 5px; border-radius: 5px; border: 2px solid black;" id="${table_comedor}"></span>
|
||||
<h2>Personas con café gratis (para el Viernes)</h2>
|
||||
<div id="${table_personasHigh}"></div>
|
||||
<h2>Materiales faltantes (o por llegar)</h2>
|
||||
@@ -58,23 +61,21 @@ PAGES.resumen_diario = {
|
||||
.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);
|
||||
});
|
||||
function add_row(data, key) {
|
||||
if (data != null) {
|
||||
data["_key"] = key;
|
||||
materiales_low[key] = data;
|
||||
} else {
|
||||
add_row(data, key);
|
||||
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() {
|
||||
@@ -123,24 +124,44 @@ PAGES.resumen_diario = {
|
||||
.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);
|
||||
});
|
||||
function add_row(data, key) {
|
||||
if (data != null) {
|
||||
data["_key"] = key;
|
||||
personas_high[key] = data;
|
||||
} else {
|
||||
add_row(data, key);
|
||||
delete personas_high[key];
|
||||
}
|
||||
render_personasHigh();
|
||||
}
|
||||
if (typeof data == "string") {
|
||||
SEA.decrypt(data, SECRET, (data) => {
|
||||
add_row(data, key);
|
||||
});
|
||||
} else {
|
||||
add_row(data, key);
|
||||
}
|
||||
});
|
||||
|
||||
// Comedor (.get("comedor").get(<current iso day>))
|
||||
gun
|
||||
.get(TABLE)
|
||||
.get("comedor")
|
||||
.get(CurrentISODate())
|
||||
.once((data, key) => {
|
||||
function add_row(data) {
|
||||
// Fix newlines
|
||||
data.Platos = data.Platos.replace(/\n/g, "<br>");
|
||||
// Display platos
|
||||
document.getElementById(table_comedor).innerHTML += data.Platos || "No hay platos registrados para hoy.";
|
||||
}
|
||||
if (typeof data == "string") {
|
||||
SEA.decrypt(data, SECRET, (data) => {
|
||||
add_row(data);
|
||||
});
|
||||
} else {
|
||||
add_row(data);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
};
|
||||
@@ -167,7 +167,6 @@ PAGES.supercafe = {
|
||||
<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>
|
||||
`;
|
||||
@@ -1,194 +0,0 @@
|
||||
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(""));
|
||||
};
|
||||
},
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
var cacheName = 'telesec_%%VERSIONCO%%';
|
||||
var cacheName = 'telesec_2025-07-30_4';
|
||||
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil(
|
||||
caches.open(cacheName)
|
||||
.then(cache => cache.addAll(%%ASSETSJSON%%))
|
||||
.then(cache => cache.addAll(["index.html", "icon512_maskable.png", "icon512_rounded.png", "cola_cao.jpg", "manifest.json", "static/webrtc.js", "static/synchronous.js", "static/sea.js", "static/gun.js", "static/toastr.min.css", "static/store.js", "static/simplemde.min.css", "static/doublescroll.js", "static/rindexed.js", "static/yson.js", "static/toastr.min.js", "static/showdown.min.js", "static/load.js", "static/radix.js", "static/axe.js", "static/TeleSec.jpg", "static/path.js", "static/radisk.js", "static/open.js", "static/simplemde.min.js", "static/jquery.js", "static/euskaditech-css/README.md", "static/euskaditech-css/.gitignore", "static/euskaditech-css/simple.css", "static/euskaditech-css/.git", "static/euskaditech-css/logos/EuskadiTech/long nobg color.svg", "static/euskaditech-css/logos/EuskadiTech/nobg color.png", "static/euskaditech-css/logos/EuskadiTech/nobg color.svg", "static/euskaditech-css/logos/EuskadiTech/long nobg color.png", "static/ico/add.png", "static/ico/user_generic.png", "static/ico/keyboard_key_g.png", "static/ico/keyboard_key_p.png", "static/ico/snowflake.png", "static/ico/coffee_bean.png", "static/ico/arrow_up_red.png", "static/ico/milk (1).png", "static/ico/azucar-moreno.png", "static/ico/arrow_down_blue.png", "static/ico/camera2.png", "static/ico/fire.png", "static/ico/cookies.png", "static/ico/checkbox_unchecked.png", "static/ico/wheat.png", "static/ico/sacarina.jpg", "static/ico/arrow_left_green.png", "static/ico/tea_bag.png", "static/ico/cow.png", "static/ico/connect_ko.svg", "static/ico/milk.png", "static/ico/user.png", "static/ico/stevia.jpg", "static/ico/water_tap.png", "static/ico/thermometer2.png", "static/ico/statusok.png", "static/ico/lollipop.png", "static/ico/colacao.jpg", "static/ico/delete.png", "static/ico/cereales.png", "static/ico/checkbox.png", "static/ico/azucar-blanco.jpg", "static/ico/preferences.png", "static/ico/sizes.png", "static/ico/stevia-gotas.webp", "static/ico/connect_ok.svg", "static/ico/layered1/Azucar-Az. Moreno.png", "static/ico/layered1/Azucar-Stevia (Pastillas).png", "static/ico/layered1/Azucar-Sacarina.png", "static/ico/layered1/Selección-ColaCao.png", "static/ico/layered1/Temperatura-Templado.png", "static/ico/layered1/Tamaño-Pequeño.png", "static/ico/layered1/Leche-Sin lactosa.png", "static/ico/layered1/Cafeina-Sin.png", "static/ico/layered1/Leche-Vegetal.png", "static/ico/layered1/Leche-de Vaca.png", "static/ico/layered1/Selección-Infusion.png", "static/ico/layered1/Azucar-Sin.png", "static/ico/layered1/Selección-Leche.png", "static/ico/layered1/Temperatura-Frio.png", "static/ico/layered1/Background.png", "static/ico/layered1/Azucar-Edulcorante.png", "static/ico/layered1/Cafeina-Con.png", "static/ico/layered1/Selección-CaféLeche.png", "static/ico/layered1/Tamaño-Grande.png", "static/ico/layered1/Selección-CafeSolo.png", "static/ico/layered1/Leche-Agua.png", "static/ico/layered1/Temperatura-Caliente.png", "static/ico/layered1/Azucar-Stevia (Gotas).png", "static/ico/layered1/Azucar-Az. Blanco.png"]))
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user