zetikettes/frontend/zetikettes.js
Paul Mathieu 3474239727 Now with edits, delete confirmations
- and also a better alignment on actions
- and konami code that works before login
2025-08-06 19:12:44 +02:00

264 lines
7.6 KiB
JavaScript

const params = {
'dluo': 'DLUO',
'lot': 'Nº de lot',
'q': 'Poids net (g)',
'teneur': 'Teneur en fruits (%)',
'f': 'Quantité de fruits pour 100g (g)',
}
var tikats;
function getCookie(name) {
const cookies = document.cookie.split(';');
for (let cookie of cookies) {
cookie = cookie.trim();
if (cookie.startsWith(name + '=')) {
return cookie.substring(name.length + 1);
}
}
return null;
}
function post(url, data) {
const csrf_token = getCookie('csrftoken');
return $.ajax({
url,
data: JSON.stringify(data),
method: 'POST',
xhrFields: { withCredentials: true },
headers: { 'X-CSRFToken': csrf_token },
});
}
function disableButtons() {
$('.btn').addClass("disabled");
}
function enableButtons() {
$('.btn').removeClass('disabled');
}
function resetEditModal(force = false) {
if ($("#new-add").text() === "Ajouter" && !force) {
return;
}
$("#new-name").val("");
$("#new-type").val("").formSelect();
$("#new-designation").val("");
$("#new-ingredients").val("");
$("#new-description").val("");
$("#new-color")[0].jscolor.fromString("#97a1cc");
$("#new-organic").prop("checked", false);
M.updateTextFields();
$("#new-add").text("Ajouter").off('click').click(() => {
const req = getTiketteData();
post(backend_api + 'newtikette', req).then(() => {
resetEditModal(true);
reload();
});
});
}
function openEditModal(zett) {
M.Modal.getInstance($("#newproduct")[0]).open();
$("#new-name").val(zett.title);
$("#new-type").val(zett.category_id).formSelect();
$("#new-designation").val(zett.designation);
$("#new-ingredients").val(zett.ingredients);
$("#new-description").val(zett.description);
$("#new-color")[0].jscolor.fromString(zett.color);
$("#new-organic").prop("checked", zett.ab === "inline");
M.updateTextFields();
$("#new-add").text("Modifier").off('click').click(() => {
const req = getTiketteData();
req.id = zett.id;
resetEditModal();
post(backend_api + 'updatetikette', req).then(reload);
});
}
function addProduct(tikette) {
const zett = tikette;
const appbody = $("#appbody");
const block = $('<div class="section">');
for (let sub in zett.subs) {
block.append($(`<div class="input-field"><label class="active">${params[sub]}</label><input type="text" name="${sub}" value="${zett.subs[sub]}">`));
}
const loader = $('<div class="progress"><div class="indeterminate"></div></div>')
.hide();
const action = $('<div class="section">')
.append($('<a class="btn">générer<a>')
.click(() => {
const subs = block.find(':text')
.toArray()
.reduce((obj, el) => ({...obj, [el.name]: el.value}), {});
const req = {
template: zett.prototempalte,
designation: zett.designation,
description: zett.description,
ingredients: zett.ingredients,
color: zett.color,
AB: zett.ab, // mind the capitalization here
subs,
landscape: zett.landscape,
};
loader.show();
disableButtons();
post(backend_api + 'generate', req)
.then(data => {
const pdfbtn = $(`<a class="btn" href="${backend_api}data/${data.file}" target="_blank">ouvrir le pdf</a>`);
action.append(pdfbtn);
})
.catch(err => {
console.error(err);
})
.always(() => {
loader.hide();
enableButtons();
});
})
.append(loader));
const deleteAction = $('<b class="material-icons">delete</b>').click(() => {
$("#delete-title").text(zett.title);
$("#delete-confirm").off('click').click(() => {
const req = {
id: zett.id,
};
post(backend_api + 'deletetikette', req).then(reload);
});
M.Modal.getInstance($("#confirmdelete")[0]).open();
return false;
});
const editAction = $('<b class="material-icons">edit</b>').click(() => {
openEditModal(zett);
return false;
});
appbody
.append($('<li>')
.append($('<div class="collapsible-header valign-wrapper">')
.append(`<h6 class="blue-text">${zett.title}</h6>`)
.append($('<span class="actions grey-text">')
.append(editAction)
.append(deleteAction)
))
.append($('<div class="collapsible-body">')
.append(block)
.append(action)));
}
function setCategories() {
const katsel = $('#new-type');
katsel.empty();
for (let kat of tikats) {
katsel.append($(`<option value="${kat.id}">${kat.name}</option>`));
}
$('select').formSelect();
}
function getTiketteData() {
const title = $("#new-name").val();
const category_id = $("#new-type").val();
const designation = $("#new-designation").val();
const ingredients = $("#new-ingredients").val();
const description = $("#new-description").val();
const color = $("#new-color").val().substring(1);
const ab = $("#new-organic").is(":checked") ? 'inline' : 'none';
return {
title,
category_id,
designation,
ingredients,
description,
color,
ab,
};
}
function loadAll(zetikettes) {
const appbody = $("#appbody");
appbody.empty();
for (let zett of zetikettes) {
addProduct(zett);
}
setCategories();
}
function konami() {
var k = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65],
n = 0;
$(document).keydown(function (e) {
if (e.keyCode === k[n++]) {
if (n === k.length) {
document.location.href = backend_api + 'admin';
}
}
else {
n = 0;
}
});
}
async function googleCred(creds) {
const token = creds.credential;
await post(backend_api + 'signin', {token});
$('#signin-prompt').hide();
reload();
}
async function reload() {
disableButtons();
try {
const resp = await $.ajax({
url: backend_api + 'list',
timeout: 1000,
xhrFields: { withCredentials: true },
});
tikats = (await $.ajax({
url: backend_api + 'categories',
timeout: 1000,
xhrFields: { withCredentials: true },
})).tikats.sort((a, b) => a.name > b.name ? 1 : -1);
loadAll(resp.tikettes.sort((a, b) => (a.title < b.title) ? -1 : 1));
enableButtons();
} catch(e) {
if (e.status === 403) {
$("#signin-prompt").show();
google.accounts.id.prompt(); // also display the One Tap dialog
return;
}
const appbody = $("#appbody");
appbody.append(`<li>Could not reach backend server`);
}
}
$(document).ready(() => {
google.accounts.id.initialize({
client_id: google_oauth_client_id,
callback: googleCred,
});
google.accounts.id.renderButton(
document.getElementById("signin-prompt"),
{ theme: "outline", size: "large" } // customization attributes
);
konami();
$('.collapsible').collapsible();
$('.modal').modal({onOpenStart: resetEditModal});
reload();
});