- Replace Layout+Card pattern with AuthLayout("Create your account", csrfToken)
- Wire GoogleButton and AuthDivider into SignupPage body
- Replace raw <input> elements with @ui.FormField/@ui.Input design system components
- Password placeholder "12 characters minimum", autocomplete="new-password"
- Add signup-copy nav link ("Already have an account? Sign in") pointing to /login
- Preserve HTMX swap: hx-post="/signup" hx-target="#signup-form" hx-swap="outerHTML"
- Remove signupCardBody helper
80 lines
2.3 KiB
Text
80 lines
2.3 KiB
Text
package templates
|
|
|
|
import "backend/internal/web/ui"
|
|
|
|
// SignupPage renders the full /signup page wrapped in AuthLayout.
|
|
// It delegates the form section to SignupFormFragment so HTMX can swap just the
|
|
// form on validation errors without re-rendering the surrounding shell.
|
|
templ SignupPage(form SignupForm, errs SignupErrors, csrfToken string, providers AuthProviderButtons) {
|
|
@AuthLayout("Create your account", csrfToken) {
|
|
<div class="auth-card-topbar"></div>
|
|
<div class="brand-header">
|
|
<img class="brand-logo" src="/static/logo_dark.png" alt="Xtablo"/>
|
|
</div>
|
|
<div class="title-group">
|
|
<h1>Create your account</h1>
|
|
</div>
|
|
<div class="auth-body">
|
|
@GoogleButton(providers.Google.StartURL, providers.Google.Configured)
|
|
@AuthDivider()
|
|
@SignupFormFragment(form, errs, csrfToken)
|
|
</div>
|
|
}
|
|
}
|
|
|
|
// SignupFormFragment is the bare form used for HTMX swaps.
|
|
// hx-post targets this component itself so the form can be replaced inline
|
|
// on validation failure (D-19, D-25).
|
|
// The outer id="signup-form" must match the hx-target on this element.
|
|
templ SignupFormFragment(form SignupForm, errs SignupErrors, csrfToken string) {
|
|
<form
|
|
id="signup-form"
|
|
method="POST"
|
|
action="/signup"
|
|
hx-post="/signup"
|
|
hx-target="#signup-form"
|
|
hx-swap="outerHTML"
|
|
class="login-form"
|
|
>
|
|
@ui.CSRFField(csrfToken)
|
|
@GeneralError(errs.General)
|
|
@ui.FormField(ui.FormFieldProps{
|
|
Label: "Email address",
|
|
For: "email",
|
|
Field: ui.Input(ui.InputProps{
|
|
ID: "email",
|
|
Name: "email",
|
|
Type: "email",
|
|
Placeholder: "you@example.com",
|
|
Value: form.Email,
|
|
Required: true,
|
|
Attrs: templ.Attributes{"autocomplete": "email"},
|
|
}),
|
|
Error: errs.Email,
|
|
})
|
|
@ui.FormField(ui.FormFieldProps{
|
|
Label: "Password",
|
|
For: "password",
|
|
Field: ui.Input(ui.InputProps{
|
|
ID: "password",
|
|
Name: "password",
|
|
Type: "password",
|
|
Placeholder: "12 characters minimum",
|
|
Required: true,
|
|
Attrs: templ.Attributes{"autocomplete": "new-password"},
|
|
}),
|
|
Error: errs.Password,
|
|
})
|
|
@ui.Button(ui.ButtonProps{
|
|
Label: "Create account",
|
|
Variant: ui.ButtonVariantDefault,
|
|
Tone: ui.ButtonToneSolid,
|
|
Size: ui.SizeMD,
|
|
Type: "submit",
|
|
})
|
|
<p class="signup-copy">
|
|
Already have an account?
|
|
<a class="signup-link" href="/login">Sign in</a>
|
|
</p>
|
|
</form>
|
|
}
|