Files
swift-hvac-toolbox/Sources/ViewController/Views/MoldRisk.swift

92 lines
3.4 KiB
Swift

import Elementary
import PsychrometricClient
import Routes
import Styleguide
struct MoldRiskForm: HTML {
var content: some HTML {
FormHeader(label: "Mold Risk Calculator", svg: .thermometer)
form {
div(.class("space-y-6")) {
LabeledContent(label: "Indoor Temperature (°F)") {
Input(id: "temperature", placeholder: "Dry bulb temperature")
.attributes(.type(.number), .step("0.1"), .min("0.1"), .autofocus)
}
LabeledContent(label: "Indor Humdity (%)") {
Input(id: "humidity", placeholder: "Relative humidity")
.attributes(.type(.number), .step("0.1"), .min("0.1"))
}
div {
SubmitButton(label: "Calculate Mold Risk")
}
div(.id("result")) {
MoldRiskResponse(response: .mock)
}
}
}
}
}
struct MoldRiskResponse: HTML {
let response: MoldRisk.Response
var content: some HTML {
ResultContainer {
// TODO: Color needs to be derived from risk level.
div(.class("p-2 rounded-lg shadow-lg bg-lime-100 border-2 border border-lime-600")) {
LabeledContent {
p(.class("text-lg font-semibold \(text: .green) dark:text-lime-600 mt-2")) {
"Risk Level: \(response.riskLevel.rawValue.capitalized)"
}
} label: {
SVG(.exclamation, color: "\(text: .green) dark:text-lime-600")
}
.attributes(.class("flex items-center gap-2"))
}
PsychrometricPropertiesGrid(properties: response.psychrometricProperties)
.attributes(.class("mx-6"))
div(.class("mt-8 p-4 bg-gray-700 rounded-md shadow-md border border-blue-500")) {
p(.class("text-sm \(text: .blue)")) {
span(.class("font-extrabold pe-2")) { "Note:" }
"""
These calculations are based on typical indoor conditions and common mold species. Actual mold growth can
vary based on surface materials, air movement, and other environmental factors. Always address moisture
issues promptly and consult professionals for severe cases.
"""
}
}
}
}
}
struct PsychrometricPropertiesGrid: HTML {
let properties: PsychrometricProperties
var content: some HTML<HTMLTag.div> {
div(.class("grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-6 md:mx-20")) {
displayProperty("Dew Point", "\(properties.dewPoint.value) \(properties.dewPoint.units.symbol)")
displayProperty("Wet Bulb", "\(properties.wetBulb.value) \(properties.wetBulb.units.symbol)")
displayProperty("Enthalpy", "\(properties.enthalpy.value) \(properties.wetBulb.units.symbol)")
displayProperty("Density", "\(properties.density.value) \(properties.density.units.rawValue)")
displayProperty("Vapor Pressure", "\(properties.vaporPressure.value) \(properties.vaporPressure.units.symbol)")
displayProperty("Specific Volume", "\(properties.specificVolume.rawValue)")
displayProperty("Absolute Humidity", "\(properties.absoluteHumidity.value) \(properties.absoluteHumidity.units.symbol)")
displayProperty("Humidity Ratio", "\(properties.humidityRatio.value)")
displayProperty("Degree of Saturation", "\(properties.degreeOfSaturation.value)")
}
}
func displayProperty(_ label: String, _ value: String) -> some HTML {
p(.class("\(text: .darkGray) dark:\(text: .white)")) {
span(.class("font-semibold")) { "\(label): " }
span(.class("font-light")) { value }
}
}
}