Add files via upload

This commit is contained in:
Tomáš Dvořák
2025-05-27 12:58:01 +02:00
committed by GitHub
parent bf2433e6ed
commit 2b7fdb4f04
+196 -83
View File
@@ -195,6 +195,8 @@
min-height: 180px;
transition: var(--transition);
box-shadow: var(--box-shadow);
width: 100%;
max-width: 100%;
}
.banner-preview:hover {
@@ -232,14 +234,11 @@
position: relative;
z-index: 2;
text-align: center;
padding: 40px 30px;
padding: 20px;
margin: 0;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 180px;
display: block;
}
.banner-preview-bg {
@@ -260,12 +259,9 @@
position: relative;
z-index: 2;
margin: 0;
padding: 20px;
font-size: 1.2rem;
line-height: 1.6;
padding: 0;
line-height: 1.5;
word-wrap: break-word;
font-weight: 500;
text-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.color-picker-container {
display: flex;
@@ -471,6 +467,59 @@
margin-bottom: 0.5rem;
}
}
.drag-drop-area {
border: 2px dashed var(--border-color);
border-radius: var(--border-radius);
padding: 30px 20px;
text-align: center;
background-color: #f8f9fa;
cursor: pointer;
transition: var(--transition);
margin-bottom: 15px;
position: relative;
}
.drag-drop-area:hover, .drag-drop-area.dragover {
border-color: var(--primary-color);
background-color: rgba(74, 108, 247, 0.05);
}
.drag-drop-message {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: var(--secondary-color);
}
.drag-drop-message i {
font-size: 2.5rem;
margin-bottom: 15px;
color: var(--primary-color);
}
.drag-drop-message p {
margin: 0;
font-size: 1rem;
}
.image-actions {
display: flex;
gap: 10px;
}
.image-preview {
max-width: 100%;
max-height: 200px;
border-radius: 4px;
margin-top: 10px;
display: none;
}
.banner-preview.with-image {
min-height: 220px;
}
</style>
</head>
<body>
@@ -500,7 +549,18 @@
<label>Nahrát obrázek</label>
<input type="file" id="bannerImage" name="image" accept="image/*" style="display: none;" onchange="handleImageUpload(event)">
<input type="hidden" id="removeImage" name="removeImage" value="false">
<div>
<div id="dragDropArea" class="drag-drop-area">
<div class="drag-drop-message">
<i class="fas fa-cloud-upload-alt"></i>
<p>Přetáhněte obrázek sem nebo klikněte pro výběr</p>
</div>
<div id="imagePreviewContainer" style="display: none; margin-top: 15px; text-align: center;">
<img id="imagePreview" style="max-width: 100%; max-height: 200px; border-radius: 4px;" />
</div>
</div>
<div class="image-actions" style="margin-top: 10px;">
<button type="button" class="btn btn-secondary" id="uploadImageBtn">
<i class="fas fa-upload"></i> Vybrat obrázek
</button>
@@ -508,10 +568,8 @@
<i class="fas fa-trash"></i> Odstranit obrázek
</button>
</div>
<div id="imagePreviewContainer" style="margin-top: 10px; display: none;">
<img id="imagePreview" style="max-width: 200px; max-height: 200px; border: 1px solid #ddd; border-radius: 4px; padding: 5px;" />
</div>
<p class="help-text" style="font-size: 0.8em; color: #666; margin-top: 5px;">
<p class="help-text" style="margin-top: 10px;">
Doporučený poměr stran: 3:1 (např. 1200x400px)
</p>
</div>
@@ -577,12 +635,11 @@
<div class="banner-preview" id="bannerPreview" style="display: none;">
<div class="banner-preview-bg"></div>
<div class="banner-preview-content">
<div class="banner-preview-text">Náhled banneru se zde zobrazí</div>
<div id="imagePreviewContainer" style="display: none; margin-top: 15px; text-align: center;">
<img id="imagePreview" style="max-width: 100%; max-height: 200px; border-radius: 4px;" />
</div>
</div>
<div class="banner-preview-content">Náhled banneru se zde zobrazí</div>
</div>
<div id="imagePreviewContainer" style="display: none; margin-top: 15px; text-align: center;">
<img id="imagePreview" style="max-width: 100%; max-height: 200px; border-radius: 4px;" />
</div>
<div class="form-actions">
@@ -676,11 +733,62 @@ window.fetch = async function(resource, init = {}) {
return originalFetch(resource, init);
};
// Image handling
document.getElementById('uploadImageBtn').addEventListener('click', function() {
document.getElementById('bannerImage').click();
// Image handling - Drag and Drop functionality
const dragDropArea = document.getElementById('dragDropArea');
const uploadImageBtn = document.getElementById('uploadImageBtn');
const bannerImage = document.getElementById('bannerImage');
// Click on drag area to select file
dragDropArea.addEventListener('click', function() {
bannerImage.click();
});
// Click on upload button to select file
uploadImageBtn.addEventListener('click', function() {
bannerImage.click();
});
// Prevent default behavior for drag events
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dragDropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// Visual feedback when dragging over the area
['dragenter', 'dragover'].forEach(eventName => {
dragDropArea.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dragDropArea.addEventListener(eventName, unhighlight, false);
});
function highlight() {
dragDropArea.classList.add('dragover');
}
function unhighlight() {
dragDropArea.classList.remove('dragover');
}
// Handle dropped files
dragDropArea.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
bannerImage.files = files;
const event = new Event('change');
bannerImage.dispatchEvent(event);
}
}
// Handle image upload
function handleImageUpload(event) {
const fileInput = event.target;
@@ -691,7 +799,7 @@ function handleImageUpload(event) {
// Check file type
const validImageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'];
if (!validImageTypes.includes(file.type)) {
alert('Vyberte prosím soubor obrázku (JPG, PNG, GIF, SVG)');
showNotification('Vyberte prosím soubor obrázku (JPG, PNG, GIF, SVG)', 'warning');
fileInput.value = ''; // Reset file input
return;
}
@@ -699,7 +807,7 @@ function handleImageUpload(event) {
// Check file size (max 5MB)
const maxSize = 5 * 1024 * 1024; // 5MB
if (file.size > maxSize) {
alert('Maximální velikost souboru je 5MB');
showNotification('Maximální velikost souboru je 5MB', 'warning');
fileInput.value = ''; // Reset file input
return;
}
@@ -710,6 +818,7 @@ function handleImageUpload(event) {
const preview = document.getElementById('imagePreview');
const previewContainer = document.getElementById('imagePreviewContainer');
const removeBtn = document.getElementById('removeImageBtn');
const dragDropMessage = document.querySelector('.drag-drop-message');
// Update preview elements if they exist
if (preview) {
@@ -725,6 +834,11 @@ function handleImageUpload(event) {
removeBtn.style.display = 'inline-block';
}
// Hide the drag & drop message when showing preview
if (dragDropMessage) {
dragDropMessage.style.display = 'none';
}
// Update hidden input
const removeImageInput = document.getElementById('removeImage');
if (removeImageInput) {
@@ -737,7 +851,7 @@ function handleImageUpload(event) {
};
reader.onerror = function() {
alert('Při načítání obrázku došlo k chybě. Zkuste to prosím znovu.');
showNotification('Při načítání obrázku došlo k chybě. Zkuste to prosím znovu.', 'error');
fileInput.value = ''; // Reset file input
};
@@ -1005,6 +1119,7 @@ function removeImage() {
const imagePreviewContainer = document.getElementById('imagePreviewContainer');
const removeBtn = document.getElementById('removeImageBtn');
const removeImageInput = document.getElementById('removeImage');
const dragDropMessage = document.querySelector('.drag-drop-message');
// Reset file input
if (bannerImage) bannerImage.value = '';
@@ -1020,6 +1135,11 @@ function removeImage() {
imagePreviewContainer.style.display = 'none';
}
// Show drag & drop message again
if (dragDropMessage) {
dragDropMessage.style.display = 'flex';
}
// Hide remove button
if (removeBtn) {
removeBtn.style.display = 'none';
@@ -1034,6 +1154,9 @@ function removeImage() {
currentImage = null;
updateBannerPreview();
// Show success notification
showNotification('Obrázek byl odstraněn', 'info');
// Trigger a change event on the file input in case any other code is listening
if (bannerImage) {
const event = new Event('change');
@@ -1044,13 +1167,13 @@ function removeImage() {
// Update banner preview
function updateBannerPreview() {
const bannerPreview = document.getElementById('bannerPreview');
const bannerPreviewText = bannerPreview?.querySelector('.banner-preview-text');
const bannerPreviewBg = bannerPreview?.querySelector('.banner-preview-bg');
const bannerPreviewContent = bannerPreview?.querySelector('.banner-preview-content');
const bannerPreviewBg = bannerPreview?.querySelector('.banner-preview-bg');
const imagePreview = document.getElementById('imagePreview');
const imagePreviewContainer = document.getElementById('imagePreviewContainer');
const bannerLink = document.getElementById('bannerLink')?.value || '';
if (!bannerPreview || !bannerPreviewText || !bannerPreviewBg || !bannerPreviewContent) {
if (!bannerPreview || !bannerPreviewContent || !bannerPreviewBg) {
return; // Elements not found
}
@@ -1064,73 +1187,63 @@ function updateBannerPreview() {
const bannerMargin = parseInt(document.getElementById('bannerMargin')?.value || '20');
const bannerBorderRadius = parseInt(document.getElementById('bannerBorderRadius')?.value || '8');
// Update banner styles
// Update banner container styles to match index.html
bannerPreview.style.display = 'block';
bannerPreview.style.padding = `${bannerPadding}px`;
bannerPreview.style.margin = `${bannerMargin}px auto`;
bannerPreview.style.borderRadius = `${bannerBorderRadius}px`;
bannerPreview.style.overflow = 'hidden';
bannerPreview.style.position = 'relative';
bannerPreview.style.backgroundColor = bannerBgColor;
bannerPreview.style.textAlign = bannerTextAlign;
bannerPreview.style.width = '100%';
bannerPreview.style.transition = 'all 0.3s ease';
bannerPreview.style.margin = '0 auto';
bannerPreview.style.maxWidth = '100%';
bannerPreview.style.padding = '0';
// Update banner content
bannerPreviewText.textContent = bannerText || 'Náhled banneru';
bannerPreviewText.style.fontSize = `${bannerFontSize}px`;
bannerPreviewText.style.color = bannerTextColor;
bannerPreviewText.style.margin = '0';
bannerPreviewText.style.padding = '15px';
bannerPreviewText.style.position = 'relative';
bannerPreviewText.style.zIndex = '2';
// Update banner content styles to match index.html
Object.assign(bannerPreviewContent.style, {
backgroundColor: bannerBgColor,
color: bannerTextColor,
textAlign: bannerTextAlign,
fontSize: `${bannerFontSize}px`,
padding: `${bannerPadding}px`,
margin: `${bannerMargin}px 0`,
borderRadius: `${bannerBorderRadius}px`,
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
display: 'block',
position: 'relative',
zIndex: '2'
});
// Handle image
// Handle content and image like in index.html
let content = bannerText || 'Náhled banneru';
const bannerImage = document.getElementById('bannerImage');
const hasImage = currentImage || (bannerImage && bannerImage.files.length > 0);
if (hasImage) {
bannerPreview.classList.add('with-image');
if (hasImage && currentImage) {
// Format content with image like in index.html
content = `
<div style="margin-bottom: 15px;">
<img src="${currentImage}" style="max-width: 100%; max-height: 200px; border-radius: 4px;">
</div>
${content}
`;
// Update background image
if (currentImage) {
bannerPreviewBg.style.backgroundImage = `url(${currentImage})`;
bannerPreviewBg.style.display = 'block';
// Show the image preview in the container
if (imagePreview && imagePreviewContainer) {
imagePreview.src = currentImage;
imagePreviewContainer.style.display = 'block';
}
} else {
bannerPreviewBg.style.backgroundImage = '';
bannerPreviewBg.style.display = 'none';
// Hide the image preview container if no image
if (imagePreviewContainer) {
imagePreviewContainer.style.display = 'none';
}
// Show the image preview in the container
if (imagePreview && imagePreviewContainer) {
imagePreview.src = currentImage;
imagePreviewContainer.style.display = 'block';
}
// Style the background image
bannerPreviewBg.style.position = 'absolute';
bannerPreviewBg.style.top = '0';
bannerPreviewBg.style.left = '0';
bannerPreviewBg.style.width = '100%';
bannerPreviewBg.style.height = '100%';
bannerPreviewBg.style.backgroundSize = 'cover';
bannerPreviewBg.style.backgroundPosition = 'center';
bannerPreviewBg.style.backgroundRepeat = 'no-repeat';
bannerPreviewBg.style.opacity = '0.7';
bannerPreviewBg.style.zIndex = '1';
} else {
bannerPreview.classList.remove('with-image');
bannerPreviewBg.style.display = 'none';
// Hide the image preview container
// Hide the image preview container if no image
if (imagePreviewContainer) {
imagePreviewContainer.style.display = 'none';
}
}
// Wrap in link if provided
if (bannerLink) {
content = `<a href="${bannerLink}" style="color: inherit; text-decoration: none; display: block;">${content}</a>`;
}
// Update content
bannerPreviewContent.innerHTML = content;
// Make sure the preview is visible
bannerPreview.style.visibility = 'visible';
}