Files
veola/templates/login.templ
2026-05-13 19:42:49 -07:00

96 lines
2.9 KiB
Plaintext

package templates
type LoginData struct {
Page
Error string
Username string
}
templ loginBody(d LoginData) {
<div class="min-h-screen grid md:grid-cols-2">
<div class="flex items-center justify-center p-8">
<div class="w-full max-w-sm">
<div class="flex items-center gap-2 mb-6">
<span class="text-3xl">🐝</span>
<span class="text-2xl font-semibold tracking-wide">Veola</span>
</div>
<h1 class="text-3xl font-semibold mb-2">Open the door.</h1>
<p class="v-muted mb-6">Sign in to continue.</p>
if d.Error != "" {
<div class="v-flash-error">{ d.Error }</div>
}
<form method="post" action="/login" class="space-y-4">
@CSRFInput(d.CSRFToken)
<div>
<label class="v-label">Username</label>
<input class="v-input" name="username" autocomplete="username" autofocus value={ d.Username }/>
</div>
<div>
<label class="v-label">Password</label>
<input class="v-input" type="password" name="password" autocomplete="current-password"/>
</div>
<button class="v-btn w-full justify-center" type="submit">Sign In</button>
</form>
</div>
</div>
<div class="hidden md:flex items-end justify-center p-8 bg-[#152560]">
<div class="v-veola-portrait max-w-md">
<img src="/static/img/veola.webp" alt="Veola"/>
</div>
</div>
</div>
}
templ Login(d LoginData) {
@Bare(d.Page, loginBody(d))
}
type SetupData struct {
Page
Error string
Username string
}
templ setupBody(d SetupData) {
<div class="min-h-screen grid md:grid-cols-2">
<div class="flex items-center justify-center p-8">
<div class="w-full max-w-sm">
<div class="flex items-center gap-2 mb-6">
<span class="text-3xl">🐝</span>
<span class="text-2xl font-semibold tracking-wide">Veola</span>
</div>
<h1 class="text-3xl font-semibold mb-2">First time here.</h1>
<p class="v-muted mb-6">Create the admin account. Password must be at least 12 characters.</p>
if d.Error != "" {
<div class="v-flash-error">{ d.Error }</div>
}
<form method="post" action="/setup" class="space-y-4">
@CSRFInput(d.CSRFToken)
<div>
<label class="v-label">Username</label>
<input class="v-input" name="username" autofocus value={ d.Username }/>
</div>
<div>
<label class="v-label">Password</label>
<input class="v-input" type="password" name="password"/>
</div>
<div>
<label class="v-label">Confirm Password</label>
<input class="v-input" type="password" name="password_confirm"/>
</div>
<button class="v-btn w-full justify-center" type="submit">Create Admin</button>
</form>
</div>
</div>
<div class="hidden md:flex items-end justify-center p-8 bg-[#152560]">
<div class="v-veola-portrait max-w-md">
<img src="/static/img/veola.webp" alt="Veola"/>
</div>
</div>
</div>
}
templ Setup(d SetupData) {
@Bare(d.Page, setupBody(d))
}