updated stuff
This commit is contained in:
86
internal/view/component/form/register.templ
Normal file
86
internal/view/component/form/register.templ
Normal file
@@ -0,0 +1,86 @@
|
||||
package form
|
||||
|
||||
templ RegisterForm(username, registerError string) {
|
||||
{{ usernameErr := "Username is taken" }}
|
||||
<form
|
||||
hx-post="/register"
|
||||
x-data={ templ.JSFuncCall(
|
||||
"registerFormData", registerError, usernameErr,
|
||||
).CallInline }
|
||||
x-on:htmx:xhr:loadstart="submitted=true;buttontext='Loading...'"
|
||||
>
|
||||
<script>
|
||||
function registerFormData(err, usernameErr) {
|
||||
return {
|
||||
submitted: false,
|
||||
buttontext: "Register",
|
||||
errorMessage: err,
|
||||
errUsername: err === usernameErr ? true : false,
|
||||
resetErr() {
|
||||
this.errorMessage = "";
|
||||
this.errUsername = false;
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<div
|
||||
class="grid gap-y-4"
|
||||
>
|
||||
<div>
|
||||
<div class="relative">
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
class="py-3 px-4 block w-full rounded-lg text-sm
|
||||
focus:border-blue focus:ring-blue bg-base
|
||||
disabled:opacity-50
|
||||
disabled:pointer-events-none"
|
||||
required
|
||||
aria-describedby="username-error"
|
||||
value={ username }
|
||||
@input="resetErr()"
|
||||
/>
|
||||
<div
|
||||
class="absolute inset-y-0 end-0
|
||||
pointer-events-none pe-3 pt-3"
|
||||
x-show="errUsername"
|
||||
x-cloak
|
||||
>
|
||||
<svg
|
||||
class="size-5 text-red"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8
|
||||
4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0
|
||||
0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1
|
||||
1 0 1 0 0 2 1 1 0 0 0 0-2z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<p
|
||||
class="text-center text-xs text-red mt-2"
|
||||
id="username-error"
|
||||
x-show="errUsername"
|
||||
x-cloak
|
||||
x-text="if (errUsername) return errorMessage;"
|
||||
></p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
x-bind:disabled="submitted"
|
||||
x-text="buttontext"
|
||||
type="submit"
|
||||
class="w-full py-3 px-4 inline-flex justify-center items-center
|
||||
gap-x-2 rounded-lg border border-transparent transition
|
||||
bg-green hover:bg-green/75 text-mantle hover:cursor-pointer
|
||||
disabled:bg-green/60 disabled:cursor-default"
|
||||
></button>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package nav
|
||||
|
||||
import "git.haelnorr.com/h/oslstats/pkg/contexts"
|
||||
import "git.haelnorr.com/h/oslstats/internal/db"
|
||||
|
||||
type ProfileItem struct {
|
||||
name string // Label to display
|
||||
@@ -23,7 +23,7 @@ func getProfileItems() []ProfileItem {
|
||||
|
||||
// Returns the right portion of the navbar
|
||||
templ navRight() {
|
||||
{{ user := contexts.CurrentUser(ctx) }}
|
||||
{{ user := db.CurrentUser(ctx) }}
|
||||
{{ items := getProfileItems() }}
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="sm:flex sm:gap-2">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package nav
|
||||
|
||||
import "git.haelnorr.com/h/oslstats/pkg/contexts"
|
||||
import "git.haelnorr.com/h/oslstats/internal/db"
|
||||
|
||||
// Returns the mobile version of the navbar thats only visible when activated
|
||||
templ sideNav(navItems []NavItem) {
|
||||
{{ user := contexts.CurrentUser(ctx) }}
|
||||
{{ user := db.CurrentUser(ctx) }}
|
||||
<div
|
||||
x-show="open"
|
||||
x-transition
|
||||
|
||||
@@ -3,32 +3,66 @@ package page
|
||||
import "git.haelnorr.com/h/oslstats/internal/view/layout"
|
||||
import "strconv"
|
||||
|
||||
// Page template for Error pages. Error code should be a HTTP status code as
|
||||
// a string, and err should be the corresponding response title.
|
||||
// Message is a custom error message displayed below the code and error.
|
||||
// Original Error template (keep for backwards compatibility where needed)
|
||||
templ Error(code int, err string, message string) {
|
||||
@ErrorWithDetails(code, err, message, "")
|
||||
}
|
||||
|
||||
// Enhanced Error template with optional details section
|
||||
templ ErrorWithDetails(code int, err string, message string, details string) {
|
||||
@layout.Global(err) {
|
||||
<div
|
||||
class="grid mt-24 left-0 right-0 top-0 bottom-0
|
||||
place-content-center bg-base px-4"
|
||||
>
|
||||
<div class="text-center">
|
||||
<h1
|
||||
class="text-9xl text-text"
|
||||
>{ strconv.Itoa(code) }</h1>
|
||||
<p
|
||||
class="text-2xl font-bold tracking-tight text-subtext1
|
||||
sm:text-4xl"
|
||||
>{ err }</p>
|
||||
<p
|
||||
class="mt-4 text-subtext0"
|
||||
>{ message }</p>
|
||||
<a
|
||||
href="/"
|
||||
class="mt-6 inline-block rounded-lg bg-mauve px-5 py-3
|
||||
text-sm text-crust transition hover:bg-mauve/75"
|
||||
>Go to homepage</a>
|
||||
<div class="grid mt-24 left-0 right-0 top-0 bottom-0 place-content-center bg-base px-4">
|
||||
<div class="text-center max-w-2xl mx-auto">
|
||||
<h1 class="text-9xl text-text">{ strconv.Itoa(code) }</h1>
|
||||
<p class="text-2xl font-bold tracking-tight text-subtext1 sm:text-4xl">{ err }</p>
|
||||
// Always show the message from hws.HWSError.Message
|
||||
<p class="mt-4 text-subtext0">{ message }</p>
|
||||
// Conditionally show technical details in dropdown
|
||||
if details != "" {
|
||||
<div class="mt-8 text-left">
|
||||
<details class="bg-surface0 rounded-lg p-4 text-right">
|
||||
<summary class="text-left cursor-pointer text-subtext1 font-semibold select-none hover:text-text">
|
||||
Details
|
||||
<span class="text-xs text-subtext0 ml-2">(click to expand)</span>
|
||||
</summary>
|
||||
<div class="text-left mt-4 relative">
|
||||
<pre id="details" class="text-xs text-subtext0 font-mono whitespace-pre-wrap break-all bg-mantle p-4 rounded overflow-x-auto">{ details }</pre>
|
||||
</div>
|
||||
<button
|
||||
onclick="copyToClipboard('details')"
|
||||
id="copyButton"
|
||||
class="mt-2 bg-mauve text-crust px-3 py-1 rounded text-xs hover:bg-mauve/75 transition hover:cursor-pointer"
|
||||
title="Copy to clipboard"
|
||||
>
|
||||
Copy
|
||||
</button>
|
||||
</details>
|
||||
</div>
|
||||
}
|
||||
<a href="/" class="mt-6 inline-block rounded-lg bg-mauve px-5 py-3 text-sm text-crust transition hover:bg-mauve/75">
|
||||
Go to homepage
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
if details != "" {
|
||||
<script>
|
||||
function copyToClipboard(id) {
|
||||
var details = document.getElementById(id).innerText;
|
||||
var button = document.getElementById("copyButton");
|
||||
navigator.clipboard
|
||||
.writeText(details)
|
||||
.then(function () {
|
||||
button.innerText = "Copied!";
|
||||
setTimeout(function () {
|
||||
button.innerText = "Copy";
|
||||
}, 2000);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error("Failed to copy:", err);
|
||||
button.innerText = "Failed";
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
internal/view/page/register.templ
Normal file
35
internal/view/page/register.templ
Normal file
@@ -0,0 +1,35 @@
|
||||
package page
|
||||
|
||||
import "git.haelnorr.com/h/oslstats/internal/view/layout"
|
||||
import "git.haelnorr.com/h/oslstats/internal/view/component/form"
|
||||
|
||||
// Returns the login page
|
||||
templ Register(username string, unique bool) {
|
||||
{{
|
||||
err := ""
|
||||
if !unique {
|
||||
err = "Username is taken"
|
||||
}
|
||||
}}
|
||||
@layout.Global("Register") {
|
||||
<div class="max-w-100 mx-auto px-2">
|
||||
<div class="mt-7 bg-mantle border border-surface1 rounded-xl">
|
||||
<div class="p-4 sm:p-7">
|
||||
<div class="text-center">
|
||||
<h1
|
||||
class="block text-2xl font-bold"
|
||||
>Set your display name</h1>
|
||||
<p
|
||||
class="mt-2 text-sm text-subtext0"
|
||||
>
|
||||
Select your display name. This must be unique, and cannot be changed.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
@form.RegisterForm(username, err)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user