🎉
【Convex】NextJs14 と Convex【#19 Convex Card Form】
【#19 Convex Card Form】
YouTube: https://youtu.be/gYNKeZANxb0
今回は前回作成したモーダルにカード作成用のフォームを実装します。
components/modals/create-card-modal.tsx
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Form, FormControl, FormField } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { useCreateCardModal } from "@/store/use-create-card-modals";
const formSchema = z.object({
title: z
.string()
.min(2, { message: "Title must be at least 2 characters." })
.max(50, { message: "Title must be less than 50 characters." }),
cardType: z.string({
required_error: "Card type is required.",
invalid_type_error: "Card type is required.",
}),
});
export const CreateCardModal = () => {
const { isOpen, onClose, initialValues } = useCreateCardModal();
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
title: "",
cardType: "comment",
},
});
const onSubmit = (values: z.infer<typeof formSchema>) => {
console.log(values);
};
return (
<Dialog open={true} onOpenChange={onClose}>
<DialogContent>
<DialogHeader>
<DialogTitle>Create Card</DialogTitle>
<DialogDescription>
Select card type & Enter card title
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="cardType"
render={({ field }) => (
<Select
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Card type" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="comment">Comment</SelectItem>
<SelectItem value="board">Board</SelectItem>
</SelectContent>
</Select>
)}
/>
<FormField
control={form.control}
name="title"
render={({ field }) => (
<Input {...field} placeholder="Card title" />
)}
/>
<DialogFooter>
<DialogClose asChild>
<Button type="button" variant="outline">
Cancel
</Button>
</DialogClose>
<Button type="submit">Create</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
};
Discussion