Files
vapor-po/Sources/App/Controllers/View/VendorViewController.swift

87 lines
2.5 KiB
Swift

import DatabaseClient
import Dependencies
import Elementary
import SharedModels
import Vapor
import VaporElementary
struct VendorViewController: RouteCollection {
@Dependency(\.database.vendors) var vendors
@Dependency(\.database.vendorBranches) var vendorBranches
func boot(routes: any RoutesBuilder) throws {
let route = routes.grouped("vendors")
route.get(use: index)
route.post(use: create)
route.get("create", use: form)
route.group(":id") {
$0.get(use: detail)
$0.put(use: update)
$0.post("branches", use: createBranch(req:))
}
}
@Sendable
func index(req: Request) async throws -> HTMLResponse {
try await req.render {
try await mainPage(VendorForm())
}
}
@Sendable
func create(req: Request) async throws -> HTMLResponse {
let vendor = try await vendors.create(req.content.decode(Vendor.Create.self))
return await req.render { VendorDetail(vendor: vendor) }
}
@Sendable
func form(req: Request) async throws -> HTMLResponse {
await req.render { VendorForm(.float(shouldShow: true)) }
}
@Sendable
func detail(req: Request) async throws -> HTMLResponse {
guard let vendor = try await vendors.get(req.ensureIDPathComponent(), .withBranches) else {
throw Abort(.badRequest, reason: "Vendor does not exist.")
}
let html = VendorDetail(vendor: vendor)
guard req.isHtmxRequest else {
return try await req.render { try await mainPage(html) }
}
return await req.render { html }
}
@Sendable
func update(req: Request) async throws -> HTMLResponse {
let vendor = try await vendors.update(
req.ensureIDPathComponent(),
with: req.content.decode(Vendor.Update.self),
returnWithBranches: true
)
return await req.render { VendorDetail(vendor: vendor) }
}
@Sendable
func createBranch(req: Request) async throws -> HTMLResponse {
let vendorID = try req.ensureIDPathComponent()
let create = try req.content.decode(CreateBranch.self)
let branch = try await vendorBranches.create(.init(name: create.name, vendorID: vendorID))
return await req.render { VendorDetail.BranchTable.Row(branch: branch) }
}
private func mainPage<C: HTML>(_ html: C) async throws -> some SendableHTMLDocument where C: Sendable {
let vendors = try await vendors.fetchAll(.withBranches)
return MainPage(displayNav: true, route: .vendors) {
div(.class("container")) {
html
VendorTable(vendors: vendors)
}
}
}
}
struct CreateBranch: Content {
let name: String
}