"use client"; import React, { useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/Card"; import { Select } from "@/components/ui/Select"; import { IMAGE_MODELS, getModelCost, formatCost } from "@/lib/constants/models"; import type { Niche } from "@/types/api"; import { InfoButton } from "@/components/ui/InfoButton"; const extensiveSchema = z.object({ niche: z.enum(["home_insurance", "glp1", "auto_insurance", "others"]), custom_niche: z.string().optional().nullable(), target_audience: z.string().optional().nullable(), offer: z.string().optional().nullable(), num_images: z.number().min(1).max(3), num_strategies: z.number().min(1).max(10), image_model: z.string().nullable().optional(), }).refine( (data) => { if (data.niche === "others") { return data.custom_niche && data.custom_niche.trim().length > 0; } return true; }, { message: "Please enter your custom niche", path: ["custom_niche"], } ); type ExtensiveFormData = z.infer; interface ExtensiveFormProps { onSubmit: (data: { niche: Niche; custom_niche?: string | null; target_audience?: string | null; offer?: string | null; num_images: number; num_strategies: number; image_model?: string | null; }) => Promise; isLoading: boolean; } export const ExtensiveForm: React.FC = ({ onSubmit, isLoading, }) => { const { register, handleSubmit, formState: { errors }, watch, setValue, } = useForm({ resolver: zodResolver(extensiveSchema), defaultValues: { niche: "home_insurance" as const, // first option; flow works for any niche custom_niche: "", target_audience: "", offer: "", num_images: 1, num_strategies: 5, image_model: null, }, }); const numImages = 1; const numStrategies = watch("num_strategies"); const selectedNiche = watch("niche"); const selectedModel = watch("image_model"); useEffect(() => { setValue("num_images", numImages, { shouldDirty: false, shouldValidate: false }); }, [numImages, setValue]); const onFormSubmit = handleSubmit(({ num_images, ...rest }) => onSubmit({ ...rest, num_images: num_images ?? 1 }) ); return (
Extensive Generation
Researcher → Creative Director → Designer → Copywriter flow
{errors.custom_niche && (

{errors.custom_niche.message}

)} )}
{errors.target_audience && (

{errors.target_audience.message}

)}
{errors.offer && (

{errors.offer.message}

)}
1 10

More strategies = more variety, but longer generation time

{/* Cost Estimator */}

💰 Estimated Cost: {formatCost(getModelCost(selectedModel || "", numStrategies))}

{numStrategies} total image{numStrategies > 1 ? 's' : ''} × {IMAGE_MODELS.find(m => m.value === (selectedModel || ""))?.label.split(' - ')[0] || "Default model"}

); };