photos section in moderation portal with slider
This commit is contained in:
@@ -99,7 +99,7 @@ $categories = get_categories();
|
||||
|
||||
// Loads all Contributions for Municipality
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT contribution_id, title, category, description, author_name,
|
||||
SELECT contribution_id, title, category, description, author_name, photo_path,
|
||||
geom_type, status, likes_count, dislikes_count, created_at, updated_at
|
||||
FROM contributions
|
||||
WHERE municipality_id = :mid
|
||||
@@ -275,9 +275,28 @@ $counts['total'] = count($all_contributions);
|
||||
<!-- Expanded Detail -->
|
||||
<div class="contribution-row-detail">
|
||||
<div class="detail-layout">
|
||||
<!-- Map Preview -->
|
||||
<div class="detail-map" id="map-<?= $item['contribution_id'] ?>"
|
||||
data-contribution-id="<?= $item['contribution_id'] ?>">
|
||||
<!-- Map and Photo Slider -->
|
||||
<div class="detail-slider" id="slider-<?= $item['contribution_id'] ?>">
|
||||
<!-- Slide 1: Map -->
|
||||
<div class="detail-slide active" data-slide="map">
|
||||
<div class="detail-map" id="map-<?= $item['contribution_id'] ?>"
|
||||
data-contribution-id="<?= $item['contribution_id'] ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php if (!empty($item['photo_path'])): ?>
|
||||
<!-- Slide 2: Photo -->
|
||||
<div class="detail-slide" data-slide="photo" style="display:none;">
|
||||
<img src="<?= htmlspecialchars($item['photo_path']) ?>" alt="Foto"
|
||||
class="detail-slide-photo" onclick="window.open('<?= htmlspecialchars($item['photo_path']) ?>', '_blank')">
|
||||
</div>
|
||||
<!-- Slider Arrows -->
|
||||
<button class="slider-arrow slider-arrow-left" onclick="slideDetail(<?= $item['contribution_id'] ?>, -1)">
|
||||
<i class="fa-solid fa-chevron-left"></i>
|
||||
</button>
|
||||
<button class="slider-arrow slider-arrow-right" onclick="slideDetail(<?= $item['contribution_id'] ?>, 1)">
|
||||
<i class="fa-solid fa-chevron-right"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
@@ -295,6 +314,10 @@ $counts['total'] = count($all_contributions);
|
||||
<i class="fa-solid fa-thumbs-up"></i> <?= $item['likes_count'] ?>
|
||||
·
|
||||
<i class="fa-solid fa-thumbs-down"></i> <?= $item['dislikes_count'] ?>
|
||||
·
|
||||
<i class="fa-solid fa-comment"></i> <?= $item['comment_count'] ?? 0 ?>
|
||||
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -537,6 +560,39 @@ $counts['total'] = count($all_contributions);
|
||||
}
|
||||
|
||||
|
||||
// =============================================================
|
||||
// Detail Slider for Maps and Photos
|
||||
// =============================================================
|
||||
|
||||
function slideDetail(contributionId, direction) {
|
||||
const slider = document.getElementById('slider-' + contributionId);
|
||||
if (!slider) return;
|
||||
|
||||
const slides = slider.querySelectorAll('.detail-slide');
|
||||
let activeIndex = -1;
|
||||
|
||||
// Finds currently active Slide
|
||||
slides.forEach(function (slide, i) {
|
||||
if (slide.style.display !== 'none') activeIndex = i;
|
||||
});
|
||||
|
||||
// Calculates next Slide Index (wraps around)
|
||||
const nextIndex = (activeIndex + direction + slides.length) % slides.length;
|
||||
|
||||
// Switches Slides
|
||||
slides.forEach(function (slide) { slide.style.display = 'none'; });
|
||||
slides[nextIndex].style.display = 'block';
|
||||
|
||||
// Loads Map if switching to Map Slide and not yet loaded
|
||||
if (slides[nextIndex].dataset.slide === 'map') {
|
||||
const mapDiv = slides[nextIndex].querySelector('.detail-map');
|
||||
if (mapDiv && !mapDiv.dataset.loaded) {
|
||||
loadMapPreview(mapDiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =============================================================
|
||||
// Map Preview (Leaflet Mini Map per Contribution)
|
||||
// =============================================================
|
||||
|
||||
@@ -1036,6 +1036,60 @@ select.form-input { cursor: pointer; }
|
||||
.back-link a { color: var(--color-text-secondary); }
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
5.8 Detail Slider (Map/Photo in Admin)
|
||||
----------------------------------------------------------------- */
|
||||
.detail-slider {
|
||||
width: 220px;
|
||||
height: 170px;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border);
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.detail-slide { width: 100%; height: 100%; }
|
||||
|
||||
.detail-slide-photo {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.detail-slider .detail-map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.slider-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.7rem;
|
||||
z-index: 1000;
|
||||
transition: background var(--transition-fast);
|
||||
}
|
||||
|
||||
.slider-arrow:hover { background: rgba(0, 0, 0, 0.7); }
|
||||
.slider-arrow-left { left: 4px; }
|
||||
.slider-arrow-right { right: 4px; }
|
||||
|
||||
|
||||
/* =================================================================
|
||||
SECTION 6: Responsive Overrides
|
||||
================================================================= */
|
||||
@@ -1075,6 +1129,8 @@ select.form-input { cursor: pointer; }
|
||||
.action-buttons .btn { justify-content: center; }
|
||||
.filter-tabs { overflow-x: auto; }
|
||||
.page-tabs { overflow-x: auto; }
|
||||
.detail-slider { width: 100%; height: 200px; }
|
||||
|
||||
|
||||
/* Legal */
|
||||
.page-content-box { padding: 20px; }
|
||||
|
||||
Reference in New Issue
Block a user