-
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
<?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 (1–50).</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>
|
||||
Reference in New Issue
Block a user