diff --git a/docker/index.html b/docker/index.html
index 93ef9b8..425014d 100644
--- a/docker/index.html
+++ b/docker/index.html
@@ -1304,6 +1304,83 @@ body {
border-color: var(--border);
}
+/* Bulk delete button in footer */
+.bulk-delete-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ width: 100%;
+ padding: 10px 14px;
+ font-size: var(--font-sm);
+ color: var(--danger);
+ cursor: pointer;
+ border: 1px solid var(--danger);
+ border-radius: var(--radius-xs);
+ background: transparent;
+ margin-top: 6px;
+ transition: background 0.15s;
+}
+.bulk-delete-btn:hover {
+ background: var(--danger);
+ color: var(--white);
+}
+
+/* ===== Diary — nested meal groups ===== */
+.delete-selected-footer-btn {
+ display: block;
+ width: 100%;
+ padding: 10px 16px;
+ margin-top: 6px;
+ background: var(--danger-light);
+ border: 1px solid var(--danger);
+ border-radius: var(--radius-sm);
+ color: var(--danger);
+ font-size: var(--font-sm);
+ font-weight: 600;
+ cursor: pointer;
+ transition: background 0.15s, opacity 0.15s;
+ text-align: center;
+ font-family: var(--body-font);
+ min-height: var(--touch-min);
+ line-height: 1.3;
+}
+.delete-selected-footer-btn:hover {
+ background: var(--danger);
+ color: var(--white);
+}
+.delete-selected-footer-btn:active {
+ background: #B71C1C;
+ color: var(--white);
+}
+.delete-selected-footer-btn.hidden {
+ 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);
@@ -1365,6 +1442,15 @@ body {
align-items: center;
gap: 4px;
}
+.eetmoment-meal-item .portion-badge {
+ background: var(--white);
+ border-color: var(--border);
+ color: var(--text);
+}
+.eetmoment-meal-item .portion-badge:hover {
+ background: var(--white);
+ border-color: var(--primary);
+}
.eetmoment-meal-item .eetmoment-item-kh {
font-size: var(--font-sm);
font-weight: 700;
@@ -3415,8 +3501,11 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
${moment.icon}
${moment.name}
- ${roundedKh > 0 ? formatKh(roundedKh) + ' g' : '—'}
- ${items.length > 0 ? '' : ''}
+
+ ${roundedKh > 0 ? formatKh(roundedKh) + ' g' : '—'}
+ ${items.length > 0 ? `` : ''}
+ ${items.length > 0 ? '' : ''}
+
${items.length > 0 ? `` : ''}
${inlineGlucoseHtml}
@@ -3425,12 +3514,15 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
${items.length > 0 ? `
` : ''}
`;
@@ -3501,26 +3593,74 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
});
});
- // Checkbox change → update save button text
+ // Checkbox change → update save/delete button state
listEl.querySelectorAll('.item-checkbox').forEach(cb => {
cb.addEventListener('change', () => {
const card = cb.closest('.eetmoment-card');
if (!card) return;
const footer = card.querySelector('.save-meal-footer');
if (!footer) return;
- const btn = footer.querySelector('.save-meal-footer-btn');
+ const saveBtn = footer.querySelector('.save-meal-footer-btn');
+ const delBtn = footer.querySelector('.delete-selected-footer-btn');
const checked = card.querySelectorAll('.item-checkbox:checked').length;
const total = card.querySelectorAll('.item-checkbox').length;
if (checked === 0) {
- btn.disabled = true;
- btn.textContent = '⭐ Selecteer ' + total + ' items';
+ saveBtn.disabled = true;
+ saveBtn.innerHTML = ` Selecteer ${total} items`;
+ if (delBtn) delBtn.classList.add('hidden');
} else {
- btn.disabled = false;
- btn.textContent = '⭐ Opslaan ' + checked + ' ' + (checked === 1 ? 'item' : 'items') + ' als maaltijd';
+ saveBtn.disabled = false;
+ saveBtn.innerHTML = ` Opslaan ${checked} ${checked === 1 ? 'item' : 'items'} als maaltijd`;
+ if (delBtn) delBtn.classList.remove('hidden');
}
});
});
+ // Delete selected items button
+ listEl.querySelectorAll('.delete-selected-footer-btn').forEach(btn => {
+ btn.addEventListener('click', async (e) => {
+ e.stopPropagation();
+ const momentId = btn.dataset.moment;
+ const card = btn.closest('.eetmoment-card');
+ if (!card) return;
+ const checked = card.querySelectorAll('.item-checkbox:checked');
+ const count = checked.length;
+ if (count === 0) return;
+ const confirmed = await confirmAction({
+ message: `Weet je zeker dat je ${count} geselecteerde ${count === 1 ? 'item' : 'items'} wilt verwijderen?`
+ });
+ if (!confirmed) return;
+ // Collect indices in reverse order to avoid index shift during splice
+ const indices = Array.from(checked).map(cb => parseInt(cb.dataset.index)).sort((a, b) => b - a);
+ const dayData = getOrCreateDay(activeDate);
+ indices.forEach(idx => {
+ dayData[momentId].splice(idx, 1);
+ });
+ saveToStorage();
+ renderDagboek();
+ showToast(`${count} ${count === 1 ? 'item verwijderd' : 'items verwijderd'}`);
+ });
+ });
+
+ // 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) => {
@@ -3759,16 +3899,55 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
renderDagboek();
}
- function removeFromMeal(dateStr, momentId, index) {
+ // 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 = `
+
+
+
+
${title}
+
${message}
+
+
+
+
+
+
+ `;
+ 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]) {
- const removed = day[momentId].splice(index, 1)[0];
+ const target = day[momentId][index];
+ if (!target) return;
+ const name = target.type === 'meal' ? target.mealNaam : target.item.naam;
+ const confirmed = await confirmAction({
+ message: `Weet je zeker dat je "${name}" wilt verwijderen?`
+ });
+ if (!confirmed) return;
+ day[momentId].splice(index, 1);
saveToStorage();
renderDagboek();
- if (removed) {
- const name = removed.type === 'meal' ? removed.mealNaam : removed.item.naam;
- showToast('"' + name + '" verwijderd');
- }
+ showToast('"' + name + '" verwijderd');
}
}
@@ -3776,20 +3955,25 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
* Remove a single item from within a meal group in the diary.
* If the last item is removed, removes the entire meal group.
*/
- function removeMealItemFromDiary(dateStr, momentId, entryIdx, mi) {
+ async function removeMealItemFromDiary(dateStr, momentId, entryIdx, mi) {
const day = dagboek[dateStr];
if (!day || !day[momentId]) return;
const entry = day[momentId][entryIdx];
if (!entry || entry.type !== 'meal') return;
- const removed = entry.items.splice(mi, 1)[0];
- if (!removed) return;
+ const item = entry.items[mi];
+ if (!item) return;
+ const confirmed = await confirmAction({
+ message: `Weet je zeker dat je "${item.item.naam}" wilt verwijderen uit deze maaltijd?`
+ });
+ if (!confirmed) return;
+ entry.items.splice(mi, 1);
// If last item — remove the whole meal group entry
if (entry.items.length === 0) {
day[momentId].splice(entryIdx, 1);
}
saveToStorage();
renderDagboek();
- showToast('"' + removed.item.naam + '" verwijderd uit maaltijd');
+ showToast('"' + item.item.naam + '" verwijderd uit maaltijd');
}
/** Show portion edit dialog for a diary item — with eenmalig/permanent choice for meal items */
@@ -4501,17 +4685,19 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
});
listEl.querySelectorAll('.meal-card-delete').forEach(btn => {
- btn.addEventListener('click', (e) => {
+ btn.addEventListener('click', async (e) => {
e.stopPropagation();
const idx = parseInt(btn.dataset.idx);
const meal = maaltijden[idx];
- showConfirmModal('Maaltijd verwijderen',
- 'Weet je zeker dat je "' + meal.naam + '" wilt verwijderen?',
- () => {
- maaltijden.splice(idx, 1);
- saveMaaltijden();
- renderMaaltijden();
- });
+ 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();
+ renderMaaltijden();
});
});
@@ -4759,6 +4945,47 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
}, 2000);
}
+ /**
+ * Show a confirmation dialog with Ja/Nee buttons.
+ * @param {string} title - Dialog title (default: 'Weet je het zeker?')
+ * @param {string} message - Description of what will be deleted
+ * @param {string} confirmText - Text for confirm button (default: 'Ja, verwijderen')
+ * @returns {Promise} true if confirmed, false if cancelled
+ */
+ function confirmAction({ title = 'Weet je het zeker?', message = '', confirmText = 'Ja, verwijderen' } = {}) {
+ return new Promise(resolve => {
+ const overlay = document.createElement('div');
+ overlay.className = 'modal-overlay';
+ overlay.style.zIndex = '500';
+ overlay.innerHTML = `
+
+
+
+
+
${escapeHtml(message)}
+
+
+
+
+
+
+ `;
+ document.body.appendChild(overlay);
+
+ const close = () => {
+ overlay.classList.add('closing');
+ setTimeout(() => overlay.remove(), 250);
+ };
+
+ overlay.querySelector('#confirmNo').addEventListener('click', () => { close(); resolve(false); });
+ overlay.querySelector('#confirmYes').addEventListener('click', () => { close(); resolve(true); });
+ overlay.addEventListener('click', (e) => { if (e.target === overlay) { close(); resolve(false); } });
+ });
+ }
+
+ /** @deprecated Use confirmAction() instead */
function showConfirmModal(title, message, onConfirm) {
const overlay = document.createElement('div');
overlay.className = 'modal-overlay';
diff --git a/index.html b/index.html
index 93ef9b8..425014d 100644
--- a/index.html
+++ b/index.html
@@ -1304,6 +1304,83 @@ body {
border-color: var(--border);
}
+/* Bulk delete button in footer */
+.bulk-delete-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ width: 100%;
+ padding: 10px 14px;
+ font-size: var(--font-sm);
+ color: var(--danger);
+ cursor: pointer;
+ border: 1px solid var(--danger);
+ border-radius: var(--radius-xs);
+ background: transparent;
+ margin-top: 6px;
+ transition: background 0.15s;
+}
+.bulk-delete-btn:hover {
+ background: var(--danger);
+ color: var(--white);
+}
+
+/* ===== Diary — nested meal groups ===== */
+.delete-selected-footer-btn {
+ display: block;
+ width: 100%;
+ padding: 10px 16px;
+ margin-top: 6px;
+ background: var(--danger-light);
+ border: 1px solid var(--danger);
+ border-radius: var(--radius-sm);
+ color: var(--danger);
+ font-size: var(--font-sm);
+ font-weight: 600;
+ cursor: pointer;
+ transition: background 0.15s, opacity 0.15s;
+ text-align: center;
+ font-family: var(--body-font);
+ min-height: var(--touch-min);
+ line-height: 1.3;
+}
+.delete-selected-footer-btn:hover {
+ background: var(--danger);
+ color: var(--white);
+}
+.delete-selected-footer-btn:active {
+ background: #B71C1C;
+ color: var(--white);
+}
+.delete-selected-footer-btn.hidden {
+ 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);
@@ -1365,6 +1442,15 @@ body {
align-items: center;
gap: 4px;
}
+.eetmoment-meal-item .portion-badge {
+ background: var(--white);
+ border-color: var(--border);
+ color: var(--text);
+}
+.eetmoment-meal-item .portion-badge:hover {
+ background: var(--white);
+ border-color: var(--primary);
+}
.eetmoment-meal-item .eetmoment-item-kh {
font-size: var(--font-sm);
font-weight: 700;
@@ -3415,8 +3501,11 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
${moment.icon}
${moment.name}
- ${roundedKh > 0 ? formatKh(roundedKh) + ' g' : '—'}
- ${items.length > 0 ? '' : ''}
+
+ ${roundedKh > 0 ? formatKh(roundedKh) + ' g' : '—'}
+ ${items.length > 0 ? `` : ''}
+ ${items.length > 0 ? '' : ''}
+
${items.length > 0 ? `` : ''}
${inlineGlucoseHtml}
@@ -3425,12 +3514,15 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
${items.length > 0 ? `
` : ''}
`;
@@ -3501,26 +3593,74 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
});
});
- // Checkbox change → update save button text
+ // Checkbox change → update save/delete button state
listEl.querySelectorAll('.item-checkbox').forEach(cb => {
cb.addEventListener('change', () => {
const card = cb.closest('.eetmoment-card');
if (!card) return;
const footer = card.querySelector('.save-meal-footer');
if (!footer) return;
- const btn = footer.querySelector('.save-meal-footer-btn');
+ const saveBtn = footer.querySelector('.save-meal-footer-btn');
+ const delBtn = footer.querySelector('.delete-selected-footer-btn');
const checked = card.querySelectorAll('.item-checkbox:checked').length;
const total = card.querySelectorAll('.item-checkbox').length;
if (checked === 0) {
- btn.disabled = true;
- btn.textContent = '⭐ Selecteer ' + total + ' items';
+ saveBtn.disabled = true;
+ saveBtn.innerHTML = ` Selecteer ${total} items`;
+ if (delBtn) delBtn.classList.add('hidden');
} else {
- btn.disabled = false;
- btn.textContent = '⭐ Opslaan ' + checked + ' ' + (checked === 1 ? 'item' : 'items') + ' als maaltijd';
+ saveBtn.disabled = false;
+ saveBtn.innerHTML = ` Opslaan ${checked} ${checked === 1 ? 'item' : 'items'} als maaltijd`;
+ if (delBtn) delBtn.classList.remove('hidden');
}
});
});
+ // Delete selected items button
+ listEl.querySelectorAll('.delete-selected-footer-btn').forEach(btn => {
+ btn.addEventListener('click', async (e) => {
+ e.stopPropagation();
+ const momentId = btn.dataset.moment;
+ const card = btn.closest('.eetmoment-card');
+ if (!card) return;
+ const checked = card.querySelectorAll('.item-checkbox:checked');
+ const count = checked.length;
+ if (count === 0) return;
+ const confirmed = await confirmAction({
+ message: `Weet je zeker dat je ${count} geselecteerde ${count === 1 ? 'item' : 'items'} wilt verwijderen?`
+ });
+ if (!confirmed) return;
+ // Collect indices in reverse order to avoid index shift during splice
+ const indices = Array.from(checked).map(cb => parseInt(cb.dataset.index)).sort((a, b) => b - a);
+ const dayData = getOrCreateDay(activeDate);
+ indices.forEach(idx => {
+ dayData[momentId].splice(idx, 1);
+ });
+ saveToStorage();
+ renderDagboek();
+ showToast(`${count} ${count === 1 ? 'item verwijderd' : 'items verwijderd'}`);
+ });
+ });
+
+ // 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) => {
@@ -3759,16 +3899,55 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
renderDagboek();
}
- function removeFromMeal(dateStr, momentId, index) {
+ // 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 = `
+
+
+
+
${title}
+
${message}
+
+
+
+
+
+
+ `;
+ 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]) {
- const removed = day[momentId].splice(index, 1)[0];
+ const target = day[momentId][index];
+ if (!target) return;
+ const name = target.type === 'meal' ? target.mealNaam : target.item.naam;
+ const confirmed = await confirmAction({
+ message: `Weet je zeker dat je "${name}" wilt verwijderen?`
+ });
+ if (!confirmed) return;
+ day[momentId].splice(index, 1);
saveToStorage();
renderDagboek();
- if (removed) {
- const name = removed.type === 'meal' ? removed.mealNaam : removed.item.naam;
- showToast('"' + name + '" verwijderd');
- }
+ showToast('"' + name + '" verwijderd');
}
}
@@ -3776,20 +3955,25 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
* Remove a single item from within a meal group in the diary.
* If the last item is removed, removes the entire meal group.
*/
- function removeMealItemFromDiary(dateStr, momentId, entryIdx, mi) {
+ async function removeMealItemFromDiary(dateStr, momentId, entryIdx, mi) {
const day = dagboek[dateStr];
if (!day || !day[momentId]) return;
const entry = day[momentId][entryIdx];
if (!entry || entry.type !== 'meal') return;
- const removed = entry.items.splice(mi, 1)[0];
- if (!removed) return;
+ const item = entry.items[mi];
+ if (!item) return;
+ const confirmed = await confirmAction({
+ message: `Weet je zeker dat je "${item.item.naam}" wilt verwijderen uit deze maaltijd?`
+ });
+ if (!confirmed) return;
+ entry.items.splice(mi, 1);
// If last item — remove the whole meal group entry
if (entry.items.length === 0) {
day[momentId].splice(entryIdx, 1);
}
saveToStorage();
renderDagboek();
- showToast('"' + removed.item.naam + '" verwijderd uit maaltijd');
+ showToast('"' + item.item.naam + '" verwijderd uit maaltijd');
}
/** Show portion edit dialog for a diary item — with eenmalig/permanent choice for meal items */
@@ -4501,17 +4685,19 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
});
listEl.querySelectorAll('.meal-card-delete').forEach(btn => {
- btn.addEventListener('click', (e) => {
+ btn.addEventListener('click', async (e) => {
e.stopPropagation();
const idx = parseInt(btn.dataset.idx);
const meal = maaltijden[idx];
- showConfirmModal('Maaltijd verwijderen',
- 'Weet je zeker dat je "' + meal.naam + '" wilt verwijderen?',
- () => {
- maaltijden.splice(idx, 1);
- saveMaaltijden();
- renderMaaltijden();
- });
+ 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();
+ renderMaaltijden();
});
});
@@ -4759,6 +4945,47 @@ button:active, .btn:active, .meal-card-main:active, .dagboek-item:active, .food-
}, 2000);
}
+ /**
+ * Show a confirmation dialog with Ja/Nee buttons.
+ * @param {string} title - Dialog title (default: 'Weet je het zeker?')
+ * @param {string} message - Description of what will be deleted
+ * @param {string} confirmText - Text for confirm button (default: 'Ja, verwijderen')
+ * @returns {Promise} true if confirmed, false if cancelled
+ */
+ function confirmAction({ title = 'Weet je het zeker?', message = '', confirmText = 'Ja, verwijderen' } = {}) {
+ return new Promise(resolve => {
+ const overlay = document.createElement('div');
+ overlay.className = 'modal-overlay';
+ overlay.style.zIndex = '500';
+ overlay.innerHTML = `
+
+
+
+
+
${escapeHtml(message)}
+
+
+
+
+
+
+ `;
+ document.body.appendChild(overlay);
+
+ const close = () => {
+ overlay.classList.add('closing');
+ setTimeout(() => overlay.remove(), 250);
+ };
+
+ overlay.querySelector('#confirmNo').addEventListener('click', () => { close(); resolve(false); });
+ overlay.querySelector('#confirmYes').addEventListener('click', () => { close(); resolve(true); });
+ overlay.addEventListener('click', (e) => { if (e.target === overlay) { close(); resolve(false); } });
+ });
+ }
+
+ /** @deprecated Use confirmAction() instead */
function showConfirmModal(title, message, onConfirm) {
const overlay = document.createElement('div');
overlay.className = 'modal-overlay';