104 lines
3.6 KiB
PHP
104 lines
3.6 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
require __DIR__ . '/../../includes/bootstrap.php';
|
||
|
||
|
||
|
||
require_admin_login();
|
||
|
||
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||
$pageTitle = $id ? 'Edit Skill • Admin' : 'New Skill • Admin';
|
||
|
||
$skill = ['label' => '', 'level' => 0, 'icon' => 'ri-code-s-slash-line'];
|
||
|
||
if ($id) {
|
||
$st = db()->prepare("SELECT * FROM skills WHERE id = ? LIMIT 1");
|
||
$st->execute([$id]);
|
||
$row = $st->fetch();
|
||
if (!$row) { flash_set('danger', 'Skill not found.'); header('Location: /public/admin/skills.php'); exit; }
|
||
$skill = $row;
|
||
}
|
||
|
||
$errors = [];
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
if (!csrf_verify($_POST['csrf'] ?? null)) $errors[] = 'CSRF failed. Refresh and try again.';
|
||
|
||
$label = trim((string)($_POST['label'] ?? ''));
|
||
$level = (int)($_POST['level'] ?? 0);
|
||
$icon = trim((string)($_POST['icon'] ?? ''));
|
||
|
||
if ($label === '' || mb_strlen($label) > 100) $errors[] = 'Label must be 1–100 chars.';
|
||
if ($level < 0 || $level > 100) $errors[] = 'Level must be 0–100.';
|
||
if ($icon === '' || mb_strlen($icon) > 80) $errors[] = 'Icon must be 1–80 chars (e.g. ri-database-2-line).';
|
||
|
||
if (!$errors) {
|
||
if ($id) {
|
||
$st = db()->prepare("UPDATE skills SET label=?, level=?, icon=? WHERE id=?");
|
||
$st->execute([$label, $level, $icon, $id]);
|
||
flash_set('success', 'Skill updated.');
|
||
} else {
|
||
$st = db()->prepare("INSERT INTO skills(label, level, icon) VALUES (?,?,?)");
|
||
$st->execute([$label, $level, $icon]);
|
||
flash_set('success', 'Skill created.');
|
||
}
|
||
header('Location: /public/admin/skills.php');
|
||
exit;
|
||
}
|
||
|
||
$skill['label'] = $label;
|
||
$skill['level'] = $level;
|
||
$skill['icon'] = $icon;
|
||
}
|
||
|
||
include __DIR__ . '/_top.php';
|
||
?>
|
||
<div class="d-flex align-items-center justify-content-between mt-4 flex-wrap gap-2">
|
||
<h1 class="h3 m-0 brand"><?= $id ? 'Edit Skill' : 'New Skill' ?></h1>
|
||
<a class="btn btn-outline-light" href="/public/admin/skills.php">Back</a>
|
||
</div>
|
||
|
||
<?php if ($errors): ?>
|
||
<div class="alert alert-danger card-glass border-0 mt-3">
|
||
<ul class="mb-0">
|
||
<?php foreach ($errors as $e): ?><li><?= htmlspecialchars($e) ?></li><?php endforeach; ?>
|
||
</ul>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="card card-glass border-0 mt-3 p-4">
|
||
<form method="post">
|
||
<input type="hidden" name="csrf" value="<?= htmlspecialchars(csrf_token()) ?>">
|
||
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label text-white-50">Label</label>
|
||
<input class="form-control" name="label" maxlength="100" required
|
||
value="<?= htmlspecialchars((string)$skill['label']) ?>">
|
||
</div>
|
||
|
||
<div class="col-md-3">
|
||
<label class="form-label text-white-50">Level (0–100)</label>
|
||
<input class="form-control" name="level" type="number" min="0" max="100" required
|
||
value="<?= (int)$skill['level'] ?>">
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label text-white-50">Remixicon class</label>
|
||
<input class="form-control" name="icon" maxlength="80" required
|
||
value="<?= htmlspecialchars((string)$skill['icon']) ?>">
|
||
<div class="form-text text-white-50">
|
||
Example: <code>ri-database-2-line</code> / <code>ri-code-s-slash-line</code>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-4 d-flex gap-2">
|
||
<button class="btn btn-violet"><?= $id ? 'Save Changes' : 'Create Skill' ?></button>
|
||
<a class="btn btn-outline-light" href="/public/admin/skills.php">Cancel</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<?php include __DIR__ . '/_bottom.php'; ?>
|