sushilideaclan01's picture
remove the variations option
4a56a0b
"use client";
import React from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { generateBatchSchema } from "@/lib/utils/validators";
import { Input } from "@/components/ui/Input";
import { Select } from "@/components/ui/Select";
import { Button } from "@/components/ui/Button";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/Card";
import { IMAGE_MODELS, getModelCost, formatCost } from "@/lib/constants/models";
import type { Niche } from "@/types/api";
import { InfoButton } from "@/components/ui/InfoButton";
interface BatchFormProps {
onSubmit: (data: { niche: Niche; count: number; image_model?: string | null; target_audience?: string | null; offer?: string | null }) => Promise<void>;
isLoading: boolean;
}
export const BatchForm: React.FC<BatchFormProps> = ({
onSubmit,
isLoading,
}) => {
const {
register,
handleSubmit,
formState: { errors },
watch,
} = useForm({
resolver: zodResolver(generateBatchSchema),
defaultValues: {
niche: "home_insurance" as const,
count: 5,
image_model: null,
target_audience: "",
offer: "",
},
});
const count = watch("count");
const selectedModel = watch("image_model");
return (
<Card variant="glass">
<CardHeader>
<div className="flex items-center gap-2">
<CardTitle>Batch Generation</CardTitle>
<InfoButton
title="Batch Generation Flow"
content="Generate multiple ads simultaneously for A/B testing and variety. Each ad is created with randomized strategies, giving you diverse options to test. You can generate up to 100 ads in a single run to quickly find winning combinations."
position="bottom"
/>
</div>
<CardDescription>
Generate multiple ads at once for testing and variety
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
<Select
label="Niche"
options={[
{ value: "home_insurance", label: "Home Insurance" },
{ value: "glp1", label: "GLP-1" },
{ value: "auto_insurance", label: "Auto Insurance" },
]}
error={errors.niche?.message}
{...register("niche")}
/>
<div>
<label className="block text-sm font-semibold text-gray-700 mb-2">
Target Audience <span className="text-gray-400 font-normal">(Optional)</span>
</label>
<input
type="text"
className="w-full px-4 py-3 rounded-xl border-2 border-gray-300 bg-white/80 backdrop-blur-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-250"
placeholder="e.g., US people over 50+ age"
{...register("target_audience")}
/>
{errors.target_audience && (
<p className="text-red-500 text-xs mt-1">{errors.target_audience.message}</p>
)}
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 mb-2">
Offer <span className="text-gray-400 font-normal">(Optional)</span>
</label>
<input
type="text"
className="w-full px-4 py-3 rounded-xl border-2 border-gray-300 bg-white/80 backdrop-blur-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-250"
placeholder="e.g., Don't overpay your insurance"
{...register("offer")}
/>
{errors.offer && (
<p className="text-red-500 text-xs mt-1">{errors.offer.message}</p>
)}
</div>
<Select
label="Image Model"
options={IMAGE_MODELS.map(model => ({ value: model.value, label: model.label }))}
error={errors.image_model?.message}
{...register("image_model")}
/>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Number of Ads: {count}
</label>
<input
type="range"
min="1"
max="100"
step="1"
className="w-full"
{...register("count", { valueAsNumber: true })}
/>
<div className="flex justify-between text-xs text-gray-500 mt-1">
<span>1</span>
<span>100</span>
</div>
{errors.count && (
<p className="mt-1 text-sm text-red-600">
{errors.count.message}
</p>
)}
</div>
{/* Cost Estimator */}
<div className="bg-gradient-to-r from-green-50 to-emerald-50 border border-green-200 rounded-xl p-4">
<p className="text-sm font-semibold text-gray-800">
💰 <strong>Estimated Cost:</strong> {formatCost(getModelCost(selectedModel || "", count))}
</p>
<p className="text-xs text-gray-600 mt-1">
{count} total image{count > 1 ? 's' : ''} × {IMAGE_MODELS.find(m => m.value === (selectedModel || ""))?.label.split(' - ')[0] || "Default model"}
</p>
</div>
<Button
type="submit"
variant="primary"
size="lg"
isLoading={isLoading}
className="w-full"
>
Generate Batch
</Button>
</form>
</CardContent>
</Card>
);
};