subman-nextjs/src/app/ui/forms/fancyForm.tsx

122 lines
3.0 KiB
TypeScript
Raw Normal View History

2024-06-12 15:53:19 +00:00
"use client"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { Genre } from "@prisma/client"
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
2024-06-13 10:11:09 +00:00
import { Checkbox } from "@/components/ui/checkbox"
2024-06-12 15:53:19 +00:00
const formSchema = z.object({
title: z.string().min(2).max(50),
word_count: z.number(),
2024-06-13 10:11:09 +00:00
genres: z.object({ id: z.number(), name: z.string() }).array()
2024-06-12 15:53:19 +00:00
})
2024-06-13 10:11:09 +00:00
export default function FancyForm({ genres }) {
2024-06-12 15:53:19 +00:00
// 1. Define your form.
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
title: "",
2024-06-13 10:11:09 +00:00
word_count: 0,
genres: genres
2024-06-12 15:53:19 +00:00
},
})
// 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)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Title</FormLabel>
<FormControl>
<Input placeholder="title goes here..." {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="word_count"
render={({ field }) => (
<FormItem>
<FormLabel>Word count</FormLabel>
<FormControl>
<Input type="number" step={500} min={0} {...field}></Input>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="genres"
render={({ field }) => (
<FormItem>
2024-06-13 10:11:09 +00:00
<div className="mb-4">
<FormLabel>Genres</FormLabel>
<FormDescription>genres baby</FormDescription>
</div>
{genres.map((item) => (
<FormField
key={item.id}
control={form.control}
name="genres"
render={({ field }) => {
return (
<FormItem
key={item.id}
className="flex flex-row items-start space-x-3 space-y-0"
>
<FormControl>
<Checkbox
checked={field.value?.includes(item.id)}
onCheckedChange={(checked) => {
return checked
? field.onChange([...field.value, item.id])
: field.onChange(
field.value?.filter(
(value) => value !== item.id
)
)
}}
/>
</FormControl>
<FormLabel className="text-sm font-normal">
{item.name}
</FormLabel>
</FormItem>
)
}}
/>
))}
2024-06-12 15:53:19 +00:00
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}