fine tuning
All checks were successful
Build and push / Pulling repo on server (push) Has been skipped

This commit is contained in:
Chris 2023-10-20 20:41:49 +02:00
parent 04af3a34bd
commit f85f354ee7
9 changed files with 308 additions and 113 deletions

11
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"recommendations": [
"zarifprogrammer.tailwind-snippets",
"dawhite.mustache",
"otovo-oss.htmx-tags",
"devsense.phptools-vscode",
"bmewburn.vscode-intelephense-client",
"github.copilot",
"github.copilot-chat"
]
}

View File

@ -70,9 +70,12 @@ function callHook($url)
$dispatch = new $componentName($component, $action, true, $queryString);
if (method_exists($componentName, $action)) {
call_user_func_array(array($dispatch, $action), $queryString);
$response = call_user_func_array(array($dispatch, $action), $queryString);
} else if (method_exists($componentName, 'catchAll'))
call_user_func_array(array($dispatch, 'catchAll'), array($params));
$response = call_user_func_array(array($dispatch, 'catchAll'), array($params));
return $dispatch->renderPagecontent();
if(is_string($response))
return $response;
else
return $dispatch->renderPagecontent();
}

View File

@ -12,13 +12,15 @@ includeManagement();
if($_GET['url'])
$url = explode('/',ltrim(parse_url($_GET['url'], PHP_URL_PATH),'/'));
else if($_SERVER['HTTP_HX_CURRENT_URL'])
$url = explode('/',ltrim(parse_url($_SERVER['HTTP_HX_CURRENT_URL'], PHP_URL_PATH),'/'));
else $url = array_filter(explode('/',ltrim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH),'/')));
if(count($url) > 0 && ($url[0]=='api' || $url[0]=='backend'))
array_shift($url);
if($url==[] && $_SERVER['HTTP_HX_CURRENT_URL'])
$url = explode('/',ltrim(parse_url($_SERVER['HTTP_HX_CURRENT_URL'], PHP_URL_PATH),'/'));
//echo print_r(['url'=>$url,'server'=>$_SERVER,'request'=>$_REQUEST,'cookie'=>$_COOKIE,'session'=>$_SESSION],true);

View File

