Skip to content

Commit

Permalink
Validate energy use fields (#160)
Browse files Browse the repository at this point in the history
* WIP: explore abstract in zod types

Co-authored-by: plocket <[email protected]>
Co-authored-by: Clayton Schneider <[email protected]>
Co-authored-by: Leopardfoot <[email protected]>
Co-authored-by: Camden Blatchly <[email protected]>

* Added zod types for CurrentHeatingSystem and change types/index.ts to zod.

Co-authored-by: Camden Blatchly <[email protected]>
Co-authored-by: plocket <[email protected]>

* fix display analysis+charts to use zod

* implement CurrentHeatingSystem form in zod/conform

Co-authored-by: plocket <[email protected]>
Co-authored-by: Clayton Schneider <[email protected]>

* update TODOs with upload

Co-authored-by: plocket <[email protected]>
Co-authored-by: Clayton Schneider <[email protected]>
Co-authored-by: AISHWARYA RAJA <[email protected]>

---------

Co-authored-by: plocket <[email protected]>
Co-authored-by: Clayton Schneider <[email protected]>
Co-authored-by: Leopardfoot <[email protected]>
Co-authored-by: Camden Blatchly <[email protected]>
Co-authored-by: AISHWARYA RAJA <[email protected]>
  • Loading branch information
6 people authored Apr 9, 2024
1 parent 5787b7d commit bb8fc68
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Form } from '@remix-run/react'

Check warning on line 1 in heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

'Form' is defined but never used
import { Button } from '#/app/components/ui/button.tsx'

Check warning on line 2 in heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

'Button' is defined but never used
import { ErrorList } from './ErrorList.tsx'

Check warning on line 3 in heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`./ErrorList.tsx` import should occur after import of `#/app/components/ui/label.tsx`

import { Input } from '#/app/components/ui/input.tsx'
import { Label } from '#/app/components/ui/label.tsx'

type CurrentHeatingSystemProps = {fields: any};
type CurrentHeatingSystemProps = { fields: any }

export function CurrentHeatingSystem(props: CurrentHeatingSystemProps) {
const titleClass = 'text-5xl font-extrabold tracking-wide'
Expand All @@ -18,107 +19,154 @@ export function CurrentHeatingSystem(props: CurrentHeatingSystemProps) {
Existing Heating System
</h2>

<Form method="post" action="/current">
<h6 className={`${subtitleClass}`}>Fuel Type</h6>
{/* <Form method="post" action="/current"> */}
<div>
{' '}
<Label htmlFor="fuelType" className={`${subtitleClass}`}>
Fuel Type
</Label>
<div className="flex space-x-4">
<div className="basis-1/4">
<Input name="fuelType" id="fuelType" type="text" />
<Input
name={props.fields.fuelType.name}
id="fuelType"
type="text"
/>
</div>
</div>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.fuelType.errorId}
errors={props.fields.fuelType.errors}
/>
</div>
</div>

<h6 className={`${subtitleClass}`}>Heating system efficiency %</h6>
<div className="flex space-x-4">
<div className={`basis-1/3`}>
<Input
name="heatingSystemEfficiency"
id="heatingSystemEfficiency"
type="text"
placeholder="(Percent)"
<Label htmlFor="heatingSystemEfficiency" className={`${subtitleClass}`}>
Heating system efficiency %
</Label>
<div className="flex space-x-4">
<div className={`basis-1/3`}>
<Input
name={props.fields.heatingSystemEfficiency.name}
id="heatingSystemEfficiency"
type="text"
placeholder="(Percent)"
/>
<div className={`${descriptiveClass}`}>
Typical natural gas efficiency is 80%-95%
</div>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.heatingSystemEfficiency.errorId}
errors={props.fields.heatingSystemEfficiency.errors}
/>
</div>
</div>
</div>

