4 Commits
Author SHA1 Message Date
jakob48 1d7389d44c README.md aktualisiert 2026-09-30 10:32:55 +02:00
jakob48 cbd62262d9 README.md aktualisiert 2026-09-29 18:59:29 +02:00
jakob48 1104c3ab25 fix 2026-09-28 22:07:02 +02:00
jakob48 50e0c10743 1.1.0 2026-09-28 22:03:00 +02:00
9 changed files with 244 additions and 132 deletions
View File
+62 -6
View File
@@ -1,15 +1,71 @@
# Wunschliste
Dies ist eine einfache Wunschliste gemacht mit PHP!
Eine einfache Wunschliste gemacht mit PHP und Tailwind CSS!
## Installation
Du installierst es einfach in dem du die ZIP Datei von den Releases Herunterlädst und es in dein Webserver mit PHP Hochlädst.
Einfach die .zip Datei von den releases downloaden und in deinem PHP fähigen Webserver hochladen.
Du kannst außerdem in der config.php deinen Namen angeben der Dan überall steht.
Mit in /admin befindet sich das Admin Panel wo die die einträge verwalten kanst.
Unter `/admin` findest du die Admin Seite wo du die Einträge bearbeiten kanst.
> [!Warning]
> Die /admin Seite ist Standardmäßig nicht geschützt! Bitte schütze diese mit z.b. einem Login über den Webserver
> Die `/admin` Seite ist standardmäßig nicht geschützt! Bitte schütze diese mit z.b. einem Login über den Webserver oder die Apache OAuth Erweiterung.
## Konfiguration
In der `config.php` Datei kanst du deinen Namen und die Farbpalette der Seite ändern. Beispiel:
```
// Seiten Name:
$page_name = 'Jakob';
// THEME -----------------------------
// Light Mode
$color_bg_light = "#ededed";
$color_fg_light = "#000000";
$color_accent_light = "#278de6";
// Dark Mode
$color_bg_dark = "#191919";
$color_fg_dark = "#ffffff";
$color_accent_dark = "#278de6";
```
# EN
# Wish List
A simple wish list built with PHP and Tailwind CSS!
## Installation
Simply download the .zip file from the releases page and upload it to your PHP-enabled web server.
You’ll find the admin page at `/admin`, where you can edit the entries.
> [!Warning]
> The `/admin` page is not protected by default! Please secure it using, for example, a login via the web server or the Apache OAuth extension.
## Configuration
In the `config.php` file, you can change your name and the site’s color palette. Example:
```
// Seiten Name:
$page_name = 'Jakob';
// THEME -----------------------------
// Light Mode
$color_bg_light = "#ededed";
$color_fg_light = "#000000";
$color_accent_light = "#278de6";
// Dark Mode
$color_bg_dark = "#191919";
$color_fg_dark = "#ffffff";
$color_accent_dark = "#278de6";
```
+1 -1
View File
@@ -9,7 +9,7 @@ $name = $_POST["name"] ?? '';
$link = $_POST["link"] ?? '';
$price = $_POST["price"] ?? '';
$jsonFile = '../wishes.json';
$jsonFile = '../assets/data.json';
$wishes = [];
if (file_exists($jsonFile)) {
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
$id = intval($_GET["id"]);
$jsonFile = '../wishes.json';
$jsonFile = '../assets/data.json';
if (file_exists($jsonFile)) {
$wishes = json_decode(file_get_contents($jsonFile), true);
+1 -1
View File
@@ -4,7 +4,7 @@ $link = $_POST["link"];
$price = $_POST["price"];
$id = intval($_POST["id"]);
$jsonFile = '../wishes.json';
$jsonFile = '../assets/data.json';
if (file_exists($jsonFile)) {
$wishes = json_decode(file_get_contents($jsonFile), true);
+94 -59
View File
@@ -1,67 +1,102 @@
<?php
require_once '../config.php';
ini_set("display_errors", 1);
error_reporting(E_ALL);
$jsonFile = '../assets/data.json';
$wishes = [];
if (file_exists($jsonFile)) {
$jsonData = file_get_contents($jsonFile);
$wishes = json_decode($jsonData, true);
if (!$wishes) $wishes = [];
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wunschliste von <?php include '../config.php'; echo $page_name; ?> [ADMIN]</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<?php
if (isset($_GET["error"])) {
echo '<div class="alert alert-danger" role="alert">
Dateisystem Fehler (Schreibrechte prüfen!).
</div>';
}
?>
<div class="container py-5">
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
<?php
ini_set("display_errors", 1);
error_reporting(E_ALL);
$jsonFile = '../wishes.json';
$wishes = [];
if (file_exists($jsonFile)) {
$jsonData = file_get_contents($jsonFile);
$wishes = json_decode($jsonData, true);
if (!$wishes) $wishes = [];
}
foreach ($wishes as $row) {
echo '
<div class="col">
<div class="card link-card h-100">
<div class="card-body">
<form action="edit.php" method="post">
<input type="hidden" name="id" value="' . $row["id"] . '">
<input type="text" name="name" class="form-control mb-2" value="' . htmlspecialchars($row["name"]) . '">
<input type="text" name="link" class="form-control mb-2" value="' . htmlspecialchars($row["link"]) . '">
<input type="text" name="price" class="form-control mb-2" value="' . htmlspecialchars($row["price"]) . '">
<button type="submit" class="btn btn-primary">Speichern</button>
<a href="delete.php?id=' . $row["id"] . '" class="btn btn-danger float-end">Löschen</a>
</form>
</div>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wunschliste von <?= htmlspecialchars($page_name) ?> [ADMIN]</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
:root {
--bg: <?= $color_bg_light ?>;
--fg: <?= $color_fg_light ?>;
--accent: <?= $color_accent_light ?>;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: <?= $color_bg_dark ?>;
--fg: <?= $color_fg_dark ?>;
--accent: <?= $color_accent_dark ?>;
}
}
</style>
</head>
<body class="min-h-screen bg-[var(--bg)] text-[var(--fg)] transition-colors">
<div class="max-w-5xl mx-auto px-4 py-10">
<h1 class="text-3xl sm:text-4xl font-bold text-center mb-8">
Wunschliste von <?= htmlspecialchars($page_name) ?> [ADMIN]
</h1>
<?php if (isset($_GET["error"])): ?>
<div class="mb-6 rounded-lg border border-red-300 bg-red-50 text-red-700 px-4 py-3 text-sm">
Dateisystem Fehler (Schreibrechte prüfen!).
</div>
<?php endif; ?>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<?php foreach ($wishes as $row):
$id = $row["id"] ?? '';
$name = $row["name"] ?? '';
$link = $row["link"] ?? '';
$price = $row["price"] ?? '';
?>
<div class="bg-[var(--bg)] border border-[var(--fg)]/10 rounded-xl shadow-sm p-5">
<form action="edit.php" method="post" class="space-y-2">
<input type="hidden" name="id" value="<?= htmlspecialchars($id) ?>">
<input type="text" name="name" value="<?= htmlspecialchars($name) ?>"
class="w-full rounded-lg border border-[var(--fg)]/20 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)]">
<input type="text" name="link" value="<?= htmlspecialchars($link) ?>"
class="w-full rounded-lg border border-[var(--fg)]/20 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)]">
<input type="text" name="price" value="<?= htmlspecialchars($price) ?>"
class="w-full rounded-lg border border-[var(--fg)]/20 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)]">
<div class="flex items-center justify-between pt-1">
<button type="submit"
class="rounded-lg bg-[var(--accent)] text-white px-4 py-2 text-sm font-medium hover:opacity-90 transition-opacity">
Speichern
</button>
<a href="delete.php?id=<?= urlencode($id) ?>"
class="rounded-lg border border-red-300 text-red-600 px-4 py-2 text-sm font-medium hover:bg-red-50 transition-colors">
Löschen
</a>
</div>
</div>';
}
?>
<div class="col">
<div class="card link-card h-100">
<div class="card-body">
<h5 class="card-title">Neuer Wunsch</h5>
<form action="add.php" method="post">
<input type="text" name="name" class="form-control mb-2" placeholder="Name">
<input type="text" name="link" class="form-control mb-2" placeholder="URL">
<input type="text" name="price" class="form-control mb-2" placeholder="Preis">
<button type="submit" class="btn btn-primary">Hinzufügen</button>
</form>
</div>
</div>
</form>
</div>
<?php endforeach; ?>
<div class="bg-[var(--bg)] border border-[var(--fg)]/10 rounded-xl shadow-sm p-5">
<h2 class="font-semibold mb-3">Neuer Wunsch</h2>
<form action="add.php" method="post" class="space-y-2">
<input type="text" name="name" placeholder="Name"
class="w-full rounded-lg border border-[var(--fg)]/20 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)]">
<input type="text" name="link" placeholder="URL"
class="w-full rounded-lg border border-[var(--fg)]/20 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)]">
<input type="text" name="price" placeholder="Preis"
class="w-full rounded-lg border border-[var(--fg)]/20 bg-transparent px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--accent)]">
<button type="submit"
class="w-full rounded-lg bg-[var(--accent)] text-white px-4 py-2 text-sm font-medium hover:opacity-90 transition-opacity">
Hinzufügen
</button>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</div>
</body>
</html>
+1 -1
View File
@@ -7,7 +7,7 @@
},
{
"id": 2,
"name": "Wunsch 1",
"name": "Wunsch 2",
"link": "https:\/\/jakob48.de",
"price": "12 EUR"
}
+14 -2
View File
@@ -9,5 +9,17 @@
// |___/
// DEIN NAME HIER:
$page_name = 'Jakob';
// Seiten Name:
$page_name = 'Jakob';
// THEME -----------------------------
// Light Mode
$color_bg_light = "#ededed";
$color_fg_light = "#000000";
$color_accent_light = "#278de6";
// Dark Mode
$color_bg_dark = "#191919";
$color_fg_dark = "#ffffff";
$color_accent_dark = "#278de6";
+70 -61
View File
@@ -1,69 +1,78 @@
<?php
require_once 'config.php';
$jsonFile = 'assets/data.json';
$wishes = [];
if (file_exists($jsonFile)) {
$jsonData = file_get_contents($jsonFile);
$wishes = json_decode($jsonData, true);
if (!$wishes)
$wishes = [];
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wunschliste von <?php include 'config.php'; echo $page_name; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
transition: background-color 0.3s, color 0.3s;
margin: 100px;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #1a1a1a;
color: #f0f0f0;
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wunschliste von <?= htmlspecialchars($page_name) ?></title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
:root {
--bg: <?= $color_bg_light ?>;
--fg: <?= $color_fg_light ?>;
--accent: <?= $color_accent_light ?>;
}
a {
color: #8ab4f8;
}
}
@media (max-whidth: 600px) {
body {
margin: 8px;
}
}
</style>
</head>
<body">
<h1 style="margin: 15px;">Wunschliste von <?php include 'config.php'; echo $page_name; ?> 🎁</h1>
<div class="content">
<?php
$jsonFile = 'wishes.json';
$wishes = [];
if (file_exists($jsonFile)) {
$jsonData = file_get_contents($jsonFile);
$wishes = json_decode($jsonData, true);
if (!$wishes) $wishes = [];
@media (prefers-color-scheme: dark) {
:root {
--bg: <?= $color_bg_dark ?>;
--fg: <?= $color_fg_dark ?>;
--accent: <?= $color_accent_dark ?>;
}
}
</style>
</head>
foreach ($wishes as $row) {
$id = $row["id"] ?? uniqid();
$name = $row["name"] ?? '';
$link = $row["link"] ?? '';
$price = $row["price"] ?? '';
<body class="min-h-screen bg-[var(--bg)] text-[var(--fg)] transition-colors">
<div class="max-w-2xl mx-auto px-4 py-10">
<h1 class="text-3xl sm:text-4xl font-bold text-center mb-8">
Wunschliste von <?= htmlspecialchars($page_name) ?> 🎁
</h1>
echo '<div class="accordion accordion-flush" id="accordionFlushExample">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-' . $id . '" aria-expanded="false" aria-controls="flush-collapseOne">
' . htmlspecialchars($name) . '
</button>
</h2>
<div id="collapse-' . $id . '" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
<div class="accordion-body"><a href="' . htmlspecialchars($link) . '" target="_blank">Zum Produkt</a>, ' . htmlspecialchars($price) . '</div>
<div class="space-y-3">
<?php foreach ($wishes as $row):
$id = $row["id"] ?? uniqid();
$name = $row["name"] ?? '';
$link = $row["link"] ?? '';
$price = $row["price"] ?? '';
?>
<details class="group bg-[var(--bg)] border border-[var(--fg)]/10 rounded-xl shadow-sm overflow-hidden">
<summary class="flex items-center justify-between gap-3 px-5 py-4 cursor-pointer select-none font-medium hover:opacity-80 transition-opacity list-none">
<span><?= htmlspecialchars($name) ?></span>
<svg class="w-5 h-5 shrink-0 transition-transform duration-200 group-open:rotate-180"
fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
</svg>
</summary>
<div class="px-5 pb-4 pt-1 border-t border-[var(--fg)]/10 flex items-center justify-between flex-wrap gap-2">
<a href="<?= htmlspecialchars($link) ?>" target="_blank" rel="noopener"
class="text-[var(--accent)] hover:underline font-medium">
Zum Produkt ↗
</a>
<span class="text-sm font-semibold opacity-70 border border-[var(--fg)]/20 px-3 py-1 rounded-full">
<?= htmlspecialchars($price) ?>
</span>
</div>
</details>
<?php endforeach; ?>
<?php if (empty($wishes)): ?>
<p class="text-center opacity-50 py-10">Noch keine Wünsche eingetragen.</p>
<?php endif; ?>
</div>
</div>
</div>
</div>';
}
?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
</body>
</html>