@ -4,7 +4,7 @@ class Auth extends Page {
function login()
{
return 'hättest gern';
return print_r($_REQUEST, true);
}
function maySeeThisPage()

View File

@ -0,0 +1,20 @@
<?php
class Err extends Page {
function notfound($params)
{
$this->set("page",$params[0]);
$this->set('template', "notfound.mustache");
}
function notallowed()
{
return json_encode(['error'=>'not allowed']);
}
function maySeeThisPage()
{
return true;
}
}

View File

@ -0,0 +1,4 @@
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4" role="alert">
<p class="font-bold">404 - Not found</p>
<p>I have no memory of {{page}}</p>
</div>

View File

@ -588,6 +588,10 @@ video {
top: 0px;
}
.left-1\/2 {
left: 50%;
}
.isolate {
isolation: isolate;
}
@ -631,6 +635,14 @@ video {
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.ml-3 {
margin-left: 0.75rem;
}
.mt-10 {
margin-top: 2.5rem;
}
@ -639,12 +651,20 @@ video {
margin-top: 1.5rem;
}
.mb-2 {
margin-bottom: 0.5rem;
.mb-6 {
margin-bottom: 1.5rem;
}
.ml-3 {
margin-left: 0.75rem;
.mb-3 {
margin-bottom: 0.75rem;
}
.mb-8 {
margin-bottom: 2rem;
}
.mt-8 {
margin-top: 2rem;
}
.block {
@ -675,14 +695,6 @@ video {
aspect-ratio: 1155/678;
}
.h-6 {
height: 1.5rem;
}
.h-8 {
height: 2rem;
}
.h-12 {
height: 3rem;
}
@ -695,6 +707,30 @@ video {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.h-8 {
height: 2rem;
}
.h-screen {
height: 100vh;
}
.h-20 {
height: 5rem;
}
.w-12 {
width: 3rem;
}
.w-4 {
width: 1rem;
}
.w-6 {
width: 1.5rem;
}
@ -711,12 +747,12 @@ video {
width: 100%;
}
.w-12 {
width: 3rem;
.w-8\/12 {
width: 66.666667%;
}
.w-4 {
width: 1rem;
.w-20 {
width: 5rem;
}
.max-w-2xl {
@ -736,11 +772,20 @@ video {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2 {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-\[30deg\] {
--tw-rotate: 30deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform-gpu {
transform: translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@ -770,18 +815,18 @@ video {
column-gap: 1.5rem;
}
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(1rem * var(--tw-space-x-reverse));
margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
@ -806,6 +851,10 @@ video {
overflow-y: auto;
}
.rounded {
border-radius: 0.25rem;
}
.rounded-full {
border-radius: 9999px;
}
@ -818,10 +867,6 @@ video {
border-radius: 0.375rem;
}
.rounded {
border-radius: 0.25rem;
}
.rounded-xl {
border-radius: 0.75rem;
}
@ -835,6 +880,11 @@ video {
border-color: rgb(209 213 219 / var(--tw-border-opacity));
}
.bg-gray-50 {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
}
.bg-indigo-600 {
--tw-bg-opacity: 1;
background-color: rgb(79 70 229 / var(--tw-bg-opacity));
@ -845,25 +895,59 @@ video {
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.bg-gray-50 {
.bg-gray-200 {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
}
.bg-gray-800 {
--tw-bg-opacity: 1;
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
}
.bg-yellow-400 {
--tw-bg-opacity: 1;
background-color: rgb(250 204 21 / var(--tw-bg-opacity));
}
.bg-blue-400 {
--tw-bg-opacity: 1;
background-color: rgb(96 165 250 / var(--tw-bg-opacity));
}
.bg-indigo-100 {
--tw-bg-opacity: 1;
background-color: rgb(224 231 255 / var(--tw-bg-opacity));
}
.bg-gradient-to-tr {
background-image: linear-gradient(to top right, var(--tw-gradient-stops));
}
.bg-gradient-to-b {
background-image: linear-gradient(to bottom, var(--tw-gradient-stops));
}
.from-\[\#ff80b5\] {
--tw-gradient-from: #ff80b5 var(--tw-gradient-from-position);
--tw-gradient-to: rgb(255 128 181 / 0) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.from-gray-700 {
--tw-gradient-from: #374151 var(--tw-gradient-from-position);
--tw-gradient-to: rgb(55 65 81 / 0) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.to-\[\#9089fc\] {
--tw-gradient-to: #9089fc var(--tw-gradient-to-position);
}
.to-gray-900 {
--tw-gradient-to: #111827 var(--tw-gradient-to-position);
}
.p-1 {
padding: 0.25rem;
}
@ -884,6 +968,14 @@ video {
padding: 1.5rem;
}
.p-12 {
padding: 3rem;
}
.p-4 {
padding: 1rem;
}
.px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
@ -894,6 +986,11 @@ video {
padding-right: 0.875rem;
}
.px-5 {
padding-left: 1.25rem;
padding-right: 1.25rem;
}
.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
@ -919,27 +1016,30 @@ video {
padding-bottom: 1.5rem;
}
.px-5 {
padding-left: 1.25rem;
padding-right: 1.25rem;
}
.py-8 {
padding-top: 2rem;
padding-bottom: 2rem;
}
.px-12 {
padding-left: 3rem;
padding-right: 3rem;
}
.pt-14 {
padding-top: 3.5rem;
}
.text-center {
text-align: center;
.pl-12 {
padding-left: 3rem;
}
.text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
.pb-10 {
padding-bottom: 2.5rem;
}
.text-center {
text-align: center;
}
.text-4xl {
@ -967,12 +1067,13 @@ video {
line-height: 1.75rem;
}
.font-bold {
font-weight: 700;
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.font-semibold {
font-weight: 600;
.font-bold {
font-weight: 700;
}
.font-light {
@ -983,6 +1084,14 @@ video {
font-weight: 500;
}
.font-semibold {
font-weight: 600;
}
.uppercase {
text-transform: uppercase;
}
.leading-6 {
line-height: 1.5rem;
}
@ -1003,6 +1112,16 @@ video {
letter-spacing: -0.025em;
}
.text-black {
--tw-text-opacity: 1;
color: rgb(0 0 0 / var(--tw-text-opacity));
}
.text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.text-gray-600 {
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
@ -1023,40 +1142,30 @@ video {
color: rgb(79 70 229 / var(--tw-text-opacity));
}
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.text-black {
--tw-text-opacity: 1;
color: rgb(0 0 0 / var(--tw-text-opacity));
}
.text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.text-slate-500 {
--tw-text-opacity: 1;
color: rgb(100 116 139 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.text-gray-100 {
--tw-text-opacity: 1;
color: rgb(243 244 246 / var(--tw-text-opacity));
}
.text-gray-200 {
--tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity));
}
.opacity-30 {
opacity: 0.3;
}
.shadow-sm {
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow {
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
@ -1069,6 +1178,17 @@ video {
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-sm {
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-gray-200 {
--tw-shadow-color: #e5e7eb;
--tw-shadow: var(--tw-shadow-colored);
}
.ring-1 {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
@ -1160,6 +1280,11 @@ video {
border-color: rgb(55 65 81 / var(--tw-border-opacity));
}
.dark\:border-gray-300 {
--tw-border-opacity: 1;
border-color: rgb(209 213 219 / var(--tw-border-opacity));
}
.dark\:bg-gray-700 {
--tw-bg-opacity: 1;
background-color: rgb(55 65 81 / var(--tw-bg-opacity));
@ -1231,14 +1356,14 @@ video {
width: 72.1875rem;
}
.sm\:max-w-sm {
max-width: 24rem;
}
.sm\:max-w-md {
max-width: 28rem;
}
.sm\:max-w-sm {
max-width: 24rem;
}
.sm\:justify-center {
justify-content: center;
}
@ -1273,16 +1398,41 @@ video {
margin-top: 0px;
}
.md\:mb-8 {
margin-bottom: 2rem;
}
.md\:h-screen {
height: 100vh;
}
.md\:w-1\/3 {
width: 33.333333%;
}
.md\:space-y-6 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
}
.md\:p-24 {
padding: 6rem;
}
.md\:p-4 {
padding: 1rem;
}
.md\:p-8 {
padding: 2rem;
}
.md\:py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.md\:text-2xl {
font-size: 1.5rem;
line-height: 2rem;
@ -1298,6 +1448,10 @@ video {
display: none;
}
.lg\:w-6\/12 {
width: 50%;
}
.lg\:flex-1 {
flex: 1 1 0%;
}

View File

@ -31,11 +31,11 @@
</button>
</div>
<div class="hidden lg:flex lg:gap-x-12">
<a href="#" hx-get="/templates/product.html" hx-target="#main" class="text-sm font-semibold leading-6 text-gray-900">Product</a>
<a href="#" hx-get="/templates/features.html" hx-target="#main" class="text-sm font-semibold leading-6 text-gray-900">Features</a>
<a href="#" hx-get="/templates/product.html" hx-push-url="/product" hx-target="#main" class="text-sm font-semibold leading-6 text-gray-900">Product</a>
<a href="#" hx-get="/templates/features.html" hx-push-url="/features" hx-target="#main" class="text-sm font-semibold leading-6 text-gray-900">Features</a>
</div>
<div class="hidden lg:flex lg:flex-1 lg:justify-end">
<a href="#" hx-get="/templates/login.html" hx-target="#main" class="text-sm font-semibold leading-6 text-gray-900">Log in <span
<a href="#" hx-get="/templates/login.html" hx-target="#main" hx-push-url="/login" class="text-sm font-semibold leading-6 text-gray-900">Log in <span
aria-hidden="true">&rarr;</span></a>
</div>
</nav>

View File

@ -1,38 +1,39 @@
<form hx-post="/api/auth/login" class="">
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
<div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Sign in to your account
</h1>
<form class="space-y-4 md:space-y-6" action="#">
<div>
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
<input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="name@company.com" required="">
</div>
<div>
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Password</label>
<input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required="">
</div>
<div class="flex items-center justify-between">
<div class="flex items-start">
<div class="flex items-center h-5">
<input id="remember" aria-describedby="remember" type="checkbox" class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800" required="">
</div>
<div class="ml-3 text-sm">
<label for="remember" class="text-gray-500 dark:text-gray-300">Remember me</label>
</div>
</div>
<a href="#" class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500">Forgot password?</a>
</div>
<button type="submit" class="w-full text-black bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
Sign in
</button>
<p class="text-sm font-light text-gray-500 dark:text-gray-400">
Dont have an account yet? <a href="#" class="font-medium text-primary-600 hover:underline dark:text-primary-500">Sign up</a>
</p>
</form>
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto lg:py-0">
<div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Sign in to your account
</h1>
<div id="response" class="text-gray-900 dark:text-white">
yes
</div>
<form class="space-y-4 md:space-y-6" hx-post="/api/auth/login" hx-target="#response">
<div>
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
<input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="name@company.com" required="">
</div>
<div>
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Password</label>
<input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required="">
</div>
<div class="flex items-center justify-between">
<div class="flex items-start">
<div class="flex items-center h-5">
<input id="remember" name="remember" aria-describedby="remember" type="checkbox" value="true" class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800">
</div>
<div class="ml-3 text-sm">
<label for="remember" class="text-gray-500 dark:text-gray-300">Remember me</label>
</div>
</div>
<a href="#" class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500 dark:text-gray-400">Forgot password?</a>
</div>
<button type="submit" class="dark:text-gray-400 w-full dark:border-primary-600 text-black bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
Sign in
</button>
<p class="text-sm font-light text-gray-500 dark:text-gray-400">
Dont have an account yet? <a href="#" class="font-medium text-primary-600 hover:underline dark:text-primary-500">Sign up</a>
</p>
</form>
</div>
</div>
</form>
</div>