<Label htmlFor="designTemperatureOverride" className={`${subtitleClass}`}>
Design temperature override (°F)
</Label>
<div className="flex space-x-4">
<div className={`basis-1/3`}>
<Input
name={props.fields.designTemperatureOverride.name}
id="designTemperatureOverride"
type="text"
placeholder="(Optional)"
/>
<div>
<div className={`${descriptiveClass}`}>
Typical natural gas efficiency is 80%-95%
65°F is the 99% ASHRAE heating design temperature at this location
</div>
</div>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.designTemperatureOverride.errorId}
errors={props.fields.designTemperatureOverride.errors}
/>
</div>
</div>
</div>

<h6 className={`${subtitleClass}`}>Design temperature override (°F)</h6>
<div className="flex space-x-4">
<div className={`basis-1/3`}>
<div>
<h6 className={`${subtitleClass}`}>Thermostat Settings</h6>
<div className="mt-4 flex space-x-4">
<div className="basis-1/3">
<Label htmlFor="thermostatSetPoint">
<b>Set Point (°F)</b>{' '}
</Label>
<Input
name="designTemperatureOverride"
id="designTemperatureOverride"
name={props.fields.thermostatSetPoint.name}
id="thermostatSetPoint"
type="text"
placeholder="(Optional)"
placeholder="(Fahrenheit)"
/>
<div>
<div className={`${descriptiveClass}`}>
65°F is the 99% ASHRAE heating design temperature at this
location
</div>
<div className={`${descriptiveClass}`}>
Usual thermostat setting for heating
</div>
</div>
</div>

<div>
<h6 className={`${subtitleClass}`}>Thermostat Settings</h6>
<div className="mt-4 flex space-x-4">
<div className="basis-1/3">
<Label htmlFor="setPoint">
<b>Set Point (°F)</b>{' '}
</Label>
<Input
name="setPointTemperature"
id="setPointTemperature"
type="text"
placeholder="(Fahrenheit)"
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.thermostatSetPoint.errorId}
errors={props.fields.thermostatSetPoint.errors}
/>
<div className={`${descriptiveClass}`}>
Usual thermostat setting for heating
</div>
</div>
<div className="basis-1/3">
<Label htmlFor="setPoint">
<b>Setback Temperature (°F)</b>
</Label>
<Input
name="setBackTemperature"
id="setBackTemperature"
type="text"
placeholder="(Optional)"
</div>
<div className="basis-1/3">
<Label htmlFor="setbackTemperature">
<b>Setback Temperature (°F)</b>
</Label>
<Input
name={props.fields.setbackTemperature.name}
id="setbackTemperature"
type="text"
placeholder="(Optional)"
/>
<div className={`${descriptiveClass}`}>
Enter if thermostat is programmed to a lower or higher temperature
during working or sleep hours
</div>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.setbackTemperature.errorId}
errors={props.fields.setbackTemperature.errors}
/>
<div className={`${descriptiveClass}`}>
Enter if thermostat is programmed to a lower or higher
temperature during working or sleep hours
</div>
</div>
<div className="basis-1/3">
<Label htmlFor="setPoint">
<b>Setback hours per day</b>
</Label>
<Input
name="setBackTime"
id="setBackTime"
type="text"
placeholder="(Optional)"
</div>
<div className="basis-1/3">
<Label htmlFor="setbackHoursPerDay">
<b>Setback hours per day</b>
</Label>
<Input
name={props.fields.setbackHoursPerDay.name}
id="setbackHoursPerDay"
type="text"
placeholder="(Optional)"
/>
<div className={`${descriptiveClass}`}>
Typical natural gas efficiency is 80%-95%
</div>
<div className={`${descriptiveClass}`}>
Average hours per day that a lower or higher temperature setting
is in effect
</div>
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.setbackHoursPerDay.errorId}
errors={props.fields.setbackHoursPerDay.errors}
/>
<div className={`${descriptiveClass}`}>
Typical natural gas efficiency is 80%-95%
</div>
<div className={`${descriptiveClass}`}>
Average hours per day that a lower or higher temperature setting
is in effect
</div>
</div>
</div>
</div>
</div>


