Update src/components/sections/contact/ContactSplit.tsx

This commit is contained in:
2026-03-08 22:19:43 +00:00
parent 5cc569fcbe
commit 8f4c4a9a8d

View File

@@ -1,171 +1,98 @@
"use client";
import ContactForm from "@/components/form/ContactForm";
import MediaContent from "@/components/shared/MediaContent";
import HeroBackgrounds, { type HeroBackgroundVariantProps } from "@/components/background/HeroBackgrounds";
import { cls } from "@/lib/utils";
import { useButtonAnimation } from "@/components/hooks/useButtonAnimation";
import { LucideIcon } from "lucide-react";
import { sendContactEmail } from "@/utils/sendContactEmail";
import type { ButtonAnimationType } from "@/types/button";
type ContactSplitBackgroundProps = Extract<
HeroBackgroundVariantProps,
| { variant: "plain" }
| { variant: "animated-grid" }
| { variant: "canvas-reveal" }
| { variant: "cell-wave" }
| { variant: "downward-rays-animated" }
| { variant: "downward-rays-animated-grid" }
| { variant: "downward-rays-static" }
| { variant: "downward-rays-static-grid" }
| { variant: "gradient-bars" }
| { variant: "radial-gradient" }
| { variant: "rotated-rays-animated" }
| { variant: "rotated-rays-animated-grid" }
| { variant: "rotated-rays-static" }
| { variant: "rotated-rays-static-grid" }
| { variant: "sparkles-gradient" }
>;
import React, { useState } from "react";
interface ContactSplitProps {
title: string;
description: string;
tag: string;
tagIcon?: LucideIcon;
tagAnimation?: ButtonAnimationType;
background: ContactSplitBackgroundProps;
useInvertedBackground: boolean;
imageSrc?: string;
videoSrc?: string;
imageAlt?: string;
videoAriaLabel?: string;
mediaPosition?: "left" | "right";
mediaAnimation: ButtonAnimationType;
inputPlaceholder?: string;
buttonText?: string;
termsText?: string;
onSubmit?: (email: string) => void;
ariaLabel?: string;
className?: string;
containerClassName?: string;
contentClassName?: string;
contactFormClassName?: string;
tagClassName?: string;
titleClassName?: string;
descriptionClassName?: string;
formWrapperClassName?: string;
formClassName?: string;
inputClassName?: string;
buttonClassName?: string;
buttonTextClassName?: string;
termsClassName?: string;
mediaWrapperClassName?: string;
mediaClassName?: string;
tag: string;
title: string;
description: string;
tagIcon?: React.ComponentType<{ className?: string }>;
background?: { variant: string };
useInvertedBackground?: boolean;
imageSrc?: string;
videoSrc?: string;
mediaPosition?: "left" | "right";
inputPlaceholder?: string;
buttonText?: string;
termsText?: string;
className?: string;
}
const ContactSplit = ({
title,
description,
tag,
tagIcon,
tagAnimation,
background,
useInvertedBackground,
imageSrc,
videoSrc,
imageAlt = "",
videoAriaLabel = "Contact section video",
mediaPosition = "right",
mediaAnimation,
inputPlaceholder = "Enter your email",
buttonText = "Sign Up",
termsText = "By clicking Sign Up you're confirming that you agree with our Terms and Conditions.",
onSubmit,
ariaLabel = "Contact section",
className = "",
containerClassName = "",
contentClassName = "",
contactFormClassName = "",
tagClassName = "",
titleClassName = "",
descriptionClassName = "",
formWrapperClassName = "",
formClassName = "",
inputClassName = "",
buttonClassName = "",
buttonTextClassName = "",
termsClassName = "",
mediaWrapperClassName = "",
mediaClassName = "",
}: ContactSplitProps) => {
const { containerRef: mediaContainerRef } = useButtonAnimation({ animationType: mediaAnimation });
const ContactSplit: React.FC<ContactSplitProps> = ({
tag,
title,
description,
imageSrc,
videoSrc,
mediaPosition = "right", inputPlaceholder = "Enter your email", buttonText = "Sign Up", termsText = "By clicking Sign Up you're confirming that you agree with our Terms and Conditions.", className = ""}) => {
const [email, setEmail] = useState("");
const handleSubmit = async (email: string) => {
try {
await sendContactEmail({ email });
console.log("Email send successfully");
} catch (error) {
console.error("Failed to send email:", error);
}
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log("Email submitted:", email);
setEmail("");
};
const contactContent = (
<div className="relative card rounded-theme-capped p-6 py-15 md:py-6 flex items-center justify-center">
<ContactForm
tag={tag}
tagIcon={tagIcon}
tagAnimation={tagAnimation}
title={title}
description={description}
useInvertedBackground={useInvertedBackground}
inputPlaceholder={inputPlaceholder}
buttonText={buttonText}
termsText={termsText}
onSubmit={handleSubmit}
centered={true}
className={cls("w-full", contactFormClassName)}
tagClassName={tagClassName}
titleClassName={titleClassName}
descriptionClassName={descriptionClassName}
formWrapperClassName={cls("w-full md:w-8/10 2xl:w-7/10", formWrapperClassName)}
formClassName={formClassName}
inputClassName={inputClassName}
buttonClassName={buttonClassName}
buttonTextClassName={buttonTextClassName}
termsClassName={termsClassName}
/>
<div className="absolute inset w-full h-full z-0 rounded-theme-capped overflow-hidden" >
<HeroBackgrounds {...background} />
</div>
const formContent = (
<div className="flex-1">
<div className="mb-4 text-sm font-semibold text-blue-600">{tag}</div>
<h2 className="text-3xl font-bold mb-4">{title}</h2>
<p className="text-gray-600 mb-8">{description}</p>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="flex gap-2">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder={inputPlaceholder}
required
className="flex-1 px-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button
type="submit"
className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
{buttonText}
</button>
</div>
);
<p className="text-xs text-gray-500">{termsText}</p>
</form>
</div>
);
const mediaContent = (
<div ref={mediaContainerRef} className={cls("overflow-hidden rounded-theme-capped card h-130", mediaWrapperClassName)}>
<MediaContent
imageSrc={imageSrc}
videoSrc={videoSrc}
imageAlt={imageAlt}
videoAriaLabel={videoAriaLabel}
imageClassName={cls("relative z-1 w-full h-full object-cover", mediaClassName)}
/>
const mediaContent = imageSrc || videoSrc ? (
<div className="flex-1">
{imageSrc && (
<img
src={imageSrc}
alt="Contact"
className="w-full h-full object-cover rounded-lg"
/>
)}
{videoSrc && (
<video
src={videoSrc}
autoPlay
loop
muted
className="w-full h-full object-cover rounded-lg"
/>
)}
</div>
) : null;
return (
<section className={`py-20 px-4 ${className}`}>
<div className="max-w-6xl mx-auto">
<div className="flex flex-col lg:flex-row gap-12 items-center">
{mediaPosition === "left" && mediaContent}
{formContent}
{mediaPosition === "right" && mediaContent}
</div>
);
return (
<section aria-label={ariaLabel} className={cls("relative py-20 w-full", useInvertedBackground && "bg-foreground", className)}>
<div className={cls("w-content-width mx-auto relative z-10", containerClassName)}>
<div className={cls("grid grid-cols-1 md:grid-cols-2 gap-6 md:auto-rows-fr", contentClassName)}>
{mediaPosition === "left" && mediaContent}
{contactContent}
{mediaPosition === "right" && mediaContent}
</div>
</div>
</section>
);
</div>
</section>
);
};
ContactSplit.displayName = "ContactSplit";
export default ContactSplit;