"use client"; import * as z from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm, useFieldArray } from "react-hook-form"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { X } from "lucide-react"; import { cn } from "@/lib/utils"; import { Textarea } from "./ui/textarea"; const formSchema = z.object({ name: z.string().min(2, { message: "Name must be at least 2 characters.", }), description: z.string().min(2, { message: "Description must be at least 2 characters.", }), stack: z.array(z.string()).min(1, { message: "Project tech stack must have at least one item.", }), questions: z.array( z.object({ question: z.string().optional(), }) ), }); export function CreateProject({ workspaceID }: { workspaceID: string }) { const form = useForm>({ resolver: zodResolver(formSchema), mode: "all", defaultValues: { name: "", description: "", stack: [], questions: [], }, }); const { setValue, formState } = form; const [stackInput, setStackInput] = useState(""); const [isDialogOpen, setIsDialogOpen] = useState(false); const [formStep, setFormStep] = useState(0); const [questions, setQuestions] = useState([]); // TODO: [] as Question[] const router = useRouter(); const { fields, append, remove } = useFieldArray({ name: "questions", control: form.control, }); async function onSubmit(values: z.infer) { try { const res = await fetch(`/w/${workspaceID}/p`, { method: "POST", body: JSON.stringify({ ...values, questionsText: questions, }), }); const data = await res.json(); console.log("===>", res); if (!res.ok) throw new Error("Something went wrong."); router.push(`/w/${workspaceID}/p/${data.project.id}`); setIsDialogOpen(false); return res; } catch (err) { console.error(err); } } async function generateQuestions() { try { const res = await fetch(`/w/${workspaceID}/p/gen`, { method: "POST", body: JSON.stringify(form.getValues()), }); if (!res.ok) throw new Error("Something went wrong."); const data = await res.json(); console.log("===>", data.questions); setQuestions(data.questions); append(data.questions); return res; } catch (err) { console.error(err); } } const keyHandler = (e: React.KeyboardEvent) => { if ((e.key === "Enter" || e.key === "Tab") && stackInput !== "") { e.preventDefault(); setValue("stack", [...form.getValues("stack"), stackInput]); setStackInput(""); } }; return ( {formStep == 0 && ( Create a Project Give your project a name, description, and tech stack. )} {formStep == 1 && ( Extra Questions We've like to know some more about the specifics of your project, feel free to answer any of the following additional questions. )}
( Name This is your project name. )} /> ( Description This is your project description. )} /> ( Tech Stack setStackInput(e.target.value)} onKeyDown={keyHandler} /> This is your project tech stack.
{form.getValues("stack").map((stack) => ( {stack} setValue( "stack", form .getValues("stack") .filter((s) => s !== stack) ) } /> ))}
)} />
{questions.length == 0 && (

Generating questions...

)} {fields.map((field, index) => ( ( Question {index + 1} {questions[index]}