From 59b6d46606d5c7848c7ef342f395bbe88a2188de Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Fri, 10 Jan 2025 17:13:43 -0500 Subject: [PATCH] feat: Begins po detail. --- Public/css/main.css | 35 ++++++++++++++ Resources/Views/navbar.leaf | 2 +- Resources/Views/purchaseOrders/detail.leaf | 46 +++++++++++++++++++ Resources/Views/purchaseOrders/index.leaf | 22 +++++++++ Resources/Views/purchaseOrders/table-row.leaf | 9 +++- .../View/PurchaseOrderViewController.swift | 42 +++++++++++++++-- .../View/UsersViewController.swift | 2 +- Sources/App/Controllers/ViewController.swift | 5 +- 8 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 Resources/Views/purchaseOrders/detail.leaf diff --git a/Public/css/main.css b/Public/css/main.css index 0ebaeba..7a519f5 100644 --- a/Public/css/main.css +++ b/Public/css/main.css @@ -301,3 +301,38 @@ tr.htmx-swapping td { margin-right: 15px; font-size: 1.5em; } + +.btn-row button { + border: none; + text-decoration: none; + color: grey; + background-color: inherit; + font-size: 1.3em; + padding-bottom: 10px; +} + +.btn-row button:hover { + color: blue; +} + +.btn-detail { + border: none; + text-decoration: none; + color: grey; + background-color: inherit; + font-size: 1.3em; +} + +.po-detail table { + border-collapse: collapse; + border: none; + max-width: 300px; +} + +.po-detail td { + border: none; +} + +.label { + color: #00ffcc; +} diff --git a/Resources/Views/navbar.leaf b/Resources/Views/navbar.leaf index a2a1b05..975a90a 100644 --- a/Resources/Views/navbar.leaf +++ b/Resources/Views/navbar.leaf @@ -1,6 +1,6 @@
× - diff --git a/Resources/Views/purchaseOrders/detail.leaf b/Resources/Views/purchaseOrders/detail.leaf new file mode 100644 index 0000000..64db5ce --- /dev/null +++ b/Resources/Views/purchaseOrders/detail.leaf @@ -0,0 +1,46 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Purchase Order:

#(purchaseOrder.id)

Work Order:

#(purchaseOrder.workOrder)

Customer:

#(purchaseOrder.customer)

Vendor:

#capitalized(purchaseOrder.vendorBranch.vendor.name) - #capitalized(purchaseOrder.vendorBranch.name)

Materials:

#(purchaseOrder.materials)

Created For:

#capitalized(purchaseOrder.createdFor.firstName) #capitalized(purchaseOrder.createdFor.lastName)

Truck Stock:

#capitalized(purchaseOrder.truckStock)

Created By:

#(purchaseOrder.createdBy.username)

Date:

#date(purchaseOrder.createdAt)

Updated:

#date(purchaseOrder.updatedAt)

+
diff --git a/Resources/Views/purchaseOrders/index.leaf b/Resources/Views/purchaseOrders/index.leaf index 2713e09..f35cf8f 100644 --- a/Resources/Views/purchaseOrders/index.leaf +++ b/Resources/Views/purchaseOrders/index.leaf @@ -8,6 +8,28 @@ #extend("form-container"): #export("formContent"): #extend("purchaseOrders/form", form) #endexport #endextend +
+ #if(hasPrevious): + + #endif + #if(hasNext): + + #endif +
#extend("purchaseOrders/table")
#endexport diff --git a/Resources/Views/purchaseOrders/table-row.leaf b/Resources/Views/purchaseOrders/table-row.leaf index 50acb84..4fd1791 100644 --- a/Resources/Views/purchaseOrders/table-row.leaf +++ b/Resources/Views/purchaseOrders/table-row.leaf @@ -7,7 +7,14 @@ #capitalized(createdFor.firstName) #capitalized(createdFor.lastName) #(createdBy.username) #capitalized(truckStock) - + + diff --git a/Sources/App/Controllers/View/PurchaseOrderViewController.swift b/Sources/App/Controllers/View/PurchaseOrderViewController.swift index d6b826f..508a089 100644 --- a/Sources/App/Controllers/View/PurchaseOrderViewController.swift +++ b/Sources/App/Controllers/View/PurchaseOrderViewController.swift @@ -12,24 +12,36 @@ struct PurchaseOrderViewController: RouteCollection { pos.get(use: index(req:)) pos.post(use: create(req:)) + pos.group(":id") { + $0.get(use: detail(req:)) + } } - // TODO: Use pageinated version. @Sendable func index(req: Request) async throws -> View { - let purchaseOrders = try await api2.fetchAll(on: req.db) + let params = try? req.query.decode(PurchaseOrderIndex.self) + let purchaseOrdersPage = try await api2.fetchPage(params?.page ?? 1, limit: params?.limit ?? 50, on: req.db) let branches = try await self.branches.getBranches(req: req) let employees = try await employeesApi.index(req: req) req.logger.debug("Branches: \(branches)") return try await req.view.render( "purchaseOrders/index", PurchaseOrderCTX( - purchaseOrders: purchaseOrders, + page: purchaseOrdersPage, form: .create(branches: branches, employees: employees) ) ) } + @Sendable + func detail(req: Request) async throws -> View { + guard let id = req.parameters.get("id", as: PurchaseOrder.IDValue.self) else { + throw Abort(.badRequest, reason: "Id not supplied.") + } + let purchaseOrder = try await api2.get(id: id, on: req.db) + return try await req.view.render("purchaseOrders/detail", ["purchaseOrder": purchaseOrder]) + } + @Sendable func create(req: Request) async throws -> View { try PurchaseOrder.FormCreate.validate(content: req) @@ -40,9 +52,33 @@ struct PurchaseOrderViewController: RouteCollection { } } +private struct PurchaseOrderIndex: Content { + let page: Int? + let limit: Int? +} + private struct PurchaseOrderCTX: Content { let purchaseOrders: [PurchaseOrder.DTO] + let page: Int + let limit: Int + let hasNext: Bool + let hasPrevious: Bool let form: PurchaseOrderFormCTX? + + init(page: Page, form: PurchaseOrderFormCTX?) { + self.purchaseOrders = page.items + self.page = page.metadata.page + self.limit = page.metadata.per + self.hasNext = page.metadata.hasNext + self.hasPrevious = page.metadata.page > 1 + self.form = form + } +} + +private extension PageMetadata { + var hasNext: Bool { + total > (page * per) + } } private struct PurchaseOrderFormCTX: Content { diff --git a/Sources/App/Controllers/View/UsersViewController.swift b/Sources/App/Controllers/View/UsersViewController.swift index 32a262a..c172dbd 100644 --- a/Sources/App/Controllers/View/UsersViewController.swift +++ b/Sources/App/Controllers/View/UsersViewController.swift @@ -49,7 +49,7 @@ struct UserFormCTX: Content { htmxForm: .init( formClass: "user-form", formId: "user-form", - htmxTargetUrl: .post("/login\(next != nil ? "?next=\(next!)" : "")"), + htmxTargetUrl: .post("/login\((next != nil && next != "/") ? "?next=\(next!)" : "")"), htmxTarget: "body", htmxPushUrl: true, htmxResetAfterRequest: true, diff --git a/Sources/App/Controllers/ViewController.swift b/Sources/App/Controllers/ViewController.swift index 4d3fd24..43c4be3 100644 --- a/Sources/App/Controllers/ViewController.swift +++ b/Sources/App/Controllers/ViewController.swift @@ -35,7 +35,9 @@ struct ViewController: RouteCollection { func getLogin(req: Request) async throws -> View { req.logger.debug("Login Query: \(req.url.query ?? "n/a")") let params = try? req.query.decode(LoginParameter.self) - return try await req.view.render("login", UserFormCTX.signIn(next: params?.next)) + return try await req.view.render( + "login", UserFormCTX.signIn(next: params?.next) + ) } @Sendable @@ -95,6 +97,7 @@ private struct UserForm: Content { enum HomeRoute: String, Content { case employees + case purchaseOrders case users case vendors }