feat: Begins vendor views
This commit is contained in:
@@ -4,6 +4,7 @@ import ElementaryHTMX
|
||||
struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable {
|
||||
|
||||
var title: String { "Purchase Orders" }
|
||||
var lang: String { "en" }
|
||||
|
||||
let inner: Inner
|
||||
let displayNav: Bool
|
||||
@@ -56,7 +57,7 @@ struct RouteHeaderView: HTML {
|
||||
div(.class("container"), .style("padding: 20px 20px;")) {
|
||||
h1 { title }
|
||||
br()
|
||||
p { description }
|
||||
p(.class("secondary")) { i { description } }
|
||||
br()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,20 +19,20 @@ struct UserDetail: HTML, Sendable {
|
||||
) {
|
||||
div(.class("row")) {
|
||||
makeLabel(for: "username", value: "Username:")
|
||||
input(.class("col-5"), .type(.text), .id("username"), .name("username"), .value(user.username), .required)
|
||||
input(.class("col-4"), .type(.text), .id("username"), .name("username"), .value(user.username), .required)
|
||||
makeLabel(for: "email", value: "Email:")
|
||||
input(.class("col-5"), .type(.email), .id("email"), .name("email"), .value(user.email), .required)
|
||||
input(.class("col-4"), .type(.email), .id("email"), .name("email"), .value(user.email), .required)
|
||||
}
|
||||
div(.class("row")) {
|
||||
span(.class("label col-1")) { "Created:" }
|
||||
span(.class("label col-2")) { "Created:" }
|
||||
span(.class("date col-4")) { dateFormatter.formattedDate(user.createdAt) }
|
||||
span(.class("label col-1")) { "Updated:" }
|
||||
span(.class("label col-2")) { "Updated:" }
|
||||
span(.class("date col-4")) { dateFormatter.formattedDate(user.updatedAt) }
|
||||
}
|
||||
div(.class("btn-row user-buttons")) {
|
||||
button(
|
||||
.type(.submit),
|
||||
.style("background-color: blue; color: white;")
|
||||
.class("btn-secondary")
|
||||
) { "Update" }
|
||||
Button.danger { "Delete" }
|
||||
.attributes(
|
||||
@@ -40,6 +40,7 @@ struct UserDetail: HTML, Sendable {
|
||||
.hx.trigger(.event(.click)),
|
||||
.hx.swap(.outerHTML),
|
||||
.hx.target("#user_\(user.id)"),
|
||||
.hx.confirm("Are you sure you want to delete this user?"),
|
||||
.custom(name: "hx-on::after-request", value: "toggleContent('float'); window.location.href='/users';")
|
||||
)
|
||||
}
|
||||
@@ -52,7 +53,7 @@ struct UserDetail: HTML, Sendable {
|
||||
for name: String,
|
||||
value: String
|
||||
) -> some HTML {
|
||||
label(.for(name), .class("col-1")) { span(.class("label")) { value } }
|
||||
label(.for(name), .class("col-2")) { span(.class("label")) { value } }
|
||||
}
|
||||
|
||||
func row(_ label: String, _ value: String) -> some HTML<HTMLTag.tr> {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
|
||||
// Form used to login or create a new user.
|
||||
struct UserForm: HTML, Sendable {
|
||||
let context: Context
|
||||
|
||||
@@ -27,25 +28,31 @@ struct UserForm: HTML, Sendable {
|
||||
value: "if(event.detail.successful) this.reset(); toggleContent('float');"
|
||||
)
|
||||
) {
|
||||
input(.type(.text), .id("username"), .name("username"), .placeholder("Username"), .autofocus, .required)
|
||||
br()
|
||||
div(.class("row")) {
|
||||
input(.type(.text), .id("username"), .name("username"), .placeholder("Username"), .autofocus, .required)
|
||||
}
|
||||
if context.showEmailInput {
|
||||
input(.type(.email), .id("email"), .name("email"), .placeholder("Email"), .required)
|
||||
br()
|
||||
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)
|
||||
}
|
||||
input(.type(.password), .id("password"), .name("password"), .placeholder("Password"), .required)
|
||||
br()
|
||||
if context.showConfirmPassword {
|
||||
input(
|
||||
.type(.password),
|
||||
.id("confirmPassword"),
|
||||
.name("confirmPassword"),
|
||||
.placeholder("Confirm Password"),
|
||||
.required
|
||||
)
|
||||
br()
|
||||
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 }
|
||||
}
|
||||
input(.type(.submit), .value(context.buttonLabel))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,15 +44,12 @@ struct UserTable: HTML {
|
||||
td { user.username }
|
||||
td { user.email }
|
||||
td {
|
||||
button(
|
||||
Button.detail().attributes(
|
||||
.hx.get("/users/\(user.id.uuidString)"),
|
||||
.hx.target("#float"),
|
||||
.hx.swap(.outerHTML),
|
||||
.hx.pushURL(true),
|
||||
.class("btn-detail")
|
||||
) {
|
||||
"〉"
|
||||
}
|
||||
.hx.pushURL(true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ struct ToggleFormButton: HTML {
|
||||
enum Button {
|
||||
|
||||
static func add() -> some HTML<HTMLTag.button> {
|
||||
button(.class("btn-add")) { "+" }
|
||||
button(.class("btn btn-add")) { "+" }
|
||||
}
|
||||
|
||||
static func danger<C: HTML>(@HTMLBuilder body: () -> C) -> some HTML<HTMLTag.button> {
|
||||
@@ -28,8 +28,14 @@ enum Button {
|
||||
button(.class("btn-update")) { "Update" }
|
||||
}
|
||||
|
||||
static func detail() -> some HTML<HTMLTag.button> {
|
||||
button(.class("btn-detail")) {
|
||||
"〉"
|
||||
}
|
||||
}
|
||||
|
||||
private static func makeOnClick(_ id: String, _ resetURL: String?) -> String {
|
||||
var output = "toggleContent('\(id)');"
|
||||
let output = "toggleContent('\(id)');"
|
||||
if let resetURL {
|
||||
return "\(output) window.location.href='\(resetURL)';"
|
||||
}
|
||||
15
Sources/App/Views/Vendors/VendorDetail.swift
Normal file
15
Sources/App/Views/Vendors/VendorDetail.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
import SharedModels
|
||||
|
||||
struct VendorDetail: HTML {
|
||||
let vendor: Vendor?
|
||||
|
||||
var content: some HTML {
|
||||
div(.class("container")) {
|
||||
VendorForm(vendor: vendor)
|
||||
// TODO: Branch table + form.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
37
Sources/App/Views/Vendors/VendorForm.swift
Normal file
37
Sources/App/Views/Vendors/VendorForm.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
import SharedModels
|
||||
|
||||
struct VendorForm: HTML {
|
||||
let vendor: Vendor?
|
||||
|
||||
var content: some HTML<HTMLTag.form> {
|
||||
form(
|
||||
.id("vendor-form"),
|
||||
vendor != nil ? .hx.put(targetURL) : .hx.post(targetURL),
|
||||
.hx.target("this"),
|
||||
.hx.swap(.outerHTML)
|
||||
) {
|
||||
div(.class("row")) {
|
||||
input(
|
||||
.id("vendor-name"),
|
||||
.name("name"),
|
||||
.value(vendor?.name ?? ""),
|
||||
.placeholder("Vendor Name"),
|
||||
.required
|
||||
)
|
||||
button(.type(.submit), .class("btn-primary")) { buttonLabel }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var buttonLabel: String {
|
||||
guard vendor != nil else { return "Update" }
|
||||
return "Create"
|
||||
}
|
||||
|
||||
var targetURL: String {
|
||||
guard let vendor else { return "/vendors" }
|
||||
return "/vendors/\(vendor.id)"
|
||||
}
|
||||
}
|
||||
34
Sources/App/Views/Vendors/VendorTable.swift
Normal file
34
Sources/App/Views/Vendors/VendorTable.swift
Normal file
@@ -0,0 +1,34 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
import SharedModels
|
||||
|
||||
struct VendorTable: HTML {
|
||||
let vendors: [Vendor]
|
||||
|
||||
var content: some HTML {
|
||||
table {
|
||||
thead {
|
||||
th { "Name" }
|
||||
th {}
|
||||
th { Button.add() }
|
||||
}
|
||||
tbody(.id("vendor-table")) {
|
||||
for vendor in vendors {
|
||||
Row(vendor: vendor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Row: HTML {
|
||||
let vendor: Vendor
|
||||
|
||||
var content: some HTML<HTMLTag.tr> {
|
||||
tr(.id("vendor_\(vendor.id)")) {
|
||||
td { vendor.name.capitalized }
|
||||
td { "(\(vendor.branches?.count ?? 0)) Branches" }
|
||||
td {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user