New Calendar 060220261631
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 303 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 239 KiB |
|
After Width: | Height: | Size: 349 KiB |
|
After Width: | Height: | Size: 249 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 261 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 227 KiB |
|
After Width: | Height: | Size: 200 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 277 KiB |
|
After Width: | Height: | Size: 314 KiB |
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
After Width: | Height: | Size: 614 B |
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||