138 lines
4.7 KiB
Swift
138 lines
4.7 KiB
Swift
import Elementary
|
|
import ElementaryHTMX
|
|
import Routes
|
|
import Styleguide
|
|
|
|
struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable {
|
|
let title = "HVAC-Toolbox"
|
|
let lang = "en-US"
|
|
let inner: @Sendable () -> Inner
|
|
|
|
var head: some HTML {
|
|
meta(.charset(.utf8))
|
|
meta(.name("viewport"), .content("width=device-width, initial-scale=1.0"))
|
|
meta(.name("author"), .content("Michael Housh and Dustin Cole"))
|
|
meta(.name("og:site-name"), .content("HVAC-Toolbox"))
|
|
meta(.name("apple-mobile-web-app-title"), .content("HVAC-Toolbox"))
|
|
meta(.name("format-detection"), .content("telephone=no"))
|
|
meta(.name("HandheldFriendly"), .content("True"))
|
|
meta(.name("MobileOptimized"), .content("320"))
|
|
meta(.name("keywords"), .content("hvac, HVAC, design, system-design, calculators"))
|
|
Elementary.title { self.title }
|
|
link(.rel(.stylesheet), .href("/output.css"))
|
|
link(
|
|
.rel(.icon),
|
|
.href("/favicon-32x32.png"),
|
|
.init(name: "type", value: "image/png"),
|
|
.init(name: "sizes", value: "32x32")
|
|
)
|
|
link(
|
|
.rel(.icon),
|
|
.href("/favicon-16x16.png"),
|
|
.init(name: "type", value: "image/png"),
|
|
.init(name: "sizes", value: "16x16")
|
|
)
|
|
link(
|
|
.rel(.init(rawValue: "apple-touch-icon")),
|
|
.href("/apple-touch-icon.png"),
|
|
.init(name: "sizes", value: "180x180")
|
|
)
|
|
link(.rel(.init(rawValue: "mainifest")), .href("/site.webmanifest"))
|
|
script(.src("https://unpkg.com/htmx.org@2.0.4")) {}
|
|
}
|
|
|
|
var body: some HTML {
|
|
main(.class("bg-slate-100 dark:bg-gray-800")) {
|
|
div(.class("min-h-screen")) {
|
|
Header()
|
|
PageContent(body: inner)
|
|
}
|
|
Footer()
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct Header: HTML {
|
|
|
|
var content: some HTML {
|
|
header(.class("\(bg: .blue) mb-8 flex flex-row gap-2 border \(border: .yellow)")) {
|
|
a(
|
|
.href(route: .index),
|
|
.class("group flex flex-row gap-2 \(bg: .yellow) pe-2 rounded-e-lg \(text: .blue) hover:text-blue-600")
|
|
) {
|
|
img(.src("/images/toolbox.svg"), .width(40), .height(40), .class("py-1"))
|
|
div(.class("flex flex-row mt-2")) {
|
|
h2(.class("text-2xl font-extrabold pe-3")) { "HVAC-Toolbox" }
|
|
SVG(.wind, color: .blue)
|
|
.attributes(.class("group-hover:text-blue-600"))
|
|
}
|
|
}
|
|
// nav(.class("flex flex-row gap-2 p-2 mt-2")) {
|
|
// // TODO: Add class active, to button that is the active route.
|
|
// ul(.class("flex flex-wrap gap-x-2 lg:gap-x-5 \(text: .yellow) font-bold")) {
|
|
// navLink(label: "Mold-Risk", route: .moldRisk(.index))
|
|
// navLink(label: "Dehumidifier-Sizing", route: .dehumidifierSize(.index))
|
|
// navLink(label: "HVAC-System-Performance", route: .hvacSystemPerformance(.index))
|
|
// navLink(label: "Room-Pressure", route: .roomPressure(.index))
|
|
// navLink(label: "Capcitor-Calculator", route: .capacitor(.index))
|
|
// navLink(label: "Attic-Ventilation", route: .atticVentilation(.index))
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
func navLink(label: String, route: SiteRoute.View) -> some HTML<HTMLTag.li> {
|
|
li {
|
|
a(.class("hover:border-b border-yellow-300"), .hx.get(route: route), .hx.target("#content"), .hx.pushURL(true)) {
|
|
label
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct Footer: HTML {
|
|
var content: some HTML {
|
|
div(.class("bg-blue-500 text-yellow-300 text-sm font-semibold border-t border-yellow-300 mt-20")) {
|
|
div(.class("sm:grid sm:grid-cols-1 lg:flex lg:justify-between")) {
|
|
div(.class("grid grid-cols-1 p-4")) {
|
|
div(.class("flex")) {
|
|
span { "Toolbox icon by" }
|
|
a(.class("mx-1"), .href("https://dribbble.com/Laridae?ref=svgrepo.com"), .target(.blank)) {
|
|
u { "Laridae" }
|
|
}
|
|
span { "in CC Attribution License via" }
|
|
a(.class("mx-1"), .href("https://www.svgrepo.com/"), .target(.blank)) { u { "SVG Repo" } }
|
|
}
|
|
|
|
div(.class("flex")) {
|
|
span { "Other SVG's by" }
|
|
a(.class("mx-1"), .href("https://lucide.dev"), .target(.blank)) { u { "Lucide" } }
|
|
span { "and licensed under" }
|
|
a(.class("mx-1"), .href("https://lucide.dev/license")) { u { "MIT." } }
|
|
}
|
|
}
|
|
|
|
div(.class("lg:p-8 sm:p-4")) {
|
|
p { "© Copyright 2025 Michael Housh and Dustin Cole" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct PageContent<Body: HTML>: HTML where Body: Sendable {
|
|
let body: () -> Body
|
|
|
|
var content: some HTML {
|
|
div(.class("mx-5 lg:mx-20")) {
|
|
div(.class("rounded-xl shadow-lg bg-white dark:bg-slate-700 p-8 text-gray-600 dark:text-slate-200")) {
|
|
div(.id("content")) {
|
|
body()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protocol SendableHTMLDocument: HTMLDocument, Sendable {}
|