From 6df5dc4b23dd8e1876f9f168b905531bdfe743c9 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 20 Oct 2025 18:14:07 +0000 Subject: [PATCH] fixed form logic --- .../[slug]/components/FormSchema.tsx | 13 +- .../remote-assessment/ScenarioSetup.tsx | 297 +++++++++++++++--- 2 files changed, 262 insertions(+), 48 deletions(-) diff --git a/src/app/portfolio/[slug]/components/FormSchema.tsx b/src/app/portfolio/[slug]/components/FormSchema.tsx index 1a2c36f1..1591f650 100644 --- a/src/app/portfolio/[slug]/components/FormSchema.tsx +++ b/src/app/portfolio/[slug]/components/FormSchema.tsx @@ -50,11 +50,14 @@ export const uploadCsvSchema = baseFormSchema.extend({ if (val === "" || val === undefined) return undefined; return Number(val); }, z.number().min(0.1)), - budget: z.preprocess((val) => { - if (val === "" || val === undefined) return undefined; - if (val === null) return null; - return Number(val); - }, z.union([z.number(), z.null()]).optional()), + budget: z.preprocess( + (val) => { + if (val === "" || val === undefined) return undefined; + if (val === null) return null; + return Number(val); + }, + z.union([z.number(), z.null()]).optional() + ), }); export type UploadCsvFormValues = z.infer; diff --git a/src/app/portfolio/[slug]/remote-assessment/ScenarioSetup.tsx b/src/app/portfolio/[slug]/remote-assessment/ScenarioSetup.tsx index a12a51c3..36074538 100644 --- a/src/app/portfolio/[slug]/remote-assessment/ScenarioSetup.tsx +++ b/src/app/portfolio/[slug]/remote-assessment/ScenarioSetup.tsx @@ -1,27 +1,122 @@ "use client"; -import { useState } from "react"; +import { useState, useMemo } from "react"; +import { useForm, FormProvider } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; + +import { + FormField, + FormItem, + FormLabel, + FormControl, + FormMessage, +} from "@/app/shadcn_components/ui/form"; + import { Card } from "@/app/shadcn_components/ui/card"; import { Input } from "@/app/shadcn_components/ui/input"; import { Button } from "@/app/shadcn_components/ui/button"; -import { SelectDropdown } from "@/app/portfolio/[slug]/components/RemoteAssessmentDropdowns"; +import { + SelectScenarioDropdown, + SelectDropdown, + ScenarioOption, +} from "@/app/portfolio/[slug]/components/RemoteAssessmentDropdowns"; +import MeasuresCheckboxes from "@/app/portfolio/[slug]/components/MeasuresCheckboxes"; +import { measuresList } from "@/app/db/schema/recommendations"; +import { ScenarioSelect } from "@/app/db/schema/recommendations"; +import { + RemoteAssessmentFormSchema, + type RemoteAssessmentFormValues, +} from "@/app/portfolio/[slug]/components/FormSchema"; +const housingTypeOptions = [ + { label: "Social", value: "Social" }, + { label: "Private", value: "Private" }, +]; + +// ------------------- +// Component +// ------------------- export default function ScenarioSetup({ portfolioId, scenarios, disabled = false, + onSubmitScenario, }: { portfolioId: string; - scenarios: { - id: string; - name: string; - housingType: string; - goal: string; - goalValue: string | null; - }[]; + scenarios: ScenarioSelect[]; disabled?: boolean; + onSubmitScenario?: (values: RemoteAssessmentFormValues) => void; }) { + const NEW_SENTINEL = "__new__"; const [selectedScenario, setSelectedScenario] = useState(null); + const [showMeasures, setShowMeasures] = useState(false); + + const form = useForm({ + resolver: zodResolver(RemoteAssessmentFormSchema), + mode: "onChange", + defaultValues: { + scenario: "", + goal: "", + goalValue: "", + budget: undefined, + housingType: "Social", + addressLineOne: "", + postcode: "", + uprn: 0, + valuation: 0, + propertyType: null, + builtForm: null, + measures: measuresList, + }, + }); + + const { setValue, watch, handleSubmit, formState } = form; + const values = watch(); + + const scenarioOptions: ScenarioOption[] = useMemo( + () => + scenarios.map((s) => ({ + label: s.name || "", + value: String(s.id) || "", + housingType: s.housingType || "", + goal: s.goal || "", + goalValue: s.goalValue || "", + })), + [scenarios] + ); + + function handleSelect(opt: ScenarioOption) { + setSelectedScenario(opt.value); + + if (opt.value === NEW_SENTINEL) { + form.reset({ + ...form.getValues(), + scenario: "", + housingType: "", + goal: "", + goalValue: "", + budget: undefined, + valuation: undefined, + measures: measuresList, // all measures preselected + }); + } else { + form.reset({ + scenario: opt.label || "", + housingType: opt.housingType || "", + goal: opt.goal || "", + goalValue: opt.goalValue || "", + budget: undefined, + valuation: undefined, + measures: measuresList, + }); + } + } + + function onSubmit(data: RemoteAssessmentFormValues) { + if (onSubmitScenario) onSubmitScenario(data); + console.log("Submitted scenario data:", data); + } return ( - ({ - label: s.name, - value: s.id, - })), - ]} - selectedOption={selectedScenario || ""} - onSelectOption={(opt) => setSelectedScenario(opt.value)} - /> + +
+
+ + +
-
- - - -
+ {selectedScenario && ( + <> + {/* Scenario Name + Housing Type */} +
+ ( + + Scenario Name + + + + + + )} + /> - + ( + + Housing Type + + {selectedScenario === NEW_SENTINEL ? ( + field.onChange(opt.value)} + /> + ) : ( + + )} + + + + )} + /> +
+ + {/* Goal + EPC */} +
+ ( + + Goal + + {selectedScenario === NEW_SENTINEL ? ( + field.onChange(opt.value)} + /> + ) : ( + + )} + + + + )} + /> + + {values.goal === "Increasing EPC" && ( + ( + + Target EPC Rating + + {selectedScenario === NEW_SENTINEL ? ( + + field.onChange(opt.value) + } + /> + ) : ( + + )} + + + + )} + /> + )} +
+ + {/* Measures Section */} +
+ + {showMeasures && } +
+ +
+ +
+ + )} +
+
); }