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