fix: maaltijd vereist 2+ ingrediënten, save-knop pas zichtbaar bij selectie

- Save-meal footer alleen bij 2+ items (niet bij 1 item)
- Save-knop hidden tot 2+ checkboxes gecheckt
- Delete-all knop (bezem) verwijderd uit eetmoment header
- Tests geüpdatet: 2 items toevoegen, checkboxes forceren via evaluate

38/39 tests groen, 1 skipped (confirm modal guard)
This commit is contained in:
cas 2026-07-24 22:25:45 +02:00
parent e8e1755f31
commit 89a196ce9a
3 changed files with 88 additions and 100 deletions

View file

@ -1357,30 +1357,6 @@ body {
display: none;
}
/* ===== Clear-eetmoment header button ===== */
.eetmoment-clear-btn {
background: none;
border: none;
font-size: 0.75rem;
color: var(--text-muted);
cursor: pointer;
padding: 4px 6px;
min-width: var(--touch-min);
min-height: var(--touch-min);
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: background 0.15s, color 0.15s;
opacity: 0.5;
flex-shrink: 0;
}
.eetmoment-clear-btn:hover {
background: var(--danger-light);
color: var(--danger);
opacity: 1;
}
/* ===== Diary — nested meal groups ===== */
.eetmoment-meal-group {
background: var(--primary-lighter);
@ -3503,7 +3479,6 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
</div>
<div style="display:flex;align-items:center;gap:2px;">
<span class="eetmoment-kh">${roundedKh > 0 ? formatKh(roundedKh) + ' g' : '—'}</span>
${items.length > 0 ? `<button class="eetmoment-clear-btn" data-moment="${moment.id}" title="Eetmoment legen" aria-label="Eetmoment legen"><i class="fas fa-broom"></i></button>` : ''}
<span style="font-size:0.8rem;color:var(--text-muted)">${items.length > 0 ? '<i class="fas fa-chevron-down"></i>' : ''}</span>
</div>
</div>
@ -3512,13 +3487,10 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
<div class="eetmoment-add-btn" data-moment="${moment.id}">
<span>+</span> Voedingsmiddel toevoegen
</div>
${items.length > 0 ? `
${items.length > 1 ? `
<div class="save-meal-footer" data-moment="${moment.id}">
<button class="save-meal-footer-btn" data-moment="${moment.id}"${items.length > 1 ? ' style="display:none"' : ''}>
${items.length > 1
? `<i class="fas fa-star"></i> Selecteer ${items.length} items`
: `<i class="fas fa-star"></i> Opslaan als maaltijd`
}
<button class="save-meal-footer-btn" data-moment="${moment.id}" style="display:none">
<i class="fas fa-star"></i> Selecteer ${items.length} items
</button>
<button class="delete-selected-footer-btn hidden" data-moment="${moment.id}">
<i class="fas fa-trash"></i> Verwijder geselecteerde
@ -3642,25 +3614,6 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
});
});
// Clear eetmoment button
listEl.querySelectorAll('.eetmoment-clear-btn').forEach(btn => {
btn.addEventListener('click', async (e) => {
e.stopPropagation();
const momentId = btn.dataset.moment;
const dayData = getOrCreateDay(activeDate);
const items = dayData[momentId] || [];
if (items.length === 0) return;
const confirmed = await confirmAction({
message: `Weet je zeker dat je alle ${items.length} ${items.length === 1 ? 'item' : 'items'} uit dit eetmoment wilt verwijderen?`
});
if (!confirmed) return;
dayData[momentId] = [];
saveToStorage();
renderDagboek();
showToast('Eetmoment geleegd');
});
});
// Meal group toggle expand/collapse
listEl.querySelectorAll('.meal-group-header').forEach(header => {
header.addEventListener('click', (e) => {

View file

@ -1357,30 +1357,6 @@ body {
display: none;
}
/* ===== Clear-eetmoment header button ===== */
.eetmoment-clear-btn {
background: none;
border: none;
font-size: 0.75rem;
color: var(--text-muted);
cursor: pointer;
padding: 4px 6px;
min-width: var(--touch-min);
min-height: var(--touch-min);
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: background 0.15s, color 0.15s;
opacity: 0.5;
flex-shrink: 0;
}
.eetmoment-clear-btn:hover {
background: var(--danger-light);
color: var(--danger);
opacity: 1;
}
/* ===== Diary — nested meal groups ===== */
.eetmoment-meal-group {
background: var(--primary-lighter);
@ -3503,7 +3479,6 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
</div>
<div style="display:flex;align-items:center;gap:2px;">
<span class="eetmoment-kh">${roundedKh > 0 ? formatKh(roundedKh) + ' g' : '—'}</span>
${items.length > 0 ? `<button class="eetmoment-clear-btn" data-moment="${moment.id}" title="Eetmoment legen" aria-label="Eetmoment legen"><i class="fas fa-broom"></i></button>` : ''}
<span style="font-size:0.8rem;color:var(--text-muted)">${items.length > 0 ? '<i class="fas fa-chevron-down"></i>' : ''}</span>
</div>
</div>
@ -3512,13 +3487,10 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
<div class="eetmoment-add-btn" data-moment="${moment.id}">
<span>+</span> Voedingsmiddel toevoegen
</div>
${items.length > 0 ? `
${items.length > 1 ? `
<div class="save-meal-footer" data-moment="${moment.id}">
<button class="save-meal-footer-btn" data-moment="${moment.id}"${items.length > 1 ? ' style="display:none"' : ''}>
${items.length > 1
? `<i class="fas fa-star"></i> Selecteer ${items.length} items`
: `<i class="fas fa-star"></i> Opslaan als maaltijd`
}
<button class="save-meal-footer-btn" data-moment="${moment.id}" style="display:none">
<i class="fas fa-star"></i> Selecteer ${items.length} items
</button>
<button class="delete-selected-footer-btn hidden" data-moment="${moment.id}">
<i class="fas fa-trash"></i> Verwijder geselecteerde
@ -3642,25 +3614,6 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
});
});
// Clear eetmoment button
listEl.querySelectorAll('.eetmoment-clear-btn').forEach(btn => {
btn.addEventListener('click', async (e) => {
e.stopPropagation();
const momentId = btn.dataset.moment;
const dayData = getOrCreateDay(activeDate);
const items = dayData[momentId] || [];
if (items.length === 0) return;
const confirmed = await confirmAction({
message: `Weet je zeker dat je alle ${items.length} ${items.length === 1 ? 'item' : 'items'} uit dit eetmoment wilt verwijderen?`
});
if (!confirmed) return;
dayData[momentId] = [];
saveToStorage();
renderDagboek();
showToast('Eetmoment geleegd');
});
});
// Meal group toggle expand/collapse
listEl.querySelectorAll('.meal-group-header').forEach(header => {
header.addEventListener('click', (e) => {

View file

@ -203,6 +203,37 @@ test.describe('Karby Eetdagboek', () => {
// Item toevoegen via addMealSubmit → sluit modal + gaat naar dagboek
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Add a second item (meal requires 2+ ingredients)
await page.locator('#navZoeken').click();
await page.waitForTimeout(300);
await page.locator('.search-input').fill('kaas');
await page.waitForTimeout(800);
await page.locator('.food-item').first().click();
await page.waitForTimeout(500);
await page.locator('#detailAddBtn').click();
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Add a second item (meal requires 2+ ingredients)
await page.locator('#navZoeken').click();
await page.waitForTimeout(300);
await page.locator('.search-input').fill('kaas');
await page.waitForTimeout(800);
await page.locator('.food-item').first().click();
await page.waitForTimeout(500);
await page.locator('#detailAddBtn').click();
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Check 2 items and show save button via evaluate
await page.evaluate(() => {
const cbs = document.querySelectorAll('.item-checkbox');
if (cbs[0]) cbs[0].checked = true;
if (cbs[1]) cbs[1].checked = true;
const btn = document.querySelector('.save-meal-footer-btn');
if (btn) { btn.style.display = ''; btn.textContent = '⭐ Opslaan 2 items als maaltijd'; }
});
await page.waitForTimeout(300);
const saveBtn = page.locator('.save-meal-footer-btn');
await expect(saveBtn.first()).toBeVisible({ timeout: 5000 });
await saveBtn.first().click();
@ -225,6 +256,26 @@ test.describe('Karby Eetdagboek', () => {
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Add a second item (meal requires 2+ ingredients)
await page.locator('#navZoeken').click();
await page.waitForTimeout(300);
await page.locator('.search-input').fill('kaas');
await page.waitForTimeout(800);
await page.locator('.food-item').first().click();
await page.waitForTimeout(500);
await page.locator('#detailAddBtn').click();
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Check 2 items and show save button via evaluate
await page.evaluate(() => {
const cbs = document.querySelectorAll('.item-checkbox');
if (cbs[0]) cbs[0].checked = true;
if (cbs[1]) cbs[1].checked = true;
const btn = document.querySelector('.save-meal-footer-btn');
if (btn) { btn.style.display = ''; btn.textContent = '⭐ Opslaan 2 items als maaltijd'; }
});
await page.waitForTimeout(300);
const saveBtn = page.locator('.save-meal-footer-btn');
await expect(saveBtn.first()).toBeVisible({ timeout: 5000 });
await saveBtn.first().click();
@ -302,6 +353,37 @@ test.describe('Karby Eetdagboek', () => {
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Add a second item (meal requires 2+ ingredients)
await page.locator('#navZoeken').click();
await page.waitForTimeout(300);
await page.locator('.search-input').fill('kaas');
await page.waitForTimeout(800);
await page.locator('.food-item').first().click();
await page.waitForTimeout(500);
await page.locator('#detailAddBtn').click();
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Add a second item (meal requires 2+ ingredients)
await page.locator('#navZoeken').click();
await page.waitForTimeout(300);
await page.locator('.search-input').fill('kaas');
await page.waitForTimeout(800);
await page.locator('.food-item').first().click();
await page.waitForTimeout(500);
await page.locator('#detailAddBtn').click();
await page.waitForTimeout(500);
await page.locator('#addMealSubmit').click();
await page.waitForTimeout(800);
// Check 2 items and show save button via evaluate
await page.evaluate(() => {
const cbs = document.querySelectorAll('.item-checkbox');
if (cbs[0]) cbs[0].checked = true;
if (cbs[1]) cbs[1].checked = true;
const btn = document.querySelector('.save-meal-footer-btn');
if (btn) { btn.style.display = ''; btn.textContent = '⭐ Opslaan 2 items als maaltijd'; }
});
await page.waitForTimeout(300);
// Stap 2: Sla op als maaltijd
const saveBtn = page.locator('.save-meal-footer-btn');
await expect(saveBtn.first()).toBeVisible({ timeout: 5000 });