diff --git a/wwwroot/js/i18n.js b/wwwroot/js/i18n.js
index 2fb592f..8e01ad2 100644
--- a/wwwroot/js/i18n.js
+++ b/wwwroot/js/i18n.js
@@ -98,6 +98,8 @@ const translations = {
"modal.editTitle": "Edit game",
"modal.addTitle": "Suggest a game",
+ "modal.confirmDeleteTitle": "Are you sure?",
+ "modal.confirmDelete": "Confirm delete",
"modal.save": "Save changes",
"modal.cancel": "Cancel",
"modal.close": "Close",
@@ -203,6 +205,8 @@ const translations = {
"modal.editTitle": "Spiel bearbeiten",
"modal.addTitle": "Spiel vorschlagen",
+ "modal.confirmDeleteTitle": "Bist du sicher?",
+ "modal.confirmDelete": "Löschen bestätigen",
"modal.save": "Änderungen speichern",
"modal.cancel": "Abbrechen",
"modal.close": "Schließen",
diff --git a/wwwroot/js/ui.js b/wwwroot/js/ui.js
index 4648abb..d0af2ee 100644
--- a/wwwroot/js/ui.js
+++ b/wwwroot/js/ui.js
@@ -353,13 +353,7 @@ export function buildCard(
if (allowDelete) {
const del = card.querySelector("[data-delete]");
del.addEventListener("click", async () => {
- try {
- await api.deleteSuggestion(s.id);
- toast(t("toast.suggestionDeleted"));
- await window.loadSuggestData();
- } catch (err) {
- toast(err.message, true);
- }
+ openDeleteConfirmModal(s);
});
}
return card;
@@ -596,6 +590,64 @@ function formatMyVote(score) {
return `${score} ${scoreToEmoji(score)}`;
}
+function openDeleteConfirmModal(s) {
+ const overlay = document.createElement("div");
+ overlay.className = "edit-modal";
+ const panel = document.createElement("div");
+ panel.className = "edit-panel";
+ panel.innerHTML = `
+
+
+ `;
+
+ const preview = buildCard(
+ { ...s, id: s.id }, // shallow copy to avoid mutations
+ { showAuthor: true, allowDelete: false, allowEdit: false },
+ );
+ preview.classList.add("preview-card");
+
+ const actions = document.createElement("div");
+ actions.className = "stack horizontal";
+ const confirmBtn = document.createElement("button");
+ confirmBtn.className = "danger";
+ confirmBtn.textContent = t("modal.confirmDelete");
+ const cancelBtn = document.createElement("button");
+ cancelBtn.type = "button";
+ cancelBtn.className = "ghost";
+ cancelBtn.textContent = t("modal.cancel");
+ actions.append(confirmBtn, cancelBtn);
+
+ const body = panel.querySelector(".delete-body");
+ body?.append(preview, actions);
+
+ const close = () => overlay.remove();
+ overlay.addEventListener("click", (e) => {
+ if (
+ e.target.classList.contains("edit-modal") ||
+ e.target.classList.contains("lightbox-close")
+ )
+ close();
+ });
+ cancelBtn.addEventListener("click", close);
+
+ confirmBtn.addEventListener("click", async () => {
+ try {
+ await api.deleteSuggestion(s.id);
+ toast(t("toast.suggestionDeleted"));
+ close();
+ await window.loadSuggestData();
+ } catch (err) {
+ toast(err.message, true);
+ }
+ });
+
+ overlay.appendChild(panel);
+ document.body.appendChild(overlay);
+}
+
function isValidImageUrl(url) {
if (!url) return true;
try {
diff --git a/wwwroot/styles.css b/wwwroot/styles.css
index b3e9f67..4012bda 100644
--- a/wwwroot/styles.css
+++ b/wwwroot/styles.css
@@ -610,6 +610,14 @@ input[type="range"].full-slider::-moz-range-track {
overflow: auto;
max-height: 70vh;
}
+.edit-modal .delete-body {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+.preview-card {
+ pointer-events: none;
+}
.panel-header {
display: flex;