-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
697 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
"use client" | ||
|
||
import { Pie, PieChart } from "recharts" | ||
|
||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card" | ||
import { | ||
ChartConfig, | ||
ChartContainer, | ||
ChartTooltip, | ||
ChartTooltipContent, | ||
ChartLegend, | ||
ChartLegendContent, | ||
} from "@/components/ui/chart" | ||
const chartData1 = [ | ||
{ expenses: "housing", amount: 3219, fill: "var(--color-housing)" }, | ||
{ expenses: "food", amount: 3432, fill: "var(--color-food)" }, | ||
{ expenses: "transportation", amount: 3214, fill: "var(--color-transportation)" }, | ||
{ expenses: "healthcare", amount: 3213, fill: "var(--color-healthcare)" }, | ||
{ expenses: "entertainment", amount: 3211, fill: "var(--color-entertainment)" }, | ||
] | ||
const chartData2 = [ | ||
{ expenses: "housing", amount: 3219, fill: "var(--color-housing)" }, | ||
{ expenses: "food", amount: 3432, fill: "var(--color-food)" }, | ||
{ expenses: "healthcare", amount: 3213, fill: "var(--color-healthcare)" }, | ||
] | ||
|
||
const chartConfig1 = { | ||
amount: { | ||
label: "Amount", | ||
}, | ||
housing: { | ||
label: "Housing", | ||
color: "hsl(var(--chart-1))", | ||
}, | ||
food: { | ||
label: "Food", | ||
color: "hsl(var(--chart-2))", | ||
}, | ||
transportation: { | ||
label: "Transportation", | ||
color: "hsl(var(--chart-3))", | ||
}, | ||
healthcare: { | ||
label: "Healthcare", | ||
color: "hsl(var(--chart-4))", | ||
}, | ||
entertainment: { | ||
label: "Entertainment", | ||
color: "hsl(var(--chart-5))", | ||
}, | ||
} satisfies ChartConfig | ||
const chartConfig2 = { | ||
amount: { | ||
label: "Amount", | ||
}, | ||
housing: { | ||
label: "Housing", | ||
color: "hsl(var(--chart-1))", | ||
}, | ||
food: { | ||
label: "Food", | ||
color: "hsl(var(--chart-2))", | ||
}, | ||
healthcare: { | ||
label: "Healthcare", | ||
color: "hsl(var(--chart-4))", | ||
}, | ||
} satisfies ChartConfig | ||
|
||
export function Chart1() { | ||
return ( | ||
<Card className="flex flex-col"> | ||
<CardHeader className="items-center pb-0"> | ||
<CardTitle>Plan1</CardTitle> | ||
<CardDescription>50 - 30 - 20</CardDescription> | ||
</CardHeader> | ||
<CardContent className="flex-1 pb-0"> | ||
<ChartContainer | ||
config={chartConfig1} | ||
className="mx-auto aspect-square max-h-[300px]" | ||
> | ||
<PieChart> | ||
<ChartTooltip content={<ChartTooltipContent hideLabel />} /> | ||
<Pie data={chartData1} label dataKey="amount" /> | ||
<ChartLegend | ||
content={<ChartLegendContent nameKey="expenses" />} | ||
className="-translate-y-2 flex-wrap gap-2 [&>*]:basis-1/4 [&>*]:justify-center" | ||
/> | ||
</PieChart> | ||
</ChartContainer> | ||
</CardContent> | ||
</Card> | ||
) | ||
} | ||
|
||
export function Chart2() { | ||
return ( | ||
<Card className="flex flex-col"> | ||
<CardHeader className="items-center pb-0"> | ||
<CardTitle>Plan 2</CardTitle> | ||
<CardDescription>60 - 20 - 20</CardDescription> | ||
</CardHeader> | ||
<CardContent className="flex-1 pb-0"> | ||
<ChartContainer | ||
config={chartConfig2} | ||
className="mx-auto aspect-square max-h-[300px]" | ||
> | ||
<PieChart> | ||
<ChartTooltip content={<ChartTooltipContent hideLabel />} /> | ||
<Pie data={chartData2} label dataKey="amount" /> | ||
<ChartLegend | ||
content={<ChartLegendContent nameKey="expenses" />} | ||
className="-translate-y-2 flex-wrap gap-2 [&>*]:basis-1/4 [&>*]:justify-center" | ||
/> | ||
</PieChart> | ||
</ChartContainer> | ||
</CardContent> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
"use client" | ||
|
||
import { useState } from "react" | ||
import { zodResolver } from "@hookform/resolvers/zod" | ||
import { useForm } from "react-hook-form" | ||
import { z } from "zod" | ||
import { useRouter } from "next/navigation" | ||
import Link from "next/link" | ||
|
||
const items = [ | ||
{ | ||
id: "housing", | ||
label: "Housing", | ||
}, | ||
{ | ||
id: "food", | ||
label: "Food", | ||
}, | ||
{ | ||
id: "transportation", | ||
label: "Transportation", | ||
}, | ||
{ | ||
id: "healthcare", | ||
label: "Healthcare", | ||
}, | ||
{ | ||
id: "entertainment", | ||
label: "Entertainment", | ||
}, | ||
] | ||
|
||
const formSchema = z.object({ | ||
income: z.string() | ||
.min(1, "Income is required.") | ||
.regex(/^\d+$/, "Income must be a number."), | ||
housing: z.string() | ||
.min(1, "Housing expenses is required.") | ||
.regex(/^\d+$/, "Housing expenses must be a number."), | ||
food: z.string() | ||
.min(1, "Food expenses is required.") | ||
.regex(/^\d+$/, "Food expenses must be a number."), | ||
transportation: z.string() | ||
.min(1, "Transportation expenses is required.") | ||
.regex(/^\d+$/, "Transportation expenses must be a number."), | ||
healthcare: z.string() | ||
.min(1, "Healthcare expenses is required.") | ||
.regex(/^\d+$/, "Healthcare expenses must be a number."), | ||
entertainment: z.string() | ||
.min(1, "Entertainment expenses is required.") | ||
.regex(/^\d+$/, "Entertainment expenses must be a number."), | ||
}) | ||
|
||
import { Button } from "@/components/ui/button" | ||
import { | ||
Form, | ||
FormControl, | ||
FormDescription, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage, | ||
} from "@/components/ui/form" | ||
import { Input } from "@/components/ui/input" | ||
import { Checkbox } from "@/components/ui/checkbox" | ||
import { Chart1, Chart2 } from "./chart" | ||
|
||
export function QuestionForm() { | ||
const router = useRouter() | ||
const [selectedItems, setSelectedItems] = useState<string[]>([]) | ||
|
||
const form = useForm<z.infer<typeof formSchema>>({ | ||
resolver: zodResolver(formSchema), | ||
defaultValues: { | ||
income: "", | ||
housing: "", | ||
food: "", | ||
transportation: "", | ||
healthcare: "", | ||
entertainment: "", | ||
}, | ||
}) | ||
|
||
function onSubmit(values: z.infer<typeof formSchema>) { | ||
console.log(values) | ||
} | ||
|
||
return ( | ||
<div className="w-full max-w-md md:max-w-xl"> | ||
<Form {...form}> | ||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8"> | ||
<FormField | ||
control={form.control} | ||
name="income" | ||
render={({ field }) => ( | ||
<FormItem> | ||
<FormLabel>What is your income?</FormLabel> | ||
<FormControl> | ||
<Input placeholder="1000" type="number" {...field} /> | ||
</FormControl> | ||
<FormDescription> | ||
Enter your income in THB. | ||
</FormDescription> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<FormItem> | ||
<div className="mb-4"> | ||
<FormLabel className="text-base">Expenses</FormLabel> | ||
<FormDescription>Select your expenses.</FormDescription> | ||
</div> | ||
{items.map((item) => ( | ||
<FormItem key={item.id} className="flex flex-col space-y-2"> | ||
<div className="flex items-center space-x-3"> | ||
<FormControl> | ||
<Checkbox | ||
checked={selectedItems.includes(item.id)} | ||
onCheckedChange={(checked) => { | ||
setSelectedItems((prev) => | ||
checked | ||
? [...prev, item.id] | ||
: prev.filter((value) => value !== item.id) | ||
) | ||
form.setValue( | ||
item.id as "housing" | "food" | "transportation" | "healthcare" | "entertainment" | "income", | ||
checked ? form.getValues(item.id as "housing" | "food" | "transportation" | "healthcare" | "entertainment" | "income") : "" | ||
) | ||
}} | ||
/> | ||
</FormControl> | ||
<FormLabel className="font-normal">{item.label}</FormLabel> | ||
</div> | ||
{selectedItems.includes(item.id) && ( | ||
<FormField | ||
control={form.control} | ||
name={item.id as "income" | "housing" | "food" | "transportation" | "healthcare" | "entertainment"} | ||
render={({ field }) => ( | ||
<FormControl> | ||
<Input placeholder={`Enter ${item.label} expenses`} type="number" {...field} /> | ||
</FormControl> | ||
)} | ||
/> | ||
)} | ||
</FormItem> | ||
))} | ||
<FormMessage /> | ||
</FormItem> | ||
<div className="grid grid-cols-2 gap-4"> | ||
<Chart1 /> | ||
<Chart2 /> | ||
</div> | ||
<Link href="/"> | ||
<Button type="submit">Submit</Button> | ||
</Link> | ||
</form> | ||
</Form> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { QuestionForm } from "./form"; | ||
|
||
export default function Page() { | ||
return ( | ||
<div className="flex flex-col m-12 items-center space-y-4"> | ||
<h1 className="text-4xl font-bold">Question</h1> | ||
<QuestionForm /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.