953 lines
40 KiB
PHP
953 lines
40 KiB
PHP
<?php
|
||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
|
||
require_once __DIR__ . '/news_cleanup.php';
|
||
|
||
// Zugriff nur für Benutzer mit Rolle "Allgemein"
|
||
if (!isset($groups["Allgemein"]) || $groups["Allgemein"] != 1) {
|
||
header("Location: /intranet_repo/projects/intranet/index.php");
|
||
exit();
|
||
}
|
||
|
||
// Abgelaufene Aushänge entfernen
|
||
cleanupExpiredNews();
|
||
|
||
|
||
$meldung_gottesdienst = '';
|
||
$meldung_ansage = '';
|
||
$meldung_dateien = '';
|
||
|
||
// Funktion, um den Dokumentnamen zu bereinigen
|
||
function sanitizeFileName($fileName) {
|
||
// Entferne Leerzeichen und ersetze unzulässige Zeichen durch einen Unterstrich
|
||
return preg_replace('/[^A-Za-z0-9_\-]/', '_', str_replace(' ', '_', $fileName));
|
||
}
|
||
|
||
/** PDF -> Text per pdftotext (Poppler) */
|
||
function pdfToText($pdfFullPath) {
|
||
$bin = trim(shell_exec('command -v pdftotext'));
|
||
if ($bin === '') { $_SESSION['meldung_gottesdienst'] = "Fehler: 'pdftotext' nicht gefunden."; return false; }
|
||
$tmpTxt = tempnam(sys_get_temp_dir(), 'lg_').'.txt';
|
||
$cmd = escapeshellcmd($bin).' -layout -enc UTF-8 '.escapeshellarg($pdfFullPath).' '.escapeshellarg($tmpTxt).' 2>&1';
|
||
exec($cmd, $out, $ret);
|
||
if ($ret !== 0) { @unlink($tmpTxt); $_SESSION['meldung_gottesdienst'] = "Fehler beim PDF-Import:\n".htmlspecialchars(implode("\n", $out)); return false; }
|
||
$txt = file_get_contents($tmpTxt);
|
||
@unlink($tmpTxt);
|
||
return $txt;
|
||
}
|
||
|
||
function parseLeitgedanken($textRaw) {
|
||
// Zeilenenden normalisieren + Silbentrennungen (…-\n…) zusammenziehen
|
||
$text = preg_replace("/\r\n?/", "\n", $textRaw);
|
||
$text = preg_replace("/(?<=\p{L})-\n(?=\p{L})/u", "", $text);
|
||
$lines = explode("\n", $text);
|
||
|
||
// Abschnittsüberschriften mit Datum am Zeilenende
|
||
$dateHeaderRegex = '/(?P<prefix>.*?)(?P<d1>\d{1,2})(?:\.\s*\/\s*(?P<d2>\d{1,2}))?\.(?P<m>\d{1,2})\.(?P<y>\d{4})\s*$/u';
|
||
|
||
// Whitelist der (deutschen) Buchkürzel
|
||
$BOOKS = '(?:Mo|Sam|Kön|Chr|Dan|Ps|Spr|Pred|Hld|Hi|Jes|Jer|Klgl|Hes|Ez|Hos|Joel|Am|Ob|Mi|Nah|Hab|Zef|Hag|Sach|Mal|Rut|Ri|Jos|Esra|Neh|Est|'
|
||
. 'Mt|Mk|Lk|Joh|Apg|Röm|Kor|Gal|Eph|Phil|Kol|Thess|Tim|Tit|Phlm|Hebr|Jak|Petr|Joh|Jud|Offb)';
|
||
|
||
// Referenz am Zeilenende
|
||
$refRegex = '/(?P<ref>(?:[1-3]\.?\s*)?' . $BOOKS . '\s*\d{1,3}\s*,\s*\d{1,3}(?:[–\-]\d{1,3}(?:[a-z])?|(?:\.\d{1,3})+(?:[a-z])?|[a-z])?)\s*$/u';
|
||
|
||
// Abschnittsgrenzen sammeln
|
||
$sections = [];
|
||
for ($i = 0; $i < count($lines); $i++) {
|
||
if (preg_match($dateHeaderRegex, $lines[$i], $m)) {
|
||
$d = str_pad((int)$m['d1'], 2, '0', STR_PAD_LEFT);
|
||
$mn = str_pad((int)$m['m'], 2, '0', STR_PAD_LEFT);
|
||
$y = (int)$m['y'];
|
||
$sections[] = ['start'=>$i, 'date'=>sprintf('%04d-%02d-%02d',$y,$mn,$d)];
|
||
}
|
||
}
|
||
if (empty($sections)) return [];
|
||
$sections[array_key_last($sections)]['end'] = count($lines);
|
||
for ($s = 0; $s < count($sections)-1; $s++) { $sections[$s]['end'] = $sections[$s+1]['start']; }
|
||
|
||
$out = [];
|
||
foreach ($sections as $sec) {
|
||
for ($i = $sec['start']; $i < $sec['end']; $i++) {
|
||
$line = rtrim($lines[$i]); if ($line === '') continue;
|
||
if (preg_match($refRegex, $line, $mRef)) {
|
||
$beforeRef = trim(preg_replace($refRegex, '', $line));
|
||
$blkPrev = [];
|
||
for ($k = $i - 1; $k >= $sec['start'] && $k >= $i - 15; $k--) {
|
||
$pl = rtrim($lines[$k]); if ($pl === '') break;
|
||
if (preg_match($refRegex, $pl)) break;
|
||
$blkPrev[] = $pl;
|
||
}
|
||
$block = array_reverse($blkPrev);
|
||
if ($beforeRef !== '') $block[] = $beforeRef;
|
||
$vers = trim(preg_replace('/\s+/', ' ', implode(' ', $block)));
|
||
if ($vers !== '') {
|
||
$out[] = ['bibeldatum'=>$sec['date'], 'bibelwort'=>trim($mRef['ref']), 'bibelvers'=>$vers];
|
||
break; // pro Abschnitt nur das erste Bibelwort
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// Dubletten raus
|
||
$uniq=[]; $final=[];
|
||
foreach ($out as $e) { $key=$e['bibeldatum'].'|'.$e['bibelwort']; if (!isset($uniq[$key])) { $uniq[$key]=1; $final[]=$e; } }
|
||
return $final;
|
||
}
|
||
|
||
// Hilfsfunktion, um PDF in PNG umzuwandeln
|
||
function convertPDFtoPNG($pdfFilePath, $outputDirectory, $baseFileName) {
|
||
if (!is_file($pdfFilePath)) {
|
||
error_log('PDF-Datei nicht gefunden: ' . $pdfFilePath);
|
||
return false;
|
||
}
|
||
|
||
$outputFilePath = $outputDirectory . '/' . $baseFileName . '_page_%d.png';
|
||
|
||
$command =
|
||
'gs -dSAFER -dBATCH -dNOPAUSE '
|
||
. '-sDEVICE=png16m -r300 '
|
||
. '-sOutputFile=' . escapeshellarg($outputFilePath) . ' '
|
||
. escapeshellarg($pdfFilePath)
|
||
. ' 2>&1';
|
||
|
||
$output = [];
|
||
$returnCode = 0;
|
||
exec($command, $output, $returnCode);
|
||
|
||
if ($returnCode !== 0) {
|
||
error_log(
|
||
'Ghostscript-Konvertierung fehlgeschlagen: '
|
||
. implode("\n", $output)
|
||
);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// LG-PDF importieren -> direkt alles in DB
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['leitgedanken_pdf'])) {
|
||
if ($_FILES['leitgedanken_pdf']['error'] !== UPLOAD_ERR_OK) {
|
||
$_SESSION['meldung_gottesdienst'] = 'Fehler beim Upload der Leitgedanken-PDF.';
|
||
} else {
|
||
$ext = strtolower(pathinfo($_FILES['leitgedanken_pdf']['name'], PATHINFO_EXTENSION));
|
||
if ($ext !== 'pdf') {
|
||
$_SESSION['meldung_gottesdienst'] = 'Nur PDF-Dateien sind für den Import erlaubt.';
|
||
} else {
|
||
$txt = pdfToText($_FILES['leitgedanken_pdf']['tmp_name']);
|
||
if ($txt !== false) {
|
||
$items = parseLeitgedanken($txt);
|
||
|
||
// vorbereitete Statements
|
||
$stmtExists = $pdo->prepare("SELECT 1 FROM gottesdienst WHERE bibeldatum = ? AND bibelwort = ? LIMIT 1");
|
||
$stmtInsert = $pdo->prepare("INSERT INTO gottesdienst (bibelwort, bibelvers, bibeldatum) VALUES (?, ?, ?)");
|
||
|
||
$ok=0; $dup=0;
|
||
foreach ($items as $it) {
|
||
$stmtExists->execute([$it['bibeldatum'], $it['bibelwort']]);
|
||
if ($stmtExists->fetchColumn() !== false) { $dup++; continue; }
|
||
|
||
$stmtInsert->execute([$it['bibelwort'], $it['bibelvers'], $it['bibeldatum']]); $ok++;
|
||
}
|
||
|
||
if ($ok > 0) {
|
||
$_SESSION['meldung_gottesdienst'] = "Leitgedanken importiert: $ok Einträge angelegt".($dup?(", $dup dupliziert übersprungen"):"").".";
|
||
} else {
|
||
$_SESSION['meldung_gottesdienst'] = "Keine neuen Einträge erkannt.".($dup?(" ($dup Duplikate)"):"");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
header("Location: ".$_SERVER['PHP_SELF']);
|
||
exit();
|
||
}
|
||
|
||
// Aushang manuell löschen
|
||
if (
|
||
$_SERVER['REQUEST_METHOD'] === 'POST' &&
|
||
isset($_POST['delete_file_base'])
|
||
) {
|
||
$fileBase = (string) $_POST['delete_file_base'];
|
||
|
||
if (!isValidNewsFileBase($fileBase)) {
|
||
$_SESSION['meldung_dateien'] = 'Ungültiger Dateiname.';
|
||
} elseif (deleteNewsFiles($fileBase)) {
|
||
$_SESSION['meldung_dateien'] = 'Aushang wurde vollständig gelöscht.';
|
||
} else {
|
||
$_SESSION['meldung_dateien'] =
|
||
'Aushang konnte nicht vollständig gelöscht werden. Bitte Logs prüfen.';
|
||
}
|
||
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
// Neuen Aushang hochladen und direkt in PNG-Seiten umwandeln
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['fileToUpload'])) {
|
||
$date = (string) ($_POST['date'] ?? '');
|
||
$dateObject = DateTimeImmutable::createFromFormat('!Y-m-d', $date);
|
||
|
||
if ($dateObject === false || $dateObject->format('Y-m-d') !== $date) {
|
||
$_SESSION['meldung_dateien'] = 'Ungültiges Verfallsdatum.';
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
$name = trim(sanitizeFileName((string) ($_POST['name'] ?? '')), '_-');
|
||
|
||
if ($name === '') {
|
||
$_SESSION['meldung_dateien'] = 'Bitte einen gültigen Titel eingeben.';
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
if (
|
||
$_FILES['fileToUpload']['error'] !== UPLOAD_ERR_OK ||
|
||
strtolower(pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION)) !== 'pdf'
|
||
) {
|
||
$_SESSION['meldung_dateien'] = 'Bitte eine gültige PDF-Datei hochladen.';
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
$baseFileName = $date . '-' . $name;
|
||
|
||
if (!is_dir(NEWS_PNG_DIRECTORY) && !mkdir(NEWS_PNG_DIRECTORY, 0755, true)) {
|
||
$_SESSION['meldung_dateien'] = 'Das Aushang-Verzeichnis konnte nicht angelegt werden.';
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
if (!convertPDFtoPNG(
|
||
$_FILES['fileToUpload']['tmp_name'],
|
||
NEWS_PNG_DIRECTORY,
|
||
$baseFileName
|
||
)) {
|
||
deleteNewsFiles($baseFileName);
|
||
$_SESSION['meldung_dateien'] = 'Fehler bei der Umwandlung der PDF.';
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
$_SESSION['meldung_dateien'] = 'Aushang wurde erfolgreich hochgeladen.';
|
||
header('Location: insert.php#dateien');
|
||
exit();
|
||
}
|
||
|
||
|
||
// Löschen eines Gottesdienstes
|
||
if (isset($_POST['delete_id'])) {
|
||
$delete_id = $_POST['delete_id'];
|
||
|
||
// Löschanfrage vorbereiten
|
||
try {
|
||
$sql_delete = "DELETE FROM gottesdienst WHERE id = ?";
|
||
$stmt = $pdo->prepare($sql_delete);
|
||
$stmt->execute([$delete_id]);
|
||
$_SESSION['meldung_gottesdienst'] = "Eintrag erfolgreich gelöscht!";
|
||
header("Location: " . $_SERVER['PHP_SELF']); // Seite neu laden
|
||
exit(); // Skript nach dem Redirect beenden
|
||
} catch (Exception $e) {
|
||
$_SESSION['meldung_gottesdienst'] = "Fehler beim Löschen: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
// Gottesdienst anlegen (ohne EL)
|
||
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['bibelwort']) && isset($_POST['bibelvers']) && isset($_POST['bibeldatum'])) {
|
||
$bibelwort = $_POST['bibelwort'];
|
||
$bibelvers = $_POST['bibelvers'];
|
||
$bibeldatum = $_POST['bibeldatum'];
|
||
|
||
try {
|
||
$sql = "INSERT INTO gottesdienst (bibelwort, bibelvers, bibeldatum) VALUES (?, ?, ?)";
|
||
$stmt = $pdo->prepare($sql);
|
||
$stmt->execute([$bibelwort, $bibelvers, $bibeldatum]);
|
||
setlocale(LC_TIME, 'de_DE.UTF-8');
|
||
$formattedDate = strftime('%d. %B', strtotime($bibeldatum));
|
||
$_SESSION['meldung_gottesdienst'] = "Gottesdienst am " . $formattedDate . " erfolgreich angelegt!";
|
||
header("Location: " . $_SERVER['PHP_SELF']); exit();
|
||
} catch (Exception $e) {
|
||
$_SESSION['meldung_gottesdienst'] = "Fehler beim Einfügen: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
|
||
// Ansage anlegen
|
||
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['ansage_datum_von'])) {
|
||
$ansage_datum_von = $_POST['ansage_datum_von'];
|
||
$ansage_datum_bis = !empty($_POST['ansage_datum_bis']) ? $_POST['ansage_datum_bis'] : NULL;
|
||
$ansage_uhrzeit = !empty($_POST['ansage_uhrzeit']) ? $_POST['ansage_uhrzeit'] : NULL;
|
||
$ansage_ort = $_POST['ansage_ort'];
|
||
$ansage_titel = $_POST['ansage_titel'];
|
||
$ansage_untertitel = $_POST['ansage_untertitel'];
|
||
|
||
try {
|
||
// SQL-Anweisung
|
||
$sql = "INSERT INTO ansagen (ansage_datum_von, ansage_datum_bis, ansage_uhrzeit, ansage_ort, ansage_titel, ansage_untertitel)
|
||
VALUES (?, ?, ?, ?, ?, ?)";
|
||
|
||
// Statement vorbereiten
|
||
$stmt = $pdo->prepare($sql);
|
||
|
||
// Statement ausführen
|
||
$stmt->execute([$ansage_datum_von, $ansage_datum_bis, $ansage_uhrzeit, $ansage_ort, $ansage_titel, $ansage_untertitel]);
|
||
setlocale(LC_TIME, 'de_DE.UTF-8');
|
||
$formattedDate = strftime('%d. %B', strtotime($ansage_datum_von));
|
||
$_SESSION['meldung_ansage'] = $ansage_titel . " am " . $formattedDate . " erfolgreich angelegt!";
|
||
header("Location: " . $_SERVER['PHP_SELF']);
|
||
exit();
|
||
} catch (Exception $e) {
|
||
$_SESSION['meldung_ansage'] = "Fehler beim Einfügen: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
// Löschen einer Ansage
|
||
if (isset($_POST['delete_ansage_id'])) {
|
||
$delete_ansage_id = $_POST['delete_ansage_id'];
|
||
|
||
// Löschanfrage vorbereiten
|
||
try {
|
||
$sql_delete_ansage = "DELETE FROM ansagen WHERE id = ?";
|
||
$stmt = $pdo->prepare($sql_delete_ansage);
|
||
$stmt->execute([$delete_ansage_id]);
|
||
$_SESSION['meldung_ansage'] = "Ansage erfolgreich gelöscht!";
|
||
header("Location: " . $_SERVER['PHP_SELF']);
|
||
exit();
|
||
} catch (Exception $e) {
|
||
$_SESSION['meldung_ansage'] = "Fehler beim Löschen: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
// Meldungen aus der Session übernehmen
|
||
if (isset($_SESSION['meldung_gottesdienst'])) {
|
||
$meldung_gottesdienst = $_SESSION['meldung_gottesdienst'];
|
||
unset($_SESSION['meldung_gottesdienst']);
|
||
}
|
||
|
||
if (isset($_SESSION['meldung_ansage'])) {
|
||
$meldung_ansage = $_SESSION['meldung_ansage'];
|
||
unset($_SESSION['meldung_ansage']);
|
||
}
|
||
|
||
if (isset($_SESSION['meldung_dateien'])) {
|
||
$meldung_dateien = $_SESSION['meldung_dateien'];
|
||
unset($_SESSION['meldung_dateien']);
|
||
}
|
||
|
||
$heute = date('Y-m-d');
|
||
|
||
// Gottesdienste aus der Datenbank abrufen
|
||
$sql_fetch_gottesdienste = "SELECT id, bibelwort, bibelvers, TO_CHAR(bibeldatum, 'DD.MM.YYYY') AS datum FROM gottesdienst WHERE bibeldatum >= ? ORDER BY bibeldatum ASC";
|
||
$stmt = $pdo->prepare($sql_fetch_gottesdienste);
|
||
$stmt->execute([$heute]);
|
||
$planung_gottesdienste = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
|
||
// Ansagen aus der Datenbank abrufen
|
||
$sql_fetch_ansagen = "SELECT id, ansage_untertitel, ansage_titel, ansage_ort, ansage_uhrzeit, TO_CHAR(ansage_datum_von, 'DD.MM.YYYY') AS datum_von, TO_CHAR(ansage_datum_bis, 'DD.MM.YYYY') AS datum_bis FROM ansagen WHERE ansage_datum_von >= ? OR ansage_datum_bis >= ? ORDER BY ansage_datum_von ASC";
|
||
$stmt = $pdo->prepare($sql_fetch_ansagen);
|
||
$stmt->execute([$heute, $heute]);
|
||
$planung_ansagen = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
|
||
// Schließe die Datenbankverbindung
|
||
$pdo = null;
|
||
?>
|
||
|
||
|
||
<!DOCTYPE html>
|
||
<html lang="de" dir="ltr">
|
||
<head>
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
|
||
<style>
|
||
/* ── Schwarzes Brett – NAK Redesign ── */
|
||
|
||
/* Page background gradient (matching Hauptmenü) */
|
||
.sb-page {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-top: calc(var(--header-height) + var(--header-title-height));
|
||
width: 100%;
|
||
min-height: calc(100vh - var(--header-height) - var(--header-title-height) - var(--footer-height));
|
||
background: linear-gradient(135deg, var(--gray-50) 0%, hsl(330, 60%, 95%) 100%);
|
||
padding: var(--space-lg) var(--space-md) var(--space-3xl);
|
||
}
|
||
|
||
/* ── Tab Navigation (uses standard content-tab-bar from nak-design.css) ── */
|
||
.sb-page > .content-tab-bar {
|
||
margin: calc(-1 * var(--space-lg)) calc(-1 * var(--space-md)) 0;
|
||
width: calc(100% + 2 * var(--space-md));
|
||
}
|
||
|
||
/* ── Tab Content ── */
|
||
.sb-tab-content {
|
||
display: none;
|
||
width: 100%;
|
||
max-width: 960px;
|
||
margin: var(--space-lg) auto 0;
|
||
animation: sbFadeIn 300ms ease;
|
||
}
|
||
.sb-tab-content.active { display: block; }
|
||
|
||
@keyframes sbFadeIn {
|
||
from { opacity: 0; transform: translateY(8px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
/* ── Cards ── */
|
||
.sb-card {
|
||
background: #ffffff;
|
||
box-shadow: var(--shadow-md);
|
||
padding: 24px 28px;
|
||
margin-bottom: var(--space-lg);
|
||
}
|
||
.sb-card-title {
|
||
font-size: 1rem;
|
||
font-weight: 600;
|
||
color: var(--gray-800);
|
||
margin: 0 0 var(--space-md) 0;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.04em;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.sb-card-title svg {
|
||
width: 20px;
|
||
height: 20px;
|
||
fill: var(--nak-raspberry);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* ── Existing entries list ── */
|
||
.sb-entry-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0;
|
||
border: 1px solid var(--gray-200);
|
||
margin-bottom: var(--space-lg);
|
||
max-height: 360px;
|
||
overflow-y: auto;
|
||
}
|
||
.sb-entry-list:empty::after {
|
||
content: 'Keine Einträge vorhanden.';
|
||
display: block;
|
||
padding: 16px;
|
||
text-align: center;
|
||
color: var(--gray-500);
|
||
font-size: var(--font-size-sm);
|
||
}
|
||
.sb-entry {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 12px 16px;
|
||
border-bottom: 1px solid var(--gray-100);
|
||
gap: 12px;
|
||
}
|
||
.sb-entry:last-child { border-bottom: none; }
|
||
.sb-entry-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
.sb-entry-date {
|
||
font-size: var(--font-size-xs);
|
||
font-weight: 600;
|
||
color: var(--nak-raspberry);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.03em;
|
||
}
|
||
.sb-entry-title {
|
||
font-size: var(--font-size-sm);
|
||
font-weight: 600;
|
||
color: var(--gray-800);
|
||
margin-top: 2px;
|
||
}
|
||
.sb-entry-subtitle {
|
||
font-size: var(--font-size-xs);
|
||
color: var(--gray-500);
|
||
font-style: italic;
|
||
margin-top: 2px;
|
||
}
|
||
.sb-entry-meta {
|
||
font-size: var(--font-size-xs);
|
||
color: var(--gray-500);
|
||
margin-top: 2px;
|
||
}
|
||
|
||
/* ── Form styles ── */
|
||
.sb-form-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: var(--space-md);
|
||
}
|
||
.sb-form-grid-single {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
.sb-form-full {
|
||
grid-column: 1 / -1;
|
||
}
|
||
.sb-field-group {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
}
|
||
.sb-label {
|
||
font-size: var(--font-size-sm);
|
||
font-weight: 500;
|
||
color: var(--gray-700);
|
||
}
|
||
.sb-field {
|
||
padding: 10px 14px;
|
||
font-size: var(--font-size-base);
|
||
font-family: var(--font-primary);
|
||
font-weight: 300;
|
||
border: 1px solid var(--gray-300);
|
||
background: var(--gray-50);
|
||
outline: none;
|
||
transition: border-color 150ms ease, box-shadow 150ms ease;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
.sb-field:focus {
|
||
border-color: var(--nak-raspberry);
|
||
box-shadow: 0 0 0 3px rgba(215, 50, 130, 0.15);
|
||
background: #ffffff;
|
||
}
|
||
|
||
/* ── Buttons ── */
|
||
.sb-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
min-height: 40px;
|
||
padding: 10px 20px;
|
||
font-size: var(--font-size-sm);
|
||
font-weight: 600;
|
||
font-family: var(--font-primary);
|
||
border: 1px solid var(--gray-300);
|
||
background: #ffffff;
|
||
color: var(--gray-700);
|
||
cursor: pointer;
|
||
transition: background 150ms ease, transform 150ms ease, box-shadow 150ms ease;
|
||
white-space: nowrap;
|
||
}
|
||
.sb-btn:hover {
|
||
background: var(--gray-100);
|
||
transform: translateY(-1px);
|
||
box-shadow: var(--shadow-sm);
|
||
}
|
||
.sb-btn-primary {
|
||
background: linear-gradient(135deg, var(--nak-raspberry), #b8296e);
|
||
border-color: var(--nak-raspberry);
|
||
color: #ffffff;
|
||
}
|
||
.sb-btn-primary:hover {
|
||
background: linear-gradient(135deg, #b8296e, #9c2260);
|
||
border-color: #b8296e;
|
||
}
|
||
.sb-btn-danger {
|
||
background: none;
|
||
border: 1px solid var(--gray-300);
|
||
color: var(--nak-red);
|
||
font-size: var(--font-size-xs);
|
||
padding: 6px 12px;
|
||
min-height: 30px;
|
||
}
|
||
.sb-btn-danger:hover {
|
||
background: hsl(0, 78%, 96%);
|
||
border-color: var(--nak-red);
|
||
}
|
||
|
||
/* ── Meldung / Alert ── */
|
||
.sb-alert {
|
||
padding: 10px 16px;
|
||
margin-bottom: var(--space-md);
|
||
font-size: var(--font-size-sm);
|
||
font-weight: 500;
|
||
background: hsl(145, 50%, 93%);
|
||
color: hsl(145, 50%, 28%);
|
||
border: 1px solid hsl(145, 50%, 85%);
|
||
}
|
||
|
||
/* ── Dateiverwaltung: Aushang Grid ── */
|
||
.sb-aushang-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||
gap: var(--space-md);
|
||
margin-bottom: var(--space-lg);
|
||
}
|
||
.sb-aushang-card {
|
||
background: var(--gray-50);
|
||
border: 1px solid var(--gray-200);
|
||
padding: 12px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 8px;
|
||
transition: box-shadow 200ms ease, transform 200ms ease;
|
||
}
|
||
.sb-aushang-card:hover {
|
||
box-shadow: var(--shadow-md);
|
||
transform: translateY(-2px);
|
||
}
|
||
.sb-aushang-card img {
|
||
width: 100%;
|
||
height: 180px;
|
||
object-fit: cover;
|
||
border: 1px solid var(--gray-200);
|
||
}
|
||
.sb-aushang-title {
|
||
font-size: var(--font-size-sm);
|
||
font-weight: 600;
|
||
color: var(--gray-800);
|
||
text-align: center;
|
||
}
|
||
.sb-aushang-meta {
|
||
font-size: var(--font-size-xs);
|
||
color: var(--gray-500);
|
||
text-align: center;
|
||
}
|
||
|
||
/* ── Loading Spinner ── */
|
||
.sb-spinner {
|
||
display: none;
|
||
width: 24px;
|
||
height: 24px;
|
||
border: 3px solid var(--gray-200);
|
||
border-top-color: var(--nak-raspberry);
|
||
border-radius: 50%;
|
||
animation: sbSpin 0.8s linear infinite;
|
||
margin: 0 auto;
|
||
}
|
||
@keyframes sbSpin { to { transform: rotate(360deg); } }
|
||
|
||
/* ── Separator ── */
|
||
.sb-divider {
|
||
border: none;
|
||
border-top: 1px solid var(--gray-200);
|
||
margin: var(--space-lg) 0;
|
||
}
|
||
|
||
/* ── Responsive ── */
|
||
@media (max-width: 768px) {
|
||
.sb-page { padding: var(--space-md) var(--space-sm); }
|
||
.sb-card { padding: 16px; }
|
||
.sb-form-grid { grid-template-columns: 1fr; }
|
||
.sb-tab { padding: 10px 8px; font-size: var(--font-size-xs); }
|
||
.sb-tab svg { width: 14px; height: 14px; }
|
||
.sb-aushang-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
|
||
}
|
||
@media (max-width: 480px) {
|
||
.sb-tabs { gap: 0; }
|
||
.sb-tab { padding: 8px 4px; font-size: 0.65rem; gap: 4px; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="theme-raspberry">
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
|
||
<div class="header_title ht_raspberry text_white" id="header_title">
|
||
<span class="header_title_text">Schwarzes Brett</span>
|
||
</div>
|
||
|
||
<div class="sb-page">
|
||
|
||
<!-- Tab Navigation -->
|
||
<div class="content-tab-bar">
|
||
<div class="content-tab-bar__item active" data-tab="gottesdienst" onclick="sbSwitchTab('gottesdienst')">Gottesdienst</div>
|
||
<div class="content-tab-bar__item" data-tab="ansagen" onclick="sbSwitchTab('ansagen')">Ansagen</div>
|
||
<div class="content-tab-bar__item" data-tab="dateien" onclick="sbSwitchTab('dateien')">Dateiverwaltung</div>
|
||
</div>
|
||
|
||
<!-- ═══════════════════════════════════════════════ -->
|
||
<!-- TAB 1: Gottesdienst -->
|
||
<!-- ═══════════════════════════════════════════════ -->
|
||
<div class="sb-tab-content active" id="tab-gottesdienst">
|
||
|
||
<!-- Meldung -->
|
||
<?php if (!empty($meldung_gottesdienst)) : ?>
|
||
<div class="sb-alert" style="margin-top:var(--space-md);"><?php echo htmlspecialchars($meldung_gottesdienst); ?></div>
|
||
<?php endif; ?>
|
||
|
||
<!-- Bisherige Planung -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z"/></svg>
|
||
Geplante Gottesdienste
|
||
</div>
|
||
<div class="sb-entry-list">
|
||
<?php if (count($planung_gottesdienste) > 0) : ?>
|
||
<?php foreach ($planung_gottesdienste as $row) : ?>
|
||
<div class="sb-entry">
|
||
<div class="sb-entry-info">
|
||
<div class="sb-entry-date"><?php echo $row['datum']; ?></div>
|
||
<div class="sb-entry-title"><?php echo htmlspecialchars($row['bibelwort']); ?></div>
|
||
<div class="sb-entry-subtitle"><?php echo htmlspecialchars($row['bibelvers']); ?></div>
|
||
</div>
|
||
<form method="POST" action="">
|
||
<input type="hidden" name="delete_id" value="<?php echo $row['id']; ?>">
|
||
<button type="submit" class="sb-btn sb-btn-danger" onclick="return confirm('Eintrag wirklich löschen?')">Löschen</button>
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Leitgedanken Import -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"/></svg>
|
||
Leitgedanken importieren
|
||
</div>
|
||
<form action="" method="post" enctype="multipart/form-data">
|
||
<div class="sb-form-grid sb-form-grid-single">
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">PDF hochladen (LG_*.pdf)</label>
|
||
<input class="sb-field" type="file" name="leitgedanken_pdf" accept=".pdf" required>
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<button type="submit" class="sb-btn sb-btn-primary">Import starten</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Neuen Gottesdienst planen -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||
Neuen Gottesdienst planen
|
||
</div>
|
||
<form method="POST" action="">
|
||
<div class="sb-form-grid">
|
||
<div class="sb-field-group sb-form-full">
|
||
<label class="sb-label">Datum des Gottesdienstes <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="date" name="bibeldatum" required>
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Bibelstelle <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="text" name="bibelwort" required placeholder="z.B. Joh 3,16">
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Bibelvers <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="text" name="bibelvers" required placeholder="Bibelvers eingeben">
|
||
</div>
|
||
<div class="sb-field-group sb-form-full" style="margin-top:var(--space-sm);">
|
||
<button type="submit" class="sb-btn sb-btn-primary">Eintragen</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ═══════════════════════════════════════════════ -->
|
||
<!-- TAB 2: Ansagen -->
|
||
<!-- ═══════════════════════════════════════════════ -->
|
||
<div class="sb-tab-content" id="tab-ansagen">
|
||
|
||
<!-- Meldung -->
|
||
<?php if (!empty($meldung_ansage)) : ?>
|
||
<div class="sb-alert" style="margin-top:var(--space-md);"><?php echo htmlspecialchars($meldung_ansage); ?></div>
|
||
<?php endif; ?>
|
||
|
||
<!-- Bisherige Ansagen -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/></svg>
|
||
Geplante Ansagen
|
||
</div>
|
||
<div class="sb-entry-list">
|
||
<?php if (count($planung_ansagen) > 0) : ?>
|
||
<?php foreach ($planung_ansagen as $row) : ?>
|
||
<div class="sb-entry">
|
||
<div class="sb-entry-info">
|
||
<div class="sb-entry-date">
|
||
<?php echo $row['datum_von']; ?>
|
||
<?php if (!empty($row['datum_bis'])): ?> – <?php echo $row['datum_bis']; ?><?php endif; ?>
|
||
</div>
|
||
<div class="sb-entry-title"><?php echo htmlspecialchars($row['ansage_titel']); ?></div>
|
||
<?php if (!empty($row['ansage_untertitel'])): ?>
|
||
<div class="sb-entry-subtitle"><?php echo htmlspecialchars($row['ansage_untertitel']); ?></div>
|
||
<?php endif; ?>
|
||
<div class="sb-entry-meta">
|
||
<?php if (!empty($row['ansage_uhrzeit'])): ?>
|
||
<?php echo date('H:i', strtotime($row['ansage_uhrzeit'])); ?> Uhr
|
||
<?php endif; ?>
|
||
<?php if (!empty($row['ansage_ort'])): ?>
|
||
· <?php echo htmlspecialchars($row['ansage_ort']); ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<form method="POST" action="">
|
||
<input type="hidden" name="delete_ansage_id" value="<?php echo $row['id']; ?>">
|
||
<button type="submit" class="sb-btn sb-btn-danger" onclick="return confirm('Ansage wirklich löschen?')">Löschen</button>
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Neue Ansage planen -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||
Neue Ansage planen
|
||
</div>
|
||
<form method="POST" action="">
|
||
<div class="sb-form-grid">
|
||
<div class="sb-field-group sb-form-full">
|
||
<label class="sb-label">Titel <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="text" name="ansage_titel" required placeholder="Titel der Ansage">
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Datum <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="date" name="ansage_datum_von" required>
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Datum bis <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
|
||
<input class="sb-field" type="date" name="ansage_datum_bis">
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Uhrzeit <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
|
||
<input class="sb-field" type="time" name="ansage_uhrzeit">
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Ort <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
|
||
<input class="sb-field" type="text" name="ansage_ort" placeholder="z.B. Gemeindesaal">
|
||
</div>
|
||
<div class="sb-field-group sb-form-full">
|
||
<label class="sb-label">Weitere Informationen <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
|
||
<input class="sb-field" type="text" name="ansage_untertitel" placeholder="Zusätzliche Hinweise">
|
||
</div>
|
||
<div class="sb-field-group sb-form-full" style="margin-top:var(--space-sm);">
|
||
<button type="submit" class="sb-btn sb-btn-primary">Eintragen</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ═══════════════════════════════════════════════ -->
|
||
<!-- TAB 3: Dateiverwaltung -->
|
||
<!-- ═══════════════════════════════════════════════ -->
|
||
<div class="sb-tab-content" id="tab-dateien">
|
||
|
||
<!-- Meldung -->
|
||
<?php if (!empty($meldung_dateien)) : ?>
|
||
<div class="sb-alert" style="margin-top:var(--space-md);"><?php echo htmlspecialchars($meldung_dateien); ?></div>
|
||
<?php endif; ?>
|
||
|
||
<!-- Aktuelle Aushänge -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/></svg>
|
||
Aktuelle Aushänge
|
||
</div>
|
||
<div class="sb-aushang-grid">
|
||
<?php
|
||
$aushangFiles = glob(NEWS_PNG_DIRECTORY . '/*_page_1.png') ?: [];
|
||
|
||
if (!$aushangFiles) {
|
||
echo '<p style="color:var(--gray-500);font-size:var(--font-size-sm);grid-column:1/-1;text-align:center;padding:var(--space-lg) 0;">Keine Aushänge vorhanden.</p>';
|
||
} else {
|
||
foreach ($aushangFiles as $file) {
|
||
$baseFileName = basename($file, '_page_1.png');
|
||
$expiryDate = substr($baseFileName, 0, 10);
|
||
$title = substr($baseFileName, 11);
|
||
$numPages = count(glob(NEWS_PNG_DIRECTORY . '/' . $baseFileName . '_page_*.png') ?: []);
|
||
$formattedExpiryDate = DateTime::createFromFormat('!Y-m-d', $expiryDate)?->format('d.m.Y') ?? $expiryDate;
|
||
$safeBase = htmlspecialchars($baseFileName, ENT_QUOTES, 'UTF-8');
|
||
|
||
echo '<div class="sb-aushang-card">';
|
||
echo '<img src="/intranet_repo/projects/contentpanel/insertion/news/png/' . rawurlencode($baseFileName) . '_page_1.png" alt="Aushang">';
|
||
echo '<div class="sb-aushang-title">' . htmlspecialchars($title) . '</div>';
|
||
echo '<div class="sb-aushang-meta">' . $numPages . ($numPages === 1 ? ' Seite' : ' Seiten') . ' · Verfällt ' . $formattedExpiryDate . '</div>';
|
||
echo '<form method="POST" action="" style="width:100%;text-align:center;">';
|
||
echo '<input type="hidden" name="delete_file_base" value="' . $safeBase . '">';
|
||
echo '<button type="submit" class="sb-btn sb-btn-danger" onclick="return confirm(\'Aushang wirklich löschen?\')">Löschen</button>';
|
||
echo '</form>';
|
||
echo '</div>';
|
||
}
|
||
}
|
||
?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Neuen Aushang hochladen -->
|
||
<div class="sb-card">
|
||
<div class="sb-card-title">
|
||
<svg viewBox="0 0 24 24"><path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"/></svg>
|
||
Neuen Aushang hochladen
|
||
</div>
|
||
<form action="insert.php" method="post" enctype="multipart/form-data" id="uploadForm">
|
||
<div class="sb-form-grid">
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Verfallsdatum <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="date" name="date" required>
|
||
</div>
|
||
<div class="sb-field-group">
|
||
<label class="sb-label">Titel des Aushangs <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="text" name="name" required placeholder="Name des Dokuments">
|
||
</div>
|
||
<div class="sb-field-group sb-form-full">
|
||
<label class="sb-label">PDF-Datei auswählen <span style="color:var(--nak-red);">*</span></label>
|
||
<input class="sb-field" type="file" name="fileToUpload" accept=".pdf" required>
|
||
</div>
|
||
<div class="sb-field-group sb-form-full" style="margin-top:var(--space-sm);">
|
||
<button type="submit" class="sb-btn sb-btn-primary" id="uploadButton">Datei hochladen</button>
|
||
<span class="sb-spinner" id="loadingSpinner"></span>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- .sb-page -->
|
||
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
|
||
|
||
<script>
|
||
function sbSwitchTab(tabName) {
|
||
// Deactivate all tabs
|
||
document.querySelectorAll('.content-tab-bar__item').forEach(function(t) { t.classList.remove('active'); });
|
||
document.querySelectorAll('.sb-tab-content').forEach(function(c) { c.classList.remove('active'); });
|
||
// Activate selected
|
||
document.querySelector('.content-tab-bar__item[data-tab="' + tabName + '"]').classList.add('active');
|
||
document.getElementById('tab-' + tabName).classList.add('active');
|
||
// Save to URL hash
|
||
history.replaceState(null, '', '#' + tabName);
|
||
}
|
||
|
||
// Restore tab from URL hash
|
||
(function() {
|
||
var hash = window.location.hash.replace('#', '');
|
||
if (hash && document.getElementById('tab-' + hash)) {
|
||
sbSwitchTab(hash);
|
||
}
|
||
})();
|
||
|
||
// Upload spinner
|
||
var uploadForm = document.getElementById('uploadForm');
|
||
if (uploadForm) {
|
||
uploadForm.addEventListener('submit', function() {
|
||
document.getElementById('uploadButton').style.display = 'none';
|
||
document.getElementById('loadingSpinner').style.display = 'inline-block';
|
||
});
|
||
}
|
||
|
||
// Auto-switch to tab with message
|
||
<?php if (!empty($meldung_dateien)) : ?>
|
||
sbSwitchTab('dateien');
|
||
<?php elseif (!empty($meldung_ansage)) : ?>
|
||
sbSwitchTab('ansagen');
|
||
<?php endif; ?>
|
||
</script>
|
||
</body>
|
||
</html>
|