feat: Refactors / renames some modules.

This commit is contained in:
2025-02-26 08:27:39 -05:00
parent 30cfde9f30
commit cce99ce5e9
12 changed files with 32 additions and 53 deletions

View File

@@ -0,0 +1,13 @@
import Elementary
extension HTMLAttribute where Tag == HTMLTag.input {
static func min(_ value: String) -> Self {
.init(name: "min", value: value)
}
static func step(_ value: String) -> Self {
.init(name: "step", value: value)
}
}

View File

@@ -0,0 +1,9 @@
import Elementary
import Routes
import URLRouting
extension HTMLAttribute where Tag: HTMLTrait.Attributes.href {
static func href(route: SiteRoute.View) -> Self {
.href(SiteRoute.View.router.path(for: route))
}
}

View File

@@ -20,3 +20,13 @@ public struct ViewController: Sendable {
extension ViewController: TestDependencyKey {
public static let testValue: ViewController = Self()
}
extension ViewController: DependencyKey {
public static var liveValue: ViewController {
.init(view: { _ in
MainPage {
MoldRiskForm()
}
})
}
}

View File

@@ -0,0 +1,75 @@
import Elementary
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"))
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"))
}
var body: some HTML {
main(.class("bg-white dark:bg-gray-800")) {
div(.class("min-h-screen")) {
Header()
inner()
}
}
}
}
struct Header: HTML {
var content: some HTML {
header(.class("bg-blue-500 mb-8 flex flex-row gap-2 border-b border-yellow-300")) {
a(
.href(route: .index),
.class("flex flex-row gap-2 bg-yellow-300 pe-2 rounded-e-lg text-blue-500 [&: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")) { "HVAC-Toolbox" }
SVG.wind
}
}
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-300 font-bold")) {
li {
a(.href(route: .moldRisk(.index)), .class("[&:hover]:border-b border-yellow-300")) {
"Mold-Risk"
}
}
li {
a(.href("#"), .class("[&:hover]:border-b border-yellow-300")) {
"Dehumidifier-Sizing"
}
}
}
}
}
}
}
protocol SendableHTMLDocument: HTMLDocument, Sendable {}

View File

@@ -0,0 +1,56 @@
import Elementary
import Routes
struct MoldRiskForm: HTML {
var content: some HTML {
div(.class("grid grid-cols-1 lg:grid-cols-12")) {
div(.class("col-span-1")) {}
div(.class("col-span-10 rounded-xl shadow-lg bg-slate-300 dark:bg-slate-700 p-8")) {
div(.class("flex items-center gap-3 mb-6")) {
SVG.thermometer
h2(.class("text-2xl font-extrabold dark:text-white")) { "Mold Risk Calculator" }
}
form {
div(.class("space-y-6")) {
div {
label(.for("temperature"), .class("block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2")) {
"Indoor Temperature"
}
input(
.type(.number), .id("temperature"), .placeholder("Dry bulb temperature"), .required,
.step("0.1"), .min("0.1"),
.class("""
w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-yellow-800
focus:border-yellow-800 text-gray-700 dark:text-white
""")
)
}
div {
label(.for("humidity"), .class("block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2")) {
"Indoor Humidity (%)"
}
input(
.type(.number), .id("humidity"), .name("humidity"), .placeholder("Relative humidity"), .required,
.step("0.1"), .min("0.1"),
.class("""
w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-yellow-800
focus:border-yellow-800 text-gray-700 dark:text-white
""")
)
}
div {
button(.type(.submit), .class("""
w-full bg-\(Colors.blue) text-\(Colors.yellow) font-bold py-3 rounded-md hover:bg-blue-600
transition-colors
""")) {
"Calculate Mold Risk"
}
}
}
}
div(.class("col-span-1")) {}
}
}
}
}

View File

@@ -0,0 +1,46 @@
import Elementary
enum SVG {
static let wind = HTMLRaw("""
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="w-8 h-8">
<path d="M17.7 7.7a2.5 2.5 0 1 1 1.8 4.3H2"></path>
<path d="M9.6 4.6A2 2 0 1 1 11 8H2"></path>
<path d="M12.6 19.4A2 2 0 1 0 14 16H2"></path>
</svg>
""")
static let calculator = HTMLRaw("""
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="w-5 h-5">
<rect width="16" height="20" x="4" y="2" rx="2"></rect>
<line x1="8" x2="16" y1="6" y2="6"></line>
<line x1="16" x2="16" y1="14" y2="18"></line>
<path d="M16 10h.01"></path>
<path d="M12 10h.01"></path>
<path d="M8 10h.01"></path>
<path d="M12 14h.01"></path>
<path d="M8 14h.01"></path>
<path d="M12 18h.01"></path><path d="M8 18h.01"></path>
</svg>
""")
static let thermometer = HTMLRaw("""
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="w-8 h-8 text-blue-500">
<path d="M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z"></path>
</svg>
""")
static let menu = HTMLRaw("""
<svg class="block h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor"
viewBox="0 0 24 24" x="0" y="0" id="menu-icon">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
""")
}

View File

@@ -0,0 +1,7 @@
// NOTE: These don't always work as expected with tailwind they generally
// need to be in the class itself, but here for reference of the primary
// colors.
enum Colors {
static let yellow = "yellow-300"
static let blue = "blue-500"
}