feat: Begins migrating views from leaf to elementary
This commit is contained in:
9
Sources/App/Views/Buttons.swift
Normal file
9
Sources/App/Views/Buttons.swift
Normal file
@@ -0,0 +1,9 @@
|
||||
import Elementary
|
||||
|
||||
struct ToggleFormButton: HTML {
|
||||
var content: some HTML<HTMLTag.a> {
|
||||
a(.href("javascript:void(0)"), .on(.click, "toggleContent('form')"), .class("btn-add")) {
|
||||
"+"
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Sources/App/Views/Main.swift
Normal file
43
Sources/App/Views/Main.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
|
||||
struct MainPage<Inner: HTML>: HTMLDocument {
|
||||
|
||||
var title: String { "Purchase Orders" }
|
||||
|
||||
let inner: Inner
|
||||
let displayNav: Bool
|
||||
|
||||
init(displayNav: Bool = false, _ inner: () -> Inner) {
|
||||
self.displayNav = displayNav
|
||||
self.inner = inner()
|
||||
}
|
||||
|
||||
var head: some HTML {
|
||||
meta(.charset(.utf8))
|
||||
script(.src("https://unpkg.com/htmx.org@2.0.4")) {}
|
||||
script(.src("/js/main.js")) {}
|
||||
link(.rel(.stylesheet), .href("/css/main.css"))
|
||||
}
|
||||
|
||||
var body: some HTML {
|
||||
header {
|
||||
Logo()
|
||||
if displayNav {
|
||||
Navbar()
|
||||
}
|
||||
}
|
||||
inner
|
||||
}
|
||||
}
|
||||
|
||||
extension MainPage: Sendable where Inner: Sendable {}
|
||||
|
||||
struct Logo: HTML, Sendable {
|
||||
|
||||
var content: some HTML {
|
||||
div(.id("logo")) {
|
||||
"HHE - Purchase Orders"
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Sources/App/Views/Navbar.swift
Normal file
31
Sources/App/Views/Navbar.swift
Normal file
@@ -0,0 +1,31 @@
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
|
||||
struct Navbar: HTML {
|
||||
var content: some HTML {
|
||||
div(.class("sidepanel"), .id("sidepanel")) {
|
||||
a(.href("javascript:void(0)"), .class("closebtn"), .on(.click, "closeSidepanel()")) {
|
||||
"x"
|
||||
}
|
||||
a(.hx.get("/purchase-orders?page=1&limit=50"), .hx.target("body"), .hx.pushURL(true)) {
|
||||
"Purchae Orders"
|
||||
}
|
||||
a(.hx.get("/users"), .hx.target("body"), .hx.pushURL(true)) {
|
||||
"Users"
|
||||
}
|
||||
a(.hx.get("/employees"), .hx.target("body"), .hx.pushURL(true)) {
|
||||
"Employees"
|
||||
}
|
||||
a(.hx.get("/vendors"), .hx.target("body"), .hx.pushURL(true)) {
|
||||
"Vendors"
|
||||
}
|
||||
div(.style("border-bottom: 1px solid grey; margin-bottom: 5px;")) {}
|
||||
a(.hx.post("/logout"), .hx.target("#content"), .hx.swap(.outerHTML), .hx.trigger(.event(.click))) {
|
||||
"Logout"
|
||||
}
|
||||
}
|
||||
button(.class("openbtn"), .on(.click, "openSidepanel()")) {
|
||||
img(.src("/images/menu.svg"), .style("width: 30px;, height: 30px;"))
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Sources/App/Views/Users/UserForm.swift
Normal file
78
Sources/App/Views/Users/UserForm.swift
Normal file
@@ -0,0 +1,78 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Sources/App/Views/Users/UserTable.swift
Normal file
40
Sources/App/Views/Users/UserTable.swift
Normal file
@@ -0,0 +1,40 @@
|
||||
import DatabaseClient
|
||||
import Dependencies
|
||||
import Elementary
|
||||
import ElementaryHTMX
|
||||
import SharedModels
|
||||
|
||||
struct UserTable: HTML {
|
||||
|
||||
@Dependency(\.database.users.fetchAll) var fetchAll
|
||||
|
||||
var content: some HTML {
|
||||
table(.id("user-table")) {
|
||||
thead {
|
||||
tr {
|
||||
th { "Username" }
|
||||
th { "Email" }
|
||||
th { ToggleFormButton() }
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
let users = try await fetchAll()
|
||||
for user in users {
|
||||
Row(user: user)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Row: HTML {
|
||||
let user: User
|
||||
|
||||
var content: some HTML<HTMLTag.tr> {
|
||||
tr {
|
||||
td { user.username }
|
||||
td { user.email }
|
||||
td { "Fix me." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user