import { t } from "./i18n.js"; import { toast } from "./dom.js"; import { escapeHtml } from "./ui-utils.js"; export function openLightbox(url, title) { const overlay = document.createElement("div"); overlay.className = "lightbox"; const safeTitle = escapeHtml(title || ""); overlay.innerHTML = ` `; overlay.addEventListener("click", (e) => { if ( e.target.classList.contains("lightbox") || e.target.classList.contains("lightbox-close") ) { overlay.remove(); } }); document.body.appendChild(overlay); } export function openConfirmModal({ title, body, confirmLabel, cancelLabel = t("modal.cancel"), confirmClass = null, requirePassword = false, passwordLabel = t("auth.password"), onConfirm, }) { const overlay = document.createElement("div"); overlay.className = "edit-modal"; const panel = document.createElement("div"); panel.className = "edit-panel"; panel.innerHTML = `

${title}

${body}

`; const close = () => overlay.remove(); const actions = document.createElement("div"); actions.className = "stack horizontal confirm-actions"; const confirmBtn = document.createElement("button"); if (confirmClass) confirmBtn.className = confirmClass; confirmBtn.textContent = confirmLabel ?? t("modal.confirm"); confirmBtn.disabled = requirePassword; actions.append(confirmBtn); if (cancelLabel !== null && cancelLabel !== undefined) { const cancelBtn = document.createElement("button"); cancelBtn.className = "ghost"; cancelBtn.type = "button"; cancelBtn.textContent = cancelLabel; actions.append(cancelBtn); cancelBtn.addEventListener("click", close); } const bodyContainer = panel.querySelector(".edit-body"); let passwordInput = null; if (requirePassword && bodyContainer) { const field = document.createElement("label"); field.className = "stack"; const label = document.createElement("span"); label.className = "label"; label.textContent = passwordLabel; passwordInput = document.createElement("input"); passwordInput.type = "password"; passwordInput.autocomplete = "current-password"; field.append(label, passwordInput); bodyContainer.appendChild(field); passwordInput.addEventListener("input", () => { confirmBtn.disabled = !(passwordInput.value || "").trim(); }); } bodyContainer?.appendChild(actions); overlay.addEventListener("click", (e) => { if ( e.target.classList.contains("edit-modal") || e.target.classList.contains("lightbox-close") ) { close(); } }); confirmBtn.addEventListener("click", async () => { try { await onConfirm?.(close, { password: passwordInput?.value ?? "" }); } catch (err) { toast(err.message, true); } }); overlay.appendChild(panel); document.body.appendChild(overlay); } export function openResultsRelockModal() { openConfirmModal({ title: t("results.relockedTitle"), body: t("results.relockedBody"), confirmLabel: t("results.relockedConfirm"), cancelLabel: null, onConfirm: (close) => close(), }); } export function openSuggestionsChangedModal(names) { const uniq = Array.from(new Set(names)).filter(Boolean); if (uniq.length === 0) return; openConfirmModal({ title: t("vote.listUpdatedTitle"), body: t("vote.listUpdatedBody", { names: uniq.join(", ") }), confirmLabel: t("vote.listUpdatedConfirm"), cancelLabel: null, onConfirm: (close) => close(), }); }