feat: add cover image field to album creation and editing

- Added dedicated cover image upload field in create_album.php form
- Display current cover image preview when editing
- Drag-and-drop support for cover image with real-time preview
- Shows filename and file size after selection
- Updated save_album.php to handle cover image upload
- Updated update_album.php to handle cover image replacement
- Deletes old cover image when updating
- Cover image optional - first photo in album used as fallback
- Recommended cover dimensions: 500x500px or larger (square)
- File validation: max 5MB, supports JPG, PNG, GIF, WEBP
- All cover image changes included in transaction with rollback on error
This commit is contained in:
twotalesanimation
2025-12-05 10:14:35 +02:00
parent ad460ef85a
commit 5736757f19
3 changed files with 188 additions and 3 deletions

View File

@@ -208,6 +208,27 @@ require_once($rootPath . '/components/banner.php');
color: #999;
margin-top: 5px;
}
.cover-preview-area {
margin-bottom: 15px;
}
.current-cover {
border-radius: 8px;
overflow: hidden;
margin-bottom: 15px;
}
.current-cover img {
width: 100%;
max-height: 250px;
object-fit: cover;
display: block;
}
#coverUploadArea {
cursor: pointer;
}
</style>
<section class="tour-list-page py-100 rel">
@@ -234,6 +255,27 @@ require_once($rootPath . '/components/banner.php');
<div class="helper-text">Optional: Share details about when, where, or why you created this album</div>
</div>
<div class="form-group">
<label for="cover_image">Album Cover Image</label>
<div class="cover-preview-area">
<?php if ($album && $album['cover_image']): ?>
<div class="current-cover">
<img id="currentCoverImg" src="<?php echo htmlspecialchars($album['cover_image']); ?>" alt="Current cover">
<p style="margin-top: 10px; font-size: 0.9rem; color: #666;">Current cover image</p>
</div>
<?php else: ?>
<div id="currentCoverImg" style="width: 100%; height: 200px; background: #f0f0f0; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: #999; margin-bottom: 15px;">No cover image yet</div>
<?php endif; ?>
</div>
<div class="upload-area" id="coverUploadArea" style="margin-top: 15px;">
<input type="file" id="cover_image" name="cover_image" accept="image/*" class="upload-input">
<div style="font-size: 1.5rem; margin-bottom: 10px;">🖼️</div>
<p class="upload-text">Click to select cover image</p>
<div class="helper-text">Image will be used as album thumbnail. Recommended: Square image (500x500px or larger)</div>
</div>
<div id="coverFileName" style="margin-top: 10px;"></div>
</div>
<?php if ($album): ?>
<div class="photos-section">
<h4>Photos in Album</h4>
@@ -280,8 +322,60 @@ require_once($rootPath . '/components/banner.php');
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('photos');
const fileList = document.getElementById('fileList');
const coverUploadArea = document.getElementById('coverUploadArea');
const coverImageInput = document.getElementById('cover_image');
const coverFileName = document.getElementById('coverFileName');
// Drag and drop
// Cover image handling
coverUploadArea.addEventListener('click', () => {
coverImageInput.click();
});
coverImageInput.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (event) => {
const preview = document.getElementById('currentCoverImg');
if (preview.tagName === 'IMG') {
preview.src = event.target.result;
} else {
const img = document.createElement('img');
img.src = event.target.result;
img.alt = 'Cover preview';
preview.replaceWith(img);
img.id = 'currentCoverImg';
}
};
reader.readAsDataURL(file);
coverFileName.innerHTML = '<p style="color: #667eea; font-weight: 500;">Selected: ' + file.name + ' (' + (file.size / 1024 / 1024).toFixed(2) + ' MB)</p>';
}
});
// Drag and drop for cover
coverUploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
coverUploadArea.classList.add('dragover');
});
coverUploadArea.addEventListener('dragleave', () => {
coverUploadArea.classList.remove('dragover');
});
coverUploadArea.addEventListener('drop', (e) => {
e.preventDefault();
coverUploadArea.classList.remove('dragover');
if (e.dataTransfer.files.length > 0) {
coverImageInput.files = e.dataTransfer.files;
const event = new Event('change', { bubbles: true });
coverImageInput.dispatchEvent(event);
}
});
// Regular photos drag and drop
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('dragover');