new moderation portal with CRUD operations and map preview function, bugfixes, comments and improved textblocks #7

Merged
lukas.uptmoor merged 11 commits from dev/patrick into main 2026-04-23 08:41:29 +02:00
Showing only changes of commit f30a01615e - Show all commits

View File

@@ -367,7 +367,7 @@ function styleLinePolygon(feature) {
// Block 9: Feature Popups for Read, Edit, Delete and Vote // Block 9: Feature Popups for Read, Edit, Delete and Vote
// ===================================================================== // =====================================================================
function bindFeaturePopup(feature, layer) { function buildPopupHtml(feature) {
const props = feature.properties; const props = feature.properties;
const cat = CATEGORIES[props.category] || CATEGORIES.other; const cat = CATEGORIES[props.category] || CATEGORIES.other;
@@ -377,8 +377,7 @@ function bindFeaturePopup(feature, layer) {
day: '2-digit', month: '2-digit', year: 'numeric' day: '2-digit', month: '2-digit', year: 'numeric'
}); });
// Builds Popup on Click return '' +
const html = '' +
'<div class="popup-detail">' + '<div class="popup-detail">' +
'<span class="popup-detail-category">' + categoryIcon(cat) + ' ' + cat.label + '</span>' + '<span class="popup-detail-category">' + categoryIcon(cat) + ' ' + cat.label + '</span>' +
'<div class="popup-detail-title">' + escapeHtml(props.title) + '</div>' + '<div class="popup-detail-title">' + escapeHtml(props.title) + '</div>' +
@@ -401,11 +400,17 @@ function bindFeaturePopup(feature, layer) {
'<button class="btn btn-danger" onclick="deleteContribution(' + props.contribution_id + ')"><i class="fa-solid fa-trash"></i> Löschen</button>' + '<button class="btn btn-danger" onclick="deleteContribution(' + props.contribution_id + ')"><i class="fa-solid fa-trash"></i> Löschen</button>' +
'</div>' : '') + '</div>' : '') +
'</div>'; '</div>';
}
layer.bindPopup(html, { maxWidth: 320, minWidth: 240 }); // Binds Popup and Tooltip to Feature Layer
function bindFeaturePopup(feature, layer) {
const cat = CATEGORIES[feature.properties.category] || CATEGORIES.other;
// Builds Tooltip on Hover // Rebuilts if Popup opens
layer.bindTooltip(categoryIcon(cat) + ' ' + escapeHtml(props.title), { layer.bindPopup(function () { return buildPopupHtml(feature); }, { maxWidth: 320, minWidth: 240 });
// Tooltip on Hover
layer.bindTooltip(categoryIcon(cat) + ' ' + escapeHtml(feature.properties.title), {
direction: 'top', direction: 'top',
offset: [0, -10] offset: [0, -10]
}); });
@@ -575,39 +580,53 @@ function voteContribution(contributionId, voteType) {
const likesSpan = document.getElementById('likes-' + contributionId); const likesSpan = document.getElementById('likes-' + contributionId);
const dislikesSpan = document.getElementById('dislikes-' + contributionId); const dislikesSpan = document.getElementById('dislikes-' + contributionId);
// Finds Feature in Contributions to update Properties
const feature = contributionsData.find(function (f) {
return f.properties.contribution_id === contributionId;
});
if (response.action === 'created') { if (response.action === 'created') {
// New Vote — Highlights Button and updates Count
userVotes[contributionId] = voteType; userVotes[contributionId] = voteType;
if (voteType === 'like') { if (voteType === 'like') {
likeBtn.classList.add('liked'); likeBtn.classList.add('liked');
likesSpan.textContent = parseInt(likesSpan.textContent) + 1; likesSpan.textContent = parseInt(likesSpan.textContent) + 1;
if (feature) feature.properties.likes_count++;
} else { } else {
dislikeBtn.classList.add('disliked'); dislikeBtn.classList.add('disliked');
dislikesSpan.textContent = parseInt(dislikesSpan.textContent) + 1; dislikesSpan.textContent = parseInt(dislikesSpan.textContent) + 1;
if (feature) feature.properties.dislikes_count++;
} }
} else if (response.action === 'removed') { } else if (response.action === 'removed') {
// Vote removed — Removes Button Highlight and updates Count
delete userVotes[contributionId]; delete userVotes[contributionId];
if (voteType === 'like') { if (voteType === 'like') {
likeBtn.classList.remove('liked'); likeBtn.classList.remove('liked');
likesSpan.textContent = Math.max(0, parseInt(likesSpan.textContent) - 1); likesSpan.textContent = Math.max(0, parseInt(likesSpan.textContent) - 1);
if (feature) feature.properties.likes_count = Math.max(0, feature.properties.likes_count - 1);
} else { } else {
dislikeBtn.classList.remove('disliked'); dislikeBtn.classList.remove('disliked');
dislikesSpan.textContent = Math.max(0, parseInt(dislikesSpan.textContent) - 1); dislikesSpan.textContent = Math.max(0, parseInt(dislikesSpan.textContent) - 1);
if (feature) feature.properties.dislikes_count = Math.max(0, feature.properties.dislikes_count - 1);
} }
} else if (response.action === 'changed') { } else if (response.action === 'changed') {
// Vote changed — Switches Highlights and updates both Counts
userVotes[contributionId] = voteType; userVotes[contributionId] = voteType;
if (voteType === 'like') { if (voteType === 'like') {
likeBtn.classList.add('liked'); likeBtn.classList.add('liked');
dislikeBtn.classList.remove('disliked'); dislikeBtn.classList.remove('disliked');
likesSpan.textContent = parseInt(likesSpan.textContent) + 1; likesSpan.textContent = parseInt(likesSpan.textContent) + 1;
dislikesSpan.textContent = Math.max(0, parseInt(dislikesSpan.textContent) - 1); dislikesSpan.textContent = Math.max(0, parseInt(dislikesSpan.textContent) - 1);
if (feature) {
feature.properties.likes_count++;
feature.properties.dislikes_count = Math.max(0, feature.properties.dislikes_count - 1);
}
} else { } else {
dislikeBtn.classList.add('disliked'); dislikeBtn.classList.add('disliked');
likeBtn.classList.remove('liked'); likeBtn.classList.remove('liked');
dislikesSpan.textContent = parseInt(dislikesSpan.textContent) + 1; dislikesSpan.textContent = parseInt(dislikesSpan.textContent) + 1;
likesSpan.textContent = Math.max(0, parseInt(likesSpan.textContent) - 1); likesSpan.textContent = Math.max(0, parseInt(likesSpan.textContent) - 1);
if (feature) {
feature.properties.dislikes_count++;
feature.properties.likes_count = Math.max(0, feature.properties.likes_count - 1);
}
} }
} }
}); });