diff options
| author | Mathias Magnusson <mathias@magnusson.space> | 2025-09-23 00:07:35 +0200 |
|---|---|---|
| committer | Mathias Magnusson <mathias@magnusson.space> | 2025-09-23 00:07:35 +0200 |
| commit | c70851504652267c95194a98756c6875271cdda7 (patch) | |
| tree | 2c7cd22ad17567e907d36ccf76d7fcad6073a6e1 | |
| parent | a2827963fbf6847166360be635c65dc85d20dd0d (diff) | |
| download | traedgaardstomten-c70851504652267c95194a98756c6875271cdda7.tar.gz | |
Implement reviews
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 19 | ||||
| -rw-r--r-- | compose.yaml | 3 | ||||
| -rw-r--r-- | include/layout.php | 14 | ||||
| -rw-r--r-- | include/sqlite.php | 19 | ||||
| -rw-r--r-- | nginx.conf | 3 | ||||
| -rw-r--r-- | public/index.php | 12 | ||||
| -rw-r--r-- | public/kontakt.php | 10 | ||||
| -rw-r--r-- | public/omdömen.php | 32 | ||||
| -rw-r--r-- | public/omdömen/edit.php | 33 | ||||
| -rw-r--r-- | public/omdömen/index.php | 60 | ||||
| -rw-r--r-- | public/style.css | 6 |
12 files changed, 155 insertions, 57 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82f0c3a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/data/ @@ -2,3 +2,22 @@ Optimize images: ```sh magick $x.jpg -interlace Plane -quality 80 inter-$x.jpg ``` + +Init database: +```sh +mkdir data +sqlite3 data/data.db +``` + +```sql +PRAGMA journal_mode=WAL; +create table reviews ( + name text not null, + content text not null +) strict; +``` + +```sh +chmod a+w data/ +chmod a+w data/data.db +``` diff --git a/compose.yaml b/compose.yaml index 6e78b8c..244a83c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -7,6 +7,9 @@ services: volumes: - ./public:/var/www/trädgårdstomten/public:ro - ./include:/var/www/trädgårdstomten/include:ro + - ./data:/data:rw + - type: tmpfs + target: /tmp nginx: image: docker.io/nginx:1.27-alpine restart: unless-stopped diff --git a/include/layout.php b/include/layout.php index ba79595..7bc67d2 100644 --- a/include/layout.php +++ b/include/layout.php @@ -1,6 +1,6 @@ <?php -include "defer.php"; +require "defer.php"; function layout(&$context): void { ?> @@ -13,8 +13,20 @@ function layout(&$context): void { <link rel="stylesheet" href="/style.css"> <script src="https://unpkg.com/hyperscript.org@0.9.14" crossorigin="anonymous" integrity="sha384-NzchC8z9HmP/Ed8cheGl9XuSrFSkDNHPiDl+ujbHE0F0I7tWC4rUnwPXP+7IvVZv"></script> + <script src="https://unpkg.com/htmx.org@2.0.7" crossorigin="anonymous" + integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ"></script> </head> <body> +<header> + <section> + <p>Trädgårdstomten ✂️</p> + </section> + <nav> + <a href="/">Tjänster</a> + <a href="/omdömen">Omdömen</a> + <a href="/kontakt">Kontakt</a> + </nav> +</header> <?php defer($context, function () { echo "</body></html>"; }); } diff --git a/include/sqlite.php b/include/sqlite.php new file mode 100644 index 0000000..6759e36 --- /dev/null +++ b/include/sqlite.php @@ -0,0 +1,19 @@ +<?php + +$db = new SQLite3("/data/data.db"); + +function query($q, ...$values) { + global $db; + + $stmt = $db->prepare($q); + foreach ($values as $key => $value) { + $stmt->bindValue(is_int($key) ? $key + 1 : $key, $value); + } + return $stmt->execute(); +} + +function lastRowId() { + global $db; + + return $db->lastInsertRowId(); +} @@ -5,9 +5,10 @@ server { } server { - listen 8009; + listen 8009 default_server; server_name xn--trdgrdstomten-cfbr.se; root /var/www/trädgårdstomten/public; + rewrite ^/([^/]+/)*[^.]+[^/]$ $http_x_forwarded_proto://$host$request_uri/ permanent; set_real_ip_from 127.0.0.1/8; gzip on; default_type "text/html"; diff --git a/public/index.php b/public/index.php index 8e6f565..0dd4d48 100644 --- a/public/index.php +++ b/public/index.php @@ -1,16 +1,6 @@ <?php require "../include/layout.php"; layout($_); ?> -<header> - <section> - <p>Trädgårdstomten ✂️</p> - </section> - <nav> - <a href="/">Tjänster</a> - <a href="/omdömen">Omdömen</a> - <a href="/kontakt">Kontakt</a> - </nav> -</header> <main> - <article> + <article id="about-text"> <p style="grid-area: p1"> Jag heter Lucas Magnusson, är 26 år gammal och har flera års yrkeserfarenhet och är även utbildad inom trädgård. Jag har alltid varit intresserad av allt som diff --git a/public/kontakt.php b/public/kontakt.php index a23e0c6..ed60c0d 100644 --- a/public/kontakt.php +++ b/public/kontakt.php @@ -1,14 +1,4 @@ <?php require "../include/layout.php"; layout($_); ?> -<header> - <section> - <p>Trädgårdstomten ✂️</p> - </section> - <nav> - <a href="/">Tjänster</a> - <a href="/omdömen">Omdömen</a> - <a href="/kontakt">Kontakt</a> - </nav> -</header> <main> <p>Kontakta mig gärna så hör jag av mig så fort jag kan!</p> <br> diff --git a/public/omdömen.php b/public/omdömen.php deleted file mode 100644 index c4a912a..0000000 --- a/public/omdömen.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php require "../include/layout.php"; layout($_); ?> -<header> - <section> - <p>Trädgårdstomten ✂️</p> - </section> - <nav> - <a href="/">Tjänster</a> - <a href="/omdömen">Omdömen</a> - <a href="/kontakt">Kontakt</a> - </nav> -</header> -<main> - <div class="height-transition-wrapper"> - <form> - <label for="name">Namn:</label> - <input type="text" name="name" id="name"> - <br> - <label for="review">Omdöme:</label> - <textarea name="review" id="review"></textarea> - <br> - <button>Skicka!</button> - </form> - </div> - <button _=" - on click - toggle .open on previous <div/> - if (previous <div/>) match .open then - set my.innerText to 'Stäng formulär' - else - set my.innerText to 'Lämna ett omdöme' - ">Lämna ett omdöme</button> -</main> diff --git a/public/omdömen/edit.php b/public/omdömen/edit.php new file mode 100644 index 0000000..00b2d3b --- /dev/null +++ b/public/omdömen/edit.php @@ -0,0 +1,33 @@ +<?php +require "../../include/sqlite.php"; + +session_start(); + +if (!isset($_SESSION["editable review"])) die("Kan ej redigera något omdöme."); + +$rowid = $_SESSION["editable review"]; +$res = query('select name, content from reviews where rowid = ?', $rowid); +$review = (object) $res->fetchArray(); + +if ($_SERVER["REQUEST_METHOD"] === "POST") { + $name = $_POST["name"]; + $content = $_POST["content"]; + + query("update reviews set name = ?, content = ? where rowid = ?", $name, $content, $rowid); + + header("HX-Redirect: /omd%c3%b6men/"); + exit; +} + +require "../../include/layout.php"; layout($_); +?> + +<form hx-post="/omdömen/edit/"> + <label for="name">Namn:</label> + <input type="text" name="name" id="name" value="<?= htmlspecialchars($review->name) ?>"> + <br> + <label for="content" style="vertical-align: top">Omdöme:</label> + <textarea name="content" id="content" style="height: 10em; width: 20em"><?= htmlspecialchars($review->content) ?></textarea> + <br> + <button>Skicka!</button> +</form> diff --git a/public/omdömen/index.php b/public/omdömen/index.php new file mode 100644 index 0000000..53a9123 --- /dev/null +++ b/public/omdömen/index.php @@ -0,0 +1,60 @@ +<?php +require "../../include/sqlite.php"; + +session_start(); + +if ($_SERVER["REQUEST_METHOD"] === "POST") { + $name = $_POST["name"]; + $content = $_POST["content"]; + + query("insert into reviews (name, content) values (?, ?)", $name, $content); + + $_SESSION["editable review"] = lastRowId(); + + header("HX-Refresh: true"); + exit; +} + +$res = query('select rowid, name, content from reviews'); +$reviews = []; +while ($row = $res->fetchArray()) { + $row["editable"] = isset($_SESSION["editable review"]) && $_SESSION["editable review"] === $row["rowid"]; + $row = (object) $row; + $reviews[] = $row; +} + +require "../../include/layout.php"; layout($_); +?> +<main> + <div class="height-transition-wrapper"> + <form hx-post="/omdömen/"> + <label for="name">Namn:</label> + <input type="text" name="name" id="name"> + <br> + <br> + <label for="content" style="vertical-align: top">Omdöme:</label> + <textarea name="content" id="content" style="height: 10em; width: 20em"></textarea> + <br> + <button>Skicka!</button> + <p style="margin-bottom: 1em; font-size: 0.8em"><i>Du kommer kunna redigera ditt omdöme tills du stänger fliken</i></p> + </form> + </div> + <button _=" + on click + toggle .open on previous <div/> + if (previous <div/>) match .open then + set my.innerText to 'Stäng formulär' + else + set my.innerText to 'Lämna ett omdöme' + ">Lämna ett omdöme</button> + + <? foreach ($reviews as $review) { ?> + <article style="padding: 0.25em;"> + <p><i style="color: #333"><?= htmlspecialchars($review->name) ?>:</i></p> + <p style="white-space: pre-line"><?= htmlspecialchars($review->content) ?></p> + <? if ($review->editable) { ?> + <a class="nf nf-fa-edit" href="/omdömen/edit/"></a> + <? } ?> + </article> + <? } ?> +</main> diff --git a/public/style.css b/public/style.css index 6f145db..c157f7d 100644 --- a/public/style.css +++ b/public/style.css @@ -1,3 +1,5 @@ +@import "https://www.nerdfonts.com/assets/css/webfont.css"; + * { margin: 0; box-sizing: border-box; @@ -62,7 +64,7 @@ main { margin-inline: auto; } -main article { +#about-text { padding-bottom: 4em; display: grid; gap: 2em; @@ -71,7 +73,7 @@ main article { } @media (min-width: 500px) { - main article { + #about-text { grid-template-columns: auto auto; grid-template-areas: "p1 img" "p2 p2" "p3 p3"; } |
