From e334b64529a991e8f8c9397e4975ff4f24d3b976 Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Wed, 14 Feb 2024 01:57:18 +0000 Subject: [PATCH 1/7] Did a first draft of zod+conform v1 Must move action to a route for submit to work. Co-authored-by: plocket Co-authored-by: Clayton Schneider Co-authored-by: teykamp --- .../CaseSummaryComponents/HomeInformation.tsx | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx index 8d8ce730..05c38d21 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx @@ -1,8 +1,46 @@ import { Form } from '@remix-run/react' -// import { Button } from '#/app/components/ui/button.tsx' +import { Button } from '#/app/components/ui/button.tsx' import { Input } from '#/app/components/ui/input.tsx' import { Label } from '#/app/components/ui/label.tsx' +/** THE BELOW PROBABLY NEED TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ +// import { redirect } from '@remix-run/react' +import { json, ActionFunctionArgs } from '@remix-run/node' +import { invariantResponse } from '@epic-web/invariant' +import { parseWithZod } from '@conform-to/zod' +import { z } from 'zod' + +const nameMaxLength = 1 +const addressMaxLength = 1 + +/** Modeled off the conform example at + * https://github.com/epicweb-dev/web-forms/blob/b69e441f5577b91e7df116eba415d4714daacb9d/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L48 */ +const HomeInformationSchema = z.object({ + name: z.string().max(nameMaxLength), + address: z.string().max(addressMaxLength), + livingSpace: z.number().min(1), +}) + +export async function action({ request, params }: ActionFunctionArgs) { + invariantResponse(params.homeId, 'homeId param is required') + + const formData = await request.formData() + const submission = parseWithZod(formData, { + schema: HomeInformationSchema, + }) + + if (!submission.value) { + return json({ status: 'error', submission } as const, { + status: 400, + }) + } + const { name, address, livingSpace } = submission.value + + // await updateNote({ id: params.noteId, title, content }) + + // return redirect(`/inputs1`) +} + export function HomeInformation() { const titleClass = 'text-5xl font-extrabold tracking-wide' const subtitleClass = 'text-2xl font-semibold text-zinc-950 mt-9' @@ -12,7 +50,7 @@ export function HomeInformation() {

Home Information

