Add delete confirmation modal with preview
This commit is contained in:
@@ -98,6 +98,8 @@ const translations = {
|
|||||||
|
|
||||||
"modal.editTitle": "Edit game",
|
"modal.editTitle": "Edit game",
|
||||||
"modal.addTitle": "Suggest a game",
|
"modal.addTitle": "Suggest a game",
|
||||||
|
"modal.confirmDeleteTitle": "Are you sure?",
|
||||||
|
"modal.confirmDelete": "Confirm delete",
|
||||||
"modal.save": "Save changes",
|
"modal.save": "Save changes",
|
||||||
"modal.cancel": "Cancel",
|
"modal.cancel": "Cancel",
|
||||||
"modal.close": "Close",
|
"modal.close": "Close",
|
||||||
@@ -203,6 +205,8 @@ const translations = {
|
|||||||
|
|
||||||
"modal.editTitle": "Spiel bearbeiten",
|
"modal.editTitle": "Spiel bearbeiten",
|
||||||
"modal.addTitle": "Spiel vorschlagen",
|
"modal.addTitle": "Spiel vorschlagen",
|
||||||
|
"modal.confirmDeleteTitle": "Bist du sicher?",
|
||||||
|
"modal.confirmDelete": "Löschen bestätigen",
|
||||||
"modal.save": "Änderungen speichern",
|
"modal.save": "Änderungen speichern",
|
||||||
"modal.cancel": "Abbrechen",
|
"modal.cancel": "Abbrechen",
|
||||||
"modal.close": "Schließen",
|
"modal.close": "Schließen",
|
||||||
|
|||||||
@@ -353,13 +353,7 @@ export function buildCard(
|
|||||||
if (allowDelete) {
|
if (allowDelete) {
|
||||||
const del = card.querySelector("[data-delete]");
|
const del = card.querySelector("[data-delete]");
|
||||||
del.addEventListener("click", async () => {
|
del.addEventListener("click", async () => {
|
||||||
try {
|
openDeleteConfirmModal(s);
|
||||||
await api.deleteSuggestion(s.id);
|
|
||||||
toast(t("toast.suggestionDeleted"));
|
|
||||||
await window.loadSuggestData();
|
|
||||||
} catch (err) {
|
|
||||||
toast(err.message, true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return card;
|
return card;
|
||||||
@@ -596,6 +590,64 @@ function formatMyVote(score) {
|
|||||||
return `${score} ${scoreToEmoji(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 = `
|
||||||
|
<div class="edit-header">
|
||||||
|
<h3>${t("modal.confirmDeleteTitle")}</h3>
|
||||||
|
<button class="lightbox-close" aria-label="${t("modal.close")}">x</button>
|
||||||
|
</div>
|
||||||
|
<div class="edit-body delete-body"></div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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) {
|
function isValidImageUrl(url) {
|
||||||
if (!url) return true;
|
if (!url) return true;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -610,6 +610,14 @@ input[type="range"].full-slider::-moz-range-track {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
}
|
}
|
||||||
|
.edit-modal .delete-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.preview-card {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.panel-header {
|
.panel-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user