Compare commits

...

4 Commits
v1.0.3 ... main

Author SHA1 Message Date
2ea5131739 Fix multiple buttons
All checks were successful
Docker Build and Publish / build (release) Successful in 6s
2025-02-01 11:23:58 -05:00
c10ac8669c Deletes work, tested on DWS
All checks were successful
Docker Build and Publish / build (release) Successful in 6s
2025-01-31 18:54:04 -05:00
682cdfa95c update listener model 2025-01-31 18:49:44 -05:00
0436d6e24a update app.py to provide nonce
All checks were successful
Docker Build and Publish / build (release) Successful in 6s
2025-01-31 18:41:44 -05:00
2 changed files with 41 additions and 31 deletions

1
app.py
View File

@ -331,6 +331,7 @@ def admin():
photos=photos, photos=photos,
accent_color=config["appearance"]["accent_color"], accent_color=config["appearance"]["accent_color"],
config=config, config=config,
nonce=g.csp_nonce,
) )
@app.route("/admin/logout") @app.route("/admin/logout")

View File

@ -203,8 +203,8 @@
<td class="editable" data-field="iso">{{ photo.iso }}</td> <td class="editable" data-field="iso">{{ photo.iso }}</td>
<td>{{ photo.width }}x{{ photo.height }}</td> <td>{{ photo.width }}x{{ photo.height }}</td>
<td> <td>
<button id="save-btn">Save</button> <button class="save-btn">Save</button>
<button class="delete-btn" id="delete-btn">Delete</button> <button class="delete-btn">Delete</button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -244,7 +244,7 @@
<label for="about.profile_image">Profile Image:</label> <label for="about.profile_image">Profile Image:</label>
<div style="display: flex; align-items: center; gap: 1rem;"> <div style="display: flex; align-items: center; gap: 1rem;">
<img id="profile-preview" src="/static/profile.jpeg" alt="Profile" style="width: 100px; height: 100px; object-fit: cover; border-radius: 50%;"> <img id="profile-preview" src="/static/profile.jpeg" alt="Profile" style="width: 100px; height: 100px; object-fit: cover; border-radius: 50%;">
<input type="file" id="profile_image_upload" accept="image/jpeg,image/png" style="flex: 1;"> <input type="file" class="profile-image-upload" accept="image/jpeg,image/png" style="flex: 1;">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -284,7 +284,8 @@
}); });
}); });
function saveChanges(button) { function saveChanges(event) {
const button = event.target;
const row = button.closest('tr'); const row = button.closest('tr');
const photoId = row.dataset.id; const photoId = row.dataset.id;
const updatedData = {}; const updatedData = {};
@ -314,8 +315,9 @@
}); });
} }
function deletePhoto(button) { function deletePhoto(event) {
if (confirm('Are you sure you want to delete this photo?')) { if (confirm('Are you sure you want to delete this photo?')) {
const button = event.target;
const row = button.closest('tr'); const row = button.closest('tr');
const photoId = row.dataset.id; const photoId = row.dataset.id;
@ -338,43 +340,50 @@
} }
} }
document.getElementById('delete-btn').addEventListener('click', deletePhoto); document.querySelectorAll('.delete-btn').forEach(button => {
document.getElementById('save-btn').addEventListener('click', saveChanges); button.addEventListener('click', (event) => deletePhoto(event));
});
document.getElementById('profile_image_upload').addEventListener('change', async (e) => { document.querySelectorAll('.save-btn').forEach(button => {
const file = e.target.files[0]; button.addEventListener('click', (event) => saveChanges(event));
if (!file) return; });
const formData = new FormData(); document.querySelectorAll('.profile-image-upload').forEach(input => {
formData.append('profile_image', file); input.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (!file) return;
try { const formData = new FormData();
const response = await fetch('/admin/upload_profile', { formData.append('profile_image', file);
method: 'POST',
body: formData try {
}); const response = await fetch('/admin/upload_profile', {
method: 'POST',
const result = await response.json(); body: formData
if (result.success) { });
document.getElementById('profile-preview').src = '/static/profile.jpeg?' + new Date().getTime();
} else { const result = await response.json();
alert('Error uploading profile image: ' + result.error); if (result.success) {
document.getElementById('profile-preview').src = '/static/profile.jpeg?' + new Date().getTime();
} else {
alert('Error uploading profile image: ' + result.error);
}
} catch (error) {
alert('Error uploading profile image: ' + error);
} }
} catch (error) { });
alert('Error uploading profile image: ' + error);
}
}); });
document.getElementById('configForm').addEventListener('submit', async (e) => { document.getElementById('configForm').addEventListener('submit', async (e) => {
e.preventDefault(); e.preventDefault();
const formData = {}; const formData = {};
const inputs = e.target.querySelectorAll('input:not([type="file"]), textarea'); const inputs = e.target.querySelectorAll('input:not([type="file"]), textarea');
inputs.forEach(input => { inputs.forEach(input => {
formData[input.name] = input.value; formData[input.name] = input.value;
}); });
try { try {
const response = await fetch('/admin/update_config', { const response = await fetch('/admin/update_config', {
method: 'POST', method: 'POST',
@ -383,9 +392,9 @@
}, },
body: JSON.stringify(formData) body: JSON.stringify(formData)
}); });
const result = await response.json(); const result = await response.json();
if (result.success) { if (result.success) {
alert('Configuration saved successfully'); alert('Configuration saved successfully');
location.reload(); location.reload();