Updates to documentation, fixes for edit buttons in map shifts, and CORS for local dev and access
This commit is contained in:
@@ -99,6 +99,26 @@
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
/* Editing State for Shifts */
|
||||
.shift-admin-item.editing {
|
||||
border: 2px solid #a02c8d;
|
||||
background-color: #f9f0f8;
|
||||
}
|
||||
|
||||
.shift-admin-item.editing::before {
|
||||
content: "EDITING";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
background: #a02c8d;
|
||||
color: white;
|
||||
padding: 2px 8px;
|
||||
font-size: 11px;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.shift-admin-item p {
|
||||
margin: 5px 0;
|
||||
color: var(--secondary-color);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
let adminMap = null;
|
||||
let startMarker = null;
|
||||
let storedQRCodes = {};
|
||||
let editingShiftId = null;
|
||||
|
||||
// Utility function to create a local date from YYYY-MM-DD string
|
||||
// This prevents timezone issues when displaying dates
|
||||
@@ -357,7 +358,13 @@ function setupEventListeners() {
|
||||
// Clear shift form button
|
||||
const clearShiftBtn = document.getElementById('clear-shift-form');
|
||||
if (clearShiftBtn) {
|
||||
clearShiftBtn.addEventListener('click', clearShiftForm);
|
||||
clearShiftBtn.addEventListener('click', function() {
|
||||
const wasEditing = editingShiftId !== null;
|
||||
clearShiftForm();
|
||||
if (wasEditing) {
|
||||
showStatus('Edit cancelled', 'info');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// User form submission
|
||||
@@ -1267,47 +1274,133 @@ async function deleteShift(shiftId) {
|
||||
}
|
||||
|
||||
// Update editShift function (remove window. prefix)
|
||||
function editShift(shiftId) {
|
||||
showStatus('Edit functionality coming soon', 'info');
|
||||
async function editShift(shiftId) {
|
||||
try {
|
||||
// Find the shift in the current data
|
||||
const response = await fetch('/api/shifts/admin');
|
||||
const data = await response.json();
|
||||
|
||||
if (!data.success) {
|
||||
showStatus('Failed to load shift data', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const shift = data.shifts.find(s => s.ID === parseInt(shiftId));
|
||||
if (!shift) {
|
||||
showStatus('Shift not found', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Set editing mode
|
||||
editingShiftId = shiftId;
|
||||
|
||||
// Populate the form
|
||||
document.getElementById('shift-title').value = shift.Title || '';
|
||||
document.getElementById('shift-description').value = shift.Description || '';
|
||||
document.getElementById('shift-date').value = shift.Date || '';
|
||||
document.getElementById('shift-start').value = shift['Start Time'] || '';
|
||||
document.getElementById('shift-end').value = shift['End Time'] || '';
|
||||
document.getElementById('shift-location').value = shift.Location || '';
|
||||
document.getElementById('shift-max-volunteers').value = shift['Max Volunteers'] || '';
|
||||
|
||||
// Update public checkbox if it exists
|
||||
const publicCheckbox = document.getElementById('shift-is-public');
|
||||
if (publicCheckbox) {
|
||||
publicCheckbox.checked = shift['Is Public'] !== false;
|
||||
}
|
||||
|
||||
// Change submit button text
|
||||
const submitBtn = document.querySelector('#shift-form button[type="submit"]');
|
||||
if (submitBtn) {
|
||||
submitBtn.textContent = 'Update Shift';
|
||||
}
|
||||
|
||||
// Remove editing class from any previous item
|
||||
document.querySelectorAll('.shift-admin-item.editing').forEach(el => {
|
||||
el.classList.remove('editing');
|
||||
});
|
||||
|
||||
// Add editing class to current item
|
||||
const shiftElement = document.querySelector(`[data-shift-id="${shiftId}"]`);
|
||||
if (shiftElement) {
|
||||
const shiftItem = shiftElement.closest('.shift-admin-item');
|
||||
if (shiftItem) {
|
||||
shiftItem.classList.add('editing');
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll to form
|
||||
document.getElementById('shift-form').scrollIntoView({ behavior: 'smooth' });
|
||||
|
||||
showStatus('Editing shift: ' + shift.Title, 'info');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading shift for edit:', error);
|
||||
showStatus('Failed to load shift for editing', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Add function to create shift
|
||||
async function createShift(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = {
|
||||
title: document.getElementById('shift-title').value,
|
||||
description: document.getElementById('shift-description').value,
|
||||
date: document.getElementById('shift-date').value,
|
||||
startTime: document.getElementById('shift-start').value,
|
||||
endTime: document.getElementById('shift-end').value,
|
||||
location: document.getElementById('shift-location').value,
|
||||
maxVolunteers: document.getElementById('shift-max-volunteers').value,
|
||||
isPublic: document.getElementById('shift-is-public')?.checked !== false
|
||||
const title = document.getElementById('shift-title').value;
|
||||
const description = document.getElementById('shift-description').value;
|
||||
const date = document.getElementById('shift-date').value;
|
||||
const startTime = document.getElementById('shift-start').value;
|
||||
const endTime = document.getElementById('shift-end').value;
|
||||
const location = document.getElementById('shift-location').value;
|
||||
const maxVolunteers = document.getElementById('shift-max-volunteers').value;
|
||||
|
||||
// Get public checkbox value
|
||||
const isPublic = document.getElementById('shift-is-public')?.checked ?? true;
|
||||
|
||||
const shiftData = {
|
||||
title,
|
||||
description,
|
||||
date,
|
||||
startTime,
|
||||
endTime,
|
||||
location,
|
||||
maxVolunteers: parseInt(maxVolunteers),
|
||||
isPublic
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/shifts/admin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(formData)
|
||||
});
|
||||
let response;
|
||||
if (editingShiftId) {
|
||||
// Update existing shift
|
||||
response = await fetch(`/api/shifts/admin/${editingShiftId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(shiftData)
|
||||
});
|
||||
} else {
|
||||
// Create new shift
|
||||
response = await fetch('/api/shifts/admin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(shiftData)
|
||||
});
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showStatus('Shift created successfully', 'success');
|
||||
document.getElementById('shift-form').reset();
|
||||
showStatus(editingShiftId ? 'Shift updated successfully' : 'Shift created successfully', 'success');
|
||||
clearShiftForm();
|
||||
await loadAdminShifts();
|
||||
console.log('Refreshed shifts list after creating new shift');
|
||||
console.log('Refreshed shifts list after saving shift');
|
||||
} else {
|
||||
showStatus(data.error || 'Failed to create shift', 'error');
|
||||
showStatus(data.error || 'Failed to save shift', 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating shift:', error);
|
||||
showStatus('Failed to create shift', 'error');
|
||||
console.error('Error saving shift:', error);
|
||||
showStatus('Failed to save shift', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1315,6 +1408,21 @@ function clearShiftForm() {
|
||||
const form = document.getElementById('shift-form');
|
||||
if (form) {
|
||||
form.reset();
|
||||
|
||||
// Reset editing state
|
||||
editingShiftId = null;
|
||||
|
||||
// Reset submit button text
|
||||
const submitBtn = document.querySelector('#shift-form button[type="submit"]');
|
||||
if (submitBtn) {
|
||||
submitBtn.textContent = 'Create Shift';
|
||||
}
|
||||
|
||||
// Remove editing class from any shift items
|
||||
document.querySelectorAll('.shift-admin-item.editing').forEach(el => {
|
||||
el.classList.remove('editing');
|
||||
});
|
||||
|
||||
showStatus('Form cleared', 'info');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user