index_html Products at a Glance

Products at a Glance

Add or Edit Product





--------------------- app_js let productData = JSON.parse(localStorage.getItem("productData") || "null") || {}; let editingKey = null; function init() { const stateSel = document.getElementById("stateSelect"); stateSel.innerHTML = ''; Object.keys(productData).forEach(state => { const opt = document.createElement("option"); opt.value = state; opt.textContent = state; stateSel.appendChild(opt); }); stateSel.addEventListener("change", () => { const categorySel = document.getElementById("categorySelect"); const state = stateSel.value; categorySel.innerHTML = ''; if (productData[state]) { Object.keys(productData[state]).forEach(cat => { const opt = document.createElement("option"); opt.value = cat; opt.textContent = cat; categorySel.appendChild(opt); }); } document.getElementById("itemSelectBox").innerHTML = ""; document.getElementById("horizontalDisplay").innerHTML = ""; }); document.getElementById("categorySelect").addEventListener("change", () => { const state = stateSel.value; const category = document.getElementById("categorySelect").value; const box = document.getElementById("itemSelectBox"); box.innerHTML = ""; if (productData[state] && productData[state][category]) { productData[state][category].forEach(prod => { const label = document.createElement("label"); const cb = document.createElement("input"); cb.type = "checkbox"; cb.value = prod.title; label.appendChild(cb); label.append(` ${prod.title}`); box.appendChild(label); }); } }); } function renderSelected() { const state = document.getElementById("stateSelect").value; const category = document.getElementById("categorySelect").value; const selected = Array.from(document.querySelectorAll("#itemSelectBox input:checked")).map(cb => cb.value); const display = document.getElementById("horizontalDisplay"); display.innerHTML = ""; if (productData[state] && productData[state][category]) { productData[state][category].filter(p => selected.includes(p.title)).forEach(product => { const div = document.createElement("div"); div.innerHTML = `

${product.title}

${product.content}
`; display.appendChild(div); }); } } function saveProduct() { const state = document.getElementById("stateEntry").value.trim() || document.getElementById("stateEntrySelect").value; const category = document.getElementById("categoryEntry").value.trim() || document.getElementById("categoryEntrySelect").value; const title = document.getElementById("productTitle").value.trim(); const content = document.getElementById("productContent").value.trim(); if (!state || !category || !title || !content) { alert("All fields required."); return; } if (!productData[state]) productData[state] = {}; if (!productData[state][category]) productData[state][category] = []; const list = productData[state][category]; const index = list.findIndex(p => p.title === title); if (index >= 0) { list[index].content = content; } else { list.push({ title, content }); } localStorage.setItem("productData", JSON.stringify(productData)); alert("Product saved."); editingKey = null; location.reload(); } function editProduct(state, category, title) { const product = productData[state][category].find(p => p.title === title); if (!product) return; document.getElementById("stateEntry").value = state; document.getElementById("categoryEntry").value = category; document.getElementById("productTitle").value = title; document.getElementById("productContent").value = product.content; editingKey = { state, category, title }; } document.addEventListener("DOMContentLoaded", init); window.exportDataToFile = function () { const content = `const seedData = ${JSON.stringify(productData, null, 2)}; if (!localStorage.getItem("productData")) { localStorage.setItem("productData", JSON.stringify(seedData)); }`; const blob = new Blob([content], { type: "application/javascript" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "product_data.js"; a.click(); URL.revokeObjectURL(url); document.getElementById("editorStatus").textContent = "Exported to JS file."; }; window.exportDataAsTxt = function () { const content = JSON.stringify(productData, null, 2); const blob = new Blob([content], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "product_data.txt"; a.click(); URL.revokeObjectURL(url); document.getElementById("editorStatus").textContent = "Exported to TXT file."; }; window.importDataFromFile = function (input) { const file = input.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function (e) { let text = e.target.result; try { if (text.trim().startsWith("const productData")) { text = text.replace(/const productData\s*=\s*/, "").replace(/;\s*$/, ""); } const parsed = JSON.parse(text); if (parsed && typeof parsed === "object") { productData = parsed; localStorage.setItem("productData", JSON.stringify(productData)); alert("Data imported successfully."); document.getElementById("editorStatus").textContent = "Import successful."; location.reload(); } else { alert("Invalid data format."); } } catch (err) { alert("Failed to import data."); } }; reader.readAsText(file); }; function populateEditorDropdowns() { const stateDropdown = document.getElementById("stateEntrySelect"); stateDropdown.innerHTML = ''; Object.keys(productData).forEach(state => { const opt = document.createElement("option"); opt.value = state; opt.textContent = state; stateDropdown.appendChild(opt); }); stateDropdown.addEventListener("change", () => { const selectedState = stateDropdown.value; const catDropdown = document.getElementById("categoryEntrySelect"); catDropdown.innerHTML = ''; if (productData[selectedState]) { Object.keys(productData[selectedState]).forEach(cat => { const opt = document.createElement("option"); opt.value = cat; opt.textContent = cat; catDropdown.appendChild(opt); }); } }); } document.addEventListener("DOMContentLoaded", () => { init(); populateEditorDropdowns(); }); function deleteProduct() { const state = document.getElementById("stateEntry").value.trim() || document.getElementById("stateEntrySelect").value; const category = document.getElementById("categoryEntry").value.trim() || document.getElementById("categoryEntrySelect").value; const title = document.getElementById("productTitle").value.trim(); if (!state || !category || !title) return alert("Provide state, category, and product title"); if (productData[state] && productData[state][category]) { productData[state][category] = productData[state][category].filter(p => p.title !== title); if (productData[state][category].length === 0) delete productData[state][category]; localStorage.setItem("productData", JSON.stringify(productData)); alert("Product deleted."); location.reload(); } } function deleteCategory() { const state = document.getElementById("stateEntry").value.trim() || document.getElementById("stateEntrySelect").value; const category = document.getElementById("categoryEntry").value.trim() || document.getElementById("categoryEntrySelect").value; if (!state || !category) return alert("Provide state and category"); if (confirm(`Delete category "${category}" from ${state}?`)) { if (productData[state]) { delete productData[state][category]; localStorage.setItem("productData", JSON.stringify(productData)); alert("Category deleted."); location.reload(); } } } function deleteState() { const state = document.getElementById("stateEntry").value.trim() || document.getElementById("stateEntrySelect").value; if (!state) return alert("Provide a state"); if (confirm(`Delete state "${state}" and all its contents?`)) { delete productData[state]; localStorage.setItem("productData", JSON.stringify(productData)); alert("State deleted."); location.reload(); } } --------------------- product_data_js const seedData = { "Arizona": { "Category 1": [{ "title": "Product A", "content": "

Info on Product A

" }] }, "Texas": { "Category 2": [{ "title": "Product B", "content": "

Details on Product B

" }] } }; if (!localStorage.getItem("productData")) { localStorage.setItem("productData", JSON.stringify(seedData)); } --------------------- styles_css body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 0; background-color: #f0f2f5; color: #333; } main.content { max-width: 1200px; margin: auto; padding: 40px; background: #ffffff; border-radius: 10px; box-shadow: 0 4px 10px rgba(0,0,0,0.05); } h1 { font-size: 32px; color: #1a1a2e; margin-bottom: 30px; } label { font-weight: bold; margin-top: 20px; display: block; } select { width: 100%; padding: 12px; font-size: 16px; margin-top: 6px; border: 1px solid #ccc; border-radius: 6px; margin-bottom: 20px; } .checkbox-group { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; } .checkbox-group label { background: #fefefe; padding: 10px 15px; border: 1px solid #ccc; border-radius: 6px; cursor: pointer; transition: all 0.2s ease; } .checkbox-group label:hover { background-color: #eef1f4; } button { background-color: #0066cc; color: white; padding: 12px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; transition: background-color 0.2s ease-in-out; margin-bottom: 30px; } button:hover { background-color: #004999; } .scroll-container { display: flex; overflow-x: auto; gap: 20px; padding: 20px; background-color: #fafafa; border: 1px solid #ddd; border-radius: 8px; } .scroll-container > div { flex: 0 0 auto; min-width: 250px; max-width: 500px; background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.05); border: 1px solid #e0e0e0; } .scroll-container h3 { margin-top: 0; color: #00509e; } #editorSection { background-color: #fdfdfd; border: 1px solid #ddd; border-radius: 8px; padding: 30px; margin-top: 50px; box-shadow: 0 2px 10px rgba(0,0,0,0.03); } #editorSection h2 { margin-bottom: 20px; color: #1a1a2e; } #editorForm label { font-weight: bold; margin-top: 15px; display: block; } #editorForm input[type="text"], #editorForm textarea, #editorForm select { width: 100%; padding: 12px; font-size: 14px; border: 1px solid #ccc; border-radius: 6px; margin-top: 6px; margin-bottom: 20px; } #editorForm button { margin-right: 10px; margin-top: 10px; } #saveItem { background-color: #28a745; } #saveItem:hover { background-color: #218838; } #deleteItem { background-color: #dc3545; } #deleteItem:hover { background-color: #c82333; } #exportJsButton { background-color: #007bff; } #exportJsButton:hover { background-color: #0069d9; } #exportTxtButton { background-color: #6f42c1; } #exportTxtButton:hover { background-color: #5936a2; } #fileInput { background-color: #ffcc00; font-weight: bold; } #fileInput:hover { background-color: #e0b800; }