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

114 lines
2.6 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(route: context.targetURL),
.hx.pushURL(context.pushURL),
.hx.target(context.target),
.hx.swap(context == .create ? .afterBegin.transition(true).swap("0.5s") : .outerHTML),
.hx.on(
.afterRequest,
.ifSuccessful(.resetForm, .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, Sendable {
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: HXTarget {
switch self {
case .create:
return .id(.user(.table))
case .login:
return .body
}
}
var targetURL: SiteRoute.View {
switch self {
case .create:
return .user(.index)
case .login:
return .login(.index())
}
}
}
}