import Elementary import ElementaryHTMX struct UserForm: HTML, Sendable { let context: Context var content: some HTML { form( .id("user-form"), .class("user-form"), .hx.post(context.targetURL), .hx.pushURL(context.pushURL), .custom(name: "hx-on::after-request", value: "if(event.detail.successful) this.reset(); toggleContent('form');") ) { input(.type(.text), .id("username"), .name("username"), .placeholder("Username"), .autofocus, .required) br() if context.showEmailInput { input(.type(.email), .id("email"), .name("email"), .placeholder("Email"), .required) br() } input(.type(.password), .id("password"), .name("password"), .placeholder("Password"), .required) br() if context.showConfirmPassword { input(.type(.password), .id("confirmPassword"), .name("confirmPassword"), .required) br() } input(.type(.submit), .value(context.buttonLabel)) } } enum Context { 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 targetURL: String { switch self { case .create: return "/users" case let .login(next: next): let path = "/login" if let next { return "\(path)?next=\(next)" } return path } } } }