import DatabaseClient import Dependencies import Elementary import SharedModels import Vapor import VaporElementary struct UserViewController: RouteCollection { @Dependency(\.database.users) var users func boot(routes: any RoutesBuilder) throws { // let users = routes.protected.grouped("users") let users = routes.grouped("users") users.get(use: index) users.post(use: create) users.get("create", use: form) users.group(":id") { $0.post(use: update) $0.get(use: get) $0.delete(use: delete) } } @Sendable func index(req: Request) async throws -> HTMLResponse { try await req.render { try await mainPage(UserDetail(user: nil)) } } @Sendable func get(req: Request) async throws -> HTMLResponse { let user = try await users.get(req.ensureIDPathComponent()) let detail = UserDetail(user: user) guard req.isHtmxRequest else { return try await req.render { try await mainPage(detail) } } return await req.render { UserDetail(user: user) } } @Sendable func create(req: Request) async throws -> HTMLResponse { _ = try await users.create(req.content.decode(User.Create.self)) let users = try await users.fetchAll() // return req.redirect(to: "/users") return await req.render { UserTable(users: users) } } @Sendable func delete(req: Request) async throws -> HTTPStatus { try await users.delete(req.ensureIDPathComponent()) return .ok } @Sendable func form(req: Request) async throws -> HTMLResponse { await req.render { UserForm(context: .create) } } @Sendable func update(req: Request) async throws -> HTMLResponse { let updates = try req.content.decode(User.Update.self) req.logger.info("\(updates)") let user = try await users.update(req.ensureIDPathComponent(), updates) return await req.render { UserTable.Row(user: user) } } private func mainPage(_ html: C) async throws -> some SendableHTMLDocument where C: Sendable { let users = try await users.fetchAll() return MainPage(displayNav: true, route: .users) { div(.class("container")) { html UserTable(users: users) } } } }