Compare commits

..

No commits in common. "bd151ab4e671ce25f1bd531862d6cbc9f03e6593" and "f7a7c3457bdaed4aadfe29ce4ff8e0b61529d6ae" have entirely different histories.

20 changed files with 163 additions and 164 deletions

View File

@ -5,9 +5,8 @@ https://gitea.haschek.at/Crispi/dogstats
## Techstack
- [HTMX](https://htmx.org/docs/)
- [Bootstrap 5](https://getbootstrap.com/docs/5.3/layout/breakpoints/)
- [Tailwind](https://flowbite.com/docs/components/accordion/)
- [Font Awesome 5 Pro](https://fontawesome.com/v5/search)
- [Animate.css](https://animate.style/)
## Start Dev
@ -19,9 +18,21 @@ Config file erstellen bzw kopieren
2. Datei `example.config.inc.php` umbenennen auf `config.inc.php`
3. Gegebenenfalls Werte anpassen in der Config
### Jedes Mal
### Linux
Im Terminal dann Webserver starten
Erst Tailwind starten
1. `cd tools`
2. `./tailwindcss-linux-x64 -i ../web/css/input.css -o ../web/css/output.css --watch`
### Windows
Erst Tailwind starten
1. `cd tools`
2. `./tailwindcss-windows-x64.exe -i ../web/css/input.css -o ../web/css/output.css --watch`
In zweitem Terminal dann Webserver starten
1. `cd web`
2. `php -S localhost:8080`

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
web/css/flowbite.min.css vendored Normal file

File diff suppressed because one or more lines are too long

3
web/css/input.css Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -65,10 +65,13 @@ class Model {
{
if(isset($this->data[$field]))
{
error_log($field.' -> '.$options['type']);
if($options['type']=='array')
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,json_encode($this->data[$field]));
else
{
error_log("hset $this->dbTable:$this->id $field {$this->data[$field]}");
$GLOBALS['redis']->hset($this->dbTable.':'.$this->id,$field,$this->data[$field]);
}
}
@ -82,7 +85,7 @@ class Model {
{
$this->id = $id;
if(!$GLOBALS['redis']->exists($this->dbTable.':'.$this->id))
throw new Exception($this->dbTable.':'.$this->id.' not found');
return false;
$keys = array_keys($this->dbFields);
foreach($keys as $key)

File diff suppressed because one or more lines are too long

2
web/js/flowbite.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -9,8 +9,8 @@ class Dog extends Model {
'kennel_name' => ['type'=>'text'],
'breed' => ['type'=>'text'],
'size' => ['type'=>'text'], //in cm
'birthday' => ['type'=>'text'],
'agility_size' => ['type'=>'text'], //S,M,I,L
'birthday' => ['type'=>'int'], //unix timestamp
'agility_size' => ['type'=>'int'], //S,M,I,L
'active' => ['type'=>'int','default'=>1]
);

View File

@ -19,18 +19,14 @@ class Dogs extends Page {
$dogs = $_SESSION['user']->data['dogs'];
$doggos = [];
foreach($dogs as $key => $dogid)
foreach($dogs as $dogid)
{
//var_dump($dogid);
$dog = new Dog();
try{
$dog->load($dogid);
}
catch(Exception $e)
{
error_log("Dog $dogid not found. Deleting from user");
unset($_SESSION['user']->data['dogs'][$key]);
$_SESSION['user']->save();
continue;
}
if($dog->data)

View File

@ -1,5 +1,5 @@
<div>
<h1>Hund hinzufügen/bearbeiten</h1>
<div class="container mx-auto">
<h1 class="text-4xl md:text-5xl">Hund hinzufügen/bearbeiten</h1>
<form hx-post="/dogs/edit" hx-target="#response">
<input type="hidden" name="dog_id" value="<?= $dogid; ?>">
@ -32,7 +32,7 @@
<option value="L" <?= $dogdata['agility_size']=='L'?'selected':''; ?>>L</option>
</select>
</div>
<button type="submit" name="submit" value="true" class="btn btn-primary">Submit</button>
<button type="submit" name="submit" value="true" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Submit</button>
</form>
<div id="response"></div>
</div>

View File

@ -1,43 +1,48 @@
<h1">Meine Hunde</h1>
<h1 class="text-2xl p-6 text-center">Meine Hunde</h1>
<div class="container flex justify-center mx-auto">
<div class="flex flex-col">
<div class="w-full">
<div class="border-b border-gray-200 shadow">
<table class="divide-y divide-gray-300 ">
<thead class="bg-gray-50">
<tr>
<?php foreach (array_keys($doggos[0]) as $key) : ?>
<th class="px-6 py-2 text-xs text-gray-500">
<?= $key ?>
</th>
<?php endforeach; ?>
<figure>
<table>
<thead>
<tr>
<?php foreach (array_keys($doggos[0]) as $key) : ?>
<th>
<?= $key ?>
</th>
<?php endforeach; ?>
<th class="px-6 py-2 text-xs text-gray-500">
Bearbeiten
</th>
<th class="px-6 py-2 text-xs text-gray-500">
Löschen
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-300">
<?php foreach ($doggos as $dog) : ?>
<th>
Bearbeiten
</th>
<th>
Löschen
</th>
</tr>
</thead>
<tbody>
<?php foreach ($doggos as $dog) : ?>
<tr class="whitespace-nowrap">
<?php foreach (array_keys($dog) as $key) : ?>
<td class="px-6 py-4 text-sm text-gray-500">
<?= $dog[$key] ?>
</td>
<?php endforeach; ?>
<tr>
<?php foreach (array_keys($dog) as $key) : ?>
<td>
<?= $dog[$key] ?>
</td>
<?php endforeach; ?>
<td class="px-6 py-4">
<button hx-get="/dogs/edit/<?= $dog['id'] ?>" hx-push-url="/dogs/edit/<?= $dog['id'] ?>" hx-target="#main" class="px-4 py-1 text-sm text-indigo-600 bg-indigo-200 rounded-full">Bearbeiten</button>
</td>
<td class="px-6 py-4">
<button hx-get="/dogs/delete/<?= $dog['id'] ?>" hx-target="#main" class="px-4 py-1 text-sm text-red-400 bg-red-200 rounded-full">Löschen</button>
</td>
</tr>
<td>
<button hx-get="/dogs/edit/<?= $dog['id'] ?>" hx-push-url="/dogs/edit/<?= $dog['id'] ?>" hx-target="#main" >Bearbeiten</button>
</td>
<td>
<button hx-get="/dogs/delete/<?= $dog['id'] ?>" hx-target="#main" >Löschen</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</figure>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@ -1,7 +1,6 @@
<div class="hidden sm:mb-8 sm:flex sm:justify-center">
<div class="relative rounded-full px-3 py-1 text-sm leading-6 text-gray-600 ring-1 ring-gray-900/10 hover:ring-gray-900/20">
Currently logged in as:
<?= $_SESSION['userid']?:'nobody' ?>
Currently logged in as: <?= $_SESSION['userid']?:'nobody' ?>
</div>
</div>
<div class="text-center">
@ -15,44 +14,51 @@
</div>
</div>
<h1>Admin stuff</h1>
<figure>
<table role="grid">
<thead>
<tr>
<?php foreach (array_keys($userdata[0]) as $key) : ?>
<th>
<?= $key ?>
</th>
<?php endforeach; ?>
<h1 class="text-2xl p-6 text-center">Admin stuff</h1>
<th>
Login
</th>
<th>
Edit
</th>
</tr>
</thead>
<tbody>
<?php foreach ($userdata as $user) : ?>
<div class="container flex justify-center mx-auto">
<div class="flex flex-col">
<div class="w-full">
<div class="border-b border-gray-200 shadow">
<table class="divide-y divide-gray-300 ">
<thead class="bg-gray-50">
<tr>
<?php foreach (array_keys($userdata[0]) as $key) : ?>
<th class="px-6 py-2 text-xs text-gray-500">
<?= $key ?>
</th>
<?php endforeach; ?>
<tr>
<?php foreach (array_keys($user) as $key) : ?>
<td class="px-6 py-4 text-sm text-gray-500">
<?= is_array($user[$key])?json_encode($user[$key]):$user[$key] ?>
</td>
<?php endforeach; ?>
<th class="px-6 py-2 text-xs text-gray-500">
Login
</th>
<th class="px-6 py-2 text-xs text-gray-500">
Edit
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-300">
<?php foreach ($userdata as $user) : ?>
<td>
<button name="email" value="<?= $user['email'] ?>" hx-post="/admin/loginas/">Login</button>
</td>
<td>
<button name="email" value="<?= $user['email'] ?>" hx-post="/admin/edituser/" hx-target="#main">Edit</button>
</td>
</tr>
<tr class="whitespace-nowrap">
<?php foreach (array_keys($user) as $key) : ?>
<td class="px-6 py-4 text-sm text-gray-500">
<?= is_array($user[$key])?json_encode($user[$key]):$user[$key] ?>
</td>
<?php endforeach; ?>
<?php endforeach; ?>
</tbody>
</table>
</figure>
<td class="px-6 py-4">
<button name="email" value="<?= $user['email'] ?>" hx-post="/admin/loginas/" class="px-4 py-1 text-sm text-indigo-600 bg-indigo-200 rounded-full">Login as this user</button>
</td>
<td class="px-6 py-4">
<button name="email" value="<?= $user['email'] ?>" hx-post="/admin/edituser/" hx-target="#main" class="px-4 py-1 text-sm text-red-400 bg-red-200 rounded-full">Edit</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@ -5,23 +5,24 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dogstats</title>
<link href="/css/animate.min.css" rel="stylesheet">
<link href="/css/output.css" rel="stylesheet">
<link href="/css/fontawesome.min.css" rel="stylesheet">
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/style.css" rel="stylesheet">
<link href="/css/flowbite.min.css" rel="stylesheet">
</head>
<body>
<?php include(ROOT."/templates/menu.html") ?>
<div class="bg-white">
<main id="main" class="container" hx-get="/" hx-trigger="load" hx-indicator="#spinner">
<i id="spinner" class="fa-solid fa-spinner"></i>
</main>
<?php include(ROOT."/templates/menu.html") ?>
<div id="main" hx-get="/" hx-trigger="load" hx-indicator="#spinner">
<i id="spinner" class="fa-solid fa-spinner"></i>
</div>
</div>
<script src="/js/htmx.min.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
<script src="/js/flowbite.min.js"></script>
</body>
</html>

View File

@ -1,27 +1,25 @@
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="/home" hx-push-url="/home" hx-get="/home" hx-target="#main">
<img src="/imgs/dogstats-50.png" alt="Logo" width="50" height="50" class="d-inline-block align-text-top">
Dogstats
<header class="text-gray-600 body-font">
<div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
<a class="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0">
<img class="h-8 w-auto" src="/imgs/dogstats-50.png" alt="">
<span class="ml-3 text-xl">Dogstats</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<nav class="md:ml-auto flex flex-wrap items-center text-base justify-center">
<?php foreach(getMenu() as $item) : ?>
<?php if (count($item['submenu'])) : ?>
<button id="dropdownDefaultButton-<?= $item['url'] ?>" data-dropdown-toggle="dropdown-<?= $item['url'] ?>" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" type="button">
<?= $item['text'] ?>
<svg class="w-2.5 h-2.5 ml-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4" />
</svg>
</button>
<?php foreach(getMenu() as $item) : ?>
<li <?php if (count($item['submenu'])) : ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<?= $item['text']?>
</a>
<ul class="dropdown-menu">
<?php foreach($item['submenu'] as $sub) : ?>
<div id="dropdown-<?= $item['url'] ?>" class="z-10 hidden bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700">
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownDefaultButton-<?= $item['url'] ?>">
<?php foreach($item['submenu'] as $sub) : ?>
<li>
<a href="<?= $sub['action'] ?>" hx-push-url="<?= $sub['action'] ?>" hx-get="<?= $sub['action'] ?>" hx-target="#main" class="dropdown-item <?= $sub['classes']?:'' ?>">
<a href="<?= $sub['action'] ?>" hx-push-url="<?= $sub['action'] ?>" hx-get="<?= $sub['action'] ?>" hx-target="#main" class="<?= $sub['classes']?:'' ?> block px-4 py-2">
<?php if($sub['icon']) : ?>
<i class="<?= $sub['icon'] ?>"></i>
<?php endif; ?>
@ -29,22 +27,16 @@
<?= $sub['text'] ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php else : ?>
<li class="nav-item">
<a class="nav-link" aria-current="page" href="/<?= $item['url'] ?>" hx-push-url="/<?= $item['url'] ?>" hx-get="/<?= $item['url'] ?>" hx-target="#main">
<i class="<?= $item['image'] ?>"></i>
<?= $item['text'] ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php else : ?>
<a href="/<?= $item['url'] ?>" hx-push-url="/<?= $item['url'] ?>" hx-get="/<?= $item['url'] ?>" hx-target="#main" class="mr-5 hover:text-gray-900"><i class="<?= $item['image'] ?>"></i>
<?= $item['text'] ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</nav>
<?php endif; ?>
</li>
<?php endforeach; ?>
</div>
</div>
</nav>
</header>

View File

@ -1,4 +1,4 @@
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 animate__animated animate__fadeInDown" role="alert">
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4" role="alert">
<p class="font-bold"><?= $errorTitle ?></p>
<p><?= $errorMessage ?></p>
</div>

View File

@ -1,4 +1,4 @@
<div class="bg-blue-100 border-l-4 border-blue-500 text-blue-700 p-4 animate__animated animate__fadeInDown" role="alert">
<div class="bg-blue-100 border-l-4 border-blue-500 text-blue-700 p-4" role="alert">
<p class="font-bold"><?= $infoTitle ?></p>
<p><?= $infoMessage ?></p>
</div>

View File

@ -1,4 +1,4 @@
<div class="bg-orange-100 border-l-4 border-orange-500 text-orange-700 p-4 animate__animated animate__fadeInDown" role="alert">
<div class="bg-orange-100 border-l-4 border-orange-500 text-orange-700 p-4" role="alert">
<p class="font-bold"><?= $title ?></p>
<p><?= $message ?></p>
</div>

View File

@ -1,4 +1,4 @@
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 animate__animated animate__fadeInDown" role="alert">
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4" role="alert">
<p class="font-bold"><?= $successTitle ?></p>
<p><?= $successMessage ?></p>
</div>