import DatabaseClient import Dependencies import Elementary import SharedModels import Vapor import VaporElementary struct EmployeeViewController: RouteCollection { @Dependency(\.database.employees) var employees func boot(routes: any RoutesBuilder) throws { let route = routes.protected.grouped("employees") route.get(use: index) route.get("create", use: form) route.post(use: create) route.group(":id") { $0.get(use: get) $0.put(use: update) } } @Sendable func index(req: Request) async throws -> HTMLResponse { try await req.render { try await mainPage(EmployeeForm()) } } @Sendable func form(req: Request) async throws -> HTMLResponse { await req.render { EmployeeForm(shouldShow: true) } } @Sendable func create(req: Request) async throws -> HTMLResponse { let employee = try await employees.create(req.content.decode(Employee.Create.self)) return await req.render { EmployeeTable.Row(employee: employee) } } @Sendable func get(req: Request) async throws -> HTMLResponse { guard let employee = try await employees.get(req.ensureIDPathComponent()) else { throw Abort(.badRequest, reason: "Employee not found.") } guard req.isHtmxRequest else { return try await req.render { try await mainPage(EmployeeForm(employee: employee)) } } return await req.render { EmployeeForm(employee: employee) } } @Sendable func update(req: Request) async throws -> HTMLResponse { let employee = try await employees.update(req.ensureIDPathComponent(), req.content.decode(Employee.Update.self)) return await req.render { EmployeeTable.Row(employee: employee) } } private func mainPage(_ html: C) async throws -> some SendableHTMLDocument where C: Sendable { let employees = try await self.employees.fetchAll() return MainPage(displayNav: true, route: .employees) { div(.class("container")) { html EmployeeTable(employees: employees) } } } }