From 7f68fdebf0f34ac3f4d9c24f80bfd8df1693914e Mon Sep 17 00:00:00 2001 From: Maxime Boucher Date: Sun, 16 Feb 2025 08:01:07 -0700 Subject: [PATCH 1/3] finish basic form --- src/App.tsx | 38 +++++++-------- src/components/Form1.tsx | 82 +++++++++++++++++++-------------- src/components/Form2.tsx | 73 +++++++++++++++++++++++++---- src/components/Form3.tsx | 31 ------------- src/components/FormPage.tsx | 73 +++++++++++++++++++++++++++-- src/components/ui/Button.tsx | 9 +++- src/components/ui/Input.tsx | 7 ++- src/components/ui/Label.tsx | 13 ++++-- src/components/ui/SelectBox.tsx | 20 ++++++-- src/types.ts | 29 ++++++++++++ 10 files changed, 263 insertions(+), 112 deletions(-) delete mode 100644 src/components/Form3.tsx create mode 100644 src/types.ts diff --git a/src/App.tsx b/src/App.tsx index 83ec1f9..3c87792 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,30 +1,30 @@ -import { useState } from 'react' -import './App.css' -import AuthPage from './components/AuthPage' -import DashboardPage from './components/DashboardPage' -import FormPage from './components/FormPage' -import Header from './components/Header' +import { useState } from "react"; +import "./App.css"; +import AuthPage from "./components/AuthPage"; +import DashboardPage from "./components/DashboardPage"; +import FormPage from "./components/FormPage"; +import Header from "./components/Header"; function App() { - const [page, setPage] = useState("auth") + const [page, setPage] = useState("auth"); return ( <> -
+
-
-
    -
  • setPage("auth")}>Auth
  • -
  • setPage("form")}>Form
  • -
  • setPage("dashboard")}>Dashboard
  • -
- {page == "auth" && } - {page == "form" && } - {page == "dashboard" && } +
+
    +
  • setPage("auth")}>Auth
  • +
  • setPage("form")}>Form
  • +
  • setPage("dashboard")}>Dashboard
  • +
+ {page == "auth" && } + {page == "form" && } + {page == "dashboard" && }
- ) + ); } -export default App +export default App; diff --git a/src/components/Form1.tsx b/src/components/Form1.tsx index a2bbdc2..0bb2020 100644 --- a/src/components/Form1.tsx +++ b/src/components/Form1.tsx @@ -1,81 +1,93 @@ -import { useState } from "react"; import Input from "./ui/Input"; import Label from "./ui/Label"; import SelectBox from "./ui/SelectBox"; +import { FormData } from "../types"; +import Button from "./ui/Button"; interface Form1Props { setStep: (step: number) => void; + formData: FormData; } -export default function Form1({ setStep }: Form1Props) { - const [age, setAge] = useState(null); - const [gender, setGender] = useState(null); - const [debtComfortLevel, setDebtComfortLevel] = useState< - number | string | null - >(5); - const [annualIncome, setAnnualIncome] = useState( - null - ); - const [avgMonthlySavings, setAvgMonthlySavings] = useState< - number | string | null - >(null); - +export default function Form1({ setStep, formData }: Form1Props) { return (
{ e.preventDefault(); setStep(2); - console.log( - `age: ${age}, gender: ${gender}, debt comfort level: ${debtComfortLevel}, annual income: ${annualIncome}, avg monthly savings: ${avgMonthlySavings}` - ); }} >
setAge(e.target.value)} + value={formData.age} + onChange={(e) => formData.setAge(e.target.value)} + required />
- setGender("male")}>Male - setGender("void")}> + + Male + + Prefer not to say - setGender("female")}>Female + + Female +
- setDebtComfortLevel(e.target.value)} - /> +
+

0

+ formData.setDebtComfortLevel(e.target.value)} + className="w-70" + required + /> +

10

