Add files via upload

This commit is contained in:
Tomáš Dvořák
2025-05-27 09:13:03 +02:00
committed by GitHub
parent 7e119ab943
commit 6f1d593a42
+91 -88
View File
@@ -464,13 +464,13 @@
<script> <script>
// Get token and check authentication // Get token and check authentication
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
if (!token) { if (!token) {
window.location.href = '/login.html'; window.location.href = '/login.html';
} }
// Show notification to user // Show notification to user
function showNotification(message, type = 'info') { function showNotification(message, type = 'info') {
const notification = document.createElement('div'); const notification = document.createElement('div');
notification.className = `notification ${type}`; notification.className = `notification ${type}`;
@@ -493,11 +493,11 @@
notification.classList.add('fade-out'); notification.classList.add('fade-out');
setTimeout(() => notification.remove(), 300); setTimeout(() => notification.remove(), 300);
}, delay); }, delay);
} }
// Override fetch to include token // Override fetch to include token (but NOT for FormData requests)
const originalFetch = window.fetch; const originalFetch = window.fetch;
window.fetch = async function(resource, init = {}) { window.fetch = async function(resource, init = {}) {
// Add token to headers if it's an API request // Add token to headers if it's an API request
if (typeof resource === 'string' && resource.startsWith('/api/')) { if (typeof resource === 'string' && resource.startsWith('/api/')) {
const headers = new Headers(init.headers || {}); const headers = new Headers(init.headers || {});
@@ -505,8 +505,8 @@
headers.set('Authorization', `Bearer ${token}`); headers.set('Authorization', `Bearer ${token}`);
} }
// Set content type if not set // Only set content type if not FormData (FormData sets its own)
if (!headers.has('Content-Type') && init.body) { if (!headers.has('Content-Type') && init.body && !(init.body instanceof FormData)) {
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
} }
@@ -514,15 +514,15 @@
} }
return originalFetch(resource, init); return originalFetch(resource, init);
}; };
// Image handling // Image handling
document.getElementById('uploadImageBtn').addEventListener('click', function() { document.getElementById('uploadImageBtn').addEventListener('click', function() {
document.getElementById('bannerImage').click(); document.getElementById('bannerImage').click();
}); });
// Handle image upload // Handle image upload
function handleImageUpload(event) { function handleImageUpload(event) {
const fileInput = event.target; const fileInput = event.target;
const file = fileInput.files[0]; const file = fileInput.files[0];
@@ -582,36 +582,36 @@
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
// Logout functionality // Logout functionality
document.getElementById('logoutBtn').addEventListener('click', function() { document.getElementById('logoutBtn').addEventListener('click', function() {
localStorage.removeItem('token'); localStorage.removeItem('token');
window.location.href = '/'; window.location.href = '/';
}); });
// DOM Elements // DOM Elements
const bannerText = document.getElementById('bannerText'); const bannerText = document.getElementById('bannerText');
const bannerVisible = document.getElementById('bannerVisible'); const bannerVisible = document.getElementById('bannerVisible');
const bannerBgColor = document.getElementById('bannerBgColor'); const bannerBgColor = document.getElementById('bannerBgColor');
const bannerTextColor = document.getElementById('bannerTextColor'); const bannerTextColor = document.getElementById('bannerTextColor');
const bannerTextAlign = document.getElementById('bannerTextAlign'); const bannerTextAlign = document.getElementById('bannerTextAlign');
const bannerFontSize = document.getElementById('bannerFontSize'); const bannerFontSize = document.getElementById('bannerFontSize');
const bannerPadding = document.getElementById('bannerPadding'); const bannerPadding = document.getElementById('bannerPadding');
const bannerMargin = document.getElementById('bannerMargin'); const bannerMargin = document.getElementById('bannerMargin');
const bannerBorderRadius = document.getElementById('bannerBorderRadius'); const bannerBorderRadius = document.getElementById('bannerBorderRadius');
const bannerPreview = document.getElementById('bannerPreview'); const bannerPreview = document.getElementById('bannerPreview');
const bannerPreviewContent = bannerPreview.querySelector('.banner-preview-content'); const bannerPreviewContent = bannerPreview.querySelector('.banner-preview-content');
const bannerPreviewText = bannerPreview.querySelector('.banner-preview-text'); const bannerPreviewText = bannerPreview.querySelector('.banner-preview-text');
const bannerPreviewBg = bannerPreview.querySelector('.banner-preview-bg'); const bannerPreviewBg = bannerPreview.querySelector('.banner-preview-bg');
const bgColorPreview = document.getElementById('bgColorPreview'); const bgColorPreview = document.getElementById('bgColorPreview');
const textColorPreview = document.getElementById('textColorPreview'); const textColorPreview = document.getElementById('textColorPreview');
const saveBannerBtn = document.getElementById('saveBannerBtn'); const saveBannerBtn = document.getElementById('saveBannerBtn');
const stylePresets = document.querySelectorAll('.style-preset'); const stylePresets = document.querySelectorAll('.style-preset');
let currentImage = null; let currentImage = null;
// Preset styles // Preset styles
const presets = { const presets = {
info: { info: {
backgroundColor: '#cce5ff', backgroundColor: '#cce5ff',
textColor: '#004085', textColor: '#004085',
@@ -632,10 +632,10 @@
textColor: '#721c24', textColor: '#721c24',
textAlign: 'center' textAlign: 'center'
} }
}; };
// Load current banner // Load current banner
async function loadBanner() { async function loadBanner() {
try { try {
const response = await fetch('/api/banner'); const response = await fetch('/api/banner');
if (!response.ok) { if (!response.ok) {
@@ -708,10 +708,9 @@
console.error('Chyba při načítání banneru:', error); console.error('Chyba při načítání banneru:', error);
showNotification('Chyba při načítání banneru', 'error'); showNotification('Chyba při načítání banneru', 'error');
} }
} }
// Save banner async function saveBanner(event) {
async function saveBanner(event) {
event.preventDefault(); event.preventDefault();
const form = document.getElementById('bannerForm'); const form = document.getElementById('bannerForm');
@@ -730,15 +729,20 @@
formData.append('text', document.getElementById('bannerText').value); formData.append('text', document.getElementById('bannerText').value);
formData.append('link', document.getElementById('bannerLink').value); formData.append('link', document.getElementById('bannerLink').value);
// Add style properties to form data with the correct format // Create style object with default values
formData.append('style.backgroundColor', document.getElementById('bannerBgColor').value); const style = {
formData.append('style.textColor', document.getElementById('bannerTextColor').value); backgroundColor: document.getElementById('bannerBgColor').value,
formData.append('style.textAlign', document.getElementById('bannerTextAlign').value); textColor: document.getElementById('bannerTextColor').value,
formData.append('style.fontSize', document.getElementById('bannerFontSize').value); textAlign: document.getElementById('bannerTextAlign').value,
formData.append('style.padding', document.getElementById('bannerPadding').value); fontSize: document.getElementById('bannerFontSize').value || '16px',
formData.append('style.margin', document.getElementById('bannerMargin').value); padding: document.getElementById('bannerPadding').value || '0px',
formData.append('style.borderRadius', document.getElementById('bannerBorderRadius').value); margin: document.getElementById('bannerMargin').value || '0px',
formData.append('style.isVisible', document.getElementById('bannerVisible').checked); borderRadius: document.getElementById('bannerBorderRadius').value || '0px',
isVisible: document.getElementById('bannerVisible').checked
};
// Convert style object to JSON string and append to form data
formData.append('style', JSON.stringify(style));
// Log form data for debugging // Log form data for debugging
console.log('Odesílám data:'); console.log('Odesílám data:');
@@ -746,20 +750,19 @@
console.log(key, value); console.log(key, value);
} }
// Create a new headers object // Create headers object - DO NOT set Content-Type for FormData!
const headers = new Headers(); const headers = {};
// Don't set Content-Type header manually when using FormData
// The browser will set it automatically with the correct boundary
// Add Authorization header if token exists // Add Authorization header if token exists
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
if (token) { if (token) {
headers.append('Authorization', `Bearer ${token}`); headers['Authorization'] = `Bearer ${token}`;
} }
// Send request with FormData (browser will set correct Content-Type with boundary)
const response = await fetch('/api/banner/update', { const response = await fetch('/api/banner/update', {
method: 'POST', method: 'POST',
headers: headers, headers: headers, // No Content-Type header!
body: formData body: formData
}); });
@@ -812,10 +815,10 @@
submitButton.innerHTML = originalButtonText; submitButton.innerHTML = originalButtonText;
} }
} }
} }
// Update color previews // Update color previews
function updateColorPreviews() { function updateColorPreviews() {
const bgColorPreview = document.getElementById('bgColorPreview'); const bgColorPreview = document.getElementById('bgColorPreview');
const textColorPreview = document.getElementById('textColorPreview'); const textColorPreview = document.getElementById('textColorPreview');
@@ -826,10 +829,10 @@
if (textColorPreview) { if (textColorPreview) {
textColorPreview.style.backgroundColor = document.getElementById('bannerTextColor').value; textColorPreview.style.backgroundColor = document.getElementById('bannerTextColor').value;
} }
} }
// Remove image // Remove image
function removeImage() { function removeImage() {
const bannerImage = document.getElementById('bannerImage'); const bannerImage = document.getElementById('bannerImage');
const imagePreview = document.getElementById('imagePreview'); const imagePreview = document.getElementById('imagePreview');
const imagePreviewContainer = document.getElementById('imagePreviewContainer'); const imagePreviewContainer = document.getElementById('imagePreviewContainer');
@@ -869,10 +872,10 @@
const event = new Event('change'); const event = new Event('change');
bannerImage.dispatchEvent(event); bannerImage.dispatchEvent(event);
} }
} }
// Update banner preview // Update banner preview
function updateBannerPreview() { function updateBannerPreview() {
const bannerPreview = document.getElementById('bannerPreview'); const bannerPreview = document.getElementById('bannerPreview');
const bannerPreviewText = bannerPreview?.querySelector('.banner-preview-text'); const bannerPreviewText = bannerPreview?.querySelector('.banner-preview-text');
const bannerPreviewBg = bannerPreview?.querySelector('.banner-preview-bg'); const bannerPreviewBg = bannerPreview?.querySelector('.banner-preview-bg');
@@ -963,10 +966,10 @@
// Make sure the preview is visible // Make sure the preview is visible
bannerPreview.style.visibility = 'visible'; bannerPreview.style.visibility = 'visible';
} }
// Apply preset // Apply preset
function applyPreset(preset) { function applyPreset(preset) {
const style = presets[preset]; const style = presets[preset];
if (!style) return; if (!style) return;
@@ -976,32 +979,32 @@
updateColorPreviews(); updateColorPreviews();
updateBannerPreview(); updateBannerPreview();
} }
// Event Listeners // Event Listeners
bannerBgColor.addEventListener('input', () => { bannerBgColor.addEventListener('input', () => {
updateColorPreviews(); updateColorPreviews();
updateBannerPreview(); updateBannerPreview();
}); });
bannerTextColor.addEventListener('input', () => { bannerTextColor.addEventListener('input', () => {
updateColorPreviews(); updateColorPreviews();
updateBannerPreview(); updateBannerPreview();
}); });
[bannerText, bannerTextAlign, bannerFontSize, bannerPadding, bannerVisible].forEach(el => { [bannerText, bannerTextAlign, bannerFontSize, bannerPadding, bannerVisible].forEach(el => {
el.addEventListener('change', updateBannerPreview); el.addEventListener('change', updateBannerPreview);
el.addEventListener('input', updateBannerPreview); el.addEventListener('input', updateBannerPreview);
}); });
stylePresets.forEach(preset => { stylePresets.forEach(preset => {
preset.addEventListener('click', () => applyPreset(preset.dataset.preset)); preset.addEventListener('click', () => applyPreset(preset.dataset.preset));
}); });
saveBannerBtn.addEventListener('click', saveBanner); saveBannerBtn.addEventListener('click', saveBanner);
// Load banner when page loads // Load banner when page loads
document.addEventListener('DOMContentLoaded', loadBanner); document.addEventListener('DOMContentLoaded', loadBanner);
</script> </script>
</body> </body>
</html> </html>