663fde3909
Full source for loveandrosary.com: slide-based Rosary/novena/Divine Mercy Chaplet presentation tool with multi-user roles, SVG bead ring, audio uploads, donate strip, and public session profiles. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
248 lines
11 KiB
PHP
248 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* admin/index.php — Dashboard. Shows sessions for current user (or all for admin+).
|
|
*/
|
|
require_once __DIR__ . '/../config/db.php';
|
|
require_once __DIR__ . '/../includes/auth.php';
|
|
|
|
require_auth();
|
|
|
|
$pdo = get_pdo();
|
|
$user = current_user();
|
|
$uid = (int)$user['id'];
|
|
$is_admin = has_role('admin');
|
|
$site_name = get_setting('site_name', APP_NAME);
|
|
|
|
// Handle deletions
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if (isset($_POST['delete_group_id'])) {
|
|
$gid = (int)$_POST['delete_group_id'];
|
|
// Verify ownership or admin
|
|
if ($is_admin) {
|
|
$pdo->prepare('DELETE FROM sessions WHERE novena_group_id = ?')->execute([$gid]);
|
|
$pdo->prepare('DELETE FROM novena_groups WHERE id = ?')->execute([$gid]);
|
|
} else {
|
|
$pdo->prepare('DELETE FROM sessions WHERE novena_group_id = ? AND (SELECT user_id FROM novena_groups WHERE id = ?) = ?')
|
|
->execute([$gid, $gid, $uid]);
|
|
$pdo->prepare('DELETE FROM novena_groups WHERE id = ? AND user_id = ?')->execute([$gid, $uid]);
|
|
}
|
|
header('Location: ' . BASE_URL . '/admin/');
|
|
exit;
|
|
}
|
|
|
|
if (isset($_POST['delete_id'])) {
|
|
$id = (int)$_POST['delete_id'];
|
|
if ($is_admin) {
|
|
$pdo->prepare('DELETE FROM sessions WHERE id = ?')->execute([$id]);
|
|
} else {
|
|
$pdo->prepare('DELETE FROM sessions WHERE id = ? AND user_id = ?')->execute([$id, $uid]);
|
|
}
|
|
header('Location: ' . BASE_URL . '/admin/');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Load sessions
|
|
if ($is_admin) {
|
|
$regular = $pdo->query("
|
|
SELECT s.*, 'session' AS row_type, u.username, u.display_name
|
|
FROM sessions s
|
|
LEFT JOIN users u ON u.id = s.user_id
|
|
WHERE s.novena_group_id IS NULL
|
|
ORDER BY s.created_at DESC
|
|
")->fetchAll();
|
|
|
|
$novena_groups = $pdo->query("
|
|
SELECT ng.*, 'novena_group' AS row_type, COUNT(s.id) AS day_count,
|
|
u.username, u.display_name
|
|
FROM novena_groups ng
|
|
LEFT JOIN sessions s ON s.novena_group_id = ng.id
|
|
LEFT JOIN users u ON u.id = ng.user_id
|
|
GROUP BY ng.id
|
|
ORDER BY ng.created_at DESC
|
|
")->fetchAll();
|
|
} else {
|
|
$regular = $pdo->prepare("
|
|
SELECT s.*, 'session' AS row_type, u.username, u.display_name
|
|
FROM sessions s
|
|
LEFT JOIN users u ON u.id = s.user_id
|
|
WHERE s.novena_group_id IS NULL AND s.user_id = ?
|
|
ORDER BY s.created_at DESC
|
|
");
|
|
$regular->execute([$uid]);
|
|
$regular = $regular->fetchAll();
|
|
|
|
$ng_stmt = $pdo->prepare("
|
|
SELECT ng.*, 'novena_group' AS row_type, COUNT(s.id) AS day_count,
|
|
u.username, u.display_name
|
|
FROM novena_groups ng
|
|
LEFT JOIN sessions s ON s.novena_group_id = ng.id
|
|
LEFT JOIN users u ON u.id = ng.user_id
|
|
WHERE ng.user_id = ?
|
|
GROUP BY ng.id
|
|
ORDER BY ng.created_at DESC
|
|
");
|
|
$ng_stmt->execute([$uid]);
|
|
$novena_groups = $ng_stmt->fetchAll();
|
|
}
|
|
|
|
$all_rows = array_merge($regular, $novena_groups);
|
|
usort($all_rows, fn($a, $b) => strcmp($b['created_at'], $a['created_at']));
|
|
|
|
$occasion_labels = [
|
|
'novena_deceased' => 'Novena for Deceased',
|
|
'divine_mercy_novena' => 'Divine Mercy Novena',
|
|
'general_rosary' => 'General Rosary',
|
|
'memorial' => 'Memorial',
|
|
];
|
|
$mystery_labels = [
|
|
'sorrowful' => 'Sorrowful',
|
|
'joyful' => 'Joyful',
|
|
'glorious' => 'Glorious',
|
|
'luminous' => 'Luminous',
|
|
'by_day_of_week' => 'By Day',
|
|
];
|
|
|
|
$novena_created = isset($_GET['novena_created']) ? (int)$_GET['novena_created'] : 0;
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="icon" type="image/svg+xml" href="<?= BASE_URL ?>/favicon.svg">
|
|
<title>Dashboard — <?= htmlspecialchars($site_name) ?></title>
|
|
<link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/setup.css">
|
|
</head>
|
|
<body>
|
|
<div class="admin-container">
|
|
|
|
<header class="admin-header">
|
|
<h1>✝ <?= htmlspecialchars($site_name) ?></h1>
|
|
<div class="header-actions">
|
|
<a href="<?= BASE_URL ?>/" class="btn btn-ghost" style="font-size:13px">← View Site</a>
|
|
<?php if (has_role('admin')): ?>
|
|
<a href="<?= BASE_URL ?>/admin/users.php" class="btn btn-ghost">Users</a>
|
|
<a href="<?= BASE_URL ?>/admin/audio.php" class="btn btn-ghost">Audio</a>
|
|
<?php endif; ?>
|
|
<?php if (has_role('superadmin')): ?>
|
|
<a href="<?= BASE_URL ?>/admin/settings.php" class="btn btn-ghost">Settings</a>
|
|
<?php endif; ?>
|
|
<a href="<?= BASE_URL ?>/admin/profile.php" class="btn btn-ghost"><?= htmlspecialchars($user['display_name'] ?: $user['username']) ?></a>
|
|
<a href="<?= BASE_URL ?>/logout" class="btn btn-ghost">Logout</a>
|
|
</div>
|
|
</header>
|
|
|
|
<main>
|
|
<?php if ($novena_created > 0): ?>
|
|
<div class="alert alert-success">
|
|
✓ <?= $novena_created ?> novena day sessions created.
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px">
|
|
<h2 style="margin:0"><?= $is_admin ? 'All Sessions' : 'My Sessions' ?></h2>
|
|
<a href="<?= BASE_URL ?>/admin/setup.php" class="btn btn-primary">+ New Session</a>
|
|
</div>
|
|
|
|
<?php if (empty($all_rows)): ?>
|
|
<div class="empty-state">
|
|
<p>No sessions yet.</p>
|
|
<a href="<?= BASE_URL ?>/admin/setup.php" class="btn btn-primary">Create Your First Session</a>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="sessions-table-wrap">
|
|
<table class="sessions-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Occasion</th>
|
|
<th>Mysteries</th>
|
|
<?php if ($is_admin): ?><th>Owner</th><?php endif; ?>
|
|
<th>Public</th>
|
|
<th>Created</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($all_rows as $row): ?>
|
|
|
|
<?php if ($row['row_type'] === 'novena_group'): ?>
|
|
<tr class="novena-group-row">
|
|
<td class="session-name">
|
|
<span class="novena-group-icon">✝</span>
|
|
<?= htmlspecialchars($row['name']) ?>
|
|
<?php if ($row['subject_name']): ?>
|
|
<span class="subject-name"><?= htmlspecialchars($row['subject_name']) ?></span>
|
|
<?php endif; ?>
|
|
<span class="novena-badge">9-Day Novena</span>
|
|
</td>
|
|
<td><?= ($row['mystery_set'] === 'chaplet') ? 'Divine Mercy Novena' : 'Novena for Deceased' ?></td>
|
|
<td><?= htmlspecialchars($mystery_labels[$row['mystery_set']] ?? $row['mystery_set']) ?></td>
|
|
<?php if ($is_admin): ?>
|
|
<td><?= htmlspecialchars($row['display_name'] ?: ($row['username'] ?? '—')) ?></td>
|
|
<?php endif; ?>
|
|
<td><?= $row['is_public'] ? '<span style="color:#15803d">✓ Yes</span>' : '<span style="color:#9ca3af">No</span>' ?></td>
|
|
<td><?= date('M j, Y', strtotime($row['created_at'])) ?></td>
|
|
<td class="actions">
|
|
<a href="<?= BASE_URL ?>/admin/novena_group.php?id=<?= $row['id'] ?>"
|
|
class="btn btn-sm btn-primary">View Days →</a>
|
|
<?php if ($is_admin || (int)$row['user_id'] === $uid): ?>
|
|
<form method="post" style="display:inline"
|
|
onsubmit="return confirm('Delete this entire novena (all 9 days)?')">
|
|
<input type="hidden" name="delete_group_id" value="<?= $row['id'] ?>">
|
|
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
|
|
<?php else: ?>
|
|
<tr>
|
|
<td class="session-name">
|
|
<?= htmlspecialchars($row['name']) ?>
|
|
<?php if ($row['subject_name']): ?>
|
|
<span class="subject-name"><?= htmlspecialchars($row['subject_name']) ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?= htmlspecialchars($occasion_labels[$row['occasion']] ?? $row['occasion']) ?></td>
|
|
<td><?= htmlspecialchars($mystery_labels[$row['mystery_set']] ?? $row['mystery_set']) ?></td>
|
|
<?php if ($is_admin): ?>
|
|
<td><?= htmlspecialchars($row['display_name'] ?: ($row['username'] ?? '—')) ?></td>
|
|
<?php endif; ?>
|
|
<td><?= $row['is_public'] ? '<span style="color:#15803d">✓ Yes</span>' : '<span style="color:#9ca3af">No</span>' ?></td>
|
|
<td><?= date('M j, Y', strtotime($row['created_at'])) ?></td>
|
|
<td class="actions">
|
|
<?php
|
|
$slug_val = $row['slug'] ?? '';
|
|
$owner = $row['username'] ?? '';
|
|
$present_url = ($slug_val && $owner)
|
|
? BASE_URL . '/' . rawurlencode($owner) . '/' . rawurlencode($slug_val)
|
|
: BASE_URL . '/present.php?id=' . $row['id'];
|
|
?>
|
|
<a href="<?= htmlspecialchars($present_url) ?>"
|
|
target="_blank"
|
|
class="btn btn-sm btn-primary">Present</a>
|
|
<?php if ($is_admin || (int)$row['user_id'] === $uid): ?>
|
|
<a href="<?= BASE_URL ?>/admin/setup.php?id=<?= $row['id'] ?>"
|
|
class="btn btn-sm btn-secondary">Edit</a>
|
|
<form method="post" style="display:inline"
|
|
onsubmit="return confirm('Delete this session?')">
|
|
<input type="hidden" name="delete_id" value="<?= $row['id'] ?>">
|
|
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php endif; ?>
|
|
</main>
|
|
</div>
|
|
</body>
|
|
</html>
|