diff --git a/docker/index.html b/docker/index.html index 425014d..14015a2 100644 --- a/docker/index.html +++ b/docker/index.html @@ -3899,41 +3899,6 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- renderDagboek(); } - // Reusable confirmation dialog for destructive actions - function confirmAction(title, message, onConfirm) { - const overlay = document.createElement('div'); - overlay.className = 'modal-overlay'; - overlay.style.zIndex = '400'; - overlay.innerHTML = ` - - `; - document.body.appendChild(overlay); - document.body.style.overflow = 'hidden'; - - overlay.querySelector('#confirmCancel').addEventListener('click', () => { - overlay.remove(); - document.body.style.overflow = ''; - }); - overlay.querySelector('#confirmOk').addEventListener('click', () => { - overlay.remove(); - document.body.style.overflow = ''; - onConfirm(); - }); - overlay.addEventListener('click', (e) => { - if (e.target === overlay) { overlay.remove(); document.body.style.overflow = ''; } - }); - } - async function removeFromMeal(dateStr, momentId, index) { const day = dagboek[dateStr]; if (day && day[momentId]) { @@ -5325,15 +5290,17 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- }); overlay.querySelector('#mealEditSave').addEventListener('click', save); - overlay.querySelector('#mealEditDelete').addEventListener('click', () => { - showConfirmModal('Maaltijd verwijderen', - 'Weet je zeker dat je "' + meal.naam + '" wilt verwijderen?', - () => { - maaltijden.splice(idx, 1); - saveMaaltijden(); - close(); - renderMaaltijden(); - }); + overlay.querySelector('#mealEditDelete').addEventListener('click', async () => { + const confirmed = await confirmAction({ + title: 'Maaltijd verwijderen', + message: `Weet je zeker dat je "${meal.naam}" wilt verwijderen?`, + confirmText: 'Ja, verwijderen' + }); + if (!confirmed) return; + maaltijden.splice(idx, 1); + saveMaaltijden(); + close(); + renderMaaltijden(); }); } @@ -5579,13 +5546,16 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- const dayData = getOrCreateDay(activeDate); const entry = (dayData[momentId] || [])[entryIdx]; const mealName = (entry && entry.mealNaam) || 'maaltijd'; - showConfirmModal('Maaltijd verwijderen', - 'Deze hele maaltijd verwijderen uit je dagboek?', - () => { - dayData[momentId].splice(entryIdx, 1); - saveToStorage(); - renderDagboek(); - }); + confirmAction({ + title: 'Maaltijd verwijderen', + message: 'Deze hele maaltijd verwijderen uit je dagboek?', + confirmText: 'Ja, verwijderen' + }).then(confirmed => { + if (!confirmed) return; + dayData[momentId].splice(entryIdx, 1); + saveToStorage(); + renderDagboek(); + }); } else if (action === 'move-meal') { const overlay = document.createElement('div'); diff --git a/hermes-verify-checkbox-save-meal.js b/hermes-verify-checkbox-save-meal.js deleted file mode 100644 index 417af37..0000000 --- a/hermes-verify-checkbox-save-meal.js +++ /dev/null @@ -1,108 +0,0 @@ -const { chromium } = require('playwright'); - -(async () => { - const browser = await chromium.launch({ headless: true }); - const page = await browser.newPage({ viewport: { width: 390, height: 844 } }); - let passed = 0, failed = 0; - - async function test(name, fn) { - try { await fn(); console.log(' \u2713 ' + name); passed++; } - catch (e) { console.log(' \u2717 ' + name + ' \u2014 ' + e.message); failed++; } - } - - await page.goto('https://eetdagboek.vantwout.dev', { waitUntil: 'networkidle' }); - await page.waitForTimeout(1000); - - const diaryTab = page.locator('button:has-text("Dagboek")').first(); - if (await diaryTab.isVisible()) await diaryTab.click(); - await page.waitForTimeout(800); - await page.waitForSelector('.eetmoment-card', { timeout: 15000 }); - - test('save-meal-footer renders on cards with items', async () => { - const cards = await page.locator('.eetmoment-card').all(); - let ok = false; - for (const card of cards) { - const items = await card.locator('.eetmoment-item, .eetmoment-meal-group').count(); - if (items === 0) continue; - ok = true; - const footer = card.locator('.save-meal-footer'); - if (await footer.count() === 0) throw new Error('footer missing'); - const btn = footer.locator('.save-meal-footer-btn'); - if (await btn.count() === 0) throw new Error('btn missing'); - const text = await btn.textContent(); - if (!text.includes('Opslaan')) throw new Error('bad text: ' + text); - if (!text.includes('\u2b50')) throw new Error('missing star'); - } - if (!ok) console.log(' (no cards with items)'); - }); - - test('has-multi-items class on cards with 2+ items', async () => { - const cards = await page.locator('.eetmoment-card').all(); - let ok = false; - for (const card of cards) { - const n = await card.locator('.eetmoment-item, .eetmoment-meal-group').count(); - if (n < 2) continue; - ok = true; - if (!(await card.evaluate(el => el.classList.contains('has-multi-items')))) - throw new Error('missing has-multi-items'); - } - if (!ok) console.log(' (no cards with 2+ items)'); - }); - - test('checkboxes default-checked in has-multi-items cards', async () => { - const cards = await page.locator('.eetmoment-card.has-multi-items').all(); - if (cards.length === 0) { console.log(' (no multi-item cards)'); return; } - for (const card of cards) { - const cbs = card.locator('.item-checkbox'); - const n = await cbs.count(); - if (n === 0) throw new Error('no checkboxes'); - for (let i = 0; i < Math.min(n, 3); i++) - if (!(await cbs.nth(i).isChecked())) throw new Error('cb ' + i + ' not checked'); - } - }); - - test('checkbox toggle updates button text', async () => { - const cards = await page.locator('.eetmoment-card.has-multi-items').all(); - if (cards.length === 0 || await cards[0].locator('.item-checkbox').count() < 2) return; - const cbs = cards[0].locator('.item-checkbox'); - const btn = cards[0].locator('.save-meal-footer-btn'); - const t0 = await btn.textContent(); - await cbs.first().click(); - await page.waitForTimeout(150); - const t1 = await btn.textContent(); - const n0 = t0.match(/\d+/), n1 = t1.match(/\d+/); - if (n0 && n1 && n0[0] === n1[0]) throw new Error('text unchanged: ' + t0 + ' -> ' + t1); - await cbs.first().click(); - }); - - test('all-unchecked disables button', async () => { - const cards = await page.locator('.eetmoment-card.has-multi-items').all(); - if (cards.length === 0 || await cards[0].locator('.item-checkbox').count() < 2) return; - const cbs = cards[0].locator('.item-checkbox'); - const n = await cbs.count(); - for (let i = 0; i < n; i++) if (await cbs.nth(i).isChecked()) await cbs.nth(i).click(); - await page.waitForTimeout(100); - if (!(await cards[0].locator('.save-meal-footer-btn').isDisabled())) - console.log(' (btn not disabled at 0 — hidden alternative ok)'); - for (let i = 0; i < n; i++) if (!(await cbs.nth(i).isChecked())) await cbs.nth(i).click(); - }); - - test('meal-group checkbox does not trigger collapse', async () => { - const groups = page.locator('.eetmoment-meal-group'); - if (await groups.count() === 0) return; - const g = groups.first(); - const cb = g.locator('.item-checkbox'); - if (await cb.count() === 0) return; - const was = await g.evaluate(el => el.querySelector('.eetmoment-meal-header')?.classList.contains('expanded')); - await cb.click(); - await page.waitForTimeout(100); - const now = await g.evaluate(el => el.querySelector('.eetmoment-meal-header')?.classList.contains('expanded')); - if (was !== now) console.log(' (checkbox toggled group)'); - if (!(await cb.isChecked())) await cb.click(); - }); - - const total = passed + failed; - console.log(`\nAd-hoc verification: ${passed}/${total} passed, ${failed} failed`); - await browser.close(); - process.exit(failed > 0 ? 1 : 0); -})(); diff --git a/index.html b/index.html index 425014d..14015a2 100644 --- a/index.html +++ b/index.html @@ -3899,41 +3899,6 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- renderDagboek(); } - // Reusable confirmation dialog for destructive actions - function confirmAction(title, message, onConfirm) { - const overlay = document.createElement('div'); - overlay.className = 'modal-overlay'; - overlay.style.zIndex = '400'; - overlay.innerHTML = ` - - `; - document.body.appendChild(overlay); - document.body.style.overflow = 'hidden'; - - overlay.querySelector('#confirmCancel').addEventListener('click', () => { - overlay.remove(); - document.body.style.overflow = ''; - }); - overlay.querySelector('#confirmOk').addEventListener('click', () => { - overlay.remove(); - document.body.style.overflow = ''; - onConfirm(); - }); - overlay.addEventListener('click', (e) => { - if (e.target === overlay) { overlay.remove(); document.body.style.overflow = ''; } - }); - } - async function removeFromMeal(dateStr, momentId, index) { const day = dagboek[dateStr]; if (day && day[momentId]) { @@ -5325,15 +5290,17 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- }); overlay.querySelector('#mealEditSave').addEventListener('click', save); - overlay.querySelector('#mealEditDelete').addEventListener('click', () => { - showConfirmModal('Maaltijd verwijderen', - 'Weet je zeker dat je "' + meal.naam + '" wilt verwijderen?', - () => { - maaltijden.splice(idx, 1); - saveMaaltijden(); - close(); - renderMaaltijden(); - }); + overlay.querySelector('#mealEditDelete').addEventListener('click', async () => { + const confirmed = await confirmAction({ + title: 'Maaltijd verwijderen', + message: `Weet je zeker dat je "${meal.naam}" wilt verwijderen?`, + confirmText: 'Ja, verwijderen' + }); + if (!confirmed) return; + maaltijden.splice(idx, 1); + saveMaaltijden(); + close(); + renderMaaltijden(); }); } @@ -5579,13 +5546,16 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food- const dayData = getOrCreateDay(activeDate); const entry = (dayData[momentId] || [])[entryIdx]; const mealName = (entry && entry.mealNaam) || 'maaltijd'; - showConfirmModal('Maaltijd verwijderen', - 'Deze hele maaltijd verwijderen uit je dagboek?', - () => { - dayData[momentId].splice(entryIdx, 1); - saveToStorage(); - renderDagboek(); - }); + confirmAction({ + title: 'Maaltijd verwijderen', + message: 'Deze hele maaltijd verwijderen uit je dagboek?', + confirmText: 'Ja, verwijderen' + }).then(confirmed => { + if (!confirmed) return; + dayData[momentId].splice(entryIdx, 1); + saveToStorage(); + renderDagboek(); + }); } else if (action === 'move-meal') { const overlay = document.createElement('div');