Add multi-announcement management system
- Update inc/announcements.php to support listing, fetching by ID, toggling, and deleting multiple announcements - Upgrade admin/index.php to an announcement management view with data table, status indicators, and create/edit sub-views - Add admin table and action styles to styles.css without using inline style blocks - Update index.php to render all currently active banner and hours announcements dynamically
This commit is contained in:
1 parent
e4cd4f6cfb
commit
bd22299247
4 files changed
+329
-119
No files matched your search
+207
-100
@@ -4,48 +4,58 @@ require_once __DIR__ . '/../inc/announcements.php';
|
||||
|
||||
require_auth();
|
||||
$user = get_logged_in_user();
|
||||
$pdo = get_db();
|
||||
|
||||
$successMsg = '';
|
||||
$errorMsg = '';
|
||||
|
||||
// Handle announcement form submission
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'save_announcement') {
|
||||
// Handle Actions (Save, Delete, Toggle)
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verify_csrf_token($_POST['csrf_token'] ?? '')) {
|
||||
$errorMsg = 'Session expired or invalid security token. Please try again.';
|
||||
} else {
|
||||
$annId = !empty($_POST['announcement_id']) ? (int)$_POST['announcement_id'] : null;
|
||||
save_announcement([
|
||||
'is_active' => isset($_POST['is_active']) ? 1 : 0,
|
||||
'type' => $_POST['type'] ?? 'holiday',
|
||||
'headline' => $_POST['headline'] ?? '',
|
||||
'message' => $_POST['message'] ?? '',
|
||||
'start_date' => $_POST['start_date'] ?? null,
|
||||
'end_date' => $_POST['end_date'] ?? null,
|
||||
'show_banner' => isset($_POST['show_banner']) ? 1 : 0,
|
||||
'show_in_hours' => isset($_POST['show_in_hours']) ? 1 : 0,
|
||||
], $annId);
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
$successMsg = 'Announcement updated successfully!';
|
||||
if ($action === 'save_announcement') {
|
||||
$annId = !empty($_POST['announcement_id']) ? (int)$_POST['announcement_id'] : null;
|
||||
save_announcement([
|
||||
'is_active' => isset($_POST['is_active']) ? 1 : 0,
|
||||
'type' => $_POST['type'] ?? 'holiday',
|
||||
'headline' => $_POST['headline'] ?? '',
|
||||
'message' => $_POST['message'] ?? '',
|
||||
'start_date' => $_POST['start_date'] ?? null,
|
||||
'end_date' => $_POST['end_date'] ?? null,
|
||||
'show_banner' => isset($_POST['show_banner']) ? 1 : 0,
|
||||
'show_in_hours' => isset($_POST['show_in_hours']) ? 1 : 0,
|
||||
], $annId);
|
||||
|
||||
$successMsg = $annId ? 'Announcement updated successfully!' : 'New announcement created successfully!';
|
||||
} elseif ($action === 'delete_announcement') {
|
||||
$annId = (int)($_POST['announcement_id'] ?? 0);
|
||||
if ($annId > 0) {
|
||||
delete_announcement($annId);
|
||||
$successMsg = 'Announcement deleted successfully.';
|
||||
}
|
||||
} elseif ($action === 'toggle_active') {
|
||||
$annId = (int)($_POST['announcement_id'] ?? 0);
|
||||
if ($annId > 0) {
|
||||
toggle_announcement_active($annId);
|
||||
$successMsg = 'Status updated.';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch current announcement (or default empty template)
|
||||
$announcement = get_active_announcement();
|
||||
if (!$announcement) {
|
||||
$stmt = $pdo->query("SELECT * FROM announcements ORDER BY id DESC LIMIT 1");
|
||||
$announcement = $stmt->fetch() ?: [
|
||||
'id' => 0,
|
||||
'is_active' => 0,
|
||||
'type' => 'holiday',
|
||||
'headline' => 'Holiday Closure',
|
||||
'message' => 'The Old Fitz will be closed for the holiday weekend.',
|
||||
'start_date' => '',
|
||||
'end_date' => '',
|
||||
'show_banner' => 1,
|
||||
'show_in_hours' => 1
|
||||
];
|
||||
// Check if editing a specific announcement or creating new
|
||||
$editingId = isset($_GET['edit']) ? (int)$_GET['edit'] : null;
|
||||
$isCreatingNew = isset($_GET['new']);
|
||||
$editItem = null;
|
||||
|
||||
if ($editingId) {
|
||||
$editItem = get_announcement_by_id($editingId);
|
||||
}
|
||||
|
||||
$announcements = get_all_announcements();
|
||||
$today = date('Y-m-d');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
@@ -88,87 +98,184 @@ if (!$announcement) {
|
||||
<div class="alert-error" role="alert"><?= htmlspecialchars($errorMsg) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" action="index.php">
|
||||
<input type="hidden" name="action" value="save_announcement">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars(get_csrf_token()) ?>">
|
||||
<input type="hidden" name="announcement_id" value="<?= (int)($announcement['id'] ?? 0) ?>">
|
||||
<?php if ($isCreatingNew || $editItem): ?>
|
||||
<!-- Announcement Editor Form (Create / Edit) -->
|
||||
<form method="POST" action="index.php">
|
||||
<input type="hidden" name="action" value="save_announcement">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars(get_csrf_token()) ?>">
|
||||
<input type="hidden" name="announcement_id" value="<?= (int)($editItem['id'] ?? 0) ?>">
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>
|
||||
<span><?= $editItem ? '✏️ Edit Announcement' : '✨ New Announcement' ?></span>
|
||||
</h2>
|
||||
<a href="index.php" class="btn btn-outline btn-sm">← Back to List</a>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div class="form-group full-width">
|
||||
<label class="checkbox-label checkbox-label-lg">
|
||||
<input type="checkbox" name="is_active" value="1" <?= (!empty($editItem['is_active']) || $isCreatingNew) ? 'checked' : '' ?>>
|
||||
<strong>Enable Announcement on Site</strong>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="headline">Notice Headline</label>
|
||||
<input type="text" id="headline" name="headline" class="form-control"
|
||||
value="<?= htmlspecialchars($editItem['headline'] ?? '') ?>"
|
||||
placeholder="e.g. Labor Day Closure" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="type">Style / Category</label>
|
||||
<select id="type" name="type" class="form-control">
|
||||
<option value="holiday" <?= ($editItem['type'] ?? '') === 'holiday' ? 'selected' : '' ?>>Holiday / Special Schedule (Warm Brass & Green)</option>
|
||||
<option value="special" <?= ($editItem['type'] ?? '') === 'special' ? 'selected' : '' ?>>Event / Live Music Announcement</option>
|
||||
<option value="closure" <?= ($editItem['type'] ?? '') === 'closure' ? 'selected' : '' ?>>Urgent Closure / Weather Alert</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width">
|
||||
<label for="message">Notice Message</label>
|
||||
<textarea id="message" name="message" class="form-control" required
|
||||
placeholder="Write details of closure, dates, and when regular hours resume..."><?= htmlspecialchars($editItem['message'] ?? '') ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="start_date">Start Date (Optional Auto-Schedule)</label>
|
||||
<input type="date" id="start_date" name="start_date" class="form-control"
|
||||
value="<?= htmlspecialchars($editItem['start_date'] ?? '') ?>">
|
||||
<span class="muted font-mono" style="font-size: 0.78rem;">Leave blank to show immediately while enabled.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="end_date">End Date (Optional Expiration)</label>
|
||||
<input type="date" id="end_date" name="end_date" class="form-control"
|
||||
value="<?= htmlspecialchars($editItem['end_date'] ?? '') ?>">
|
||||
<span class="muted font-mono" style="font-size: 0.78rem;">Auto-hides after 11:59 PM on this date.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width">
|
||||
<label>Display Placements</label>
|
||||
<div class="checkbox-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" name="show_banner" value="1" <?= (!isset($editItem) || !empty($editItem['show_banner'])) ? 'checked' : '' ?>>
|
||||
Show as top alert banner across the site
|
||||
</label>
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" name="show_in_hours" value="1" <?= (!isset($editItem) || !empty($editItem['show_in_hours'])) ? 'checked' : '' ?>>
|
||||
Highlight inside the "Hours & Visit" card
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions" style="display: flex; gap: 0.75rem; align-items: center;">
|
||||
<button type="submit" class="btn btn-primary">Save Announcement</button>
|
||||
<a href="index.php" class="btn btn-outline">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<!-- Announcements List View -->
|
||||
<div class="panel">
|
||||
<div class="panel-head">
|
||||
<h2>
|
||||
<span>📢 Announcement Settings</span>
|
||||
<span>📢 All Announcements (<?= count($announcements) ?>)</span>
|
||||
</h2>
|
||||
<?php if (!empty($announcement['is_active'])): ?>
|
||||
<span class="status-badge active">● Live on site</span>
|
||||
<?php else: ?>
|
||||
<span class="status-badge inactive">○ Inactive / Off</span>
|
||||
<?php endif; ?>
|
||||
<a href="index.php?new=1" class="btn btn-primary btn-sm">+ Create Announcement</a>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div class="form-group full-width">
|
||||
<label class="checkbox-label checkbox-label-lg">
|
||||
<input type="checkbox" name="is_active" value="1" <?= !empty($announcement['is_active']) ? 'checked' : '' ?>>
|
||||
<strong>Enable Announcement on Site</strong>
|
||||
</label>
|
||||
<?php if (empty($announcements)): ?>
|
||||
<div class="empty-state">
|
||||
<p>No announcements created yet.</p>
|
||||
<a href="index.php?new=1" class="btn btn-primary btn-sm">+ Create Your First Announcement</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="admin-table-wrap">
|
||||
<table class="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<th>Headline</th>
|
||||
<th>Type</th>
|
||||
<th>Schedule</th>
|
||||
<th>Placements</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($announcements as $ann): ?>
|
||||
<?php
|
||||
$isCurrentlyActive = $ann['is_active'] &&
|
||||
(empty($ann['start_date']) || $ann['start_date'] <= $today) &&
|
||||
(empty($ann['end_date']) || $ann['end_date'] >= $today);
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php if ($isCurrentlyActive): ?>
|
||||
<span class="status-badge active">● Live</span>
|
||||
<?php elseif ($ann['is_active']): ?>
|
||||
<span class="status-badge inactive">⏳ Scheduled</span>
|
||||
<?php else: ?>
|
||||
<span class="status-badge inactive">○ Off</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<strong><?= htmlspecialchars($ann['headline']) ?></strong>
|
||||
<div class="muted" style="font-size: 0.82rem; margin-top: 0.2rem; max-width: 32ch; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
<?= htmlspecialchars($ann['message']) ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="eyebrow"><?= htmlspecialchars($ann['type']) ?></span>
|
||||
</td>
|
||||
<td class="font-mono" style="font-size: 0.8rem; color: var(--ink-muted);">
|
||||
<?php if (!empty($ann['start_date']) || !empty($ann['end_date'])): ?>
|
||||
<?= htmlspecialchars($ann['start_date'] ?: 'Now') ?> → <?= htmlspecialchars($ann['end_date'] ?: 'Ongoing') ?>
|
||||
<?php else: ?>
|
||||
Always (while on)
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td style="font-size: 0.82rem; color: var(--ink-muted);">
|
||||
<?php
|
||||
$locs = [];
|
||||
if (!empty($ann['show_banner'])) $locs[] = 'Top Banner';
|
||||
if (!empty($ann['show_in_hours'])) $locs[] = 'Hours Card';
|
||||
echo implode(', ', $locs) ?: 'None';
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<div class="admin-table-actions">
|
||||
<a href="index.php?edit=<?= (int)$ann['id'] ?>" class="btn btn-outline btn-sm">Edit</a>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="headline">Notice Headline</label>
|
||||
<input type="text" id="headline" name="headline" class="form-control"
|
||||
value="<?= htmlspecialchars($announcement['headline'] ?? '') ?>"
|
||||
placeholder="e.g. Labor Day Closure" required>
|
||||
<form method="POST" action="index.php" style="display: inline;">
|
||||
<input type="hidden" name="action" value="toggle_active">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars(get_csrf_token()) ?>">
|
||||
<input type="hidden" name="announcement_id" value="<?= (int)$ann['id'] ?>">
|
||||
<button type="submit" class="btn btn-outline btn-sm">
|
||||
<?= $ann['is_active'] ? 'Turn Off' : 'Turn On' ?>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<form method="POST" action="index.php" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete this announcement?');">
|
||||
<input type="hidden" name="action" value="delete_announcement">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars(get_csrf_token()) ?>">
|
||||
<input type="hidden" name="announcement_id" value="<?= (int)$ann['id'] ?>">
|
||||
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="type">Style / Category</label>
|
||||
<select id="type" name="type" class="form-control">
|
||||
<option value="holiday" <?= ($announcement['type'] ?? '') === 'holiday' ? 'selected' : '' ?>>Holiday / Special Schedule (Warm Brass & Green)</option>
|
||||
<option value="special" <?= ($announcement['type'] ?? '') === 'special' ? 'selected' : '' ?>>Event / Live Music Announcement</option>
|
||||
<option value="closure" <?= ($announcement['type'] ?? '') === 'closure' ? 'selected' : '' ?>>Urgent Closure / Weather Alert</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width">
|
||||
<label for="message">Notice Message</label>
|
||||
<textarea id="message" name="message" class="form-control" required
|
||||
placeholder="Write details of closure, dates, and when regular hours resume..."><?= htmlspecialchars($announcement['message'] ?? '') ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="start_date">Start Date (Optional Auto-Schedule)</label>
|
||||
<input type="date" id="start_date" name="start_date" class="form-control"
|
||||
value="<?= htmlspecialchars($announcement['start_date'] ?? '') ?>">
|
||||
<span class="muted field-hint">Leave blank to show immediately while enabled.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="end_date">End Date (Optional Expiration)</label>
|
||||
<input type="date" id="end_date" name="end_date" class="form-control"
|
||||
value="<?= htmlspecialchars($announcement['end_date'] ?? '') ?>">
|
||||
<span class="muted field-hint">Auto-hides after 11:59 PM on this date.</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width">
|
||||
<label>Display Placements</label>
|
||||
<div class="checkbox-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" name="show_banner" value="1" <?= !empty($announcement['show_banner']) ? 'checked' : '' ?>>
|
||||
Show as top alert banner across the site
|
||||
</label>
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" name="show_in_hours" value="1" <?= !empty($announcement['show_in_hours']) ? 'checked' : '' ?>>
|
||||
Highlight inside the "Hours & Visit" card
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Save & Update Site</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
+28
-6
@@ -5,7 +5,7 @@
|
||||
|
||||
require_once __DIR__ . '/db.php';
|
||||
|
||||
function get_active_announcement(): ?array {
|
||||
function get_active_announcements(): array {
|
||||
$pdo = get_db();
|
||||
$today = date('Y-m-d');
|
||||
|
||||
@@ -15,7 +15,6 @@ function get_active_announcement(): ?array {
|
||||
AND (start_date IS NULL OR start_date = '' OR start_date <= :today1)
|
||||
AND (end_date IS NULL OR end_date = '' OR end_date >= :today2)
|
||||
ORDER BY id DESC
|
||||
LIMIT 1
|
||||
";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
@@ -23,15 +22,38 @@ function get_active_announcement(): ?array {
|
||||
':today1' => $today,
|
||||
':today2' => $today
|
||||
]);
|
||||
$result = $stmt->fetch();
|
||||
return $stmt->fetchAll() ?: [];
|
||||
}
|
||||
|
||||
return $result ?: null;
|
||||
function get_active_announcement(): ?array {
|
||||
$all = get_active_announcements();
|
||||
return !empty($all) ? $all[0] : null;
|
||||
}
|
||||
|
||||
function get_all_announcements(): array {
|
||||
$pdo = get_db();
|
||||
$stmt = $pdo->query("SELECT * FROM announcements ORDER BY id DESC");
|
||||
return $stmt->fetchAll();
|
||||
return $stmt->fetchAll() ?: [];
|
||||
}
|
||||
|
||||
function get_announcement_by_id(int $id): ?array {
|
||||
$pdo = get_db();
|
||||
$stmt = $pdo->prepare("SELECT * FROM announcements WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$item = $stmt->fetch();
|
||||
return $item ?: null;
|
||||
}
|
||||
|
||||
function delete_announcement(int $id): bool {
|
||||
$pdo = get_db();
|
||||
$stmt = $pdo->prepare("DELETE FROM announcements WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
function toggle_announcement_active(int $id): bool {
|
||||
$pdo = get_db();
|
||||
$stmt = $pdo->prepare("UPDATE announcements SET is_active = CASE WHEN is_active = 1 THEN 0 ELSE 1 END, updated_at = CURRENT_TIMESTAMP WHERE id = ?");
|
||||
return $stmt->execute([$id]);
|
||||
}
|
||||
|
||||
function save_announcement(array $data, ?int $id = null): int {
|
||||
@@ -46,7 +68,7 @@ function save_announcement(array $data, ?int $id = null): int {
|
||||
$showBanner = !empty($data['show_banner']) ? 1 : 0;
|
||||
$showInHours = !empty($data['show_in_hours']) ? 1 : 0;
|
||||
|
||||
if ($id) {
|
||||
if ($id && $id > 0) {
|
||||
$stmt = $pdo->prepare("
|
||||
UPDATE announcements SET
|
||||
is_active = ?,
|
||||
|
||||
@@ -3,7 +3,7 @@ require __DIR__ . '/config.php';
|
||||
require __DIR__ . '/inc/facebook-stats.php';
|
||||
require __DIR__ . '/inc/announcements.php';
|
||||
$fbStats = fritz_facebook_stats();
|
||||
$activeAnnouncement = get_active_announcement();
|
||||
$activeAnnouncements = get_active_announcements();
|
||||
$siteUrl = rtrim(SITE_URL, '/');
|
||||
?>
|
||||
<!doctype html>
|
||||
@@ -61,14 +61,21 @@ $siteUrl = rtrim(SITE_URL, '/');
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ($activeAnnouncement && !empty($activeAnnouncement['show_banner'])): ?>
|
||||
<div class="announcement-banner banner-<?= htmlspecialchars($activeAnnouncement['type']) ?>" role="region" aria-label="Important Announcement">
|
||||
<div class="container announcement-inner">
|
||||
<span class="announcement-tag"><?= htmlspecialchars($activeAnnouncement['headline']) ?></span>
|
||||
<span class="announcement-sep" aria-hidden="true">·</span>
|
||||
<span class="announcement-text"><?= htmlspecialchars($activeAnnouncement['message']) ?></span>
|
||||
<?php
|
||||
$bannerAnnouncements = array_filter($activeAnnouncements, function($a) {
|
||||
return !empty($a['show_banner']);
|
||||
});
|
||||
?>
|
||||
<?php if (!empty($bannerAnnouncements)): ?>
|
||||
<?php foreach ($bannerAnnouncements as $banner): ?>
|
||||
<div class="announcement-banner banner-<?= htmlspecialchars($banner['type']) ?>" role="region" aria-label="Important Announcement">
|
||||
<div class="container announcement-inner">
|
||||
<span class="announcement-tag"><?= htmlspecialchars($banner['headline']) ?></span>
|
||||
<span class="announcement-sep" aria-hidden="true">·</span>
|
||||
<span class="announcement-text"><?= htmlspecialchars($banner['message']) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<main id="main">
|
||||
@@ -127,12 +134,17 @@ $siteUrl = rtrim(SITE_URL, '/');
|
||||
<div class="visit-grid">
|
||||
<div class="card reveal">
|
||||
<h3>On Tap Thu–Sat</h3>
|
||||
<?php if ($activeAnnouncement && !empty($activeAnnouncement['show_in_hours'])): ?>
|
||||
<div class="hours-alert alert-<?= htmlspecialchars($activeAnnouncement['type']) ?>">
|
||||
<strong><?= htmlspecialchars($activeAnnouncement['headline']) ?>:</strong>
|
||||
<span><?= htmlspecialchars($activeAnnouncement['message']) ?></span>
|
||||
<?php
|
||||
$hoursAnnouncements = array_filter($activeAnnouncements, function($a) {
|
||||
return !empty($a['show_in_hours']);
|
||||
});
|
||||
?>
|
||||
<?php foreach ($hoursAnnouncements as $hoursNotice): ?>
|
||||
<div class="hours-alert alert-<?= htmlspecialchars($hoursNotice['type']) ?>">
|
||||
<strong><?= htmlspecialchars($hoursNotice['headline']) ?>:</strong>
|
||||
<span><?= htmlspecialchars($hoursNotice['message']) ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<dl class="hours-list">
|
||||
<div class="hours-row">
|
||||
<dt>Thursday</dt>
|
||||
|
||||
+69
@@ -1160,3 +1160,72 @@
|
||||
border: 1px solid var(--rule);
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
|
||||
/* admin table & list actions */
|
||||
.admin-table-wrap {
|
||||
overflow-x: auto;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.admin-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
.admin-table th,
|
||||
.admin-table td {
|
||||
padding: 0.85rem 0.75rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--rule);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.admin-table th {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--gold);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.admin-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.admin-table-actions {
|
||||
display: inline-flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
padding: 0.4rem 0.8rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: rgba(180, 50, 40, 0.15);
|
||||
border: 1px solid rgba(220, 80, 60, 0.5);
|
||||
color: #ff9d9d;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background: rgba(220, 60, 50, 0.3);
|
||||
border-color: #ff6e6e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 3rem 1.5rem;
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
Reference in new issue
Block a user