const EDITOR_CODE_KEY = 'boxEditorCode'; const editorCodeInput = document.getElementById('editor-code'); const loadButton = document.getElementById('load-boxes'); const saveButton = document.getElementById('save-boxes'); const editorForm = document.getElementById('editor-form'); const editorActions = document.getElementById('editor-actions'); const editorMessage = document.getElementById('editor-message'); editorCodeInput.value = localStorage.getItem(EDITOR_CODE_KEY) || ''; function setEditorMessage(message) { editorMessage.innerHTML = message; } function apiBase() { return `${window.location.protocol}//${window.location.host}/api/boxes`; } function boxCard(box, index) { const imageValue = box.image || ''; const preview = imageValue ? `${box.name || `Box ${index + 1}`} preview` : '
No picture
'; return `

${box.name || `Box ${index + 1}`}

${box.id || `box-${index + 1}`}
${preview}
`; } function bindPreviewListeners() { editorForm.querySelectorAll('.editor-image').forEach(input => { input.addEventListener('input', () => { const card = input.closest('.admin-box-card'); const oldPreview = card.querySelector('.admin-image-preview, .admin-image-placeholder'); const value = input.value.trim(); const replacement = document.createElement(value ? 'img' : 'div'); if (value) { replacement.className = 'admin-image-preview'; replacement.src = value; replacement.alt = `${card.querySelector('.editor-name').value || 'Box'} preview`; } else { replacement.className = 'admin-image-placeholder'; replacement.textContent = 'No picture'; } oldPreview.replaceWith(replacement); }); }); } function renderBoxes(boxes) { editorForm.innerHTML = boxes.map(boxCard).join(''); editorForm.style.display = 'grid'; editorActions.style.display = 'flex'; bindPreviewListeners(); } async function loadBoxes() { const code = editorCodeInput.value.trim(); localStorage.setItem(EDITOR_CODE_KEY, code); setEditorMessage('Loading boxes...'); const response = await fetch(apiBase()); const data = await response.json(); if (!data.success) { setEditorMessage(data.message || 'Could not load boxes.'); return; } renderBoxes(data.boxes); setEditorMessage(`Boxes loaded. You can also edit ${data.file} directly in the backend code.`); } function collectBoxes() { return Array.from(editorForm.querySelectorAll('.admin-box-card')).map((card, index) => ({ id: card.dataset.id || `box-${index + 1}`, name: card.querySelector('.editor-name').value.trim() || `Box ${index + 1}`, price: Number(card.querySelector('.editor-price').value || 0), image: card.querySelector('.editor-image').value.trim(), description: card.querySelector('.editor-description').value.trim(), })); } async function saveBoxes() { const code = editorCodeInput.value.trim(); if (!code) { setEditorMessage('Enter the editor code before saving.'); return; } localStorage.setItem(EDITOR_CODE_KEY, code); setEditorMessage('Saving boxes...'); const response = await fetch(apiBase(), { method: 'PUT', headers: { 'Content-Type': 'application/json', 'x-editor-code': code, }, body: JSON.stringify({ boxes: collectBoxes() }), }); const data = await response.json(); if (data.success) { renderBoxes(data.boxes); setEditorMessage(`Saved. The storefront is now reading from ${data.file}.`); } else { setEditorMessage(data.message || 'Save failed.'); } } loadButton.addEventListener('click', loadBoxes); saveButton.addEventListener('click', saveBoxes); if (editorCodeInput.value) { loadBoxes(); }