import { useRef, useState } from "react"; import { useScroll, useTransform, motion } from "motion/react"; import type { LucideIcon } from "lucide-react"; import ImageOrVideo from "@/components/ui/ImageOrVideo"; import TextAnimation from "@/components/ui/TextAnimation"; import ScrollReveal from "@/components/ui/ScrollReveal"; import { sendContactEmail } from "@/lib/api/email"; import { useButtonClick } from "@/hooks/useButtonClick"; import { resolveIcon } from "@/utils/resolve-icon"; type InputField = { name: string; type: string; placeholder: string; required?: boolean; }; type TextareaField = { name: string; placeholder: string; rows?: number; required?: boolean; }; type CtaLink = { icon: string | LucideIcon; label: string; href?: string; onClick?: () => void; }; type ContactSplitFormParallaxProps = { tag: string; title: string; description: string; inputs: InputField[]; textarea?: TextareaField; buttonText: string; onSubmit?: (data: Record) => void; ctaLinks?: CtaLink[]; } & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never }); const CtaLinkButton = ({ icon, label, href, onClick }: CtaLink) => { const Icon = resolveIcon(icon); const handleClick = useButtonClick(href, onClick); return ( {label} ); }; const ContactSplitFormParallax = ({ tag, title, description, inputs, textarea, buttonText, onSubmit, imageSrc, videoSrc, ctaLinks, }: ContactSplitFormParallaxProps) => { const imageRef = useRef(null); const [formData, setFormData] = useState>(() => { const initial: Record = {}; inputs.forEach((input) => { initial[input.name] = ""; }); if (textarea) { initial[textarea.name] = ""; } return initial; }); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const handleSubmit = async (e: React.SyntheticEvent) => { e.preventDefault(); setIsLoading(true); setError(null); try { await sendContactEmail({ formData }); onSubmit?.(formData); const reset: Record = {}; inputs.forEach((input) => { reset[input.name] = ""; }); if (textarea) { reset[textarea.name] = ""; } setFormData(reset); } catch (err) { setError(err instanceof Error ? err.message : "Failed to send. Please try again."); } finally { setIsLoading(false); } }; const { scrollYProgress } = useScroll({ target: imageRef, offset: ["start end", "end start"], }); const imageScale = useTransform(scrollYProgress, [0, 0.6], [1.3, 1]); return (

{tag}

{inputs.map((input) => ( setFormData({ ...formData, [input.name]: e.target.value })} required={input.required} aria-label={input.placeholder} className="w-full px-5 py-3 text-base bg-transparent placeholder:opacity-75 focus:outline-none card rounded" /> ))} {textarea && (