472 lines
24 KiB
PHP
472 lines
24 KiB
PHP
<?php
|
||
/* Name: admin_notices.php
|
||
Beschreibung: Verwaltung der Meldungen auf dem Intranet-Hauptmenü */
|
||
|
||
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
|
||
|
||
// Admin-Check
|
||
$stmt = $pdo->prepare('SELECT "Admin" FROM user_permissions WHERE user_id = ?');
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$isAdmin = $stmt->fetchColumn();
|
||
|
||
if ((int)$isAdmin !== 1) {
|
||
header("Location: {$g_httpHomePath}");
|
||
exit();
|
||
}
|
||
|
||
const NOTICE_MAX_TITLE_LENGTH = 180;
|
||
const NOTICE_MAX_MESSAGE_LENGTH = 4000;
|
||
|
||
$noticeTypes = [
|
||
'info' => 'Information',
|
||
'warning' => 'Warnung',
|
||
'success' => 'Erfolg',
|
||
'error' => 'Wichtig',
|
||
];
|
||
|
||
if (empty($_SESSION['admin_notices_csrf'])) {
|
||
$_SESSION['admin_notices_csrf'] = bin2hex(random_bytes(32));
|
||
}
|
||
$csrfToken = $_SESSION['admin_notices_csrf'];
|
||
|
||
function noticeRedirect(string $status): void {
|
||
header('Location: admin_notices.php?status=' . rawurlencode($status));
|
||
exit();
|
||
}
|
||
|
||
function noticeVerifyCsrf(): void {
|
||
$postedToken = $_POST['csrf_token'] ?? '';
|
||
$sessionToken = $_SESSION['admin_notices_csrf'] ?? '';
|
||
if (!is_string($postedToken) || !is_string($sessionToken) || $sessionToken === '' || !hash_equals($sessionToken, $postedToken)) {
|
||
http_response_code(400);
|
||
exit('Ungültige Anfrage. Bitte laden Sie die Seite neu.');
|
||
}
|
||
}
|
||
|
||
function noticeParseLocalDateTime(?string $value): ?string {
|
||
$value = trim((string)$value);
|
||
if ($value === '') {
|
||
return null;
|
||
}
|
||
|
||
$tz = new DateTimeZone('Europe/Berlin');
|
||
$date = DateTimeImmutable::createFromFormat('!Y-m-d\TH:i', $value, $tz);
|
||
$errors = DateTimeImmutable::getLastErrors();
|
||
|
||
if (!$date || ($errors !== false && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) {
|
||
throw new InvalidArgumentException('Ungültiges Datum.');
|
||
}
|
||
|
||
// Mit explizitem Offset an PostgreSQL senden, damit TIMESTAMPTZ eindeutig ist.
|
||
return $date->format('Y-m-d H:i:sP');
|
||
}
|
||
|
||
function noticeFormatLocalDateTime(?string $value): string {
|
||
if (empty($value)) {
|
||
return '';
|
||
}
|
||
try {
|
||
return (new DateTimeImmutable($value))->setTimezone(new DateTimeZone('Europe/Berlin'))->format('Y-m-d\TH:i');
|
||
} catch (Throwable $e) {
|
||
return '';
|
||
}
|
||
}
|
||
|
||
function noticeDisplayDate(?string $value): string {
|
||
if (empty($value)) {
|
||
return 'unbegrenzt';
|
||
}
|
||
try {
|
||
return (new DateTimeImmutable($value))->setTimezone(new DateTimeZone('Europe/Berlin'))->format('d.m.Y, H:i') . ' Uhr';
|
||
} catch (Throwable $e) {
|
||
return '–';
|
||
}
|
||
}
|
||
|
||
function noticeDbBool($value): bool {
|
||
return $value === true || $value === 1 || $value === '1' || $value === 't' || $value === 'true';
|
||
}
|
||
|
||
function noticeTextLength(string $value): int {
|
||
return function_exists('mb_strlen') ? mb_strlen($value, 'UTF-8') : strlen($value);
|
||
}
|
||
|
||
function noticeValidateInput(array $noticeTypes): array {
|
||
$title = trim((string)($_POST['title'] ?? ''));
|
||
$message = trim((string)($_POST['message'] ?? ''));
|
||
$type = (string)($_POST['type'] ?? 'info');
|
||
$sortOrder = filter_var($_POST['sort_order'] ?? 0, FILTER_VALIDATE_INT);
|
||
$isActive = isset($_POST['is_active']);
|
||
|
||
if ($title === '' || noticeTextLength($title) > NOTICE_MAX_TITLE_LENGTH) {
|
||
throw new InvalidArgumentException('Titel fehlt oder ist zu lang.');
|
||
}
|
||
if ($message === '' || noticeTextLength($message) > NOTICE_MAX_MESSAGE_LENGTH) {
|
||
throw new InvalidArgumentException('Meldung fehlt oder ist zu lang.');
|
||
}
|
||
if (!array_key_exists($type, $noticeTypes)) {
|
||
throw new InvalidArgumentException('Ungültiger Meldungstyp.');
|
||
}
|
||
if ($sortOrder === false || $sortOrder < -9999 || $sortOrder > 9999) {
|
||
throw new InvalidArgumentException('Ungültige Sortierung.');
|
||
}
|
||
|
||
$startsAt = noticeParseLocalDateTime($_POST['starts_at'] ?? null);
|
||
$endsAt = noticeParseLocalDateTime($_POST['ends_at'] ?? null);
|
||
|
||
if ($startsAt !== null && $endsAt !== null) {
|
||
$start = new DateTimeImmutable($startsAt);
|
||
$end = new DateTimeImmutable($endsAt);
|
||
if ($end <= $start) {
|
||
throw new InvalidArgumentException('Das Ende muss nach dem Beginn liegen.');
|
||
}
|
||
}
|
||
|
||
return [
|
||
'title' => $title,
|
||
'message' => $message,
|
||
'type' => $type,
|
||
'sort_order' => (int)$sortOrder,
|
||
'is_active' => $isActive,
|
||
'starts_at' => $startsAt,
|
||
'ends_at' => $endsAt,
|
||
];
|
||
}
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
noticeVerifyCsrf();
|
||
$action = (string)($_POST['action'] ?? '');
|
||
|
||
try {
|
||
if ($action === 'create') {
|
||
$data = noticeValidateInput($noticeTypes);
|
||
$stmt = $pdo->prepare(
|
||
'INSERT INTO mainpage_notices
|
||
(title, message, type, is_active, starts_at, ends_at, sort_order, created_by, created_at, updated_at)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())'
|
||
);
|
||
$stmt->execute([
|
||
$data['title'], $data['message'], $data['type'], $data['is_active'] ? 'true' : 'false',
|
||
$data['starts_at'], $data['ends_at'], $data['sort_order'], (int)$_SESSION['user_id'],
|
||
]);
|
||
noticeRedirect('created');
|
||
}
|
||
|
||
if ($action === 'update') {
|
||
$id = filter_var($_POST['id'] ?? null, FILTER_VALIDATE_INT);
|
||
if (!$id || $id < 1) {
|
||
throw new InvalidArgumentException('Ungültige Meldungs-ID.');
|
||
}
|
||
$data = noticeValidateInput($noticeTypes);
|
||
$stmt = $pdo->prepare(
|
||
'UPDATE mainpage_notices
|
||
SET title = ?, message = ?, type = ?, is_active = ?, starts_at = ?, ends_at = ?, sort_order = ?, updated_at = NOW()
|
||
WHERE id = ?'
|
||
);
|
||
$stmt->execute([
|
||
$data['title'], $data['message'], $data['type'], $data['is_active'] ? 'true' : 'false',
|
||
$data['starts_at'], $data['ends_at'], $data['sort_order'], (int)$id,
|
||
]);
|
||
noticeRedirect('updated');
|
||
}
|
||
|
||
if ($action === 'toggle') {
|
||
$id = filter_var($_POST['id'] ?? null, FILTER_VALIDATE_INT);
|
||
if (!$id || $id < 1) {
|
||
throw new InvalidArgumentException('Ungültige Meldungs-ID.');
|
||
}
|
||
$stmt = $pdo->prepare('UPDATE mainpage_notices SET is_active = NOT is_active, updated_at = NOW() WHERE id = ?');
|
||
$stmt->execute([(int)$id]);
|
||
noticeRedirect('toggled');
|
||
}
|
||
|
||
if ($action === 'delete') {
|
||
$id = filter_var($_POST['id'] ?? null, FILTER_VALIDATE_INT);
|
||
if (!$id || $id < 1) {
|
||
throw new InvalidArgumentException('Ungültige Meldungs-ID.');
|
||
}
|
||
$stmt = $pdo->prepare('DELETE FROM mainpage_notices WHERE id = ?');
|
||
$stmt->execute([(int)$id]);
|
||
noticeRedirect('deleted');
|
||
}
|
||
|
||
throw new InvalidArgumentException('Unbekannte Aktion.');
|
||
} catch (InvalidArgumentException $e) {
|
||
$_SESSION['admin_notices_error'] = $e->getMessage();
|
||
noticeRedirect('error');
|
||
} catch (PDOException $e) {
|
||
$_SESSION['admin_notices_error'] = 'Datenbankfehler. Prüfen Sie, ob die Tabelle mainpage_notices angelegt wurde.';
|
||
noticeRedirect('error');
|
||
}
|
||
}
|
||
|
||
$noticeError = $_SESSION['admin_notices_error'] ?? '';
|
||
unset($_SESSION['admin_notices_error']);
|
||
$status = (string)($_GET['status'] ?? '');
|
||
$statusMessages = [
|
||
'created' => 'Meldung wurde angelegt.',
|
||
'updated' => 'Meldung wurde gespeichert.',
|
||
'toggled' => 'Status der Meldung wurde geändert.',
|
||
'deleted' => 'Meldung wurde gelöscht.',
|
||
];
|
||
|
||
$tableAvailable = true;
|
||
$notices = [];
|
||
try {
|
||
$notices = $pdo->query(
|
||
'SELECT id, title, message, type, is_active, starts_at, ends_at, sort_order, created_at, updated_at
|
||
FROM mainpage_notices
|
||
ORDER BY sort_order ASC, created_at DESC, id DESC'
|
||
)->fetchAll(PDO::FETCH_ASSOC);
|
||
} catch (PDOException $e) {
|
||
$tableAvailable = false;
|
||
$noticeError = 'Die Tabelle mainpage_notices fehlt. Führen Sie zuerst general_files/ini/mainpage_notices.sql aus.';
|
||
}
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="de" dir="ltr">
|
||
<head>
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
|
||
<style>
|
||
.notice-admin-shell { padding: 18px; min-height: 100%; }
|
||
.notice-admin-card { background:#fff; border:1px solid var(--gray-200); box-shadow:var(--shadow-md); margin-bottom:18px; }
|
||
.notice-admin-header { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:16px 18px; border-bottom:1px solid var(--gray-200); }
|
||
.notice-admin-title { font-size:1.05em; font-weight:800; color:var(--gray-900); }
|
||
.notice-admin-hint { margin-top:3px; font-size:.86em; color:var(--gray-500); }
|
||
.notice-admin-button { display:inline-flex; align-items:center; justify-content:center; min-height:36px; padding:7px 14px; border:1px solid var(--gray-800); background:var(--gray-900); color:#fff; font:inherit; font-size:.86em; font-weight:750; cursor:pointer; text-decoration:none; }
|
||
.notice-admin-button:hover { color:#fff; background:#111; text-decoration:none; }
|
||
.notice-admin-button--secondary { color:var(--gray-800); background:#fff; border-color:var(--gray-300); }
|
||
.notice-admin-button--secondary:hover { color:var(--gray-900); background:var(--gray-50); }
|
||
.notice-admin-button--danger { color:var(--nak-red); background:#fff; border-color:hsl(352,72%,84%); }
|
||
.notice-admin-button--danger:hover { color:#fff; background:var(--nak-red); }
|
||
.notice-admin-grid { display:grid; gap:12px; padding:16px 18px 18px; }
|
||
.notice-admin-item { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:16px; padding:16px; border:1px solid var(--gray-200); background:var(--gray-50); }
|
||
.notice-admin-item.is-disabled { opacity:.62; }
|
||
.notice-admin-item-title { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:6px; font-weight:800; color:var(--gray-900); }
|
||
.notice-admin-chip { display:inline-flex; align-items:center; padding:3px 8px; font-size:.72em; font-weight:800; border-left:3px solid currentColor; background:#fff; }
|
||
.notice-admin-chip--info { color:var(--nak-blue); }
|
||
.notice-admin-chip--warning { color:var(--nak-orange); }
|
||
.notice-admin-chip--success { color:var(--nak-darkgreen); }
|
||
.notice-admin-chip--error { color:var(--nak-red); }
|
||
.notice-admin-message { white-space:pre-wrap; line-height:1.45; color:var(--gray-700); font-size:.92em; }
|
||
.notice-admin-meta { display:flex; gap:14px; flex-wrap:wrap; margin-top:10px; color:var(--gray-500); font-size:.8em; }
|
||
.notice-admin-actions { display:flex; align-items:flex-start; gap:7px; flex-wrap:wrap; justify-content:flex-end; }
|
||
.notice-admin-actions form { margin:0; }
|
||
.notice-admin-empty { padding:28px 18px; text-align:center; color:var(--gray-500); }
|
||
.notice-admin-alert { margin:16px 18px 0; padding:11px 13px; border-left:4px solid var(--nak-darkgreen); background:hsl(145,50%,94%); color:hsl(145,50%,28%); font-size:.9em; }
|
||
.notice-admin-alert--error { border-color:var(--nak-red); background:hsl(352,72%,96%); color:hsl(352,62%,35%); }
|
||
|
||
.notice-modal { position:fixed; inset:0; z-index:5000; display:none; align-items:center; justify-content:center; padding:20px; background:rgba(16,24,32,.62); }
|
||
.notice-modal.open { display:flex; }
|
||
.notice-modal-card { width:min(680px,100%); max-height:calc(100dvh - 40px); overflow:auto; background:#fff; box-shadow:var(--shadow-xl); }
|
||
.notice-modal-header { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:18px 20px; border-bottom:1px solid var(--gray-200); }
|
||
.notice-modal-title { font-size:1.08em; font-weight:800; color:var(--gray-900); }
|
||
.notice-modal-close { border:0; background:transparent; font-size:1.5em; line-height:1; cursor:pointer; color:var(--gray-500); }
|
||
.notice-modal-body { padding:20px; }
|
||
.notice-form-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
|
||
.notice-field { display:flex; flex-direction:column; gap:6px; }
|
||
.notice-field--full { grid-column:1 / -1; }
|
||
.notice-field label { font-size:.83em; font-weight:750; color:var(--gray-700); }
|
||
.notice-field input, .notice-field select, .notice-field textarea { width:100%; box-sizing:border-box; padding:10px 11px; border:1px solid var(--gray-300); background:#fff; color:var(--gray-900); font:inherit; font-size:.9em; }
|
||
.notice-field textarea { min-height:120px; resize:vertical; }
|
||
.notice-checkbox { display:flex; align-items:center; gap:8px; min-height:40px; }
|
||
.notice-checkbox input { width:auto; }
|
||
.notice-form-note { margin-top:5px; font-size:.78em; color:var(--gray-500); }
|
||
.notice-modal-actions { display:flex; justify-content:flex-end; gap:8px; padding:0 20px 20px; }
|
||
|
||
@media (max-width:760px) {
|
||
.notice-admin-shell { padding:10px; }
|
||
.notice-admin-header, .notice-admin-item { grid-template-columns:1fr; display:grid; }
|
||
.notice-admin-actions { justify-content:flex-start; }
|
||
.notice-form-grid { grid-template-columns:1fr; }
|
||
.notice-field--full { grid-column:auto; }
|
||
.content-tab-bar { overflow-x:auto; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="theme-admin">
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
|
||
<?php include $g_phpSnippetsPath.'overlay_message.php'; ?>
|
||
|
||
<div class="header_title ht_admin text_white unselectable" id="header_title">
|
||
<span class="header_title_text">Adminpanel</span>
|
||
</div>
|
||
|
||
<div class="content" id="fullsize">
|
||
<?php $adminActiveTab = 'notices'; require __DIR__.'/_tabs.php'; ?>
|
||
|
||
<div class="notice-admin-shell">
|
||
<div class="notice-admin-card">
|
||
<div class="notice-admin-header">
|
||
<div>
|
||
<div class="notice-admin-title">Meldungen im Hauptmenü</div>
|
||
<div class="notice-admin-hint">Meldungen erscheinen ausschließlich oberhalb der Kacheln auf der Intranet-Hauptseite.</div>
|
||
</div>
|
||
<?php if ($tableAvailable): ?>
|
||
<button type="button" class="notice-admin-button" onclick="openNoticeModal()">+ Neue Meldung</button>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php if ($status === 'error' && $noticeError !== ''): ?>
|
||
<div class="notice-admin-alert notice-admin-alert--error"><?= htmlspecialchars($noticeError, ENT_QUOTES, 'UTF-8') ?></div>
|
||
<?php elseif (!$tableAvailable && $noticeError !== ''): ?>
|
||
<div class="notice-admin-alert notice-admin-alert--error"><?= htmlspecialchars($noticeError, ENT_QUOTES, 'UTF-8') ?></div>
|
||
<?php elseif (isset($statusMessages[$status])): ?>
|
||
<div class="notice-admin-alert"><?= htmlspecialchars($statusMessages[$status], ENT_QUOTES, 'UTF-8') ?></div>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($tableAvailable): ?>
|
||
<?php if (empty($notices)): ?>
|
||
<div class="notice-admin-empty">Noch keine Meldungen vorhanden.</div>
|
||
<?php else: ?>
|
||
<div class="notice-admin-grid">
|
||
<?php foreach ($notices as $notice): ?>
|
||
<?php
|
||
$noticeId = (int)$notice['id'];
|
||
$noticeType = array_key_exists($notice['type'], $noticeTypes) ? $notice['type'] : 'info';
|
||
$editPayload = [
|
||
'id' => $noticeId,
|
||
'title' => $notice['title'],
|
||
'message' => $notice['message'],
|
||
'type' => $noticeType,
|
||
'is_active' => noticeDbBool($notice['is_active']),
|
||
'starts_at' => noticeFormatLocalDateTime($notice['starts_at']),
|
||
'ends_at' => noticeFormatLocalDateTime($notice['ends_at']),
|
||
'sort_order' => (int)$notice['sort_order'],
|
||
];
|
||
?>
|
||
<div class="notice-admin-item<?= noticeDbBool($notice['is_active']) ? '' : ' is-disabled' ?>">
|
||
<div>
|
||
<div class="notice-admin-item-title">
|
||
<?= htmlspecialchars($notice['title'], ENT_QUOTES, 'UTF-8') ?>
|
||
<span class="notice-admin-chip notice-admin-chip--<?= htmlspecialchars($noticeType, ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($noticeTypes[$noticeType], ENT_QUOTES, 'UTF-8') ?></span>
|
||
<?php if (!noticeDbBool($notice['is_active'])): ?><span class="notice-admin-chip">Deaktiviert</span><?php endif; ?>
|
||
</div>
|
||
<div class="notice-admin-message"><?= htmlspecialchars($notice['message'], ENT_QUOTES, 'UTF-8') ?></div>
|
||
<div class="notice-admin-meta">
|
||
<span>Von: <?= htmlspecialchars(noticeDisplayDate($notice['starts_at']), ENT_QUOTES, 'UTF-8') ?></span>
|
||
<span>Bis: <?= htmlspecialchars(noticeDisplayDate($notice['ends_at']), ENT_QUOTES, 'UTF-8') ?></span>
|
||
<span>Sortierung: <?= (int)$notice['sort_order'] ?></span>
|
||
</div>
|
||
</div>
|
||
<div class="notice-admin-actions">
|
||
<button type="button" class="notice-admin-button notice-admin-button--secondary" onclick='openNoticeModal(<?= json_encode($editPayload, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) ?>)'>Bearbeiten</button>
|
||
<form method="post">
|
||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken, ENT_QUOTES, 'UTF-8') ?>">
|
||
<input type="hidden" name="action" value="toggle">
|
||
<input type="hidden" name="id" value="<?= $noticeId ?>">
|
||
<button type="submit" class="notice-admin-button notice-admin-button--secondary"><?= noticeDbBool($notice['is_active']) ? 'Deaktivieren' : 'Aktivieren' ?></button>
|
||
</form>
|
||
<form method="post" onsubmit="return confirm('Meldung wirklich dauerhaft löschen?');">
|
||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken, ENT_QUOTES, 'UTF-8') ?>">
|
||
<input type="hidden" name="action" value="delete">
|
||
<input type="hidden" name="id" value="<?= $noticeId ?>">
|
||
<button type="submit" class="notice-admin-button notice-admin-button--danger">Löschen</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="notice-modal" id="noticeModal" aria-hidden="true">
|
||
<div class="notice-modal-card" role="dialog" aria-modal="true" aria-labelledby="noticeModalTitle">
|
||
<form method="post" id="noticeForm">
|
||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken, ENT_QUOTES, 'UTF-8') ?>">
|
||
<input type="hidden" name="action" id="noticeAction" value="create">
|
||
<input type="hidden" name="id" id="noticeId" value="">
|
||
|
||
<div class="notice-modal-header">
|
||
<div class="notice-modal-title" id="noticeModalTitle">Neue Meldung</div>
|
||
<button type="button" class="notice-modal-close" onclick="closeNoticeModal()" aria-label="Schließen">×</button>
|
||
</div>
|
||
<div class="notice-modal-body">
|
||
<div class="notice-form-grid">
|
||
<div class="notice-field notice-field--full">
|
||
<label for="noticeTitle">Titel</label>
|
||
<input id="noticeTitle" name="title" type="text" maxlength="180" required>
|
||
</div>
|
||
<div class="notice-field notice-field--full">
|
||
<label for="noticeMessage">Meldung</label>
|
||
<textarea id="noticeMessage" name="message" maxlength="4000" required></textarea>
|
||
</div>
|
||
<div class="notice-field">
|
||
<label for="noticeType">Typ</label>
|
||
<select id="noticeType" name="type">
|
||
<?php foreach ($noticeTypes as $typeKey => $typeLabel): ?>
|
||
<option value="<?= htmlspecialchars($typeKey, ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($typeLabel, ENT_QUOTES, 'UTF-8') ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="notice-field">
|
||
<label for="noticeSortOrder">Sortierung</label>
|
||
<input id="noticeSortOrder" name="sort_order" type="number" min="-9999" max="9999" value="0" required>
|
||
<div class="notice-form-note">Kleinere Zahlen erscheinen zuerst.</div>
|
||
</div>
|
||
<div class="notice-field">
|
||
<label for="noticeStartsAt">Anzeigen ab</label>
|
||
<input id="noticeStartsAt" name="starts_at" type="datetime-local">
|
||
<div class="notice-form-note">Leer = sofort.</div>
|
||
</div>
|
||
<div class="notice-field">
|
||
<label for="noticeEndsAt">Anzeigen bis</label>
|
||
<input id="noticeEndsAt" name="ends_at" type="datetime-local">
|
||
<div class="notice-form-note">Leer = ohne Ablaufdatum.</div>
|
||
</div>
|
||
<div class="notice-field notice-field--full">
|
||
<label class="notice-checkbox">
|
||
<input id="noticeIsActive" name="is_active" type="checkbox" value="1" checked>
|
||
Meldung aktiv
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="notice-modal-actions">
|
||
<button type="button" class="notice-admin-button notice-admin-button--secondary" onclick="closeNoticeModal()">Abbrechen</button>
|
||
<button type="submit" class="notice-admin-button">Speichern</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function openNoticeModal(data) {
|
||
data = data || null;
|
||
var modal = document.getElementById('noticeModal');
|
||
document.getElementById('noticeAction').value = data ? 'update' : 'create';
|
||
document.getElementById('noticeId').value = data ? data.id : '';
|
||
document.getElementById('noticeTitle').value = data ? data.title : '';
|
||
document.getElementById('noticeMessage').value = data ? data.message : '';
|
||
document.getElementById('noticeType').value = data ? data.type : 'warning';
|
||
document.getElementById('noticeSortOrder').value = data ? data.sort_order : 0;
|
||
document.getElementById('noticeStartsAt').value = data ? data.starts_at : '';
|
||
document.getElementById('noticeEndsAt').value = data ? data.ends_at : '';
|
||
document.getElementById('noticeIsActive').checked = data ? !!data.is_active : true;
|
||
document.getElementById('noticeModalTitle').textContent = data ? 'Meldung bearbeiten' : 'Neue Meldung';
|
||
modal.classList.add('open');
|
||
modal.setAttribute('aria-hidden', 'false');
|
||
document.getElementById('noticeTitle').focus();
|
||
}
|
||
|
||
function closeNoticeModal() {
|
||
var modal = document.getElementById('noticeModal');
|
||
modal.classList.remove('open');
|
||
modal.setAttribute('aria-hidden', 'true');
|
||
}
|
||
|
||
document.getElementById('noticeModal').addEventListener('click', function(event) {
|
||
if (event.target === this) closeNoticeModal();
|
||
});
|
||
document.addEventListener('keydown', function(event) {
|
||
if (event.key === 'Escape') closeNoticeModal();
|
||
});
|
||
</script>
|
||
|
||
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
|
||
</body>
|
||
</html>
|