WIP: Sidebar improvements, working on other views.

This commit is contained in:
2026-01-01 08:47:23 -05:00
parent 24c87602e9
commit 582d94d13b
10 changed files with 175 additions and 76 deletions

View File

@@ -1,62 +0,0 @@
import Elementary
import ElementaryHTMX
import ManualDCore
import Styleguide
struct ComponentPressureLossTable: HTML, Sendable {
let componentPressureLosses: [ComponentPressureLoss]
var body: some HTML {
div(.id("cplTable")) {
h1(.class("text-2xl font-bold pb-4")) { "Component Pressure Losses" }
table(
.class(
"w-full border-collapse border border-gray-200 table-fixed"
)
) {
thead { tableHeader }
tbody(.id("cplTableBody")) {
Rows(componentPressureLosses: componentPressureLosses)
}
}
}
div(.id("componentLossForm")) {}
}
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")) { "Pressure Loss" }
th(.class("border border-gray-200 text-xl font-bold")) {
Row {
div {}
button(
.class("px-2"),
.hx.get(route: .frictionRate(.form(.componentPressureLoss))),
.hx.target("#componentLossForm"),
.hx.swap(.outerHTML)
) {
Icon(.circlePlus)
}
}
}
}
}
private struct Rows: HTML, Sendable {
let componentPressureLosses: [ComponentPressureLoss]
var body: some HTML {
for cpl in componentPressureLosses {
tr {
td(.class("border border-gray-200 p-2")) { cpl.name }
td(.class("border border-gray-200 p-2")) { "\(cpl.value)" }
td(.class("border border-gray-200 p-2")) {
// FIX: Add edit button
}
}
}
}
}
}

View File

@@ -0,0 +1,50 @@
import Elementary
import ElementaryHTMX
import ManualDCore
import Styleguide
struct ComponentPressureLossesView: HTML, Sendable {
let componentPressureLosses: [ComponentPressureLoss]
private var total: Double {
componentPressureLosses.reduce(into: 0) { $0 += $1.value }
}
var body: some HTML {
div(
.class(
"""
border border-gray-200 rounded-lg shadow-lg space-y-4 p-4
"""
)
) {
Row {
h1(.class("text-2xl font-bold")) { "Component Pressure Losses" }
button(
.hx.get(route: .frictionRate(.form(.componentPressureLoss, dismiss: false))),
.hx.target("#componentLossForm"),
.hx.swap(.outerHTML)
) {
Icon(.circlePlus)
}
}
for row in componentPressureLosses {
Row {
Label { row.name }
Number(row.value)
}
.attributes(.class("border-b border-gray-200"))
}
Row {
Label { "Total" }
Number(total)
.attributes(.class("text-xl font-bold"))
}
}
div(.id("componentLossForm")) {}
}
}

View File

@@ -13,19 +13,19 @@ struct EquipmentInfoView: HTML, Sendable {
Row {
Label { "Static Pressure" }
span { "\(equipmentInfo.staticPressure)" }
Number(equipmentInfo.staticPressure)
}
.attributes(.class("border-b border-gray-200"))
Row {
Label { "Heating CFM" }
span { "\(equipmentInfo.heatingCFM)" }
Number(equipmentInfo.heatingCFM)
}
.attributes(.class("border-b border-gray-200"))
Row {
Label { "Cooling CFM" }
span { "\(equipmentInfo.coolingCFM)" }
Number(equipmentInfo.coolingCFM)
}
.attributes(.class("border-b border-gray-200"))

View File

@@ -5,10 +5,10 @@ import Styleguide
struct FrictionRateView: HTML, Sendable {
var body: some HTML {
div(.class("w-full flex-1 p-4 space-y-6")) {
div(.class("p-4 space-y-6")) {
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
EquipmentInfoView(equipmentInfo: EquipmentInfo.mock)
ComponentPressureLossTable(componentPressureLosses: ComponentPressureLoss.mock)
ComponentPressureLossesView(componentPressureLosses: ComponentPressureLoss.mock)
}
}
}

View File

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

View File

@@ -0,0 +1,54 @@
import Elementary
import ElementaryHTMX
import ManualDCore
import Styleguide
struct ProjectView: HTML, Sendable {
let project: Project
var body: some HTML {
div(
.class(
"""
border border-gray-200 rounded-lg shadow-lg space-y-4 p-4 m-4
"""
)
) {
Row {
h1(.class("text-2xl font-bold")) { "Project" }
// FIX: Add edit button.
}
Row {
Label("Name")
span { project.name }
}
.attributes(.class("border-b border-gray-200"))
Row {
Label("Address")
span { project.streetAddress }
}
.attributes(.class("border-b border-gray-200"))
Row {
Label("City")
span { project.city }
}
.attributes(.class("border-b border-gray-200"))
Row {
Label("State")
span { project.state }
}
.attributes(.class("border-b border-gray-200"))
Row {
Label("Zip")
span { project.zipCode }
}
}
div(.id("projectForm")) {}
}
}

View File

@@ -8,7 +8,9 @@ struct Sidebar: HTML {
aside(
.class(
"""
h-screen sticky top-0 min-w-[280px] flex-none border border-r-3 border-gray-800 bg-gray-100 shadow
h-screen sticky top-0 max-w-[280px] flex-none
border-r-2 border-gray-200
shadow-lg
"""
)
) {
@@ -16,6 +18,7 @@ struct Sidebar: HTML {
row(title: "Rooms", icon: .doorClosed, href: "/rooms")
row(title: "Equivalent Lengths", icon: .rulerDimensionLine, href: "#")
row(title: "Friction Rate", icon: .squareFunction, href: "/friction-rate")
.attributes(.data("active", value: "true"))
row(title: "Duct Sizes", icon: .wind, href: "#")
}
}
@@ -24,17 +27,20 @@ struct Sidebar: HTML {
title: String,
icon: Icon.Key,
href: String
) -> some HTML {
) -> some HTML<HTMLTag.a> {
a(
.class(
"""
flex w-full items-center gap-4 text-gray-800 hover:bg-gray-300 px-4 py-2
flex w-full items-center gap-4
hover:bg-gray-300 hover:text-gray-800
data-[active=true]:bg-gray-300 data-[active=true]:text-gray-800
px-4 py-2
"""
),
.href(href)
) {
Icon(icon)
span(.class("text-xl font-bold")) {
span(.class("text-xl")) {
title
}
}