WIP: Begins rooms table.

This commit is contained in:
2025-12-31 10:01:39 -05:00
parent 231f1b8de6
commit c29e1acffe
7 changed files with 192 additions and 15 deletions

View File

@@ -7,6 +7,8 @@ extension ViewController.Request {
switch route {
case .project(let route):
return try await route.renderView(isHtmxRequest: isHtmxRequest)
case .room(let route):
return try await route.renderView(isHtmxRequest: isHtmxRequest)
default:
// FIX: FIX
return mainPage
@@ -18,7 +20,9 @@ extension SiteRoute.View.ProjectRoute {
func renderView(isHtmxRequest: Bool) async throws -> AnySendableHTML {
switch self {
case .index:
return mainPage
return MainPage {
ProjectForm()
}
case .form:
return MainPage {
ProjectForm()
@@ -29,6 +33,17 @@ extension SiteRoute.View.ProjectRoute {
}
}
extension SiteRoute.View.RoomRoute {
func renderView(isHtmxRequest: Bool) async throws -> AnySendableHTML {
switch self {
case .form:
return MainPage {
RoomTable(rooms: Room.mocks)
}
}
}
}
private let mainPage: AnySendableHTML = {
MainPage {
div {

View File

@@ -20,9 +20,11 @@ public struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable
}
public var body: some HTML {
div(.class("bg-white dark:bg-gray-800 dark:text-white")) {
div(.class("flex bg-white dark:bg-gray-800 dark:text-white")) {
Sidebar()
inner
main {
inner
}
}
script(.src("https://unpkg.com/lucide@latest")) {}
script {

View File

@@ -15,6 +15,7 @@ struct ProjectForm: HTML, Sendable {
var body: some HTML {
// TODO: Add htmx attributes.
div(.class("mx-20 my-20")) {
h1(.class("text-3xl font-bold")) { "Project" }
form(.class("w-full max-w-sm")) {
div(.class("flex items-center mb-6")) {
label(

View File

@@ -0,0 +1,97 @@
import Dependencies
import Elementary
import Foundation
import ManualDCore
// TODO: Need to hold the project ID in hidden input field.
struct RoomForm: HTML, Sendable {
var body: some HTML {
div(.class("mx-10 my-10")) {
h1(.class("text-3xl font-bold pb-6")) { "Rooms " }
form(
.class(
"""
grid md:grid-cols-3 gap-4
"""
)
) {
div(.class("col-span-1")) {
div {
label(.for("name")) { "Name:" }
}
input(
.type(.text), .name("name"), .id("name"), .placeholder("Room Name"), .required,
.autofocus
)
}
div(.class("col-span-1")) {
div {
label(.for("heatingLoad")) { "Heating Load:" }
}
input(
.type(.number), .name("heatingLoad"), .id("heatingLoad"), .placeholder("Heating Load"),
.required
)
}
div(.class("col-span-1")) {
div {
label(.for("coolingLoad")) { "Cooling Load:" }
}
input(
.type(.number), .name("coolingLoad"), .id("coolingLoad"), .placeholder("Cooling Load"),
.required
)
}
}
}
}
}
struct RoomTable: HTML, Sendable {
let rooms: [Room]
var body: some HTML {
div(.class("m-10")) {
h1(.class("text-3xl font-bold")) { "Rooms" }
table(
.id("rooms"),
.class(
"w-full border-collapse border border-gray-200 table-fixed"
)
) {
thead { tableHeader }
tbody {
Rows(rooms: rooms)
}
}
}
}
private var tableHeader: some HTML<HTMLTag.tr> {
tr {
th(.class("border border-gray-200 text-xl font-bold")) { "Name" }
th(.class("border border-gray-200 text-xl font-bold")) { "Heating Load" }
th(.class("border border-gray-200 text-xl font-bold")) { "Cooling Total" }
th(.class("border border-gray-200 text-xl font-bold")) { "Cooling Sensible" }
th(.class("border border-gray-200 text-xl font-bold")) { "Register Count" }
}
}
private struct Rows: HTML, Sendable {
let rooms: [Room]
var body: some HTML {
for room in rooms {
tr {
td(.class("border border-gray-200 p-2")) { room.name }
td(.class("border border-gray-200 p-2")) { "\(room.heatingLoad)" }
td(.class("border border-gray-200 p-2")) { "\(room.coolingLoad.total)" }
td(.class("border border-gray-200 p-2")) { "\(room.coolingLoad.sensible)" }
td(.class("border border-gray-200 p-2")) { "\(room.registerCount)" }
}
}
}
}
}

View File

@@ -3,30 +3,33 @@ import Elementary
struct Sidebar: HTML {
var body: some HTML {
div(
aside(
.class(
"""
h-screen w-64 pt-10 border-r-3 border-gray-800 bg-gray-100 shadow
""")
h-screen sticky top-0 border-r-3 border-gray-800 bg-gray-100 shadow
"""
)
) {
row(title: "Project", icon: "map-pin")
row(title: "Rooms", icon: "door-closed")
row(title: "Equivalent Lengths", icon: "ruler-dimension-line")
row(title: "Friction Rate", icon: "square-function")
row(title: "Duct Sizes", icon: "wind")
row(title: "Project", icon: "map-pin", href: "/projects")
row(title: "Rooms", icon: "door-closed", href: "/rooms")
row(title: "Equivalent Lengths", icon: "ruler-dimension-line", href: "#")
row(title: "Friction Rate", icon: "square-function", href: "#")
row(title: "Duct Sizes", icon: "wind", href: "#")
}
}
private func row(
title: String,
icon: String
icon: String,
href: String
) -> some HTML {
button(
a(
.class(
"""
flex w-full items-center gap-4 text-gray-800 hover:bg-gray-300 pl-4 py-2
flex w-full items-center gap-4 text-gray-800 hover:bg-gray-300 px-4 py-2
"""
)
),
.href(href)
) {
i(.data("lucide", value: icon)) {}
p(