+
setAnnualIncome(e.target.value)} + value={formData.annualIncome} + onChange={(e) => formData.setAnnualIncome(e.target.value)} + required />
setAvgMonthlySavings(e.target.value)} + value={formData.avgMonthlySavings} + onChange={(e) => formData.setAvgMonthlySavings(e.target.value)} + required />
- +
); } diff --git a/src/components/Form2.tsx b/src/components/Form2.tsx index 511e7c2..1041908 100644 --- a/src/components/Form2.tsx +++ b/src/components/Form2.tsx @@ -1,22 +1,75 @@ +import Button from "./ui/Button"; import Input from "./ui/Input"; import Label from "./ui/Label"; +import { FormData } from "../types"; +interface Form2Props { + formData: FormData; + handleFormSubmit: (event: React.FormEvent) => void; +} -export default function Form2() { +export default function Form2({ formData, handleFormSubmit }: Form2Props) { return ( -
+ handleFormSubmit(e)}>
- -
-
- - +
+

Barely

+ formData.setPurchaseFrequency(e.target.value)} + className="w-70" + required + /> +

Every day

+
- - + +
+ + formData.setFoodSpend(e.target.value)} + /> +
+
+ + formData.setClothingSpend(e.target.value)} + /> +
+
+ + formData.setElectronicsSpend(e.target.value)} + /> +
+
+ + formData.setSubscriptionsSpend(e.target.value)} + /> +
+
+ + formData.setOtherSpend(e.target.value)} + /> +
- +
); } diff --git a/src/components/Form3.tsx b/src/components/Form3.tsx deleted file mode 100644 index fd18321..0000000 --- a/src/components/Form3.tsx +++ /dev/null @@ -1,31 +0,0 @@ -export default function Form3() { - return ( -
-
- - -
-
- -
- - - -
-
-
- - -
-
- - -
-
- - -
- -
- ); -} diff --git a/src/components/FormPage.tsx b/src/components/FormPage.tsx index 2c0fa29..e98f0c6 100644 --- a/src/components/FormPage.tsx +++ b/src/components/FormPage.tsx @@ -1,11 +1,73 @@ import { useState } from "react"; import Form1 from "./Form1"; import Form2 from "./Form2"; -import Form3 from "./Form3"; +import { InputValue } from "../types"; -export default function FormPage() { +interface FormPageProps { + setPage: (page: string) => void; +} + +export default function FormPage({ setPage }: FormPageProps) { const [step, setStep] = useState(1); + const [age, setAge] = useState(); + const [gender, setGender] = useState(); + const [debtComfortLevel, setDebtComfortLevel] = useState(5); + const [annualIncome, setAnnualIncome] = useState(); + const [avgMonthlySavings, setAvgMonthlySavings] = useState(); + + const [purchaseFrequency, setPurchaseFrequency] = useState(); + const [foodSpend, setFoodSpend] = useState(); + const [clothingSpend, setClothingSpend] = useState(); + const [electronicsSpend, setElectronicsSpend] = useState(); + const [subscriptionsSpend, setSubscriptionsSpend] = useState(); + const [otherSpend, setOtherSpend] = useState(); + + const formData = { + age, + setAge, + gender, + setGender, + debtComfortLevel, + setDebtComfortLevel, + annualIncome, + setAnnualIncome, + avgMonthlySavings, + setAvgMonthlySavings, + purchaseFrequency, + setPurchaseFrequency, + foodSpend, + setFoodSpend, + clothingSpend, + setClothingSpend, + electronicsSpend, + setElectronicsSpend, + subscriptionsSpend, + setSubscriptionsSpend, + otherSpend, + setOtherSpend, + }; + + const submitData = { + age, + gender, + debtComfortLevel, + annualIncome, + avgMonthlySavings, + purchaseFrequency, + foodSpend, + clothingSpend, + electronicsSpend, + subscriptionsSpend, + otherSpend, + }; + + function handleFormSubmit(e: React.FormEvent) { + e.preventDefault(); + console.log(submitData); + setPage("dashboard"); + } + return (
@@ -13,9 +75,10 @@ export default function FormPage() {

Help us understand your financial habits.

- {step == 1 && } - {step == 2 && } - {step == 3 && } + {step == 1 && } + {step == 2 && ( + + )}
); } diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx index 449f576..134265c 100644 --- a/src/components/ui/Button.tsx +++ b/src/components/ui/Button.tsx @@ -2,20 +2,25 @@ import React from "react"; type ButtonProps = { children: React.ReactNode; - onClick: () => void; + onClick?: () => void; disabled?: boolean; + className?: string; + type?: "submit" | "reset" | "button" | undefined; }; export default function Button({ children, onClick, disabled = false, + className, + type, }: ButtonProps) { return ( diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx index c16a282..662915f 100644 --- a/src/components/ui/Input.tsx +++ b/src/components/ui/Input.tsx @@ -1,9 +1,12 @@ +import { InputValue } from "../../types"; + interface InputProps { type?: string; placeholder?: string; className?: string; onChange?: (event: React.ChangeEvent) => void; - value?: string | number | null; + value?: InputValue; + required?: boolean; } export default function Input({ @@ -12,11 +15,13 @@ export default function Input({ className, onChange, value, + required, }: InputProps) { return ( {children} - -} \ No newline at end of file +export default function Label({ children }: LabelProps) { + return ( + + ); +} diff --git a/src/components/ui/SelectBox.tsx b/src/components/ui/SelectBox.tsx index 61695a3..068481e 100644 --- a/src/components/ui/SelectBox.tsx +++ b/src/components/ui/SelectBox.tsx @@ -1,14 +1,26 @@ +import { InputValue } from "../../types"; interface SelectBoxProps { children: React.ReactNode; - onClick: () => void; + value: InputValue; + selected: string; + setSelected: (value: InputValue) => void; } -export default function SelectBox({ children, onClick }: SelectBoxProps) { +export default function SelectBox({ + children, + value, + selected, + setSelected, +}: SelectBoxProps) { + const isSelected = value == selected; + return ( diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..127253d --- /dev/null +++ b/src/types.ts @@ -0,0 +1,29 @@ +export type InputValue = string | number | readonly string[] | undefined; + +export type SubmitData = { + age: InputValue; + gender: InputValue; + debtComfortLevel: InputValue; + annualIncome: InputValue; + avgMonthlySavings: InputValue; + purchaseFrequency: InputValue; + foodSpend: InputValue; + clothingSpend: InputValue; + electronicsSpend: InputValue; + subscriptionsSpend: InputValue; + otherSpend: InputValue; +}; + +export type FormData = SubmitData & { + setAge: React.Dispatch>; + setGender: React.Dispatch>; + setDebtComfortLevel: React.Dispatch>; + setAnnualIncome: React.Dispatch>; + setAvgMonthlySavings: React.Dispatch>; + setPurchaseFrequency: React.Dispatch>; + setFoodSpend: React.Dispatch>; + setClothingSpend: React.Dispatch>; + setElectronicsSpend: React.Dispatch>; + setSubscriptionsSpend: React.Dispatch>; + setOtherSpend: React.Dispatch>; +}; From bd9fcd9c88c38980a1f234377c5511ece00bd167 Mon Sep 17 00:00:00 2001 From: Maxime Boucher Date: Sun, 16 Feb 2025 08:11:56 -0700 Subject: [PATCH 2/3] fix type error --- src/components/ui/SelectBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/SelectBox.tsx b/src/components/ui/SelectBox.tsx index 068481e..b42f3b6 100644 --- a/src/components/ui/SelectBox.tsx +++ b/src/components/ui/SelectBox.tsx @@ -2,7 +2,7 @@ import { InputValue } from "../../types"; interface SelectBoxProps { children: React.ReactNode; value: InputValue; - selected: string; + selected: InputValue; setSelected: (value: InputValue) => void; } From 9217e8d9d70ec5fb10a744394912d167fbc16583 Mon Sep 17 00:00:00 2001 From: Maxime Boucher Date: Sun, 16 Feb 2025 08:14:00 -0700 Subject: [PATCH 3/3] fix styles --- src/App.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 3c87792..45b17d0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,7 +10,7 @@ function App() { return ( <> -
+