small tweaks

This commit is contained in:
2025-08-18 22:03:09 +02:00
parent fb182a1aec
commit 16c4d58def
7 changed files with 183 additions and 57 deletions

185
index.php
View File

@@ -77,13 +77,24 @@ function require_csrf(): void
}
}
ensure_csrf_token();
// ===== URL-Param: Liste per UUID (oder Alt-ID -> Redirect) =====
$ListID = -1;
$ListUUID = '';
if (isset($_GET['list'])) {
$showCreateEmptyState = false;
if (!isset($_GET['list'])) {
// Kein Parameter => nur Empty-State ohne Message
$showCreateEmptyState = true;
} else {
$raw = trim((string) $_GET['list']);
if (preg_match('/^[0-9a-fA-F-]{32,36}$/', $raw)) {
if ($raw === '') {
// Leerer Parameter => nur Empty-State ohne Message
$showCreateEmptyState = true;
} elseif (preg_match('/^[0-9a-fA-F-]{32,36}$/', $raw)) {
// UUID übergeben
$c = db();
$s = $c->prepare('SELECT ID, uuid FROM lists WHERE uuid=?');
$s->bind_param('s', $raw);
@@ -92,27 +103,40 @@ if (isset($_GET['list'])) {
if ($r && ($row = $r->fetch_assoc())) {
$ListID = (int) $row['ID'];
$ListUUID = (string) $row['uuid'];
} else {
// UUID-Format ok, aber nicht vorhanden => Message + Empty-State
$message = ['msg' => 'Diese Liste gibt es nicht. Lege eine neue an oder prüfe den Link.', 'type' => 'warning'];
$showCreateEmptyState = true;
}
$s->close();
$c->close();
} else {
$ListID = (int) $raw;
if ($ListID >= 0) {
$c = db();
$s = $c->prepare('SELECT uuid FROM lists WHERE ID=?');
$s->bind_param('i', $ListID);
$s->execute();
$r = $s->get_result();
if ($r && ($row = $r->fetch_assoc())) {
$ListUUID = (string) $row['uuid'];
$scheme = $secure ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
header('Location: ' . $scheme . '://' . $host . '/?list=' . urlencode($ListUUID), true, 301);
exit;
}
$s->close();
$c->close();
} elseif (preg_match('/^\d+$/', $raw)) {
// Numerische ID übergeben -> auf UUID umleiten, wenn vorhanden
$id = (int) $raw;
$c = db();
$s = $c->prepare('SELECT uuid FROM lists WHERE ID=?');
$s->bind_param('i', $id);
$s->execute();
$r = $s->get_result();
if ($r && ($row = $r->fetch_assoc())) {
$uuid = (string) $row['uuid'];
$scheme = $secure ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? '';
header('Location: ' . $scheme . '://' . $host . '/?list=' . urlencode($uuid), true, 301);
exit;
} else {
// ID-Format ok, aber nicht vorhanden => Message + Empty-State
$message = ['msg' => 'Diese Liste gibt es nicht. Lege eine neue an oder prüfe den Link.', 'type' => 'warning'];
$showCreateEmptyState = true;
}
$s->close();
$c->close();
} else {
// Weder gültige UUID noch Zahl => Message + Empty-State
$message = ['msg' => 'Diese Liste gibt es nicht. Lege eine neue an oder prüfe den Link.', 'type' => 'warning'];
$showCreateEmptyState = true;
}
}
@@ -252,7 +276,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/tweaks.css">
<link rel="stylesheet" href="css/fontawesome.min.css"/>
<link rel="stylesheet" href="css/fontawesome.min.css" />
<link rel="apple-touch-icon" sizes="180x180" href="img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="img/favicon-32x32.png">
@@ -277,29 +301,33 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
</a>
<div class="nav navbar-nav navbar-right">
<div class="d-grid gap-2 d-flex">
<?php if ($loggedin): ?>
<button type="button" class="btn btn-outline-secondary my-2 my-sm-0" data-bs-toggle="modal"
data-bs-target="#itemModal" data-mode="add" data-listuuid="<?= e($ListUUID) ?>"
data-sort="<?= e($sortby) ?>">Add Item</button>
<button type="button" class="btn btn-outline-success my-2 my-sm-0" data-bs-toggle="modal"
data-bs-target="#createListModal">Neue Liste</button>
<?php if ($showCreateEmptyState == false): ?>
<?php if ($loggedin): ?>
<button type="button" class="btn btn-outline-secondary my-2 my-sm-0" data-bs-toggle="modal"
data-bs-target="#itemModal" data-mode="add" data-listuuid="<?= e($ListUUID) ?>"
data-sort="<?= e($sortby) ?>">Add Item</button>
<form class="form-inline" action="" method="POST">
<input type="hidden" name="csrf" value="<?= e($_SESSION['csrf']) ?>">
<button type="submit" class="btn btn-outline-secondary my-2 my-sm-0" name="logout">Logout</button>
</form>
<?php else: ?>
<button type="button" class="btn btn-outline-secondary my-2 my-sm-0" data-bs-toggle="modal"
data-bs-target="#loginModal">Login</button>
<?php endif; ?>
<form class="form-inline" action="" method="POST">
<input type="hidden" name="csrf" value="<?= e($_SESSION['csrf']) ?>">
<button type="submit" class="btn btn-outline-secondary my-2 my-sm-0" name="logout">Logout</button>
<select class="form-control" name="sortby" id="sortby">
<option <?= $sortby === 'priority' ? 'selected' : '' ?> value="priority">Priorität</option>
<option <?= $sortby === 'price_asc' ? 'selected' : '' ?> value="price_asc">Preis aufsteigend</option>
<option <?= $sortby === 'price_desc' ? 'selected' : '' ?> value="price_desc">Preis absteigend</option>
<option <?= $sortby === 'date_desc' ? 'selected' : '' ?> value="date_desc">Datum, neu → alt</option>
<option <?= $sortby === 'date_asc' ? 'selected' : '' ?> value="date_asc">Datum, alt → neu</option>
<option <?= $sortby === 'random' ? 'selected' : '' ?> value="random">Zufall</option>
</select>
</form>
<?php else: ?>
<button type="button" class="btn btn-outline-secondary my-2 my-sm-0" data-bs-toggle="modal"
data-bs-target="#loginModal">Login</button>
<?php endif; ?>
<form class="form-inline" action="" method="POST">
<input type="hidden" name="csrf" value="<?= e($_SESSION['csrf']) ?>">
<select class="form-control" name="sortby" id="sortby">
<option <?= $sortby === 'priority' ? 'selected' : '' ?> value="priority">Priorität</option>
<option <?= $sortby === 'price_asc' ? 'selected' : '' ?> value="price_asc">Preis aufsteigend</option>
<option <?= $sortby === 'price_desc' ? 'selected' : '' ?> value="price_desc">Preis absteigend</option>
<option <?= $sortby === 'date_desc' ? 'selected' : '' ?> value="date_desc">Datum, neu → alt</option>
<option <?= $sortby === 'date_asc' ? 'selected' : '' ?> value="date_asc">Datum, alt → neu</option>
<option <?= $sortby === 'random' ? 'selected' : '' ?> value="random">Zufall</option>
</select>
</form>
</div>
</div>
</div>
@@ -314,13 +342,46 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
</div>
<?php endif; ?>
<?php wishlistMainBuilder($ListID, $sortby); ?>
<?php if (!empty($showCreateEmptyState)): ?>
<!-- Empty State -->
<section class="py-5 text-center container">
<div class="row py-lg-4">
<div class="col-lg-8 col-md-10 mx-auto">
<h1 class="fw-light">Willkommen bei Simple Wishlist</h1>
<p class="lead text-muted">
Es wurde keine gültige Liste ausgewählt. Du kannst jetzt eine neue Liste anlegen.
</p>
<p>
<button class="btn btn-success btn-lg" data-bs-toggle="modal" data-bs-target="#createListModal">
Neue Liste anlegen
</button>
</p>
</div>
</div>
</section>
<?php else: ?>
<?php wishlistMainBuilder($ListID, $sortby); ?>
<?php endif; ?>
</main>
<footer class="text-muted py-5">
<footer class="mt-5 text-center text-muted small">
<div class="container">
<p class="float-end mb-1"><a href="#">Back to top</a></p>
<p class="mb-1">Simple Wishlist &copy; by Marcel Peterkau</p>
<hr class="mb-3 opacity-25">
<p class="mb-1">
Made with
<img src="img/heart-icon.png" alt="Shakaru" class="icon-sm mx-1">
and
<img src="img/paw-icon.png" alt="Paw" class="icon-sm mx-1">
by
<strong>
<img src="img/shakaru-icon.png" alt="Shakaru" class="icon-sm mx-1">
Shakaru
</strong>
</p>
<p class="mb-0">
&copy; <?= date('Y') ?> Simple Wishlist · Marcel Peterkau
· <a href="#" class="text-decoration-none">Back to top ↑</a>
</p>
</div>
</footer>
@@ -478,6 +539,42 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
</div>
</div>
<!-- Create List Modal -->
<div class="modal fade" id="createListModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Neue Liste anlegen</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
</div>
<form action="" method="POST">
<div class="modal-body">
<div class="mb-3">
<label for="listName" class="form-label">Titel der Liste</label>
<input type="text" class="form-control" id="listName" name="listName" required maxlength="255">
</div>
<div class="mb-3">
<label for="listDescription" class="form-label">Beschreibung (optional)</label>
<textarea class="form-control" id="listDescription" name="listDescription" rows="3"></textarea>
</div>
<div class="mb-3">
<label for="listPassword" class="form-label">Admin-Passwort (zum Bearbeiten)</label>
<input type="password" class="form-control" id="listPassword" name="listPassword" required>
<div class="form-text">
Dieses Passwort brauchst du später für Login/Bearbeitung der Liste.
</div>
</div>
</div>
<div class="modal-footer">
<input type="hidden" name="csrf" value="<?= e($_SESSION['csrf']) ?>">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
<button type="submit" class="btn btn-primary" name="listadd">Anlegen</button>
</div>
</form>
</div>
</div>
</div>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/jquery.min.js"></script>
<script src="js/wishlist.js"></script>