feat: Añadir modo de revisión y mejorar la retroalimentación en el panel
This commit is contained in:
@@ -5,8 +5,6 @@ PAGES.pagos = {
|
|||||||
icon: 'static/appico/credit_cards.png',
|
icon: 'static/appico/credit_cards.png',
|
||||||
AccessControl: true,
|
AccessControl: true,
|
||||||
Title: 'Pagos',
|
Title: 'Pagos',
|
||||||
CajaCafeID: 'caja_cafe',
|
|
||||||
CajaCafeNombre: 'Caja Café',
|
|
||||||
|
|
||||||
__getVisiblePersonas: function () {
|
__getVisiblePersonas: function () {
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
@@ -14,70 +12,6 @@ PAGES.pagos = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
__ensureCajaCafePersona: function () {
|
|
||||||
var cajaId = PAGES.pagos.CajaCafeID;
|
|
||||||
var cajaNombre = PAGES.pagos.CajaCafeNombre;
|
|
||||||
var existing = SC_Personas[cajaId];
|
|
||||||
|
|
||||||
if (existing && existing.Nombre === cajaNombre && existing.Oculto === true) {
|
|
||||||
return Promise.resolve(cajaId);
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
Nombre: cajaNombre,
|
|
||||||
Region: 'Sistema',
|
|
||||||
Roles: '',
|
|
||||||
SC_Anilla: '',
|
|
||||||
markdown: 'Monedero interno de cafetería',
|
|
||||||
Monedero_Balance: parseFloat((existing && existing.Monedero_Balance) || 0) || 0,
|
|
||||||
Monedero_Notas: (existing && existing.Monedero_Notas) || '',
|
|
||||||
Oculto: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
return DB.put('personas', cajaId, data)
|
|
||||||
.then(() => {
|
|
||||||
SC_Personas[cajaId] = data;
|
|
||||||
return cajaId;
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.warn('DB.put error', e);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
__creditCajaCafeForGasto: function (personaOrigenId, monto, callback) {
|
|
||||||
var cajaId = PAGES.pagos.CajaCafeID;
|
|
||||||
if (personaOrigenId === cajaId) {
|
|
||||||
if (callback) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PAGES.pagos.__ensureCajaCafePersona().then((resolvedCajaId) => {
|
|
||||||
if (!resolvedCajaId) {
|
|
||||||
if (callback) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var caja = SC_Personas[resolvedCajaId];
|
|
||||||
if (!caja) {
|
|
||||||
if (callback) callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentBalance = parseFloat(caja.Monedero_Balance || 0);
|
|
||||||
caja.Monedero_Balance = fixfloat(currentBalance + monto);
|
|
||||||
|
|
||||||
DB.put('personas', resolvedCajaId, caja)
|
|
||||||
.then(() => {
|
|
||||||
if (callback) callback();
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.warn('DB.put error', e);
|
|
||||||
if (callback) callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Datafono view for creating/processing transactions
|
// Datafono view for creating/processing transactions
|
||||||
datafono: function (prefilledData = {}) {
|
datafono: function (prefilledData = {}) {
|
||||||
if (!checkRole('pagos:edit')) {
|
if (!checkRole('pagos:edit')) {
|
||||||
@@ -104,8 +38,6 @@ PAGES.pagos = {
|
|||||||
sessionStorage.removeItem('pagos_scanned_persona');
|
sessionStorage.removeItem('pagos_scanned_persona');
|
||||||
}
|
}
|
||||||
|
|
||||||
PAGES.pagos.__ensureCajaCafePersona();
|
|
||||||
|
|
||||||
var field_tipo = safeuuid();
|
var field_tipo = safeuuid();
|
||||||
var field_monto = safeuuid();
|
var field_monto = safeuuid();
|
||||||
var field_persona = safeuuid();
|
var field_persona = safeuuid();
|
||||||
@@ -577,13 +509,7 @@ PAGES.pagos = {
|
|||||||
var shouldUpdateBalance = !(tipo === 'Gasto' && metodo === 'Efectivo');
|
var shouldUpdateBalance = !(tipo === 'Gasto' && metodo === 'Efectivo');
|
||||||
|
|
||||||
function finalizeTransactionSave() {
|
function finalizeTransactionSave() {
|
||||||
if (tipo === 'Gasto') {
|
saveTransaction(ticketId, transactionData);
|
||||||
PAGES.pagos.__creditCajaCafeForGasto(personaId, monto, () => {
|
|
||||||
saveTransaction(ticketId, transactionData);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
saveTransaction(ticketId, transactionData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldUpdateBalance) {
|
if (shouldUpdateBalance) {
|
||||||
@@ -1017,14 +943,7 @@ PAGES.pagos = {
|
|||||||
});
|
});
|
||||||
} else if (tipo === 'Gasto') {
|
} else if (tipo === 'Gasto') {
|
||||||
revertWalletBalance(personaId, 'Ingreso', monto, () => {
|
revertWalletBalance(personaId, 'Ingreso', monto, () => {
|
||||||
var cajaId = PAGES.pagos.CajaCafeID;
|
deleteTransaction(tid);
|
||||||
if (personaId === cajaId) {
|
|
||||||
deleteTransaction(tid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
revertWalletBalance(cajaId, 'Gasto', monto, () => {
|
|
||||||
deleteTransaction(tid);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
} else if (tipo === 'Transferencia') {
|
} else if (tipo === 'Transferencia') {
|
||||||
var destinoId = data.PersonaDestino;
|
var destinoId = data.PersonaDestino;
|
||||||
@@ -1089,8 +1008,6 @@ PAGES.pagos = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PAGES.pagos.__ensureCajaCafePersona();
|
|
||||||
|
|
||||||
var btn_datafono = safeuuid();
|
var btn_datafono = safeuuid();
|
||||||
var total_ingresos = safeuuid();
|
var total_ingresos = safeuuid();
|
||||||
var total_gastos = safeuuid();
|
var total_gastos = safeuuid();
|
||||||
@@ -1373,8 +1290,6 @@ PAGES.pagos = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PAGES.pagos.__ensureCajaCafePersona();
|
|
||||||
|
|
||||||
var field_tipo = safeuuid();
|
var field_tipo = safeuuid();
|
||||||
var field_monto = safeuuid();
|
var field_monto = safeuuid();
|
||||||
var field_persona = safeuuid();
|
var field_persona = safeuuid();
|
||||||
|
|||||||
@@ -276,6 +276,8 @@ PAGES.panel = {
|
|||||||
answers: {},
|
answers: {},
|
||||||
score: 0,
|
score: 0,
|
||||||
feedback: '',
|
feedback: '',
|
||||||
|
feedbackType: '',
|
||||||
|
reviewMode: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
function saveResult() {
|
function saveResult() {
|
||||||
@@ -299,16 +301,36 @@ PAGES.panel = {
|
|||||||
.map((option, i) => {
|
.map((option, i) => {
|
||||||
var oid = safeuuid();
|
var oid = safeuuid();
|
||||||
var checked = selected === option ? 'checked' : '';
|
var checked = selected === option ? 'checked' : '';
|
||||||
|
var disabled = state.reviewMode ? 'disabled' : '';
|
||||||
|
var optionStyle =
|
||||||
|
'display:block;margin: 8px 0;padding: 8px;border: 1px solid #ccc;border-radius: 6px;cursor:pointer;max-width: 150px;text-align: center;';
|
||||||
|
|
||||||
|
if (state.reviewMode) {
|
||||||
|
if (option === q.correct) {
|
||||||
|
optionStyle =
|
||||||
|
'display:block;margin: 8px 0;padding: 8px;border: 2px solid #2ed573;background:#eafff1;border-radius: 6px;cursor:pointer;max-width: 150px;text-align: center;';
|
||||||
|
} else if (option === selected && option !== q.correct) {
|
||||||
|
optionStyle =
|
||||||
|
'display:block;margin: 8px 0;padding: 8px;border: 2px solid #ff4757;background:#ffecec;border-radius: 6px;cursor:pointer;max-width: 150px;text-align: center;';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var optionContent = PAGES.panel.__renderOptionContent(q, option);
|
var optionContent = PAGES.panel.__renderOptionContent(q, option);
|
||||||
return `
|
return `
|
||||||
<label class="panel-option" for="${oid}" style="display:block;margin: 8px 0;padding: 8px;border: 1px solid #ccc;border-radius: 6px;cursor:pointer;max-width: 150px;text-align: center;">
|
<label class="panel-option" for="${oid}" style="${optionStyle}">
|
||||||
<input id="${oid}" type="radio" name="panel-question" value="${option.replace(/"/g, '"')}" ${checked} />
|
<input id="${oid}" type="radio" name="panel-question" value="${option.replace(/"/g, '"')}" ${checked} ${disabled} />
|
||||||
${optionContent}
|
${optionContent}
|
||||||
</label>
|
</label>
|
||||||
`;
|
`;
|
||||||
})
|
})
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
|
var feedbackColor = '#555';
|
||||||
|
if (state.feedbackType === 'ok') feedbackColor = '#1f8f4a';
|
||||||
|
if (state.feedbackType === 'bad') feedbackColor = '#c0392b';
|
||||||
|
|
||||||
|
var nextButtonText = state.reviewMode ? 'Continuar' : 'Comprobar';
|
||||||
|
|
||||||
target.innerHTML = html`
|
target.innerHTML = html`
|
||||||
<fieldset style="max-width: 800px;">
|
<fieldset style="max-width: 800px;">
|
||||||
<legend>Pregunta ${state.idx + 1} de ${questions.length}</legend>
|
<legend>Pregunta ${state.idx + 1} de ${questions.length}</legend>
|
||||||
@@ -318,9 +340,9 @@ PAGES.panel = {
|
|||||||
${ctx.comedor.postre || '—'}
|
${ctx.comedor.postre || '—'}
|
||||||
</small>
|
</small>
|
||||||
<div style="margin-top: 10px; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px;">${optionsHtml}</div>
|
<div style="margin-top: 10px; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px;">${optionsHtml}</div>
|
||||||
<div id="panel-feedback" style="margin-top: 12px;"><i>${state.feedback || ''}</i></div>
|
<div id="panel-feedback" style="margin-top: 12px; color:${feedbackColor};"><i>${state.feedback || ''}</i></div>
|
||||||
<div style="margin-top: 12px; display:flex; gap:8px;">
|
<div style="margin-top: 12px; display:flex; gap:8px;">
|
||||||
<button class="btn5" id="panel-next">Comprobar y continuar</button>
|
<button class="btn5" id="panel-next">${nextButtonText}</button>
|
||||||
<button id="panel-cancel">Salir</button>
|
<button id="panel-cancel">Salir</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -328,9 +350,26 @@ PAGES.panel = {
|
|||||||
|
|
||||||
document.getElementById('panel-cancel').onclick = () => setUrlHash('index');
|
document.getElementById('panel-cancel').onclick = () => setUrlHash('index');
|
||||||
document.getElementById('panel-next').onclick = () => {
|
document.getElementById('panel-next').onclick = () => {
|
||||||
|
if (state.reviewMode) {
|
||||||
|
state.reviewMode = false;
|
||||||
|
state.feedback = '';
|
||||||
|
state.feedbackType = '';
|
||||||
|
|
||||||
|
if (state.idx < questions.length - 1) {
|
||||||
|
state.idx++;
|
||||||
|
renderCurrent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveResult();
|
||||||
|
renderFinal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var checked = document.querySelector('input[name="panel-question"]:checked');
|
var checked = document.querySelector('input[name="panel-question"]:checked');
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
state.feedback = 'Selecciona una opción antes de continuar.';
|
state.feedback = 'Selecciona una opción antes de continuar.';
|
||||||
|
state.feedbackType = 'bad';
|
||||||
renderCurrent();
|
renderCurrent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -342,21 +381,14 @@ PAGES.panel = {
|
|||||||
if (wasCorrect) {
|
if (wasCorrect) {
|
||||||
state.score++;
|
state.score++;
|
||||||
state.feedback = '✅ ' + q.ok;
|
state.feedback = '✅ ' + q.ok;
|
||||||
|
state.feedbackType = 'ok';
|
||||||
} else {
|
} else {
|
||||||
state.feedback = '❌ ' + q.bad + ' Respuesta esperada: ' + q.correct;
|
state.feedback = '❌ ' + q.bad + ' Respuesta esperada: ' + q.correct;
|
||||||
|
state.feedbackType = 'bad';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.idx < questions.length - 1) {
|
state.reviewMode = true;
|
||||||
state.idx++;
|
renderCurrent();
|
||||||
setTimeout(() => {
|
|
||||||
state.feedback = '';
|
|
||||||
renderCurrent();
|
|
||||||
}, 350);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveResult();
|
|
||||||
renderFinal();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,6 +415,8 @@ PAGES.panel = {
|
|||||||
state.answers = {};
|
state.answers = {};
|
||||||
state.score = 0;
|
state.score = 0;
|
||||||
state.feedback = '';
|
state.feedback = '';
|
||||||
|
state.feedbackType = '';
|
||||||
|
state.reviewMode = false;
|
||||||
renderCurrent();
|
renderCurrent();
|
||||||
};
|
};
|
||||||
document.getElementById('panel-home').onclick = () => setUrlHash('index');
|
document.getElementById('panel-home').onclick = () => setUrlHash('index');
|
||||||
|
|||||||
Reference in New Issue
Block a user