mirror of
https://github.com/Dvorinka/PPve.git
synced 2026-06-04 04:22:58 +00:00
Add files via upload
This commit is contained in:
+196
-83
@@ -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';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user