// Pages Management JavaScript let pagesData = []; let pageModal; document.addEventListener("DOMContentLoaded", function () { pageModal = new bootstrap.Modal(document.getElementById("pageModal")); checkAuth().then((authenticated) => { if (authenticated) { loadPages(); } }); const urlParams = new URLSearchParams(window.location.search); if (urlParams.get("action") === "create") { showCreatePage(); } // Auto-generate slug from title document.getElementById("pageTitle")?.addEventListener("input", function () { if (!document.getElementById("pageId").value) { document.getElementById("pageSlug").value = slugify(this.value); } }); }); async function loadPages() { try { const response = await fetch("/api/admin/pages", { credentials: "include", }); const data = await response.json(); if (data.success) { pagesData = data.pages; renderPages(pagesData); } } catch (error) { console.error("Failed to load pages:", error); } } function renderPages(pages) { const tbody = document.getElementById("pagesTableBody"); if (pages.length === 0) { tbody.innerHTML = `

No custom pages found

`; return; } tbody.innerHTML = pages .map( (p) => ` ${p.id} ${escapeHtml(p.title)} ${escapeHtml(p.slug)} ${p.ispublished ? "Published" : "Draft"} ${formatDate(p.createdat)} ` ) .join(""); } function filterPages() { const searchTerm = document.getElementById("searchInput").value.toLowerCase(); const filtered = pagesData.filter( (p) => p.title.toLowerCase().includes(searchTerm) || p.slug.toLowerCase().includes(searchTerm) ); renderPages(filtered); } function showCreatePage() { document.getElementById("modalTitle").textContent = "Create Custom Page"; document.getElementById("pageForm").reset(); document.getElementById("pageId").value = ""; document.getElementById("pagePublished").checked = true; pageModal.show(); } async function editPage(id) { try { const response = await fetch(`/api/admin/pages/${id}`, { credentials: "include", }); const data = await response.json(); if (data.success) { const page = data.page; document.getElementById("modalTitle").textContent = "Edit Custom Page"; document.getElementById("pageId").value = page.id; document.getElementById("pageTitle").value = page.title; document.getElementById("pageSlug").value = page.slug; document.getElementById("pageContent").value = page.content || ""; document.getElementById("pageMetaTitle").value = page.metatitle || ""; document.getElementById("pageMetaDescription").value = page.metadescription || ""; document.getElementById("pagePublished").checked = page.ispublished; pageModal.show(); } } catch (error) { console.error("Failed to load page:", error); showError("Failed to load page details"); } } async function savePage() { const id = document.getElementById("pageId").value; const formData = { title: document.getElementById("pageTitle").value, slug: document.getElementById("pageSlug").value, content: document.getElementById("pageContent").value, metatitle: document.getElementById("pageMetaTitle").value, metadescription: document.getElementById("pageMetaDescription").value, ispublished: document.getElementById("pagePublished").checked, }; if (!formData.title || !formData.slug || !formData.content) { showError("Please fill in all required fields"); return; } try { const url = id ? `/api/admin/pages/${id}` : "/api/admin/pages"; const method = id ? "PUT" : "POST"; const response = await fetch(url, { method: method, headers: { "Content-Type": "application/json" }, credentials: "include", body: JSON.stringify(formData), }); const data = await response.json(); if (data.success) { showSuccess( id ? "Page updated successfully" : "Page created successfully" ); pageModal.hide(); loadPages(); } else { showError(data.message || "Failed to save page"); } } catch (error) { console.error("Failed to save page:", error); showError("Failed to save page"); } } async function deletePage(id, title) { if (!confirm(`Are you sure you want to delete "${title}"?`)) return; try { const response = await fetch(`/api/admin/pages/${id}`, { method: "DELETE", credentials: "include", }); const data = await response.json(); if (data.success) { showSuccess("Page deleted successfully"); loadPages(); } else { showError(data.message || "Failed to delete page"); } } catch (error) { console.error("Failed to delete page:", error); showError("Failed to delete page"); } } function slugify(text) { return text .toLowerCase() .replace(/[^\w\s-]/g, "") .replace(/[\s_-]+/g, "-") .replace(/^-+|-+$/g, ""); } async function logout() { try { const response = await fetch("/api/admin/logout", { method: "POST", credentials: "include", }); if (response.ok) window.location.href = "/admin/login.html"; } catch (error) { console.error("Logout failed:", error); } } function escapeHtml(text) { const map = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'", }; return text.replace(/[&<>"']/g, (m) => map[m]); } function formatDate(dateString) { return new Date(dateString).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }); } function showSuccess(message) { alert(message); } function showError(message) { alert("Error: " + message); }