"use client"; import React, { useState, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/Card"; import { Select } from "@/components/ui/Select"; import { IMAGE_MODELS } from "@/lib/constants/models"; import { getAllAngles, getAllConcepts } from "@/lib/api/endpoints"; import type { ModificationMode, AnglesResponse, ConceptsResponse } from "@/types/api"; interface AngleOption { value: string; label: string; trigger: string; category: string; } interface ConceptOption { value: string; label: string; structure: string; category: string; } interface ModificationFormProps { angle: string; concept: string; mode: ModificationMode; imageModel: string | null; userPrompt: string; variationCount: number; onAngleChange: (value: string) => void; onConceptChange: (value: string) => void; onModeChange: (mode: ModificationMode) => void; onImageModelChange: (model: string | null) => void; onUserPromptChange: (value: string) => void; onVariationCountChange: (value: number) => void; onSubmit: () => void; isLoading: boolean; } import { Brain, Sparkles, Wand2, Lightbulb, ChevronDown, Check, Info } from "lucide-react"; export const ModificationForm: React.FC = ({ angle, concept, mode, imageModel, userPrompt, variationCount, onAngleChange, onConceptChange, onModeChange, onImageModelChange, onUserPromptChange, onVariationCountChange, onSubmit, isLoading, }) => { const [angleOptions, setAngleOptions] = useState([]); const [conceptOptions, setConceptOptions] = useState([]); const [loadingOptions, setLoadingOptions] = useState(true); const [angleInputMode, setAngleInputMode] = useState<"dropdown" | "custom">("dropdown"); const [conceptInputMode, setConceptInputMode] = useState<"dropdown" | "custom">("dropdown"); // Fetch angles and concepts on mount useEffect(() => { const fetchOptions = async () => { try { setLoadingOptions(true); const [anglesData, conceptsData] = await Promise.all([ getAllAngles(), getAllConcepts(), ]); const angles: AngleOption[] = []; Object.entries(anglesData.categories).forEach(([categoryKey, category]) => { category.angles.forEach((a) => { angles.push({ value: a.name, label: a.name, trigger: a.trigger, category: category.name, }); }); }); setAngleOptions(angles); const concepts: ConceptOption[] = []; Object.entries(conceptsData.categories).forEach(([categoryKey, category]) => { category.concepts.forEach((c) => { concepts.push({ value: c.name, label: c.name, structure: c.structure, category: category.name, }); }); }); setConceptOptions(concepts); } catch (error) { console.error("Failed to fetch angles/concepts:", error); } finally { setLoadingOptions(false); } }; fetchOptions(); }, []); const isValid = angle.trim() || concept.trim() || userPrompt.trim(); const groupedAngles = angleOptions.reduce((acc, angle) => { if (!acc[angle.category]) acc[angle.category] = []; acc[angle.category].push(angle); return acc; }, {} as Record); const groupedConcepts = conceptOptions.reduce((acc, concept) => { if (!acc[concept.category]) acc[concept.category] = []; acc[concept.category].push(concept); return acc; }, {} as Record); return (
Refine & Transform
Apply powerful psychological angles and visual concepts to your creative.
{/* Angle Selection */}
{angleInputMode === "dropdown" ? (
) : ( onAngleChange(e.target.value)} placeholder="e.g., Scarcity, Fear of Missing Out..." className="w-full px-4 py-4 rounded-xl border-2 border-gray-100 bg-gray-50/50 hover:bg-white focus:bg-white focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 transition-all font-medium text-gray-900" /> )}

The "Why" - triggers that motivate user action.

{/* Concept Selection */}
{conceptInputMode === "dropdown" ? (
) : ( onConceptChange(e.target.value)} placeholder="e.g., Before/After Comparison, User Testimonial..." className="w-full px-4 py-4 rounded-xl border-2 border-gray-100 bg-gray-50/50 hover:bg-white focus:bg-white focus:border-green-500 focus:ring-4 focus:ring-green-500/10 transition-all font-medium text-gray-900" /> )}

The "How" - visual structure and format.

{/* Mode Selection */}
{/* Variation Count */}
{variationCount} variation{variationCount > 1 ? "s" : ""} Up to 3 total
onVariationCountChange(Number(e.target.value))} disabled={isLoading} className="w-full accent-blue-500" />
1 2 3

Generates that many distinct remixes of your original creative.

{/* User Prompt (Optional) */}