Files
comcurrent/player/admin/settings.php
T
Ty Clifford 5f7c62f8a7 v3.1.1
2026-06-24 09:19:08 -04:00

220 lines
11 KiB
PHP
Raw 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
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/../includes/layout.php';
admin_require_auth();
$msg = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? 'settings';
if ($action === 'settings') {
$per_page = max(1, min(50, (int)($_POST['catalogue_per_page'] ?? 10)));
$site_title = trim($_POST['site_title'] ?? 'Ty Clifford');
$site_sub = trim($_POST['site_sub'] ?? 'tyclifford.com / media');
set_setting('catalogue_per_page', (string)$per_page);
set_setting('site_title', $site_title);
set_setting('site_sub', $site_sub);
$msg = 'Settings saved.';
}
if ($action === 'change_password') {
$current = $_POST['current_password'] ?? '';
$new1 = $_POST['new_password'] ?? '';
$new2 = $_POST['new_password2'] ?? '';
if (!password_verify($current, setting('admin_password'))) {
$msg = 'ERROR: Current password is incorrect.';
} elseif (strlen($new1) < 6) {
$msg = 'ERROR: New password must be at least 6 characters.';
} elseif ($new1 !== $new2) {
$msg = 'ERROR: New passwords do not match.';
} else {
set_setting('admin_password', password_hash($new1, PASSWORD_DEFAULT));
$msg = 'Password changed successfully.';
}
}
}
$per_page = setting('catalogue_per_page', '10');
$site_title = setting('site_title', 'Ty Clifford');
$site_sub = setting('site_sub', 'tyclifford.com / media');
// DB stats
$db = get_db();
$total_videos = $db->query("SELECT COUNT(*) FROM videos")->fetchColumn();
$total_sources = $db->query("SELECT COUNT(*) FROM video_sources")->fetchColumn();
$db_size = file_exists(DB_PATH) ? round(filesize(DB_PATH)/1024, 1) : 0;
$media_size = 0;
if (is_dir(MEDIA_DIR)) {
$iter = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(MEDIA_DIR, FilesystemIterator::SKIP_DOTS));
foreach ($iter as $f) $media_size += $f->getSize();
$media_size = round($media_size / 1048576, 1);
}
$msg_type = str_starts_with($msg, 'ERROR') ? 'error' : 'success';
render_head('Settings — Admin', '
.admin-layout { display:grid; grid-template-columns:1fr; gap:1.5rem; }
@media(min-width:900px) { .admin-layout { grid-template-columns:220px 1fr; } }
.admin-nav { background:var(--surface); border:1px solid var(--border); border-radius:calc(var(--r)+2px); padding:1.2rem; display:flex; flex-direction:column; gap:.4rem; align-self:start; position:sticky; top:1rem; }
.admin-nav-label { font-family:"Share Tech Mono",monospace; font-size:.58rem; letter-spacing:.18em; text-transform:uppercase; color:var(--text-3); margin-bottom:.3rem; padding-left:.5rem; }
.admin-nav a { display:flex; align-items:center; gap:.6rem; padding:.55rem .75rem; border-radius:var(--r); font-size:.82rem; color:var(--text-2); text-decoration:none; transition:background .15s,color .15s; }
.admin-nav a:hover { background:rgba(255,255,255,.05); color:var(--text); }
.admin-nav a.active { background:rgba(176,96,255,.12); color:var(--purple); }
.nav-divider { border:none; border-top:1px solid var(--border); margin:.4rem 0; }
.form-grid { display:grid; grid-template-columns:1fr; gap:1rem; }
@media(min-width:600px) { .form-grid { grid-template-columns:1fr 1fr; } }
.section-heading { font-family:"Share Tech Mono",monospace; font-size:.65rem; letter-spacing:.15em; text-transform:uppercase; color:var(--text-3); margin-bottom:.75rem; }
.hint { font-size:.72rem; color:var(--text-3); margin-top:.2rem; }
.stat-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(130px,1fr)); gap:.75rem; }
.stat-tile { background:var(--surface-2); border:1px solid var(--border); border-radius:var(--r); padding:1rem; display:flex; flex-direction:column; gap:.3rem; }
.stat-val { font-family:"Share Tech Mono",monospace; font-size:1.4rem; color:var(--text); font-weight:700; }
.stat-label{ font-family:"Share Tech Mono",monospace; font-size:.6rem; letter-spacing:.1em; text-transform:uppercase; color:var(--text-3); }
');
?>
<main class="page" role="main">
<header class="topbar">
<div class="topbar-brand">
<div>
<div class="brand-name">Ty Clifford</div>
<div class="brand-sub">admin / settings</div>
</div>
</div>
<nav class="topbar-social">
<a class="social-pill" href="../index.php" target="_blank">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"/><polyline points="15,3 21,3 21,9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
View Site
</a>
<a class="social-pill" href="logout.php">Logout</a>
</nav>
</header>
<?php if ($msg): ?>
<div class="notice notice-<?= $msg_type ?>"><?= h($msg) ?></div>
<?php endif; ?>
<div class="admin-layout">
<aside class="admin-nav">
<div class="admin-nav-label">Navigation</div>
<a href="index.php">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
Videos
</a>
<a href="add.php">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
Add Video
</a>
<hr class="nav-divider">
<a href="settings.php" class="active">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93l-1.41 1.41M4.93 4.93l1.41 1.41M19.07 19.07l-1.41-1.41M4.93 19.07l1.41-1.41M12 2v2M12 20v2M2 12h2M20 12h2"/></svg>
Settings
</a>
</aside>
<div style="display:flex;flex-direction:column;gap:1.25rem;">
<!-- Stats -->
<div class="card">
<p class="section-heading">Overview</p>
<div class="stat-grid">
<div class="stat-tile">
<span class="stat-val"><?= $total_videos ?></span>
<span class="stat-label">Videos</span>
</div>
<div class="stat-tile">
<span class="stat-val"><?= $total_sources ?></span>
<span class="stat-label">Source Files</span>
</div>
<div class="stat-tile">
<span class="stat-val"><?= $db_size ?> KB</span>
<span class="stat-label">Database</span>
</div>
<div class="stat-tile">
<span class="stat-val"><?= $media_size ?> MB</span>
<span class="stat-label">Media Storage</span>
</div>
</div>
</div>
<!-- General settings -->
<div class="card">
<p class="section-heading">General Settings</p>
<form method="post" action="settings.php">
<input type="hidden" name="action" value="settings">
<div class="form-grid" style="margin-bottom:1rem;">
<div class="form-group">
<label class="form-label" for="site_title">Site Title</label>
<input class="form-input" type="text" id="site_title" name="site_title"
value="<?= h($site_title) ?>">
</div>
<div class="form-group">
<label class="form-label" for="site_sub">Site Subtitle</label>
<input class="form-input" type="text" id="site_sub" name="site_sub"
value="<?= h($site_sub) ?>">
</div>
<div class="form-group">
<label class="form-label" for="catalogue_per_page">Videos per page</label>
<input class="form-input" type="number" id="catalogue_per_page"
name="catalogue_per_page" value="<?= h($per_page) ?>" min="1" max="50">
<span class="hint">How many thumbnails to show per page (150).</span>
</div>
</div>
<button class="btn btn-primary btn-sm" type="submit">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><polyline points="17,21 17,13 7,13 7,21"/><polyline points="7,3 7,8 15,8"/></svg>
Save Settings
</button>
</form>
</div>
<!-- Change password -->
<div class="card">
<p class="section-heading">Change Password</p>
<form method="post" action="settings.php">
<input type="hidden" name="action" value="change_password">
<div class="form-grid" style="margin-bottom:1rem;">
<div class="form-group">
<label class="form-label" for="current_password">Current Password</label>
<input class="form-input" type="password" id="current_password" name="current_password"
autocomplete="current-password">
</div>
<div></div>
<div class="form-group">
<label class="form-label" for="new_password">New Password</label>
<input class="form-input" type="password" id="new_password" name="new_password"
autocomplete="new-password" minlength="6">
<span class="hint">Minimum 6 characters.</span>
</div>
<div class="form-group">
<label class="form-label" for="new_password2">Confirm New Password</label>
<input class="form-input" type="password" id="new_password2" name="new_password2"
autocomplete="new-password">
</div>
</div>
<button class="btn btn-secondary btn-sm" type="submit">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg>
Change Password
</button>
</form>
</div>
<!-- File locations reference -->
<div class="card">
<p class="section-heading">File Locations</p>
<div style="display:flex;flex-direction:column;gap:.5rem;font-family:'Share Tech Mono',monospace;font-size:.7rem;color:var(--text-3);">
<div><span style="color:var(--text-2);">Database:</span> data/media.db</div>
<div><span style="color:var(--text-2);">Videos:</span> media/videos/</div>
<div><span style="color:var(--text-2);">Thumbnails:</span> media/thumbs/</div>
<div><span style="color:var(--text-2);">Default password:</span> <span style="color:var(--red);">admin</span> — change immediately!</div>
</div>
</div>
</div>
</div>
<?php render_footer(); ?>
</main>
</body>
</html>