restructured admin.js
This commit is contained in:
@@ -9,14 +9,10 @@
|
|||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 1: Status Filter for Contributions
|
// Block 1: Page Tab Navigation
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
let currentFilter = 'all';
|
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
|
||||||
// Restores active Tab after Page Reload
|
// Restores active Tab after Page Reload
|
||||||
// =====================================================================
|
|
||||||
const savedTab = sessionStorage.getItem('admin_active_tab');
|
const savedTab = sessionStorage.getItem('admin_active_tab');
|
||||||
if (savedTab) {
|
if (savedTab) {
|
||||||
// Delays to ensure DOM is ready
|
// Delays to ensure DOM is ready
|
||||||
@@ -27,48 +23,42 @@ if (savedTab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// Page Tab Navigation
|
||||||
// Block 3: Page Tab Navigation
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Wechselt den sichtbaren Haupt-Tab (Beiträge, Kommentare, Neuigkeiten usw.).
|
|
||||||
// Speichert den aktiven Tab in sessionStorage für Persistenz nach Reload.
|
|
||||||
function showPageTab(tabName) {
|
function showPageTab(tabName) {
|
||||||
|
// Saves active Tab for Persistence after Reload
|
||||||
sessionStorage.setItem('admin_active_tab', tabName);
|
sessionStorage.setItem('admin_active_tab', tabName);
|
||||||
|
|
||||||
document.querySelectorAll('.page-tab-content').forEach(function (el) {
|
document.querySelectorAll('.page-tab-content').forEach(function (el) {
|
||||||
el.style.display = 'none';
|
el.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Deactivates all Tab Buttons
|
||||||
document.querySelectorAll('.page-tab').forEach(function (el) {
|
document.querySelectorAll('.page-tab').forEach(function (el) {
|
||||||
el.classList.remove('active');
|
el.classList.remove('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Shows selected Tab and activates Button
|
||||||
document.getElementById('tab-' + tabName).style.display = 'block';
|
document.getElementById('tab-' + tabName).style.display = 'block';
|
||||||
event.currentTarget.classList.add('active');
|
event.currentTarget.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 4: Aufklappbare Zeilen (Collapsible Rows)
|
// Block 2: Collapsible Rows for Contributions and Comments
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Öffnet oder schließt eine Beitrags-/Kommentar-Zeile.
|
|
||||||
// Jeweils nur eine Zeile gleichzeitig geöffnet.
|
|
||||||
// Lädt bei Bedarf die Karten-Vorschau (Map Preview).
|
|
||||||
function toggleRow(row) {
|
function toggleRow(row) {
|
||||||
const wasOpen = row.classList.contains('open');
|
const wasOpen = row.classList.contains('open');
|
||||||
|
|
||||||
// Alle offenen Zeilen schließen
|
// Closes all open Rows
|
||||||
document.querySelectorAll('.contribution-row.open').forEach(function (el) {
|
document.querySelectorAll('.contribution-row.open').forEach(function (el) {
|
||||||
el.classList.remove('open');
|
el.classList.remove('open');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Toggles clicked Row
|
||||||
if (!wasOpen) {
|
if (!wasOpen) {
|
||||||
row.classList.add('open');
|
row.classList.add('open');
|
||||||
|
|
||||||
// Karten-Vorschau laden, falls noch nicht geschehen
|
// Loads Map Preview if not already loaded
|
||||||
const mapDiv = row.querySelector('.detail-map');
|
const mapDiv = row.querySelector('.detail-map');
|
||||||
if (mapDiv && !mapDiv.dataset.loaded) {
|
if (mapDiv && !mapDiv.dataset.loaded) {
|
||||||
loadMapPreview(mapDiv);
|
loadMapPreview(mapDiv);
|
||||||
@@ -78,12 +68,8 @@ function toggleRow(row) {
|
|||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 5: Detail-Slider (Karte / Foto)
|
// Block 3: Details Slider for Maps and Photos
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Wechselt zwischen den Slides (Karte und Foto) in einer Beitrags-Zeile.
|
|
||||||
// direction: -1 für zurück, +1 für vor.
|
|
||||||
// Wrapped circular: nach dem letzten Slide kommt der erste.
|
|
||||||
function slideDetail(contributionId, direction) {
|
function slideDetail(contributionId, direction) {
|
||||||
const slider = document.getElementById('slider-' + contributionId);
|
const slider = document.getElementById('slider-' + contributionId);
|
||||||
if (!slider) return;
|
if (!slider) return;
|
||||||
@@ -91,16 +77,19 @@ function slideDetail(contributionId, direction) {
|
|||||||
const slides = slider.querySelectorAll('.detail-slide');
|
const slides = slider.querySelectorAll('.detail-slide');
|
||||||
let activeIndex = -1;
|
let activeIndex = -1;
|
||||||
|
|
||||||
|
// Finds active Slide
|
||||||
slides.forEach(function (slide, i) {
|
slides.forEach(function (slide, i) {
|
||||||
if (slide.style.display !== 'none') activeIndex = i;
|
if (slide.style.display !== 'none') activeIndex = i;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Calculates next Slide Index
|
||||||
const nextIndex = (activeIndex + direction + slides.length) % slides.length;
|
const nextIndex = (activeIndex + direction + slides.length) % slides.length;
|
||||||
|
|
||||||
|
// Switches Slides
|
||||||
slides.forEach(function (slide) { slide.style.display = 'none'; });
|
slides.forEach(function (slide) { slide.style.display = 'none'; });
|
||||||
slides[nextIndex].style.display = 'block';
|
slides[nextIndex].style.display = 'block';
|
||||||
|
|
||||||
// Karte beim Zurückwechseln zum Map-Slide laden, falls noch nicht geschehen
|
// Loads Map if switching to Map Slide
|
||||||
if (slides[nextIndex].dataset.slide === 'map') {
|
if (slides[nextIndex].dataset.slide === 'map') {
|
||||||
const mapDiv = slides[nextIndex].querySelector('.detail-map');
|
const mapDiv = slides[nextIndex].querySelector('.detail-map');
|
||||||
if (mapDiv && !mapDiv.dataset.loaded) {
|
if (mapDiv && !mapDiv.dataset.loaded) {
|
||||||
@@ -111,7 +100,7 @@ function slideDetail(contributionId, direction) {
|
|||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 6: Leaflet Karten-Vorschau (Mini-Map pro Beitrag)
|
// Block 4: Map Preview (Leaflet Mini Map per Contribution)
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Erstellt eine Leaflet-Mini-Map in einem Beitrags-Detail-Container.
|
// Erstellt eine Leaflet-Mini-Map in einem Beitrags-Detail-Container.
|
||||||
@@ -119,7 +108,8 @@ function slideDetail(contributionId, direction) {
|
|||||||
// Markiert die Map als geladen (data-loaded="true"), um doppeltes Laden zu verhindern.
|
// Markiert die Map als geladen (data-loaded="true"), um doppeltes Laden zu verhindern.
|
||||||
function loadMapPreview(mapDiv) {
|
function loadMapPreview(mapDiv) {
|
||||||
const contributionId = mapDiv.dataset.contributionId;
|
const contributionId = mapDiv.dataset.contributionId;
|
||||||
|
|
||||||
|
// Fetches all Contributions to find the Geometry
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('action', 'read');
|
formData.append('action', 'read');
|
||||||
formData.append('municipality_id', ADMIN_CONFIG.municipalityId);
|
formData.append('municipality_id', ADMIN_CONFIG.municipalityId);
|
||||||
@@ -129,7 +119,8 @@ function loadMapPreview(mapDiv) {
|
|||||||
.then(function (r) { return r.json(); })
|
.then(function (r) { return r.json(); })
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
if (!data.features) return;
|
if (!data.features) return;
|
||||||
|
|
||||||
|
// Finds specific Contribution
|
||||||
const feature = data.features.find(function (f) {
|
const feature = data.features.find(function (f) {
|
||||||
return f.properties.contribution_id == contributionId;
|
return f.properties.contribution_id == contributionId;
|
||||||
});
|
});
|
||||||
@@ -139,6 +130,7 @@ function loadMapPreview(mapDiv) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates Leaflet Mini Map
|
||||||
const miniMap = L.map(mapDiv, {
|
const miniMap = L.map(mapDiv, {
|
||||||
zoomControl: false,
|
zoomControl: false,
|
||||||
attributionControl: false,
|
attributionControl: false,
|
||||||
@@ -150,6 +142,7 @@ function loadMapPreview(mapDiv) {
|
|||||||
maxZoom: 20
|
maxZoom: 20
|
||||||
}).addTo(miniMap);
|
}).addTo(miniMap);
|
||||||
|
|
||||||
|
// Adds Geometry to Mini Map
|
||||||
const geojsonLayer = L.geoJSON(feature, {
|
const geojsonLayer = L.geoJSON(feature, {
|
||||||
style: {
|
style: {
|
||||||
color: ADMIN_CONFIG.primaryColor,
|
color: ADMIN_CONFIG.primaryColor,
|
||||||
@@ -167,6 +160,7 @@ function loadMapPreview(mapDiv) {
|
|||||||
}
|
}
|
||||||
}).addTo(miniMap);
|
}).addTo(miniMap);
|
||||||
|
|
||||||
|
// Fits Map to Geometry Bounds
|
||||||
const bounds = geojsonLayer.getBounds();
|
const bounds = geojsonLayer.getBounds();
|
||||||
if (bounds.isValid()) {
|
if (bounds.isValid()) {
|
||||||
miniMap.fitBounds(bounds, { padding: [25, 25], maxZoom: 17 });
|
miniMap.fitBounds(bounds, { padding: [25, 25], maxZoom: 17 });
|
||||||
@@ -183,19 +177,21 @@ function loadMapPreview(mapDiv) {
|
|||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 7: Beitrags-Filter und Sortierung
|
// Block 5: Contributions Filter and Sorting
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Filtert Beitrags-Zeilen nach Status (pending, approved, rejected, all).
|
// Filters Contributions
|
||||||
// Aktualisiert die sichtbare Anzahl im Sort-Control.
|
let currentFilter = 'all';
|
||||||
function filterByStatus(status, tabButton) {
|
function filterByStatus(status, tabButton) {
|
||||||
currentFilter = status;
|
currentFilter = status;
|
||||||
|
|
||||||
|
// Updates active Tab
|
||||||
document.querySelectorAll('.filter-tab').forEach(function (el) {
|
document.querySelectorAll('.filter-tab').forEach(function (el) {
|
||||||
el.classList.remove('active');
|
el.classList.remove('active');
|
||||||
});
|
});
|
||||||
tabButton.classList.add('active');
|
tabButton.classList.add('active');
|
||||||
|
|
||||||
|
// Shows or Hides Contribution Rows
|
||||||
let visibleCount = 0;
|
let visibleCount = 0;
|
||||||
document.querySelectorAll('#contributions-container .contribution-row').forEach(function (row) {
|
document.querySelectorAll('#contributions-container .contribution-row').forEach(function (row) {
|
||||||
if (status === 'all' || row.dataset.status === status) {
|
if (status === 'all' || row.dataset.status === status) {
|
||||||
@@ -205,11 +201,13 @@ function filterByStatus(status, tabButton) {
|
|||||||
row.style.display = 'none';
|
row.style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Updates Count Display
|
||||||
document.getElementById('visible-count').textContent = visibleCount + ' Beiträge';
|
document.getElementById('visible-count').textContent = visibleCount + ' Beiträge';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sortiert Beitrags-Zeilen im DOM nach Datum (auf-/absteigend) oder Kategorie.
|
|
||||||
|
// Sorts Contributions
|
||||||
function sortContributions(sortBy) {
|
function sortContributions(sortBy) {
|
||||||
const container = document.getElementById('contributions-container');
|
const container = document.getElementById('contributions-container');
|
||||||
const rows = Array.from(container.querySelectorAll('.contribution-row'));
|
const rows = Array.from(container.querySelectorAll('.contribution-row'));
|
||||||
@@ -221,23 +219,25 @@ function sortContributions(sortBy) {
|
|||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Reappends sorted Rows
|
||||||
rows.forEach(function (row) { container.appendChild(row); });
|
rows.forEach(function (row) { container.appendChild(row); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 8: Kommentar-Filter und Sortierung
|
// Block 6: Comments Filter and Sorting
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Filtert Kommentar-Zeilen nach Status (pending, approved, rejected, all).
|
// Filters Comments
|
||||||
// Arbeitet ausschließlich auf dem #comment-filter-tabs Container,
|
|
||||||
// damit keine Kollision mit dem Beitrags-Filter entsteht.
|
|
||||||
function filterCommentsByStatus(status, tabButton) {
|
function filterCommentsByStatus(status, tabButton) {
|
||||||
|
|
||||||
|
// Updates active Tab
|
||||||
document.querySelectorAll('#comment-filter-tabs .filter-tab').forEach(function (el) {
|
document.querySelectorAll('#comment-filter-tabs .filter-tab').forEach(function (el) {
|
||||||
el.classList.remove('active');
|
el.classList.remove('active');
|
||||||
});
|
});
|
||||||
tabButton.classList.add('active');
|
tabButton.classList.add('active');
|
||||||
|
|
||||||
|
// Shows or Hides Comments Rows
|
||||||
let visibleCount = 0;
|
let visibleCount = 0;
|
||||||
document.querySelectorAll('.comment-mod-row').forEach(function (row) {
|
document.querySelectorAll('.comment-mod-row').forEach(function (row) {
|
||||||
if (status === 'all' || row.dataset.status === status) {
|
if (status === 'all' || row.dataset.status === status) {
|
||||||
@@ -247,11 +247,12 @@ function filterCommentsByStatus(status, tabButton) {
|
|||||||
row.style.display = 'none';
|
row.style.display = 'none';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Updates Count Display
|
||||||
document.getElementById('comment-visible-count').textContent = visibleCount + ' Kommentare';
|
document.getElementById('comment-visible-count').textContent = visibleCount + ' Kommentare';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sortiert Kommentar-Zeilen nach Datum oder Beitrags-Titel.
|
|
||||||
|
// Sorts Comments
|
||||||
function sortCommentRows(sortBy) {
|
function sortCommentRows(sortBy) {
|
||||||
const container = document.getElementById('comments-mod-container');
|
const container = document.getElementById('comments-mod-container');
|
||||||
const rows = Array.from(container.querySelectorAll('.comment-mod-row'));
|
const rows = Array.from(container.querySelectorAll('.comment-mod-row'));
|
||||||
@@ -262,49 +263,42 @@ function sortCommentRows(sortBy) {
|
|||||||
if (sortBy === 'contribution') return a.dataset.contribution.localeCompare(b.dataset.contribution);
|
if (sortBy === 'contribution') return a.dataset.contribution.localeCompare(b.dataset.contribution);
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
// Reappends sorted Rows
|
||||||
rows.forEach(function (row) { container.appendChild(row); });
|
rows.forEach(function (row) { container.appendChild(row); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 9: API-Hilfsfunktion
|
// Block 7: Helper Functions
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Sendet einen POST-Request an die API und gibt ein Promise zurück.
|
// Sends a POST request to API
|
||||||
// Analog zu apiCall() in app.js, jedoch Promise-basiert statt Callback-basiert,
|
// promise-based instead of callback-based
|
||||||
// da admin.js keine asynchrone Verkettung mit Callback-Chains benötigt.
|
|
||||||
function apiCall(data) {
|
function apiCall(data) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
for (const key in data) {
|
for (const key in data) {
|
||||||
formData.append(key, data[key]);
|
formData.append(key, data[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch(ADMIN_CONFIG.apiUrl, { method: 'POST', body: formData })
|
return fetch(ADMIN_CONFIG.apiUrl, { method: 'POST', body: formData })
|
||||||
.then(function (r) { return r.json(); });
|
.then(function (r) { return r.json(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// Escapes HTML to prevent Cross-Site Scripting (XSS) in Popups and Lists
|
||||||
// Block 10: Hilfsfunktion HTML-Escaping
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Verhindert XSS in dynamisch erzeugten SweetAlert-Dialogen.
|
|
||||||
// Identisch zu escapeHtml() in app.js — beide Dateien arbeiten unabhängig,
|
|
||||||
// daher keine gemeinsame Abhängigkeit eingeführt.
|
|
||||||
function escapeHtml(text) {
|
function escapeHtml(text) {
|
||||||
|
|
||||||
if (!text) return '';
|
if (!text) return '';
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.appendChild(document.createTextNode(text));
|
div.appendChild(document.createTextNode(text));
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 11: Beitrags-Status ändern
|
// Block 8: CRUD Operations for Contributions
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Ändert den Status eines Beitrags (approved / rejected / pending).
|
// STATUS: Changes Contribution Status
|
||||||
// Zeigt eine SweetAlert-Bestätigung und lädt die Seite nach Erfolg neu.
|
|
||||||
function changeStatus(contributionId, newStatus) {
|
function changeStatus(contributionId, newStatus) {
|
||||||
const labels = { approved: 'freigeben', rejected: 'ablehnen', pending: 'zurücksetzen' };
|
const labels = { approved: 'freigeben', rejected: 'ablehnen', pending: 'zurücksetzen' };
|
||||||
|
|
||||||
@@ -326,18 +320,14 @@ function changeStatus(contributionId, newStatus) {
|
|||||||
Swal.fire('Fehler', response.error, 'error');
|
Swal.fire('Fehler', response.error, 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Reloads Page to reflect Changes
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// UPDATE: Edits existing Contributions
|
||||||
// Block 12: Beitrag bearbeiten
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Öffnet einen SweetAlert-Dialog zum Bearbeiten von Titel und Beschreibung.
|
|
||||||
// Werte werden mit escapeHtml() gesichert, bevor sie ins HTML eingefügt werden.
|
|
||||||
function editContribution(contributionId, currentTitle, currentDescription) {
|
function editContribution(contributionId, currentTitle, currentDescription) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Beitrag bearbeiten',
|
title: 'Beitrag bearbeiten',
|
||||||
@@ -382,11 +372,7 @@ function editContribution(contributionId, currentTitle, currentDescription) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// DELETE: Deletes existing Contributions
|
||||||
// Block 13: Beitrag löschen
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Zeigt eine Lösch-Bestätigung und entfernt den Beitrag dauerhaft.
|
|
||||||
function deleteContribution(contributionId) {
|
function deleteContribution(contributionId) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Beitrag löschen?',
|
title: 'Beitrag löschen?',
|
||||||
@@ -413,12 +399,11 @@ function deleteContribution(contributionId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 14: Kommentar-Status ändern
|
// Block 9: CRUD Operations for Comments
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Ändert den Status eines Kommentars (approved / rejected / pending).
|
// STATUS: Changes Comment Status
|
||||||
function changeCommentStatus(commentId, newStatus) {
|
function changeCommentStatus(commentId, newStatus) {
|
||||||
const labels = { approved: 'akzeptieren', rejected: 'ablehnen', pending: 'zurücksetzen' };
|
const labels = { approved: 'akzeptieren', rejected: 'ablehnen', pending: 'zurücksetzen' };
|
||||||
|
|
||||||
@@ -446,11 +431,7 @@ function changeCommentStatus(commentId, newStatus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// UPDATE: Edits existing Comments
|
||||||
// Block 15: Kommentar bearbeiten
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Öffnet einen Dialog zum Bearbeiten des Kommentar-Inhalts.
|
|
||||||
function editModComment(commentId, currentContent) {
|
function editModComment(commentId, currentContent) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Kommentar bearbeiten',
|
title: 'Kommentar bearbeiten',
|
||||||
@@ -485,11 +466,7 @@ function editModComment(commentId, currentContent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// DELETE: Deletes existing Comments
|
||||||
// Block 16: Kommentar löschen
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Zeigt eine Lösch-Bestätigung und entfernt den Kommentar dauerhaft.
|
|
||||||
function deleteModComment(commentId) {
|
function deleteModComment(commentId) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Kommentar löschen?',
|
title: 'Kommentar löschen?',
|
||||||
@@ -518,11 +495,10 @@ function deleteModComment(commentId) {
|
|||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// Block 17: Neuigkeit erstellen
|
// Block 10: CRUD Operations for News
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
// Öffnet einen Dialog zum Erstellen einer neuen Neuigkeit.
|
// CREATE: Submits new News Article
|
||||||
// Titel und Inhalt sind Pflichtfelder, Autor hat einen Standardwert.
|
|
||||||
function createNews() {
|
function createNews() {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Neuigkeit hinzufügen',
|
title: 'Neuigkeit hinzufügen',
|
||||||
@@ -576,11 +552,7 @@ function createNews() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// UPDATE: Edits existing News
|
||||||
// Block 18: Neuigkeit bearbeiten
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Öffnet einen Dialog zum Bearbeiten einer bestehenden Neuigkeit.
|
|
||||||
function editNews(newsId, currentTitle, currentContent, currentAuthor) {
|
function editNews(newsId, currentTitle, currentContent, currentAuthor) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Neuigkeit bearbeiten',
|
title: 'Neuigkeit bearbeiten',
|
||||||
@@ -631,13 +603,7 @@ function editNews(newsId, currentTitle, currentContent, currentAuthor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// DELETE: Deletes existing Comments
|
||||||
// Block 19: Neuigkeit löschen
|
|
||||||
// =====================================================================
|
|
||||||
|
|
||||||
// Zeigt eine Lösch-Bestätigung und entfernt die Neuigkeit dauerhaft.
|
|
||||||
// Hinweis: Im Original-Code war dieser Block fälschlicherweise mit
|
|
||||||
// "// Create News Article" kommentiert — hier korrigiert.
|
|
||||||
function deleteNews(newsId) {
|
function deleteNews(newsId) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Neuigkeit löschen?',
|
title: 'Neuigkeit löschen?',
|
||||||
|
|||||||
Reference in New Issue
Block a user