-
+
Resident/Client
@@ -76,6 +114,7 @@ export function HomeInformation() { {/*
*/} +
) From 0470e05ff8b5827fae3aa2f14ba9903a45315e2d Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Wed, 21 Feb 2024 01:56:55 +0000 Subject: [PATCH 2/7] Route for input1 and Conform on HomeInformation Co-authored-by: plocket Co-authored-by: Clayton Schneider Co-authored-by: teykamp Co-authored-by: Jeff Korenstein Co-authored-by: Leopardfoot Co-authored-by: hectorbenitez19 --- .../CaseSummaryComponents/HomeInformation.tsx | 110 +++++++----------- heat-stack/app/routes/_heat+/Inputs1.tsx | 62 +++++++++- 2 files changed, 105 insertions(+), 67 deletions(-) diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx index 05c38d21..2d955b37 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx @@ -3,43 +3,43 @@ import { Button } from '#/app/components/ui/button.tsx' import { Input } from '#/app/components/ui/input.tsx' import { Label } from '#/app/components/ui/label.tsx' -/** THE BELOW PROBABLY NEED TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ -// import { redirect } from '@remix-run/react' -import { json, ActionFunctionArgs } from '@remix-run/node' -import { invariantResponse } from '@epic-web/invariant' -import { parseWithZod } from '@conform-to/zod' -import { z } from 'zod' - -const nameMaxLength = 1 -const addressMaxLength = 1 - -/** Modeled off the conform example at - * https://github.com/epicweb-dev/web-forms/blob/b69e441f5577b91e7df116eba415d4714daacb9d/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L48 */ -const HomeInformationSchema = z.object({ - name: z.string().max(nameMaxLength), - address: z.string().max(addressMaxLength), - livingSpace: z.number().min(1), -}) - -export async function action({ request, params }: ActionFunctionArgs) { - invariantResponse(params.homeId, 'homeId param is required') - - const formData = await request.formData() - const submission = parseWithZod(formData, { - schema: HomeInformationSchema, - }) - - if (!submission.value) { - return json({ status: 'error', submission } as const, { - status: 400, - }) - } - const { name, address, livingSpace } = submission.value - - // await updateNote({ id: params.noteId, title, content }) - - // return redirect(`/inputs1`) -} +// /** THE BELOW PROBABLY NEED TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ +// // import { redirect } from '@remix-run/react' +// import { json, ActionFunctionArgs } from '@remix-run/node' +// import { invariantResponse } from '@epic-web/invariant' +// import { parseWithZod } from '@conform-to/zod' +// import { z } from 'zod' + +// const nameMaxLength = 1 +// const addressMaxLength = 1 + +// /** Modeled off the conform example at +// * https://github.com/epicweb-dev/web-forms/blob/b69e441f5577b91e7df116eba415d4714daacb9d/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L48 */ +// const HomeInformationSchema = z.object({ +// name: z.string().max(nameMaxLength), +// address: z.string().max(addressMaxLength), +// livingSpace: z.number().min(1), +// }) + +// export async function action({ request, params }: ActionFunctionArgs) { +// invariantResponse(params.homeId, 'homeId param is required') + +// const formData = await request.formData() +// const submission = parseWithZod(formData, { +// schema: HomeInformationSchema, +// }) + +// if (!submission.value) { +// return json({ status: 'error', submission } as const, { +// status: 400, +// }) +// } +// const { name, address, livingSpace } = submission.value + +// // await updateNote({ id: params.noteId, title, content }) + +// // return redirect(`/inputs1`) +// } export function HomeInformation() { const titleClass = 'text-5xl font-extrabold tracking-wide' @@ -50,18 +50,14 @@ export function HomeInformation() {

Home Information

-
+ {/* */}
Resident/Client
- - -
-
- - + +
@@ -71,24 +67,8 @@ export function HomeInformation() {
- + - - -
-
- - -
-
- - -
-
- - -
-
@@ -112,10 +92,10 @@ export function HomeInformation() { {/* removed temporarily for single page app format */} {/*
- -
*/} - - + +
*/} + + {/* */} ) } diff --git a/heat-stack/app/routes/_heat+/Inputs1.tsx b/heat-stack/app/routes/_heat+/Inputs1.tsx index 76bdb05f..ac2c8342 100644 --- a/heat-stack/app/routes/_heat+/Inputs1.tsx +++ b/heat-stack/app/routes/_heat+/Inputs1.tsx @@ -1,9 +1,67 @@ import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/HomeInformation.tsx' +import { Form } from '@remix-run/react' + +/** THE BELOW PROBABLY NEED TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ +// import { redirect } from '@remix-run/react' +import { json, ActionFunctionArgs } from '@remix-run/node' +import { invariantResponse } from '@epic-web/invariant' +import { parseWithZod } from '@conform-to/zod' +import { z } from 'zod' + +const nameMaxLength = 1 +const addressMaxLength = 1 + +/** Modeled off the conform example at + * https://github.com/epicweb-dev/web-forms/blob/b69e441f5577b91e7df116eba415d4714daacb9d/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L48 */ +const HomeInformationSchema = z.object({ + name: z.string().min(1).max(nameMaxLength), + address: z.string().min(1).max(addressMaxLength), + livingSpace: z.number().min(1), +}) + +export async function action({ request, params }: ActionFunctionArgs) { + // invariantResponse(params.homeId, 'homeId param is required') + + const formData = await request.formData() + const submission = parseWithZod(formData, { + schema: HomeInformationSchema, + }) + + if(submission.status !== "success") { + return json( + submission.reply(), {status: submission.status === "error" ? 400 : 200} + // submission.reply({ + // // You can also pass additional error to the `reply` method + // formErrors: ['Submission failed'], + // fieldErrors: { + // address: ['Address is invalid'], + // }, + + // // or avoid sending the the field value back to client by specifying the field names + // hideFields: ['password'], + // }), + // {status: submission.status === "error" ? 400 : 200} + ); + } + + // TODO NEXT WEEK + // Add error components that will show the validation errors. See + // https://github.com/epicweb-dev/web-forms/blob/main/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx + // ErrorList, useForm, etc + // Once we get it working, break out into 2 teams, each working on the other 2 parts of the form + + const { name, address, livingSpace } = submission.value + + // await updateNote({ id: params.noteId, title, content }) + + return redirect(`/inputs1`) +} export default function Inputs1() { return ( -
+ +
-
+ ) } From 57748247397be784043507d7b50b50f282b80ce5 Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Tue, 12 Mar 2024 23:49:57 +0000 Subject: [PATCH 3/7] Client side conform form validation Co-authored-by: Clayton Schneider Co-authored-by: hectorbenitez19 Co-authored-by: Michael Hughes Co-authored-by: Leopardfoot --- .../heat/CaseSummaryComponents/ErrorList.tsx | 17 ++++++++ .../CaseSummaryComponents/HomeInformation.tsx | 42 +++++++++++++++++-- heat-stack/app/routes/_heat+/Inputs1.tsx | 32 +++++++++----- 3 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 heat-stack/app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx new file mode 100644 index 00000000..4789c7d6 --- /dev/null +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx @@ -0,0 +1,17 @@ +export function ErrorList({ + id, + errors, +}: { + id?: string + errors?: Array | null +}) { + return errors?.length ? ( +
    + {errors.map((error, i) => ( +
  • + {error} +
  • + ))} +
+ ) : null +} \ No newline at end of file diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx index 2d955b37..43da3295 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx @@ -1,7 +1,9 @@ import { Form } from '@remix-run/react' +import { ErrorList } from "./ErrorList.tsx" import { Button } from '#/app/components/ui/button.tsx' import { Input } from '#/app/components/ui/input.tsx' import { Label } from '#/app/components/ui/label.tsx' +import { FieldMetadata, useForm } from '@conform-to/react' // /** THE BELOW PROBABLY NEED TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ // // import { redirect } from '@remix-run/react' @@ -40,8 +42,22 @@ import { Label } from '#/app/components/ui/label.tsx' // // return redirect(`/inputs1`) // } +type HomeInformationProps = {fields: { + name: FieldMetadata; + address: FieldMetadata; + livingSpace: FieldMetadata; +}}; + +export function HomeInformation(props: HomeInformationProps) { -export function HomeInformation() { const titleClass = 'text-5xl font-extrabold tracking-wide' const subtitleClass = 'text-2xl font-semibold text-zinc-950 mt-9' const descriptiveClass = 'mt-2 text-sm text-slate-500' @@ -57,7 +73,13 @@ export function HomeInformation() {
- + +
+ +
@@ -68,7 +90,13 @@ export function HomeInformation() {
- + +
+ +
@@ -82,7 +110,13 @@ export function HomeInformation() {
- + +
+ +

The home's above-grade, conditioned space

diff --git a/heat-stack/app/routes/_heat+/Inputs1.tsx b/heat-stack/app/routes/_heat+/Inputs1.tsx index ac2c8342..1eb0b459 100644 --- a/heat-stack/app/routes/_heat+/Inputs1.tsx +++ b/heat-stack/app/routes/_heat+/Inputs1.tsx @@ -1,15 +1,16 @@ +import { useForm } from '@conform-to/react' import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/HomeInformation.tsx' -import { Form } from '@remix-run/react' /** THE BELOW PROBABLY NEED TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ // import { redirect } from '@remix-run/react' import { json, ActionFunctionArgs } from '@remix-run/node' -import { invariantResponse } from '@epic-web/invariant' import { parseWithZod } from '@conform-to/zod' +import { invariantResponse } from '@epic-web/invariant' +import { Form, useActionData } from '@remix-run/react' import { z } from 'zod' -const nameMaxLength = 1 -const addressMaxLength = 1 +const nameMaxLength = 50 +const addressMaxLength = 100 /** Modeled off the conform example at * https://github.com/epicweb-dev/web-forms/blob/b69e441f5577b91e7df116eba415d4714daacb9d/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L48 */ @@ -45,10 +46,9 @@ export async function action({ request, params }: ActionFunctionArgs) { } // TODO NEXT WEEK - // Add error components that will show the validation errors. See - // https://github.com/epicweb-dev/web-forms/blob/main/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx - // ErrorList, useForm, etc - // Once we get it working, break out into 2 teams, each working on the other 2 parts of the form + // Server side error checking/handling + // Save to cookie and redirect to next form + // Build form #2 and #3 const { name, address, livingSpace } = submission.value @@ -58,10 +58,22 @@ export async function action({ request, params }: ActionFunctionArgs) { } export default function Inputs1() { + const lastResult = useActionData() + const [form, fields] = useForm({ + lastResult, + onValidate({ formData }) { + return parseWithZod(formData, { schema: HomeInformationSchema }) + }, + defaultValue: { + + }, + shouldValidate: 'onBlur', + }) + return ( -
- + + ) } From 30643be84ee1d881c3f18533d2abb4a28de03852 Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Wed, 13 Mar 2024 00:29:35 +0000 Subject: [PATCH 4/7] Server side checking/handling Co-authored-by: Clayton Schneider Co-authored-by: plocket Co-authored-by: Leopardfoot --- heat-stack/app/routes/_heat+/Inputs1.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/heat-stack/app/routes/_heat+/Inputs1.tsx b/heat-stack/app/routes/_heat+/Inputs1.tsx index 1eb0b459..867238c5 100644 --- a/heat-stack/app/routes/_heat+/Inputs1.tsx +++ b/heat-stack/app/routes/_heat+/Inputs1.tsx @@ -6,8 +6,9 @@ import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/ import { json, ActionFunctionArgs } from '@remix-run/node' import { parseWithZod } from '@conform-to/zod' import { invariantResponse } from '@epic-web/invariant' -import { Form, useActionData } from '@remix-run/react' +import { Form, redirect, useActionData } from '@remix-run/react' import { z } from 'zod' +import { ErrorList } from '#app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx' const nameMaxLength = 50 const addressMaxLength = 100 @@ -21,6 +22,7 @@ const HomeInformationSchema = z.object({ }) export async function action({ request, params }: ActionFunctionArgs) { + // Checks if url has a homeId parameter, throws 400 if not there // invariantResponse(params.homeId, 'homeId param is required') const formData = await request.formData() @@ -29,8 +31,7 @@ export async function action({ request, params }: ActionFunctionArgs) { }) if(submission.status !== "success") { - return json( - submission.reply(), {status: submission.status === "error" ? 400 : 200} + return submission.reply() // submission.reply({ // // You can also pass additional error to the `reply` method // formErrors: ['Submission failed'], @@ -42,13 +43,13 @@ export async function action({ request, params }: ActionFunctionArgs) { // hideFields: ['password'], // }), // {status: submission.status === "error" ? 400 : 200} - ); } // TODO NEXT WEEK - // Server side error checking/handling - // Save to cookie and redirect to next form - // Build form #2 and #3 + // - [x] Server side error checking/handling + // - [ ] Save to cookie and redirect to next form + // - [ ] Build form #2 and #3 + // - [ ] Form errors (if we think of a use case - 2 fields conflicting...) const { name, address, livingSpace } = submission.value @@ -74,6 +75,7 @@ export default function Inputs1() {
+ ) } From f62c4f5d111d5e30652494e017563a0df32d239d Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Wed, 13 Mar 2024 00:53:12 +0000 Subject: [PATCH 5/7] consolidated form to single page Co-authored-by: Clayton Schneider Co-authored-by: Michael Hughes Co-authored-by: Leopardfoot Co-authored-by: plocket --- .../CaseSummaryComponents/HomeInformation.tsx | 2 +- heat-stack/app/routes/_heat+/single.tsx | 86 +++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx index 43da3295..82c9f9d9 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/HomeInformation.tsx @@ -128,7 +128,7 @@ export function HomeInformation(props: HomeInformationProps) { {/*
*/} - + {/* */}
) diff --git a/heat-stack/app/routes/_heat+/single.tsx b/heat-stack/app/routes/_heat+/single.tsx index 95617be5..b57a82c6 100644 --- a/heat-stack/app/routes/_heat+/single.tsx +++ b/heat-stack/app/routes/_heat+/single.tsx @@ -1,15 +1,91 @@ +/** THE BELOW PROBABLY NEEDS TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ +// import { redirect } from '@remix-run/react' +import { z } from 'zod' +import { useForm } from '@conform-to/react' +import { json, ActionFunctionArgs } from '@remix-run/node' +import { parseWithZod } from '@conform-to/zod' +import { invariantResponse } from '@epic-web/invariant' +import { Form, redirect, useActionData } from '@remix-run/react' + +// Ours +import { Button } from '#/app/components/ui/button.tsx' import { CurrentHeatingSystem } from '../../components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx' import { EnergyUseHistory } from '../../components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx' import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/HomeInformation.tsx' import HeatLoadAnalysis from './heatloadanalysis.tsx' +import { ErrorList } from '#app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx' + +const nameMaxLength = 50 +const addressMaxLength = 100 + +/** Modeled off the conform example at + * https://github.com/epicweb-dev/web-forms/blob/b69e441f5577b91e7df116eba415d4714daacb9d/exercises/03.schema-validation/03.solution.conform-form/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L48 */ +const HomeInformationSchema = z.object({ + name: z.string().min(1).max(nameMaxLength), + address: z.string().min(1).max(addressMaxLength), + livingSpace: z.number().min(1), +}) + +export async function action({ request, params }: ActionFunctionArgs) { + // Checks if url has a homeId parameter, throws 400 if not there + // invariantResponse(params.homeId, 'homeId param is required') + + const formData = await request.formData() + const submission = parseWithZod(formData, { + schema: HomeInformationSchema, + }) + + if(submission.status !== "success") { + return submission.reply() + // submission.reply({ + // // You can also pass additional error to the `reply` method + // formErrors: ['Submission failed'], + // fieldErrors: { + // address: ['Address is invalid'], + // }, + + // // or avoid sending the the field value back to client by specifying the field names + // hideFields: ['password'], + // }), + // {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 + // - [ ] Build form #2 and #3 + // - [ ] Form errors (if we think of a use case - 2 fields conflicting...) + + const { name, address, livingSpace } = submission.value + + // await updateNote({ id: params.noteId, title, content }) + + return redirect(`/inputs1`) +} export default function Inputs() { + const lastResult = useActionData() + const [form, fields] = useForm({ + lastResult, + onValidate({ formData }) { + return parseWithZod(formData, { schema: HomeInformationSchema }) + }, + defaultValue: { + + }, + shouldValidate: 'onBlur', + }) + return ( -
- - - + <> +
+ + + + + + -
+ ) } From ee739eaa382cded67813963f0ebed2e58cf7f104 Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Wed, 13 Mar 2024 01:01:23 +0000 Subject: [PATCH 6/7] WIP form #2 --- .../ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx | 6 +----- .../ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx | 6 ++++++ heat-stack/app/routes/_heat+/single.tsx | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx index 5162cae3..7b2ff0e4 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx @@ -6,7 +6,6 @@ import { Label } from '#/app/components/ui/label.tsx' export function CurrentHeatingSystem() { const titleClass = 'text-5xl font-extrabold tracking-wide' - const subtitleClass = 'text-2xl font-semibold text-zinc-950 mt-9' const descriptiveClass = 'mt-2 text-sm text-slate-500' const componentMargin = 'mt-10' @@ -110,10 +109,7 @@ export function CurrentHeatingSystem() {
-
-
Heating Fuel Usage
- -
+ {/* removed temporarily for single page app format */} diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx index 6afd08d6..25d813aa 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx @@ -1,12 +1,18 @@ import { AnalysisHeader } from './AnalysisHeader.tsx' import { EnergyUseHistoryChart } from './EnergyUseHistoryChart.tsx' +import { Button } from '#/app/components/ui/button.tsx' + export function EnergyUseHistory() { const titleClass = 'text-5xl font-extrabold tracking-wide mt-10' + const subtitleClass = 'text-2xl font-semibold text-zinc-950 mt-9' return (

Energy Use History

+
+
Upload +
diff --git a/heat-stack/app/routes/_heat+/single.tsx b/heat-stack/app/routes/_heat+/single.tsx index b57a82c6..17b1df97 100644 --- a/heat-stack/app/routes/_heat+/single.tsx +++ b/heat-stack/app/routes/_heat+/single.tsx @@ -53,7 +53,8 @@ export async function action({ request, params }: ActionFunctionArgs) { // TODO NEXT WEEK // - [x] Server side error checking/handling // - [x] ~Save to cookie and redirect to next form~ Put everything on the same page - // - [ ] Build form #2 and #3 + // - [ ] (We're here) Build form #2 + // - [ ] Build form #3 // - [ ] Form errors (if we think of a use case - 2 fields conflicting...) const { name, address, livingSpace } = submission.value From b49005961d6e8ec0e6da2ac8d30fae1a87703e96 Mon Sep 17 00:00:00 2001 From: Thad Kerosky Date: Tue, 19 Mar 2024 23:57:15 +0000 Subject: [PATCH 7/7] Finished HomeInformation on single, CurrentHeatingSystem WIP Co-authored-by: plocket Co-authored-by: Clayton Schneider Co-authored-by: Leopardfoot Co-authored-by: Camden Blatchly --- .../CurrentHeatingSystem.tsx | 1 + .../EnergyUseHistory.tsx | 8 +++++++- heat-stack/app/routes/_heat+/Inputs1.tsx | 5 +++++ heat-stack/app/routes/_heat+/single.tsx | 19 ++++++++++++++----- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx index 7b2ff0e4..cc3427d1 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx @@ -8,6 +8,7 @@ export function CurrentHeatingSystem() { const titleClass = 'text-5xl font-extrabold tracking-wide' const descriptiveClass = 'mt-2 text-sm text-slate-500' const componentMargin = 'mt-10' + const subtitleClass = 'text-2xl font-semibold text-zinc-950 mt-9' return (
diff --git a/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx b/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx index 25d813aa..45d8096a 100644 --- a/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx +++ b/heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx @@ -2,6 +2,12 @@ import { AnalysisHeader } from './AnalysisHeader.tsx' import { EnergyUseHistoryChart } from './EnergyUseHistoryChart.tsx' import { Button } from '#/app/components/ui/button.tsx' +import { Form } from '@remix-run/react' +import { ErrorList } from "./ErrorList.tsx" +import { Input } from '#/app/components/ui/input.tsx' +import { Label } from '#/app/components/ui/label.tsx' +import { FieldMetadata, useForm } from '@conform-to/react' + export function EnergyUseHistory() { const titleClass = 'text-5xl font-extrabold tracking-wide mt-10' @@ -11,7 +17,7 @@ export function EnergyUseHistory() {

Energy Use History

-
Upload +
diff --git a/heat-stack/app/routes/_heat+/Inputs1.tsx b/heat-stack/app/routes/_heat+/Inputs1.tsx index 867238c5..ab449dd8 100644 --- a/heat-stack/app/routes/_heat+/Inputs1.tsx +++ b/heat-stack/app/routes/_heat+/Inputs1.tsx @@ -1,3 +1,8 @@ + + +// Archived 03/19/2024 + + import { useForm } from '@conform-to/react' import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/HomeInformation.tsx' diff --git a/heat-stack/app/routes/_heat+/single.tsx b/heat-stack/app/routes/_heat+/single.tsx index 17b1df97..4d6e82dc 100644 --- a/heat-stack/app/routes/_heat+/single.tsx +++ b/heat-stack/app/routes/_heat+/single.tsx @@ -1,19 +1,19 @@ /** THE BELOW PROBABLY NEEDS TO MOVE TO A ROUTE RATHER THAN A COMPONENT, including action function, */ // import { redirect } from '@remix-run/react' -import { z } from 'zod' import { useForm } from '@conform-to/react' -import { json, ActionFunctionArgs } from '@remix-run/node' import { parseWithZod } from '@conform-to/zod' import { invariantResponse } from '@epic-web/invariant' +import { json, ActionFunctionArgs } from '@remix-run/node' import { Form, redirect, useActionData } from '@remix-run/react' +import { z } from 'zod' // Ours -import { Button } from '#/app/components/ui/button.tsx' +import { ErrorList } from '#app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx' import { CurrentHeatingSystem } from '../../components/ui/heat/CaseSummaryComponents/CurrentHeatingSystem.tsx' import { EnergyUseHistory } from '../../components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx' import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/HomeInformation.tsx' import HeatLoadAnalysis from './heatloadanalysis.tsx' -import { ErrorList } from '#app/components/ui/heat/CaseSummaryComponents/ErrorList.tsx' +import { Button } from '#/app/components/ui/button.tsx' const nameMaxLength = 50 const addressMaxLength = 100 @@ -26,6 +26,15 @@ const HomeInformationSchema = z.object({ livingSpace: z.number().min(1), }) +const EnergyUseSchema = z.object({ + fuelType: z.string().min(1).max(nameMaxLength), + efficiency: z.string().min(1).max(addressMaxLength), + override: z.number().min(1), + setpoint: z.string().min(1).max(nameMaxLength), + setbackTemp: z.string().min(1).max(addressMaxLength), + setbackHours: z.number().min(1), +}) + export async function action({ request, params }: ActionFunctionArgs) { // Checks if url has a homeId parameter, throws 400 if not there // invariantResponse(params.homeId, 'homeId param is required') @@ -81,7 +90,7 @@ export default function Inputs() { <>
- +