Files
pguzman 0a345d2e48 Bump photo-crop.js cache-busting version to v=3
Forces a re-fetch of the pan/zoom fix from the previous commit —
learned this lesson the hard way earlier in this same feature.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 11:17:33 -07:00

266 lines
14 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* admin/setup.php — Create or edit a rosary session.
*/
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/csrf.php';
require_once __DIR__ . '/../includes/photo.php';
require_auth();
$pdo = get_pdo();
$user = current_user();
$uid = (int)$user['id'];
$site_name = get_setting('site_name', APP_NAME);
// Load existing session for editing
$session = null;
if (isset($_GET['id'])) {
$stmt = $pdo->prepare('SELECT * FROM sessions WHERE id = ?');
$stmt->execute([(int)$_GET['id']]);
$session = $stmt->fetch();
if (!$session) {
header('Location: ' . BASE_URL . '/admin/');
exit;
}
// Ownership check: must own or be admin
if (!has_role('admin') && (int)$session['user_id'] !== $uid) {
header('Location: ' . BASE_URL . '/admin/');
exit;
}
}
// Creating new session? Check rosary limit
$limit_error = '';
if (!$session && !can_create_rosary($uid, $user['rosary_limit'])) {
$limit = $user['rosary_limit'];
$limit_error = "You have reached your rosary limit ({$limit}). Please contact an administrator to increase your limit.";
}
$page_title = $session ? 'Edit Session' : 'New Session';
?>
<!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><?= $page_title ?> — <?= htmlspecialchars($site_name) ?></title>
<link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/setup.css">
<link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/photo-crop.css?v=2">
<meta name="csrf-token" content="<?= htmlspecialchars(csrf_token()) ?>">
<script>var BASE_URL = '<?= BASE_URL ?>';</script>
</head>
<body>
<div class="admin-container">
<header class="admin-header">
<h1>&#x271D; <?= htmlspecialchars($site_name) ?></h1>
<div class="header-actions">
<a href="<?= BASE_URL ?>/" class="btn btn-ghost" style="font-size:13px">&#x2190; View Site</a>
<?php if (has_role('superuser')): ?>
<a href="<?= BASE_URL ?>/admin/builder.php" class="btn btn-ghost">&#x2712; Builder</a>
<?php endif; ?>
<?php if (has_role('admin')): ?>
<a href="<?= BASE_URL ?>/admin/prayers.php" class="btn btn-ghost">Prayers</a>
<a href="<?= BASE_URL ?>/admin/users.php" class="btn btn-ghost">Users</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 ?>/admin/" class="btn btn-ghost">&#x2190; Back</a>
<a href="<?= BASE_URL ?>/logout" class="btn btn-ghost">Logout</a>
</div>
</header>
<main>
<h2><?= $page_title ?></h2>
<?php if ($limit_error): ?>
<div class="alert alert-error"><?= htmlspecialchars($limit_error) ?></div>
<?php else: ?>
<div id="form-message" class="alert" style="display:none"></div>
<form id="session-form" novalidate>
<?= csrf_field() ?>
<?php if ($session): ?>
<input type="hidden" name="id" value="<?= (int)$session['id'] ?>">
<?php endif; ?>
<!-- Session Name -->
<div class="form-group">
<label for="name">Session Label <span class="required">*</span></label>
<input type="text" id="name" name="name"
placeholder="e.g. Medy"
value="<?= htmlspecialchars($session['name'] ?? '') ?>"
required>
<p class="help-text" id="name-help">
For novena: enter just the name (e.g. "Medy") — sessions will be created as
"Medy — Day 1" through "Medy — Day 9".
</p>
</div>
<!-- Occasion -->
<div class="form-group">
<label for="occasion">Occasion <span class="required">*</span></label>
<select id="occasion" name="occasion" required>
<option value="">— Select —</option>
<option value="novena_deceased"
<?= ($session['occasion'] ?? '') === 'novena_deceased' ? 'selected' : '' ?>>
Novena for Deceased
</option>
<option value="divine_mercy_novena"
<?= ($session['occasion'] ?? '') === 'divine_mercy_novena' ? 'selected' : '' ?>>
Divine Mercy Novena
</option>
<option value="general_rosary"
<?= ($session['occasion'] ?? '') === 'general_rosary' ? 'selected' : '' ?>>
General Rosary
</option>
<option value="memorial"
<?= ($session['occasion'] ?? '') === 'memorial' ? 'selected' : '' ?>>
Memorial / Month's Mind
</option>
</select>
</div>
<!-- Mystery Set (non-novena) -->
<div class="form-group" id="field-mystery_set_standard">
<label for="mystery_set">Mystery Set <span class="required">*</span></label>
<select id="mystery_set" name="mystery_set" required>
<option value="">— Select —</option>
<option value="sorrowful"
<?= ($session['mystery_set'] ?? '') === 'sorrowful' ? 'selected' : '' ?>>
Sorrowful Mysteries
</option>
<option value="joyful"
<?= ($session['mystery_set'] ?? '') === 'joyful' ? 'selected' : '' ?>>
Joyful Mysteries
</option>
<option value="glorious"
<?= ($session['mystery_set'] ?? '') === 'glorious' ? 'selected' : '' ?>>
Glorious Mysteries
</option>
<option value="luminous"
<?= ($session['mystery_set'] ?? '') === 'luminous' ? 'selected' : '' ?>>
Luminous Mysteries
</option>
</select>
</div>
<!-- Novena Mystery Mode (only shown for novena_deceased) -->
<div class="form-group conditional-field" id="field-novena_mystery_mode" style="display:none">
<label for="novena_mystery_mode">Mysteries for this Novena <span class="required">*</span></label>
<select id="novena_mystery_mode" name="novena_mystery_mode">
<option value="all_sorrowful"
<?= ($session['mystery_set'] ?? '') === 'sorrowful' || ($session['mystery_set'] ?? '') === 'all_sorrowful' ? 'selected' : '' ?>>
All Sorrowful (traditional for deceased)
</option>
<option value="by_day_of_week"
<?= ($session['mystery_set'] ?? '') === 'by_day_of_week' ? 'selected' : '' ?>>
By Day of Week — auto-selected at presentation time
</option>
</select>
<p class="help-text">
Day-of-week schedule: Sun &amp; Wed = Glorious &middot; Mon &amp; Sat = Joyful &middot;
Tue &amp; Fri = Sorrowful &middot; Thu = Luminous
</p>
</div>
<!-- Novena Day -->
<div class="form-group conditional-field" id="field-novena_day" style="display:none">
<?php if ($session): ?>
<label>Novena Day</label>
<div class="form-static">Day <?= (int)($session['novena_day'] ?? 1) ?> of 9</div>
<?php else: ?>
<div class="novena-auto-notice">
&#x2713;&nbsp; Will automatically create <strong>Day 1 through Day 9</strong>.
</div>
<?php endif; ?>
</div>
<!-- Subject Name (conditional) -->
<div class="form-group conditional-field" id="field-subject_name" style="display:none">
<label for="subject_name">Name of Deceased / Honoree</label>
<input type="text" id="subject_name" name="subject_name"
placeholder="e.g. Maria Santos"
value="<?= htmlspecialchars($session['subject_name'] ?? '') ?>">
</div>
<!-- Pronoun (conditional) -->
<div class="form-group conditional-field" id="field-subject_pronoun" style="display:none">
<label for="subject_pronoun">Pronoun</label>
<select id="subject_pronoun" name="subject_pronoun">
<option value="he"
<?= ($session['subject_pronoun'] ?? 'he') === 'he' ? 'selected' : '' ?>>
He / Him / His
</option>
<option value="she"
<?= ($session['subject_pronoun'] ?? '') === 'she' ? 'selected' : '' ?>>
She / Her / Her
</option>
</select>
</div>
<!-- Dates (conditional) -->
<div class="form-group conditional-field" id="field-subject_dates" style="display:none">
<label for="subject_dates">Life Dates</label>
<input type="text" id="subject_dates" name="subject_dates"
placeholder="e.g. Aug 12, 1949 July 25, 2025"
value="<?= htmlspecialchars($session['subject_dates'] ?? '') ?>">
</div>
<!-- Photo -->
<div class="form-group" id="field-photo">
<label for="photo">Photo (optional)</label>
<div class="photo-preview-wrap" style="<?= empty($session['photo_path']) ? 'display:none' : '' ?>">
<img id="photo-preview"
src="<?= !empty($session['photo_path']) ? htmlspecialchars('/' . ltrim($session['photo_path'], '/')) : '' ?>"
alt="Current photo" class="photo-preview"
style="<?= !empty($session['photo_path']) ? htmlspecialchars(photo_crop_style($session)) : '' ?>">
</div>
<input type="file" id="photo" name="photo" accept="image/*">
<p class="help-text">JPEG, PNG, WebP — max 5 MB. Recommended: square or landscape, at least 800 × 600 px. Shown on the home page card and cover slide.</p>
<input type="hidden" id="photo_path" name="photo_path"
value="<?= htmlspecialchars($session['photo_path'] ?? '') ?>">
<input type="hidden" id="photo_focal_x" name="photo_focal_x" value="<?= htmlspecialchars($session['photo_focal_x'] ?? 50) ?>">
<input type="hidden" id="photo_focal_y" name="photo_focal_y" value="<?= htmlspecialchars($session['photo_focal_y'] ?? 50) ?>">
<input type="hidden" id="photo_zoom" name="photo_zoom" value="<?= htmlspecialchars($session['photo_zoom'] ?? 1) ?>">
<button type="button" id="photo-reposition" class="btn btn-secondary" style="margin-top:8px;<?= empty($session['photo_path']) ? 'display:none' : '' ?>">
Reposition
</button>
<div id="upload-status" style="display:none" class="upload-status"></div>
</div>
<!-- Public toggle -->
<div class="form-group">
<label style="display:flex;align-items:center;gap:10px;cursor:pointer">
<input type="checkbox" name="is_public" value="1"
<?= (!$session || $session['is_public']) ? 'checked' : '' ?>
style="width:18px;height:18px">
<span>Make this session public (visible on your profile and the home page)</span>
</label>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary btn-large" id="submit-btn"
data-label-default="<?= $session ? 'Save Changes' : 'Create Session' ?>"
data-label-novena-deceased="<?= $session ? 'Save Changes' : 'Create 9-Day Novena' ?>"
data-label-divine-mercy="<?= $session ? 'Save Changes' : 'Create Divine Mercy Novena' ?>">
<?= $session ? 'Save Changes' : 'Create Session' ?>
</button>
<a href="<?= BASE_URL ?>/admin/" class="btn btn-ghost">Cancel</a>
</div>
</form>
<?php endif; ?>
</main>
</div>
<script src="<?= BASE_URL ?>/assets/js/photo-crop.js?v=3"></script>
<script src="<?= BASE_URL ?>/assets/js/setup.js?v=5"></script>
</body>
</html>