feat: adds next route to login.

This commit is contained in:
2026-01-04 09:30:14 -05:00
parent a61c772f7b
commit f159c3ab75
11 changed files with 2326 additions and 56 deletions

View File

@@ -13,15 +13,14 @@ extension ViewController.Request {
switch route {
case .login(let route):
switch route {
case .index:
case .index(let next):
return view {
LoginForm()
LoginForm(next: next)
}
case .submit(let login):
let user = try await authenticate(login)
let projects = try await database.projects.fetch(user.id, .init(page: 1, per: 25))
let _ = try await authenticate(login)
return view {
ProjectsTable(userID: user.id, projects: projects)
LoggedIn(next: login.next)
}
}
case .signup(let route):
@@ -40,8 +39,8 @@ extension ViewController.Request {
}
case .project(let route):
return try await route.renderView(on: self)
case .room(let route):
return try await route.renderView(on: self)
// case .room(let route):
// return try await route.renderView(on: self)
case .frictionRate(let route):
return try await route.renderView(isHtmxRequest: isHtmxRequest)
case .effectiveLength(let route):
@@ -102,29 +101,40 @@ extension SiteRoute.View.ProjectRoute {
}
}
case .detail(let projectID):
let project = try await database.projects.get(projectID)!
return request.view {
ProjectView(projectID: projectID, activeTab: .projects) {
ProjectDetail(project: project)
case .detail(let projectID, let route):
switch route {
case .index:
let project = try await database.projects.get(projectID)!
return request.view {
ProjectView(projectID: projectID, activeTab: .projects) {
ProjectDetail(project: project)
}
}
case .rooms(let route):
return try await route.renderView(on: request, projectID: projectID)
}
// case .rooms(let projectID, let route):
// return try await route.renderView(on: request, projectID: projectID)
}
}
}
extension SiteRoute.View.RoomRoute {
func renderView(on request: ViewController.Request) async throws -> AnySendableHTML {
extension SiteRoute.View.ProjectRoute.RoomRoute {
func renderView(
on request: ViewController.Request,
projectID: Project.ID
) async throws -> AnySendableHTML {
@Dependency(\.database) var database
switch self {
case .form(let projectID, let dismiss):
case .form(let dismiss):
return RoomForm(dismiss: dismiss, projectID: projectID)
case .index(let projectID):
case .index:
let rooms = try await database.rooms.fetch(projectID)
return request.view {
ProjectView(projectID: projectID, activeTab: .rooms) {
@@ -132,7 +142,7 @@ extension SiteRoute.View.RoomRoute {
}
}
case .submit(let projectID, let form):
case .submit(let form):
request.logger.debug("New room form submitted.")
let _ = try await database.rooms.create(.init(form: form, projectID: projectID))
let rooms = try await database.rooms.fetch(projectID)

View File

@@ -1,4 +1,7 @@
import Elementary
import ElementaryHTMX
import ManualDCore
import Styleguide
public struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable {
@@ -6,16 +9,10 @@ public struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable
public var lang: String { "en" }
let inner: Inner
// let activeTab: Sidebar.ActiveTab
// let showSidebar: Bool
init(
// active activeTab: Sidebar.ActiveTab,
// showSidebar: Bool = true,
_ inner: () -> Inner
) {
// self.activeTab = activeTab
// self.showSidebar = showSidebar
self.inner = inner()
}
@@ -39,4 +36,21 @@ public struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable
}
}
struct LoggedIn: HTML, Sendable {
let next: String?
var body: some HTML {
div(
.hx.get(next ?? SiteRoute.View.router.path(for: .project(.index))),
.hx.pushURL(true),
.hx.target("body"),
.hx.trigger(.event(.revealed)),
.hx.indicator(".hx-indicator")
) {
Indicator()
}
}
}
public protocol SendableHTMLDocument: HTMLDocument, Sendable {}

View File

@@ -56,10 +56,10 @@ struct Sidebar: HTML {
}
.attributes(.class("p-4"))
row(title: "Project", icon: .mapPin, route: .project(.detail(projectID)))
row(title: "Project", icon: .mapPin, route: .project(.detail(projectID, .index)))
.attributes(.data("active", value: active == .projects ? "true" : "false"))
row(title: "Rooms", icon: .doorClosed, route: .room(.index(projectID)))
row(title: "Rooms", icon: .doorClosed, route: .project(.detail(projectID, .rooms(.index))))
.attributes(.data("active", value: active == .rooms ? "true" : "false"))
row(title: "Equivalent Lengths", icon: .rulerDimensionLine, route: .effectiveLength(.index))

View File

@@ -69,7 +69,7 @@ extension ProjectsTable {
td {
a(
.class("btn btn-success"),
.href(route: .project(.detail(project.id)))
.href(route: .project(.detail(project.id, .index)))
) { ">" }
}
}

View File

@@ -17,7 +17,7 @@ struct RoomForm: HTML, Sendable {
// TODO: Use htmx here.
form(
.method(.post),
.action(route: .room(.index(projectID)))
.action(route: .project(.detail(projectID, .rooms(.index))))
) {
div {
label(.for("name")) { "Name:" }
@@ -45,7 +45,7 @@ struct RoomForm: HTML, Sendable {
div(.class("space-x-4")) {
CancelButton()
.attributes(
.hx.get(route: .room(.form(projectID, dismiss: true))),
.hx.get(route: .project(.detail(projectID, .rooms(.form(dismiss: true))))),
.hx.target("#roomForm"),
.hx.swap(.outerHTML)
)

View File

@@ -20,7 +20,7 @@ struct RoomsView: HTML, Sendable {
.data("tip", value: "Add room")
) {
button(
.hx.get(route: .room(.form(projectID, dismiss: false))),
.hx.get(route: .project(.detail(projectID, .rooms(.form(dismiss: false))))),
.hx.target("#roomForm"),
.hx.swap(.outerHTML),
.class("btn btn-primary w-[40px] text-2xl")

View File

@@ -5,9 +5,11 @@ import Styleguide
struct LoginForm: HTML, Sendable {
let style: Style
let next: String?
init(style: Style = .login) {
init(style: Style = .login, next: String? = nil) {
self.style = style
self.next = next
}
var body: some HTML {
@@ -18,6 +20,11 @@ struct LoginForm: HTML, Sendable {
form(
.method(.post)
) {
if let next {
input(.class("hidden"), .name("next"), .value(next))
}
fieldset(.class("fieldset bg-base-200 border-base-300 rounded-box w-xl border p-4")) {
legend(.class("fieldset-legend")) { style.title }
@@ -81,7 +88,7 @@ struct LoginForm: HTML, Sendable {
button(.class("btn btn-secondary mt-4")) { style.title }
a(
.class("btn btn-link mt-4"),
.href(route: style == .signup ? .login(.index) : .signup(.index))
.href(route: style == .signup ? .login(.index(next: next)) : .signup(.index))
) {
style == .login ? "Sign Up" : "Login"
}