</Form>
{/* </Form> */}

{/* removed temporarily for single page app format */}
{/* <div>
<Button type="submit">Next ={'>'}</Button>
</div> */}
<Button type="submit">Next ={'>'}</Button>
</div> */}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { FieldMetadata, useForm } from '@conform-to/react'

// // return redirect(`/inputs1`)
// }

type HomeInformationProps = {fields: any};

export function HomeInformation(props: HomeInformationProps) {
Expand Down
27 changes: 18 additions & 9 deletions heat-stack/app/routes/_heat+/single.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ import { json, ActionFunctionArgs } from '@remix-run/node'
import { Form, redirect, useActionData } from '@remix-run/react'
import { z } from 'zod'

// TODO NEXT WEEK
// - [x] Server side error checking/handling
// - [x] ~Save to cookie and redirect to next form~ Put everything on the same page
// - [x] - Get zod and Typescript to play nice
// - [x] (We're here) Build form #2
// - [ ] Build upload form
// - https://www.epicweb.dev/workshops/professional-web-forms/file-upload/intro-to-file-upload
// - https://github.com/epicweb-dev/web-forms/tree/main/exercises/04.file-upload
// - https://github.com/epicweb-dev/web-forms/blob/2c10993e4acffe3dd9ad7b9cb0cdf89ce8d46ecf/exercises/04.file-upload/01.solution.multi-part/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L58
// - createMemoryUploadHandler
// - parseMultipartFormData
// - avoid dealing with the server for now
// - pass the data to the rules engine/pyodide either in the component or the action (probably the action for validation, etc.)
// - [ ] (On hold for data format from rules engine) Build table form
// - [ ] Form errors (if we think of a use case - 2 fields conflicting...)

// Ours
import { ErrorList } from '#app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx'
import { Home, Location, Case } from '../../../types/index.ts'
Expand Down Expand Up @@ -38,10 +54,11 @@ const HomeFormSchema = Home.pick({ livingArea: true })
const CurrentHeatingSystemSchema = Home.pick({
fuelType: true,
heatingSystemEfficiency: true,
designTemperatureOverride: true,
thermostatSetPoint: true,
setbackTemperature: true,
setbackHoursPerDay: true,
designTemperatureOverride: true,

})

const Schema = HomeFormSchema.and(CurrentHeatingSystemSchema)
Expand Down Expand Up @@ -72,14 +89,6 @@ export async function action({ request, params }: ActionFunctionArgs) {
// {status: submission.status === "error" ? 400 : 200}
}

// TODO NEXT WEEK
// - [x] Server side error checking/handling
// - [x] ~Save to cookie and redirect to next form~ Put everything on the same page
// - [ ] - Get zod and Typescript to play nice
// - [ ] (We're here) Build form #2
// - [ ] Build form #3
// - [ ] Form errors (if we think of a use case - 2 fields conflicting...)

const { name, address, livingArea, fuelType,
heatingSystemEfficiency,
thermostatSetPoint,
Expand Down
6 changes: 3 additions & 3 deletions heat-stack/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ export const Home = z.object({
*/
livingArea: z.number().min(500).max(10000),
fuelType: z.enum(['Natural Gas','Oil','Propane']),
designTemperatureOverride: z.number(),
designTemperatureOverride: z.number().optional(),
/**
* unit: percentage in decimal numbers, but not 0 to 1
*/
heatingSystemEfficiency: z.number().min(60).max(100),
thermostatSetPoint: z.number(),
setbackTemperature: z.number(),
setbackHoursPerDay: z.number(),
setbackTemperature: z.number().optional(),
setbackHoursPerDay: z.number().optional(),
numberOfOccupants: z.number(),
estimatedWaterHeatingEfficiency: z.number(),
standByLosses: z.number(),
Expand Down

0 comments on commit bb8fc68

Please sign in to comment.