paameterize form using zod to get a type checked fields

This commit is contained in:
Viktor Barzin 2025-06-17 20:42:41 +00:00
parent a092b4e9c8
commit 1caaa247d8
No known key found for this signature in database
GPG key ID: 4056458DBDBF8863
4 changed files with 303 additions and 29 deletions

View file

@ -1,40 +1,100 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { DialogTitle } from "@radix-ui/react-dialog";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "./ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog";
import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog";
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "./ui/form";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
enum Metric {
qmprice = 'Price per square meter',
rooms = 'Number of rooms',
qm = 'Area',
price = 'Price',
}
interface ParameterValues {
metric: Metric
}
export function Parameters(
props: {
isOpen: boolean,
onSubmit: () => void,
onSubmit: (fromValues: ParameterValues) => void,
}
) {
const {
register,
watch,
formState: { errors },
} = useForm<ParameterValues>()
// const onSubmit: SubmitHandler<ParameterValues> = (data) => console.log(data)
console.log(watch("metric"))
console.log(errors)
const formSchema = z.object({
metric: z.nativeEnum(Metric, { required_error: "Metric is required" }),
})
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
metric: Metric.qmprice,
},
})
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values)
props.onSubmit(values)
}
return <>
{/* <Dialog open={props.isOpen}> */}
<Dialog >
<form>
<DialogTrigger asChild>
<Button variant="outline">Open Parameters</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Parameters</DialogTitle>
</DialogHeader>
<Select>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Metric to Visualize" />
</SelectTrigger>
<SelectContent>
<SelectItem value="qmprice">Price per squaremeter</SelectItem>
<SelectItem value="rooms">Number of rooms</SelectItem>
<SelectItem value="qm">Area</SelectItem>
<SelectItem value="total_price">Price</SelectItem>
</SelectContent>
</Select>
<DialogFooter>
<Button onClick={() => props.onSubmit()}>Fetch Data</Button>
</DialogFooter>
</DialogContent>
</form>
<DialogTrigger asChild>
<Button variant="outline">Open Parameters</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogTitle>
Visualization Parameters
</DialogTitle>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="metric"
render={({ field }) => (
<FormItem>
<FormLabel>Metric to visualize</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Metric to Visualize" />
</SelectTrigger>
</FormControl>
<SelectContent {...register('metric')} >
<SelectItem value={Metric.qmprice}>Price per squaremeter</SelectItem>
<SelectItem value={Metric.rooms}>Number of rooms</SelectItem>
<SelectItem value={Metric.qm}>Area</SelectItem>
<SelectItem value={Metric.price}>Price</SelectItem>
</SelectContent>
</Select>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
</DialogContent>
</Dialog>
</>
}