Files
vapor-po/Sources/App/Views/Users/UserForm.swift

122 lines
2.7 KiB
Swift

import Elementary
import ElementaryHTMX
import SharedModels
// Form used to login or create a new user.
struct UserForm: HTML, Sendable {
let context: Context
var content: some HTML {
if context == .create {
Float(shouldDisplay: true) {
makeForm()
}
} else {
makeForm()
}
}
private func makeForm() -> some HTML {
form(
.id(.user(.form)),
.class("user-form"),
.hx.post(context.targetURL),
.hx.pushURL(context.pushURL),
.hx.target(context.target),
.hx.swap(.outerHTML),
.custom(
name: "hx-on::after-request",
value: "if(event.detail.successful) this.reset(); toggleContent('float');"
)
) {
if case let .login(next) = context, let next {
input(.type(.hidden), .name("next"), .value(next))
}
div(.class("row")) {
input(.type(.text), .id("username"), .name("username"), .placeholder("Username"), .autofocus, .required)
}
if context.showEmailInput {
div(.class("row")) {
input(.type(.email), .id("email"), .name("email"), .placeholder("Email"), .required)
}
}
div(.class("row")) {
input(.type(.password), .id("password"), .name("password"), .placeholder("Password"), .required)
}
if context.showConfirmPassword {
div(.class("row")) {
input(
.type(.password),
.id("confirmPassword"),
.name("confirmPassword"),
.placeholder("Confirm Password"),
.required
)
}
}
div(.class("row")) {
button(.type(.submit), .class("btn-primary")) { context.buttonLabel }
}
}
}
enum Context: Equatable {
case create
case login(next: String?)
var showConfirmPassword: Bool {
switch self {
case .create: return true
case .login: return false
}
}
var showEmailInput: Bool {
switch self {
case .create: return true
case .login: return false
}
}
var pushURL: Bool {
switch self {
case .create: return false
case .login: return true
}
}
var buttonLabel: String {
switch self {
case .create:
return "Create"
case .login:
return "Login"
}
}
var target: String {
switch self {
case .create:
return "next table"
case .login:
return "body"
}
}
// TODO: Return a ViewRoute.
var targetURL: String {
switch self {
case .create:
return "/users"
case .login:
return "/login"
// let path = "/login"
// if let next {
// return "\(path)?next=\(next)"
// }
// return path
}
}
}
}