"use client" import { Button } from "@/components/ui/button" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { CommissionExtra, CommissionOption, CommissionType, CommissionTypeExtra, CommissionTypeOption } from "@/generated/prisma" import { commissionOrderSchema } from "@/schemas/commissionOrder" import { calculatePrice } from "@/utils/calculatePrice" import { zodResolver } from "@hookform/resolvers/zod" import { useMemo, useState } from "react" import { useForm, useWatch } from "react-hook-form" import * as z from "zod/v4" import { FileDropzone } from "./FileDropzone" type CommissionTypeWithRelations = CommissionType & { options: (CommissionTypeOption & { option: CommissionOption })[] extras: (CommissionTypeExtra & { extra: CommissionExtra })[] } type Props = { types: CommissionTypeWithRelations[] } export function CommissionOrderForm({ types }: Props) { const form = useForm>({ resolver: zodResolver(commissionOrderSchema), defaultValues: { typeId: "", optionId: "", extraIds: [], customerName: "", customerEmail: "", message: "", }, }) const [files, setFiles] = useState([]) const typeId = useWatch({ control: form.control, name: "typeId" }) const optionId = useWatch({ control: form.control, name: "optionId" }) const extraIds = useWatch({ control: form.control, name: "extraIds" }) const selectedType = useMemo( () => types.find((t) => t.id === typeId), [types, typeId] ) const selectedOption = useMemo( () => selectedType?.options.find((o) => o.optionId === optionId), [selectedType, optionId] ) const selectedExtras = useMemo( () => selectedType?.extras.filter((e) => extraIds?.includes(e.extraId)) ?? [], [selectedType, extraIds] ) const price = useMemo(() => { if (!selectedOption) return 0 const base = calculatePrice(selectedOption, 0) const extrasSum = selectedExtras.reduce( (sum, ext) => sum + calculatePrice(ext, base), 0 ) return base + extrasSum }, [selectedOption, selectedExtras]) async function onSubmit(values: z.infer) { console.log("Submit:", { ...values, files }) // TODO: send to server } return (
( Choose a commission type
{types.map((type) => ( ))}
)} /> {selectedType && ( <> ( Base Option
{selectedType.options.map((opt) => ( ))}
)} /> ( Extras
{selectedType?.extras.map((ext) => ( ))}
)} /> )}
( Your Name )} /> ( Email )} />
( Project Details