New Calendar 060220261631

This commit is contained in:
Manfred Aabye
2026-02-06 16:32:30 +01:00
committed by GitHub
parent a1c558d48a
commit 732a8767d8
26 changed files with 576 additions and 98 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

+359
View File
@@ -0,0 +1,359 @@
[
{
"date": "2026-01-01",
"events": [
{
"time": "",
"image": "calendar/NeujahrKalenderbild.jpg",
"texts": [
"Neujahr",
"01.01.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Neujahr",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-01-06",
"events": [
{
"time": "",
"image": "calendar/HDKKalenderbild.jpg",
"texts": [
"Heilige Drei K\u00f6nige",
"06.01.2026",
"Baden-W\u00fcrttemberg, Bayern, Sachsen-Anhalt"
],
"link": "https://de.wikipedia.org/wiki/Heilige_Drei_K%C3%B6nige",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-03-08",
"events": [
{
"time": "",
"image": "calendar/FrauentagKalenderbild.jpg",
"texts": [
"Internationaler Frauentag",
"08.03.2026",
"Berlin, Mecklenburg-Vorpommern"
],
"link": "https://de.wikipedia.org/wiki/Internationaler_Frauentag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-04-18",
"events": [
{
"time": "",
"image": "calendar/KarfreitagKalenderbild.jpg",
"texts": [
"Karfreitag",
"18.04.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Karfreitag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-04-20",
"events": [
{
"time": "",
"image": "calendar/OstersonntagKalenderbild.jpg",
"texts": [
"Ostersonntag",
"20.04.2026",
"Brandenburg (Einzig das Land Brandenburg behandelt den Ostersonntag explizit als gesetzlichen Feiertag.)"
],
"link": "https://de.wikipedia.org/wiki/Ostersonntag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-04-21",
"events": [
{
"time": "",
"image": "calendar/KalenderbildOstermontag.jpg",
"texts": [
"Ostermontag",
"21.04.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Ostermontag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-05-01",
"events": [
{
"time": "",
"image": "calendar/TagderArbeitKalenderbild.jpg",
"texts": [
"Tag der Arbeit",
"01.05.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Tag_der_Arbeit",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-05-08",
"events": [
{
"time": "",
"image": "calendar/WeltkriegKalenderbild.jpg",
"texts": [
"Jahrestag der Befreiung vom Nationalsozialismus und Ende des Zweiten Weltkriegs",
"08.05.2026",
"Berlin (nur 2026)"
],
"link": "https://de.wikipedia.org/wiki/Ende_des_Zweiten_Weltkriegs",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-05-29",
"events": [
{
"time": "",
"image": "calendar/KalenderbildHimmelfahrt.jpg",
"texts": [
"Christi Himmelfahrt",
"29.05.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Christi_Himmelfahrt",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-06-08",
"events": [
{
"time": "",
"image": "calendar/PfingstsonntagKalenderbild.jpg",
"texts": [
"Pfingstsonntag",
"08.06.2026",
"Brandenburg (Einzig das Land Brandenburg behandelt den Pfingstsonntag explizit als gesetzlichen Feiertag.)"
],
"link": "https://de.wikipedia.org/wiki/Pfingstsonntag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-06-09",
"events": [
{
"time": "",
"image": "calendar/PfingstmontagKalenderbild.jpg",
"texts": [
"Pfingstmontag",
"09.06.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Pfingstmontag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-06-19",
"events": [
{
"time": "",
"image": "calendar/FronleichnamKalenderbild.jpg",
"texts": [
"Fronleichnam",
"19.06.2026",
"Baden-W\u00fcrttemberg, Bayern, Hessen, Nordrhein-Westfalen, Rheinland-Pfalz, Saarland, In Sachsen nur teilweise.*, In Th\u00fcringen nur teilweise.**"
],
"link": "https://de.wikipedia.org/wiki/Fronleichnam",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-08-08",
"events": [
{
"time": "",
"image": "calendar/AugsburgerFriedenKalenderbild.jpg",
"texts": [
"Augsburger Friedensfest",
"08.08.2026",
"Nur im Stadtgebiet von Augsburg (nicht jedoch im angrenzenden Umland)"
],
"link": "https://de.wikipedia.org/wiki/Augsburger_Friedensfest",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-08-15",
"events": [
{
"time": "",
"image": "calendar/KalenderbildMariaHimmelfahrt.jpg",
"texts": [
"Mari\u00e4 Himmelfahrt",
"15.08.2026",
"Saarland, In Bayern nur teilweise.***"
],
"link": "https://de.wikipedia.org/wiki/Mari%C3%A4_Himmelfahrt",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-09-20",
"events": [
{
"time": "",
"image": "calendar/WeltkindertagKalenderbild.jpg",
"texts": [
"Weltkindertag",
"20.09.2026",
"Th\u00fcringen"
],
"link": "https://de.wikipedia.org/wiki/Weltkindertag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-10-03",
"events": [
{
"time": "",
"image": "calendar/DeutscheEinheitKalenderbild.jpg",
"texts": [
"Tag der deutschen Einheit",
"03.10.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Tag_der_deutschen_Einheit",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-10-31",
"events": [
{
"time": "",
"image": "calendar/ReformationstagKalenderbild.jpg",
"texts": [
"Reformationstag",
"31.10.2026",
"Brandenburg, Bremen, Hamburg, Mecklenburg-Vorpommern, Niedersachsen, Sachsen, Sachsen-Anhalt, Schleswig-Holstein, Th\u00fcringen"
],
"link": "https://de.wikipedia.org/wiki/Reformationstag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-11-01",
"events": [
{
"time": "",
"image": "calendar/KalenderbildAllerheiligen.jpg",
"texts": [
"Allerheiligen",
"01.11.2026",
"Baden-W\u00fcrttemberg, Bayern, Nordrhein-Westfalen, Rheinland-Pfalz, Saarland"
],
"link": "https://de.wikipedia.org/wiki/Allerheiligen",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-11-19",
"events": [
{
"time": "",
"image": "calendar/BussBettagKalenderbild.jpg",
"texts": [
"Bu\u00df- und Bettag",
"19.11.2026",
"Sachsen"
],
"link": "https://de.wikipedia.org/wiki/Bu%C3%9F-_und_Bettag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-12-25",
"events": [
{
"time": "",
"image": "calendar/1WeihnachtsfeiertagKalenderbild.jpg",
"texts": [
"1. Weihnachtsfeiertag",
"25.12.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Weihnachtsfeiertag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
},
{
"date": "2026-12-26",
"events": [
{
"time": "",
"image": "calendar/2WeihnachtsfeiertagKalenderbild.jpg",
"texts": [
"2. Weihnachtsfeiertag",
"26.12.2026",
"bundesweit"
],
"link": "https://de.wikipedia.org/wiki/Weihnachtsfeiertag",
"color": "#FFCC99",
"txtcolor": "#FFFFFF"
}
]
}
]
Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

+106 -44
View File
@@ -77,7 +77,7 @@
/* Event-Container am Ende der Zelle */
.event {
font-size: 0.8em;
background-color: rgba(255, 255, 255, 0.7); /* Transparenter Hintergrund */
background-color: rgba(0, 0, 0, 0.7); /* Weniger Transparenz, schwarzer Hintergrund */
padding: 2px 4px;
border-radius: 3px;
margin-top: auto; /* Nach unten schieben */
@@ -85,6 +85,11 @@
z-index: 1;
}
/* Event-Box mit Bild als Hintergrund */
.event.has-bgimg .event-content {
background: rgba(0, 0, 0, 0.7); /* Weniger Transparenz, schwarzer Hintergrund */
}
/* Event-Textzeile */
.event-text {
margin: 2px 0;
@@ -120,6 +125,34 @@
display: block;
margin-top: auto;
}
/* Event-Bild als Hintergrundbild der Zelle */
.event.has-bgimg {
background-size: cover !important;
background-position: center !important;
min-height: 120px;
min-width: 120px;
position: relative;
}
/* .event.has-bgimg .event-content {
position: relative;
z-index: 2;
background: rgba(0, 0, 0, 0.5);
border-radius: 6px;
padding: 4px;
margin: 0;
} */
.event.has-bgimg a.event-img-link, .event.has-bgimg img.event-img {
display: none !important;
}
/* Abstand zwischen Tageseinträgen (Events) */
.events-container .event {
margin-bottom: 4px;
}
.events-container .event:last-child {
margin-bottom: 0;
}
</style>
</head>
<body>
@@ -214,57 +247,86 @@
for (let day = 1; day <= daysInMonth; day++) {
const dateCell = document.createElement('div');
dateCell.classList.add('date');
// Tag-Nummer hinzufügen
const dateNumber = document.createElement('div');
dateNumber.classList.add('date-number');
dateNumber.textContent = day;
dateCell.appendChild(dateNumber);
// Event für diesen Tag suchen
const event = events.find(e =>
new Date(e.date).toDateString() === new Date(year, month, day).toDateString()
);
// Wenn ein Event existiert, Details hinzufügen
if (event) {
// Hintergrundbild falls vorhanden
if (event.image) {
const imageContainer = document.createElement('div');
imageContainer.classList.add('image-container');
const img = document.createElement('img');
img.src = event.image;
imageContainer.appendChild(img);
dateCell.appendChild(imageContainer);
}
// Hintergrundfarbe falls definiert
if (event.color) {
dateCell.style.backgroundColor = event.color;
}
// Textfarbe falls definiert
if (event.txtcolor) {
dateCell.style.color = event.txtcolor;
}
// Event-Texte hinzufügen (erste Zeile fett)
event.texts.forEach((text, index) => {
const eventTextElement = document.createElement('div');
eventTextElement.classList.add('event-text');
if (index === 0) {
eventTextElement.classList.add('event-text-bold');
// Alle Events für diesen Tag suchen (verschachteltes Format)
const dateStr = new Date(year, month, day).toISOString().slice(0, 10);
const dayEntry = events.find(e => e.date === dateStr);
if (dayEntry && Array.isArray(dayEntry.events)) {
// Container für alle Events dieses Tages
const eventsContainer = document.createElement('div');
eventsContainer.classList.add('events-container');
dayEntry.events.sort((a, b) => (a.time || '').localeCompare(b.time || ''));
dayEntry.events.forEach(event => {
// Einzelnes Event-Element
const eventBlock = document.createElement('div');
eventBlock.classList.add('event');
// Bild als Hintergrund, falls vorhanden
if (event.image) {
eventBlock.classList.add('has-bgimg');
eventBlock.style.backgroundImage = `url('${event.image}')`;
}
eventTextElement.textContent = text;
dateCell.appendChild(eventTextElement);
// Container für Event-Inhalt (Text, Uhrzeit, Link)
const eventContent = document.createElement('div');
eventContent.classList.add('event-content');
// Uhrzeit
if (event.time) {
const timeElement = document.createElement('span');
timeElement.classList.add('event-text', 'event-time');
timeElement.style.fontWeight = 'bold';
timeElement.textContent = event.time + ' ';
eventContent.appendChild(timeElement);
}
// Event-Texte (erste Zeile fett)
if (event.texts) {
event.texts.forEach((text, index) => {
const eventTextElement = document.createElement('span');
eventTextElement.classList.add('event-text');
if (index === 0) eventTextElement.classList.add('event-text-bold');
eventTextElement.textContent = text + ' ';
eventContent.appendChild(eventTextElement);
});
}
// Link
if (event.link) {
const lastWord = event.link.split('/').pop();
const linkElement = document.createElement('a');
linkElement.href = event.link;
linkElement.target = '_blank';
linkElement.classList.add('event-link');
linkElement.textContent = lastWord;
eventContent.appendChild(linkElement);
}
// Bild als Link (nur für Klick, nicht sichtbar, aber für Originalbild im neuen Tab)
if (event.image) {
const link = document.createElement('a');
link.href = event.image;
link.target = '_blank';
link.rel = 'noopener noreferrer';
link.classList.add('event-img-link');
// Unsichtbares Bild für Accessibility (optional)
const img = document.createElement('img');
img.src = event.image;
img.classList.add('event-img');
img.alt = 'Event Bild';
img.style.width = '1px';
img.style.height = '1px';
img.style.opacity = '0';
link.appendChild(img);
eventContent.appendChild(link);
}
// Farben (optional)
if (event.color) eventBlock.style.backgroundColor = event.color;
if (event.txtcolor) eventBlock.style.color = event.txtcolor;
eventBlock.appendChild(eventContent);
eventsContainer.appendChild(eventBlock);
});
// Event-Link hinzufügen (letzter Teil der URL als Text)
const eventElement = document.createElement('div');
eventElement.classList.add('event');
const lastWord = event.link.split('/').pop(); // Letzten URL-Teil extrahieren
eventElement.innerHTML = `<a href="${event.link}" target="_blank" class="event-link">${lastWord}</a>`;
dateCell.appendChild(eventElement);
dateCell.appendChild(eventsContainer);
}
// Fertige Zelle zum Kalender hinzufügen
+88 -43
View File
@@ -1,4 +1,3 @@
<?php
// Passwortschutz und Session-Start Datei: eventedit.php
// Dieser Bereich schützt den Event-Editor mit einem Passwort und startet die Session.
@@ -66,16 +65,25 @@ if (!isset($_SESSION['authenticated'])) {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
$events = json_decode($_POST['events'], true);
$eventsByDate = json_decode($_POST['events'], true);
$filename = $_POST['filename'] ?? 'events.json';
$filename = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', $filename); // Sicherheit: nur erlaubte Zeichen
$filepath = 'calendar/' . $filename;
$backupFilename = $filename . '_' . date('Y-m-d_H-i-s') . '.bak.json';
// Events nach Datum sortieren (aufsteigend)
usort($events, function($a, $b) {
// EventsByDate nach Datum sortieren (aufsteigend)
usort($eventsByDate, function($a, $b) {
return strcmp($a['date'], $b['date']);
});
// Innerhalb jedes Tages die Events nach Zeit sortieren
foreach ($eventsByDate as &$day) {
if (isset($day['events']) && is_array($day['events'])) {
usort($day['events'], function($a, $b) {
return strcmp($a['time'] ?? '', $b['time'] ?? '');
});
}
}
unset($day);
// Datei anlegen, falls sie nicht existiert
if (!file_exists($filepath)) {
@@ -86,7 +94,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
echo "<script>alert('Events erfolgreich gespeichert!');</script>";
}
// Events speichern
if (file_put_contents($filepath, json_encode($events, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) === false) {
if (file_put_contents($filepath, json_encode($eventsByDate, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) === false) {
echo "<script>alert('Fehler beim Speichern der Datei!');</script>";
}
}
@@ -121,6 +129,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
<label for="event-date">Datum:</label>
<input type="date" id="event-date" />
</div>
<div class="input-group">
<label for="event-time">Uhrzeit (z.B. 18:00):</label>
<input type="time" id="event-time" />
</div>
<div class="input-group">
<label for="event-image">Bild URL:</label>
<input type="text" id="event-image" />
@@ -159,18 +171,40 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
</div>
<script>
// JavaScript: Event-Verwaltung und UI-Funktionen
// events-Array hält alle geladenen und hinzugefügten Events
let events = [];
// JavaScript: Event-Verwaltung und UI-Funktionen für verschachtelte Events
// eventsByDate ist ein Array von {date, events: [ ... ]}
let eventsByDate = [];
// Events aus der JSON-Datei laden und anzeigen (Dateiname wählbar)
async function fetchEvents() {
const filename = document.getElementById('event-filename').value || 'events.json';
try {
const response = await fetch('calendar/' + filename);
events = await response.json();
const data = await response.json();
// Prüfen, ob verschachteltes Format (date, events)
if (Array.isArray(data) && data.length > 0 && data[0].events) {
eventsByDate = data;
} else {
// Migration: Falls altes Format, umwandeln
eventsByDate = [];
data.forEach(ev => {
let found = eventsByDate.find(e => e.date === ev.date);
if (!found) {
found = { date: ev.date, events: [] };
eventsByDate.push(found);
}
found.events.push({
time: ev.time || '',
image: ev.image,
texts: ev.texts,
link: ev.link,
color: ev.color,
txtcolor: ev.txtcolor
});
});
}
} catch (e) {
events = [];
eventsByDate = [];
}
displayEvents();
}
@@ -179,44 +213,56 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
function displayEvents() {
const eventList = document.getElementById('event-list');
eventList.innerHTML = '';
events.forEach((event, index) => {
const eventItem = document.createElement('div');
eventItem.classList.add('event-item');
eventItem.innerHTML = `
<h3>${event.date}</h3>
<p><strong>Bild URL:</strong> ${event.image}</p>
<p><strong>Texte:</strong> ${event.texts.join(', ')}</p>
<p><strong>Link:</strong> <a href="${event.link}" target="_blank">${event.link}</a></p>
<p><strong>Hintergrundfarbe:</strong> <span style="background-color:${event.color}; padding: 2px 5px;">${event.color}</span></p>
<p><strong>Schriftfarbe:</strong> <span style="background-color:${event.txtcolor}; padding: 2px 5px;">${event.txtcolor}</span></p>
<button onclick="deleteEvent(${index})">Löschen</button>
`;
eventList.appendChild(eventItem);
eventsByDate.sort((a, b) => a.date.localeCompare(b.date));
eventsByDate.forEach((day, dayIdx) => {
const dayDiv = document.createElement('div');
dayDiv.classList.add('event-item');
let html = `<h3>${day.date}</h3>`;
day.events.sort((a, b) => (a.time || '').localeCompare(b.time || ''));
day.events.forEach((ev, evIdx) => {
html += `<div style="margin-left:1em; border-left:2px solid #ccc; padding-left:0.5em; margin-bottom:0.5em;">
<strong>Zeit:</strong> ${ev.time || ''}<br>
<strong>Bild URL:</strong> ${ev.image}<br>
<strong>Texte:</strong> ${(ev.texts||[]).join(', ')}<br>
<strong>Link:</strong> <a href="${ev.link}" target="_blank">${ev.link}</a><br>
<strong>Hintergrundfarbe:</strong> <span style="background-color:${ev.color}; padding: 2px 5px;">${ev.color}</span><br>
<strong>Schriftfarbe:</strong> <span style="background-color:${ev.txtcolor}; padding: 2px 5px;">${ev.txtcolor}</span><br>
<button onclick="deleteEvent(${dayIdx},${evIdx})">Löschen</button>
</div>`;
});
dayDiv.innerHTML = html;
eventList.appendChild(dayDiv);
});
}
// Neues Event aus den Eingabefeldern hinzufügen
function addEvent() {
const date = document.getElementById('event-date').value;
const time = document.getElementById('event-time').value;
const image = document.getElementById('event-image').value;
const texts = document.getElementById('event-texts').value.split(',');
const texts = document.getElementById('event-texts').value.split(',').map(t => t.trim()).filter(Boolean);
const link = document.getElementById('event-link').value;
const color = document.getElementById('event-color').value;
const txtcolor = document.getElementById('event-txtcolor').value;
if (date && texts.length > 0 && link) {
// Prüfen, ob ein Event mit dem gleichen Datum existiert
const index = events.findIndex(event => event.date === date);
const newEvent = { date, image, texts, link, color, txtcolor };
if (index !== -1) {
// Event ersetzen
events[index] = newEvent;
} else {
// Neues Event anhängen
events.push(newEvent);
let day = eventsByDate.find(e => e.date === date);
if (!day) {
day = { date, events: [] };
eventsByDate.push(day);
}
// Nach Datum sortieren (aufsteigend)
events.sort((a, b) => a.date.localeCompare(b.date));
// Prüfen, ob Event mit gleicher Zeit existiert
const idx = day.events.findIndex(ev => ev.time === time);
const newEvent = { time, image, texts, link, color, txtcolor };
if (idx !== -1) {
day.events[idx] = newEvent;
} else {
day.events.push(newEvent);
}
// Nach Zeit sortieren
day.events.sort((a, b) => (a.time || '').localeCompare(b.time || ''));
// Nach Datum sortieren
eventsByDate.sort((a, b) => a.date.localeCompare(b.date));
displayEvents();
} else {
alert('Bitte alle Felder ausfüllen.');
@@ -224,8 +270,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
}
// Event aus der Liste löschen
function deleteEvent(index) {
events.splice(index, 1);
function deleteEvent(dayIdx, evIdx) {
eventsByDate[dayIdx].events.splice(evIdx, 1);
if (eventsByDate[dayIdx].events.length === 0) {
eventsByDate.splice(dayIdx, 1);
}
displayEvents();
}
@@ -234,12 +283,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
return JSON.stringify(json, null, 2);
}
// Events als Datei herunterladen
// Events als Datei herunterladen (Dateiname wählbar)
function downloadEvents() {
const filename = document.getElementById('event-filename').value || 'events.json';
const formattedEvents = formatJSON(events);
const formattedEvents = formatJSON(eventsByDate);
const blob = new Blob([formattedEvents], { type: 'application/json' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
@@ -247,12 +294,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['events'])) {
link.click();
}
// Events an den Server senden und speichern (optional)
// Events an den Server senden und speichern (Dateiname wählbar)
async function saveEvents() {
const filename = document.getElementById('event-filename').value || 'events.json';
const formattedEvents = formatJSON(events);
const formattedEvents = formatJSON(eventsByDate);
const formData = new FormData();
formData.append('events', formattedEvents);
formData.append('filename', filename);
+23 -11
View File
@@ -150,18 +150,30 @@ include_once "include/config.php";
$output .= '<h2>' . htmlspecialchars($xml->channel->title) . '</h2>';
//$output .= '<p><a href="' . htmlspecialchars($xml->channel->link) . '">Feed öffnen</a></p>';
// Nur den neuesten Eintrag anzeigen
$entry = $xml->channel->item[0];
$date = date('d.m.Y', strtotime($entry->pubDate));
$title = htmlspecialchars($entry->title);
$description = html_entity_decode($entry->description);
if (isset($entry->encoded)) {
$description .= '<br>' . html_entity_decode($entry->encoded);
} else if (isset($entry->content)) {
$description .= '<br>' . html_entity_decode($entry->content);
// Alle Einträge des Feeds anzeigen
foreach ($xml->channel->item as $entry) {
$date = date('d.m.Y', strtotime($entry->pubDate));
$title = htmlspecialchars($entry->title);
$description = html_entity_decode($entry->description);
$time = '';
if (preg_match('/\d{2}:\d{2}/', $entry->pubDate, $matches)) {
$time = $matches[0];
}
$image = '';
if (isset($entry->enclosure) && $entry->enclosure['url']) {
$image = htmlspecialchars($entry->enclosure['url']);
}
if (isset($entry->encoded)) {
$description .= '<br>' . html_entity_decode($entry->encoded);
} else if (isset($entry->content)) {
$description .= '<br>' . html_entity_decode($entry->content);
}
$output .= '<p><a href="'.htmlspecialchars($entry->link).'" title="'.$date.'">'. $title .'</a> <small>(' . $date . ($time ? ' ' . $time : '') . ')</small></p>';
if ($image) {
$output .= '<div><img src="'.$image.'" alt="Event-Bild" style="max-width:120px;max-height:120px;" /></div>';
}
$output .= '<div>'. $description .'</div>';
}
$output .= '<p><a href="'.htmlspecialchars($entry->link).'" title="'.$date.'">'. $title .'</a> <small>('.$date.')</small></p>';
$output .= '<div>'. $description .'</div>';
}
echo $output;