bpb-website/admin.js
chris 72e9de96e4 feat: Containerize application with Docker and improve admin error handling
This commit introduces Docker support for the application to ensure a consistent
and reproducible environment across different deployment targets.

- Added  for building a Docker image of the application.
- Added  to exclude unnecessary files from the Docker image.
- Improved error handling in  to provide more descriptive messages
  when the server returns an unexpected response, aiding in debugging.
- Included  changes, likely from local testing.
2025-11-13 11:31:58 -05:00

120 lines
4.6 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
const scrollingMessageInput = document.getElementById('scrolling-message');
const isClosedCheckbox = document.getElementById('is-closed-checkbox');
const closedMessageField = document.getElementById('closed-message-field');
const closedMessageTextarea = document.getElementById('closed-message');
const passwordInput = document.getElementById('password');
const saveButton = document.getElementById('save-button');
const spinner = document.getElementById('spinner');
const feedbackMessage = document.getElementById('feedback-message');
let initialData = {};
// --- UI Logic ---
isClosedCheckbox.addEventListener('change', () => {
closedMessageField.style.display = isClosedCheckbox.checked ? 'block' : 'none';
});
function checkForChanges() {
const currentData = {
message: scrollingMessageInput.value,
isClosed: isClosedCheckbox.checked,
closedMessage: closedMessageTextarea.value
};
const hasChanged = JSON.stringify(initialData) !== JSON.stringify(currentData);
saveButton.disabled = !hasChanged;
}
[scrollingMessageInput, isClosedCheckbox, closedMessageTextarea].forEach(el => {
el.addEventListener('input', checkForChanges);
el.addEventListener('change', checkForChanges);
});
// --- Data Handling ---
function loadInitialData() {
fetch('update.json')
.then(response => response.json())
.then(data => {
const update = data[0];
initialData = { ...update }; // Store initial state
scrollingMessageInput.value = update.message;
isClosedCheckbox.checked = update.isClosed;
closedMessageTextarea.value = update.closedMessage;
isClosedCheckbox.dispatchEvent(new Event('change'));
saveButton.disabled = true; // Start with button disabled
})
.catch(error => {
console.error('Error loading initial data:', error);
showFeedback('Error loading current status. Please check the console.', 'is-danger');
});
}
function showFeedback(message, type) {
feedbackMessage.textContent = message;
feedbackMessage.className = `notification ${type}`;
feedbackMessage.classList.remove('is-hidden');
setTimeout(() => {
feedbackMessage.classList.add('is-hidden');
}, 5000);
}
saveButton.addEventListener('click', () => {
const password = passwordInput.value;
if (!password) {
showFeedback('Please enter the password to save changes.', 'is-warning');
return;
}
// Show loading state
saveButton.disabled = true;
spinner.style.display = 'inline-block';
const newUpdateData = [
{
message: scrollingMessageInput.value,
isClosed: isClosedCheckbox.checked,
closedMessage: closedMessageTextarea.value
}
];
fetch('/api/update-status', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ password: password, data: newUpdateData }),
})
.then(response => {
const contentType = response.headers.get('content-type');
if (response.ok && contentType && contentType.includes('application/json')) {
return response.json();
}
return response.text().then(text => {
throw new Error(`Server response was not OK or not JSON. Status: ${response.status}. Body: ${text}`);
});
})
.then(result => {
if (result.success) {
showFeedback('Success! The store status has been updated.', 'is-success');
initialData = { ...newUpdateData[0] }; // Update initial state to current
passwordInput.value = ''; // Clear password field
} else {
showFeedback(`Error: ${result.message}`, 'is-danger');
}
})
.catch(error => {
console.error('Error sending update:', error);
showFeedback(error.message, 'is-danger');
})
.finally(() => {
// Hide loading state
spinner.style.display = 'none';
// Re-enable button only if there are still changes (e.g. if save failed)
checkForChanges();
});
});
// Load the data when the page loads
loadInitialData();
});