dev/patrick #1
@@ -480,7 +480,7 @@ function closeCreateModal() {
|
||||
drawnGeomType = null;
|
||||
}
|
||||
|
||||
// UPDATE: Edit existing Contributions
|
||||
// UPDATE: Edits existing Contributions
|
||||
function editContribution(contributionId) {
|
||||
// Finds Contribution in local Data
|
||||
var contribution = contributionsData.find(function (f) {
|
||||
@@ -529,11 +529,11 @@ function editContribution(contributionId) {
|
||||
});
|
||||
}
|
||||
|
||||
// DELETE — Delete a Contribution
|
||||
// DELETE: Deletes existing Contributions
|
||||
function deleteContribution(contributionId) {
|
||||
Swal.fire({
|
||||
title: 'Beitrag löschen?',
|
||||
text: 'Diese Aktion kann nicht rückgängig gemacht werden.',
|
||||
text: 'Aktion kann nicht rückgängig gemacht werden.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Löschen',
|
||||
@@ -557,10 +557,10 @@ function deleteContribution(contributionId) {
|
||||
});
|
||||
}
|
||||
|
||||
// VOTE — Like or Dislike a Contribution
|
||||
// VOTE: Like or Dislike existing Contributions
|
||||
function voteContribution(contributionId, voteType) {
|
||||
if (!currentUser) {
|
||||
Swal.fire('Bitte anmelden', 'Sie müssen sich anmelden, um abzustimmen.', 'info');
|
||||
Swal.fire('Bitte anmelden', 'Sie sollten sich anmelden, um abzustimmen.', 'info');
|
||||
showLoginModal();
|
||||
return;
|
||||
}
|
||||
@@ -576,14 +576,14 @@ function voteContribution(contributionId, voteType) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update Vote Counts in the Popup without reloading everything
|
||||
// Updates Vote Counts in the Popup without reloading everything
|
||||
loadContributions();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Block 11: Sidebar — Contributions List
|
||||
// Block 11: Sidebar Contributions List
|
||||
// =====================================================================
|
||||
|
||||
function updateContributionsList() {
|
||||
@@ -591,7 +591,7 @@ function updateContributionsList() {
|
||||
var searchInput = document.getElementById('list-search-input');
|
||||
var searchTerm = searchInput ? searchInput.value.toLowerCase() : '';
|
||||
|
||||
// Filter by active Categories and Search Term
|
||||
// Filters by Categories and Search Term
|
||||
var filtered = contributionsData.filter(function (f) {
|
||||
var props = f.properties;
|
||||
var matchesCategory = activeFilters.indexOf(props.category) !== -1;
|
||||
@@ -602,12 +602,12 @@ function updateContributionsList() {
|
||||
return matchesCategory && matchesSearch;
|
||||
});
|
||||
|
||||
// Sort by Date (newest first)
|
||||
// Sorts by Date (newest first)
|
||||
filtered.sort(function (a, b) {
|
||||
return new Date(b.properties.created_at) - new Date(a.properties.created_at);
|
||||
});
|
||||
|
||||
// Build HTML
|
||||
// Builds HTML
|
||||
if (filtered.length === 0) {
|
||||
container.innerHTML = '<p style="text-align:center;color:#999;padding:20px;">Keine Beiträge gefunden.</p>';
|
||||
return;
|
||||
@@ -638,13 +638,13 @@ function updateContributionsList() {
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
// Fly to a Contribution on the Map and open its Popup
|
||||
// Flies to a Contribution on the Map and open Popup
|
||||
function flyToContribution(contributionId) {
|
||||
if (!contributionsLayer) return;
|
||||
|
||||
contributionsLayer.eachLayer(function (layer) {
|
||||
if (layer.feature && layer.feature.properties.contribution_id === contributionId) {
|
||||
// Zoom to Feature
|
||||
// Zooms to Feature
|
||||
if (layer.getLatLng) {
|
||||
// Point Feature
|
||||
map.flyTo(layer.getLatLng(), 17);
|
||||
@@ -652,9 +652,9 @@ function flyToContribution(contributionId) {
|
||||
// Line or Polygon Feature
|
||||
map.flyToBounds(layer.getBounds(), { maxZoom: 17 });
|
||||
}
|
||||
// Open Popup
|
||||
// Opens Popup
|
||||
layer.openPopup();
|
||||
// Close Sidebar on Mobile
|
||||
// Closes Sidebar on Mobile
|
||||
if (window.innerWidth < 769) {
|
||||
sidebar.close();
|
||||
}
|
||||
@@ -669,10 +669,10 @@ document.getElementById('list-search-input').addEventListener('input', function
|
||||
|
||||
|
||||
// =====================================================================
|
||||
// Block 12: Sidebar — Category Filter and Statistics
|
||||
// Block 12: Sidebar Category Filter and Statistics
|
||||
// =====================================================================
|
||||
|
||||
// Build Category Filter Checkboxes
|
||||
// Builds Category Filter Checkboxes
|
||||
function buildCategoryFilter() {
|
||||
var container = document.getElementById('category-filter');
|
||||
var html = '';
|
||||
@@ -692,7 +692,7 @@ function buildCategoryFilter() {
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
// Toggle a Category Filter on/off
|
||||
// Toggles a Category Filter on or off
|
||||
function toggleCategoryFilter(checkbox) {
|
||||
var category = checkbox.value;
|
||||
|
||||
@@ -704,7 +704,7 @@ function toggleCategoryFilter(checkbox) {
|
||||
activeFilters = activeFilters.filter(function (c) { return c !== category; });
|
||||
}
|
||||
|
||||
// Re-filter the Map Layer
|
||||
// Refilters Map Layer
|
||||
if (contributionsLayer) {
|
||||
contributionsLayer.eachLayer(function (layer) {
|
||||
if (layer.feature) {
|
||||
@@ -720,16 +720,16 @@ function toggleCategoryFilter(checkbox) {
|
||||
});
|
||||
}
|
||||
|
||||
// Update List
|
||||
// Updates List
|
||||
updateContributionsList();
|
||||
}
|
||||
|
||||
// Update Statistics in Home Tab
|
||||
// Updates Statistics in Home Tab
|
||||
function updateStatistics() {
|
||||
var container = document.getElementById('stats-container');
|
||||
var total = contributionsData.length;
|
||||
|
||||
// Count per Category
|
||||
// Counts per Category
|
||||
var counts = {};
|
||||
contributionsData.forEach(function (f) {
|
||||
var cat = f.properties.category;
|
||||
@@ -757,7 +757,7 @@ function updateStatistics() {
|
||||
// Block 13: Modals — Welcome, Login, Info, Privacy, Imprint
|
||||
// =====================================================================
|
||||
|
||||
// Welcome Modal — show on first Visit
|
||||
// Welcome Modal shows on new Visits
|
||||
function checkWelcomeModal() {
|
||||
var hasVisited = localStorage.getItem('webgis_welcomed');
|
||||
if (!hasVisited) {
|
||||
@@ -771,7 +771,7 @@ function closeWelcomeAndShowLogin() {
|
||||
showLoginModal();
|
||||
}
|
||||
|
||||
// Login Modal
|
||||
// Login Modal shows new Session
|
||||
function showLoginModal() {
|
||||
document.getElementById('login-modal').style.display = 'flex';
|
||||
document.getElementById('user-name-input').value = currentUser;
|
||||
@@ -796,12 +796,12 @@ function skipLogin() {
|
||||
// Info Modal
|
||||
function showInfoModal() {
|
||||
Swal.fire({
|
||||
title: 'Über das Portal',
|
||||
html: '<p style="text-align:left;line-height:1.6;">Das Bürgerbeteiligungsportal ermöglicht es ' +
|
||||
title: 'Informationen',
|
||||
html: '<p style="text-align:left;line-height:1.6;">Das Bürgerbeteiligungsportal gestattet ' +
|
||||
'Bürgerinnen und Bürgern sowie der Stadtverwaltung, gemeinsam an der Gestaltung von ' +
|
||||
'<strong>' + MUNICIPALITY.name + '</strong> mitzuwirken.</p>' +
|
||||
'<p style="text-align:left;line-height:1.6;">Tragen Sie Hinweise, Ideen und Verbesserungsvorschläge ' +
|
||||
'direkt auf der Karte ein.</p>',
|
||||
'<p style="text-align:left;line-height:1.6;">Bitte tragen Sie Hinweise, Anregungen und Vorschläge ' +
|
||||
'mithilfe der Zeichenwerkzeuge auf der Karte ein.</p>',
|
||||
confirmButtonColor: MUNICIPALITY.primaryColor
|
||||
});
|
||||
}
|
||||
@@ -810,10 +810,10 @@ function showInfoModal() {
|
||||
function showPrivacyModal() {
|
||||
Swal.fire({
|
||||
title: 'Datenschutz',
|
||||
html: '<p style="text-align:left;line-height:1.6;">Dieses Portal speichert die von Ihnen ' +
|
||||
'eingegebenen Daten (Name, Beiträge, Bewertungen) zur Durchführung der Bürgerbeteiligung.</p>' +
|
||||
html: '<p style="text-align:left;line-height:1.6;">Das Bürgerbeteiligungsportal speichert die von Ihnen ' +
|
||||
'hinterlegten Daten zur Durchführung der Bürgerbeteiligung.</p>' +
|
||||
'<p style="text-align:left;line-height:1.6;">Ihre Daten werden nicht an Dritte weitergegeben. ' +
|
||||
'Details entnehmen Sie bitte der vollständigen Datenschutzerklärung der Stadt ' +
|
||||
'Details entnehmen Sie bitte der vollständigen Datenschutzerklärung von ' +
|
||||
MUNICIPALITY.name + '.</p>',
|
||||
confirmButtonColor: MUNICIPALITY.primaryColor
|
||||
});
|
||||
@@ -824,8 +824,8 @@ function showImprintModal() {
|
||||
Swal.fire({
|
||||
title: 'Impressum',
|
||||
html: '<p style="text-align:left;line-height:1.6;">Stadt ' + MUNICIPALITY.name + '</p>' +
|
||||
'<p style="text-align:left;line-height:1.6;color:#777;">Die vollständigen Angaben gemäß § 5 TMG ' +
|
||||
'werden hier ergänzt, sobald das Portal in den Produktivbetrieb geht.</p>',
|
||||
'<p style="text-align:left;line-height:1.6;color:#777;">Die vollständigen Angaben ' +
|
||||
'werden hier hinzugefügt, sobald das Portal in den Produktivbetrieb geht.</p>',
|
||||
confirmButtonColor: MUNICIPALITY.primaryColor
|
||||
});
|
||||
}
|
||||
@@ -840,7 +840,7 @@ function toggleMobileNav() {
|
||||
nav.classList.toggle('open');
|
||||
}
|
||||
|
||||
// Close Mobile Nav when clicking outside
|
||||
// Closes Mobile Nav when clicking outside
|
||||
document.addEventListener('click', function (e) {
|
||||
var nav = document.querySelector('.header-nav');
|
||||
var toggle = document.querySelector('.header-menu-toggle');
|
||||
@@ -850,7 +850,7 @@ document.addEventListener('click', function (e) {
|
||||
}
|
||||
});
|
||||
|
||||
// Close Modals on Escape Key
|
||||
// Closes Modals on Escape Key
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape') {
|
||||
document.getElementById('welcome-modal').style.display = 'none';
|
||||
@@ -864,7 +864,7 @@ document.addEventListener('keydown', function (e) {
|
||||
// Block 15: Utility Functions
|
||||
// =====================================================================
|
||||
|
||||
// Escape HTML to prevent XSS in Popups and Lists
|
||||
// Escapes HTML to prevent Cross-Site Scripting (XSS) in Popups and Lists
|
||||
function escapeHtml(text) {
|
||||
if (!text) return '';
|
||||
var div = document.createElement('div');
|
||||
|
||||
Reference in New Issue
Block a user