mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-10-07 16:18:54 +00:00
fix(form): address admin and form review findings
This commit is contained in:
parent
2f88a4a315
commit
e00d74ebad
3 changed files with 26 additions and 22 deletions
|
|
@ -28,7 +28,10 @@ function loadWeekOrders(week) {
|
|||
document.getElementById('admin-stats').textContent = '';
|
||||
|
||||
fetch(ADMIN_URL + '?week=' + encodeURIComponent(week), { headers: adminHeaders() })
|
||||
.then(r => r.json())
|
||||
.then(r => {
|
||||
if (!r.ok) throw new Error('HTTP ' + r.status);
|
||||
return r.json();
|
||||
})
|
||||
.then(data => renderAdminTable(data))
|
||||
.catch(() => {
|
||||
tbody.innerHTML = '<tr><td colspan="5" class="admin-error">Failed to load orders.</td></tr>';
|
||||
|
|
@ -187,7 +190,7 @@ function renderAdminTable(data) {
|
|||
MEALS.forEach(m => { menuPrices[m.name] = m.price; });
|
||||
const newTotal = editNames.reduce((sum, name) => {
|
||||
const price = menuPrices[name] || 0;
|
||||
return sum + price * (editQuantities[name] || 0);
|
||||
return sum + window.FormUtils.employeePrice(price) * (editQuantities[name] || 0);
|
||||
}, 0);
|
||||
totalHtml = '$' + newTotal.toFixed(2);
|
||||
tr.appendChild(empTd);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ let adminWeeks = [];
|
|||
let googleCredential = null;
|
||||
let googleUser = null;
|
||||
let reopenAtMs = null;
|
||||
let countdownTimer = null;
|
||||
let mealsListDelegationBound = false;
|
||||
|
||||
window.googleCredential = null;
|
||||
|
|
@ -103,7 +104,9 @@ function handleCredentialResponse(response) {
|
|||
|
||||
updateTotal();
|
||||
checkDuplicateOrder();
|
||||
checkAdmin();
|
||||
checkAdmin().then(() => {
|
||||
if (formClosed && !isAdmin) showClosedOverlay();
|
||||
});
|
||||
}
|
||||
|
||||
function signOut() {
|
||||
|
|
@ -257,7 +260,7 @@ function updateMealCardQty(index) {
|
|||
const qty = quantities[index] || 0;
|
||||
card.classList.toggle('selected', qty > 0);
|
||||
const qtyInput = card.querySelector('.qty');
|
||||
if (qtyInput) qtyInput.value = qty;
|
||||
if (qtyInput && qtyInput !== document.activeElement) qtyInput.value = qty;
|
||||
}
|
||||
|
||||
function setQty(index, value) {
|
||||
|
|
@ -286,14 +289,6 @@ function bindMealsListDelegation() {
|
|||
const delta = parseInt(btn.dataset.qtyDelta, 10);
|
||||
changeQty(index, delta);
|
||||
});
|
||||
list.addEventListener('change', (e) => {
|
||||
const input = e.target.closest('.qty');
|
||||
if (!input) return;
|
||||
const card = input.closest('[data-meal-index]');
|
||||
if (!card) return;
|
||||
const index = parseInt(card.dataset.mealIndex, 10);
|
||||
setQty(index, input.value);
|
||||
});
|
||||
list.addEventListener('input', (e) => {
|
||||
const input = e.target.closest('.qty');
|
||||
if (!input) return;
|
||||
|
|
@ -302,6 +297,13 @@ function bindMealsListDelegation() {
|
|||
const index = parseInt(card.dataset.mealIndex, 10);
|
||||
setQty(index, input.value);
|
||||
});
|
||||
list.addEventListener('focusout', (e) => {
|
||||
const input = e.target.closest('.qty');
|
||||
if (!input) return;
|
||||
const card = input.closest('[data-meal-index]');
|
||||
if (!card) return;
|
||||
updateMealCardQty(parseInt(card.dataset.mealIndex, 10));
|
||||
});
|
||||
}
|
||||
|
||||
function updateTotal() {
|
||||
|
|
@ -405,7 +407,7 @@ function showClosedOverlay() {
|
|||
const overlay = document.getElementById('closed-overlay');
|
||||
overlay.classList.add('is-visible');
|
||||
overlay.style.display = 'flex';
|
||||
document.querySelectorAll('.qty-control button').forEach(b => { b.disabled = true; });
|
||||
document.querySelectorAll('.qty-control button, .qty-control .qty').forEach(el => { el.disabled = true; });
|
||||
const submitBtn = document.getElementById('submit-btn');
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
if (formStatusData) startCountdown(formStatusData);
|
||||
|
|
@ -435,10 +437,10 @@ function adminBypassClosed() {
|
|||
}
|
||||
|
||||
function checkAdmin() {
|
||||
if (!ADMIN_URL) return;
|
||||
if (!ADMIN_URL) return Promise.resolve();
|
||||
const headers = {};
|
||||
if (googleCredential) headers['Authorization'] = 'Bearer ' + googleCredential;
|
||||
fetch(ADMIN_URL, { headers })
|
||||
return fetch(ADMIN_URL, { headers })
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(data => {
|
||||
if (data && data.weeks) {
|
||||
|
|
@ -520,7 +522,8 @@ function getEasternOffsetMs(date) {
|
|||
function startCountdown(data) {
|
||||
if (data && data.reopen_at) reopenAtMs = data.reopen_at * 1000;
|
||||
updateCountdown();
|
||||
setInterval(updateCountdown, 1000);
|
||||
if (countdownTimer !== null) clearInterval(countdownTimer);
|
||||
countdownTimer = setInterval(updateCountdown, 1000);
|
||||
}
|
||||
|
||||
function updateCountdown() {
|
||||
|
|
@ -561,8 +564,7 @@ async function checkFormStatus() {
|
|||
formStatusData = data;
|
||||
if (isAdmin) {
|
||||
adminBypassClosed();
|
||||
} else if (CONFIG.authMode === 'google') {
|
||||
} else {
|
||||
} else if (CONFIG.authMode !== 'google' || googleCredential) {
|
||||
showClosedOverlay();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@ class TestGenerateFormStructural:
|
|||
blob = cfg_match.group(1)
|
||||
# Literal </script> inside the CONFIG script would terminate early.
|
||||
assert "</script>" not in blob
|
||||
assert "<\\/script><script>alert(1)<\\/script>" in blob
|
||||
# Parsed JSON still contains the hostile meal name.
|
||||
cfg = json.loads(blob)
|
||||
assert any(
|
||||
|
|
@ -281,7 +280,7 @@ class TestGenerateFormPlaywright:
|
|||
# Reset first card via type-in
|
||||
qty = page.locator('[data-meal-index="0"] .qty')
|
||||
qty.fill("-3")
|
||||
qty.dispatch_event("change")
|
||||
qty.blur()
|
||||
page.wait_for_function(
|
||||
"() => document.querySelector('[data-meal-index=\"0\"] .qty').value === '0'"
|
||||
)
|
||||
|
|
@ -292,7 +291,7 @@ class TestGenerateFormPlaywright:
|
|||
"""() => {
|
||||
document.querySelectorAll('[data-meal-index] .qty').forEach((input) => {
|
||||
input.value = '0';
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
});
|
||||
}"""
|
||||
)
|
||||
|
|
@ -300,7 +299,7 @@ class TestGenerateFormPlaywright:
|
|||
"() => document.getElementById('count-display').textContent === '0 meals'"
|
||||
)
|
||||
qty.fill("2")
|
||||
qty.dispatch_event("change")
|
||||
qty.blur()
|
||||
page.wait_for_function(
|
||||
"() => document.getElementById('count-display').textContent === '2 meals'"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue