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

This commit is contained in:
2026-03-03 04:58:50 +00:00
parent 9d9e695f09
commit 56eaa7211b

View File

@@ -1,10 +1,14 @@
"use client";
import React, { useState } from "react";
import { cn } from "@/lib/utils";
import { Mail } from "lucide-react";
export interface ContactSplitProps {
tag?: string;
tag: string;
title: string;
description: string;
tagIcon?: React.ComponentType<any>;
tagAnimation?: "none" | "opacity" | "slide-up" | "blur-reveal";
background?: { variant: string };
useInvertedBackground?: boolean;
imageSrc?: string;
@@ -17,10 +21,10 @@ export interface ContactSplitProps {
buttonText?: string;
termsText?: string;
onSubmit?: (email: string) => void;
ariaLabel?: string;
className?: string;
containerClassName?: string;
contentClassName?: string;
contactFormClassName?: string;
tagClassName?: string;
titleClassName?: string;
descriptionClassName?: string;
@@ -34,90 +38,107 @@ export interface ContactSplitProps {
mediaClassName?: string;
}
export const ContactSplit: React.FC<ContactSplitProps> = ({
tag,
title,
description,
imageSrc,
videoSrc,
imageAlt = "", mediaPosition = "right", inputPlaceholder = "Enter your email", buttonText = "Sign Up", termsText,
useInvertedBackground = false,
className,
containerClassName,
contentClassName,
tagClassName,
titleClassName,
descriptionClassName,
formWrapperClassName,
formClassName,
inputClassName,
buttonClassName,
buttonTextClassName,
termsClassName,
mediaWrapperClassName,
mediaClassName
}) => {
const [email, setEmail] = useState("");
const ContactSplit = React.forwardRef<HTMLDivElement, ContactSplitProps>(
(
{
tag,
title,
description,
tagIcon: TagIcon,
tagAnimation = "none", background,
useInvertedBackground = false,
imageSrc,
videoSrc,
imageAlt = "", videoAriaLabel = "Contact section video", mediaAnimation = "none", 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.", onSubmit,
ariaLabel = "Contact section", className = "", containerClassName = "", contentClassName = "", tagClassName = "", titleClassName = "", descriptionClassName = "", formWrapperClassName = "", formClassName = "", inputClassName = "", buttonClassName = "", buttonTextClassName = "", termsClassName = "", mediaWrapperClassName = "", mediaClassName = ""},
ref
) => {
const [email, setEmail] = useState("");
const handleFormSubmit = (e: React.FormEvent) => {
e.preventDefault();
setEmail("");
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit?.(email);
setEmail("");
};
return (
<div
className={cn(
"w-full py-20 px-4", useInvertedBackground && "bg-accent/10", containerClassName
)}
>
<div className={cn("max-w-6xl mx-auto", contentClassName)}>
<div className={cn("grid grid-cols-1 md:grid-cols-2 gap-12 items-center", className)}>
{mediaPosition === "left" && imageSrc && (
<div className={cn("order-first", mediaWrapperClassName)}>
<img src={imageSrc} alt={imageAlt} className={cn("w-full rounded-lg", mediaClassName)} />
</div>
)}
return (
<div
ref={ref}
className={`w-full py-20 ${className}`}
aria-label={ariaLabel}
>
<div className={`max-w-7xl mx-auto px-4 ${containerClassName}`}>
<div className={`grid grid-cols-1 md:grid-cols-2 gap-12 ${contentClassName}`}>
{/* Text Content */}
<div className={formWrapperClassName}>
{tag && (
<div className={`flex items-center gap-2 mb-4 ${tagClassName}`}>
{TagIcon && <TagIcon className="w-4 h-4" />}
<span className="text-sm font-medium">{tag}</span>
</div>
)}
<h2 className={`text-4xl font-bold mb-4 ${titleClassName}`}>
{title}
</h2>
<p
className={`text-lg text-foreground/75 mb-8 ${descriptionClassName}`}
>
{description}
</p>
<div className={cn("space-y-6", contactFormClassName)}>
{tag && <p className={cn("text-sm font-semibold text-accent", tagClassName)}>{tag}</p>}
<h2 className={cn("text-4xl font-bold", titleClassName)}>{title}</h2>
<p className={cn("text-lg text-muted-foreground", descriptionClassName)}>{description}</p>
<form onSubmit={handleFormSubmit} className={cn("space-y-4", formWrapperClassName)}>
<div className={cn("space-y-2", formClassName)}>
<form
onSubmit={handleSubmit}
className={`space-y-4 ${formClassName}`}
>
<input
type="email"
placeholder={inputPlaceholder}
value={email}
onChange={(e) => setEmail(e.target.value)}
className={cn(
"w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary", inputClassName
)}
placeholder={inputPlaceholder}
required
className={`w-full px-4 py-3 bg-secondary-cta text-foreground rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-cta ${inputClassName}`}
/>
<button
type="submit"
className={cn(
"w-full px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors", buttonClassName
)}
className={`w-full px-4 py-3 bg-primary-cta text-primary-cta-text font-medium rounded-lg hover:opacity-90 transition-opacity ${buttonClassName}`}
>
<span className={buttonTextClassName}>{buttonText}</span>
</button>
</div>
</form>
</form>
{termsText && <p className={cn("text-xs text-muted-foreground", termsClassName)}>{termsText}</p>}
</div>
{mediaPosition === "right" && imageSrc && (
<div className={cn("order-last", mediaWrapperClassName)}>
<img src={imageSrc} alt={imageAlt} className={cn("w-full rounded-lg", mediaClassName)} />
{termsText && (
<p className={`text-xs text-foreground/60 mt-4 ${termsClassName}`}>
{termsText}
</p>
)}
</div>
)}
{/* Media */}
{(imageSrc || videoSrc) && (
<div className={`flex items-center justify-center ${mediaWrapperClassName}`}>
{videoSrc ? (
<video
src={videoSrc}
aria-label={videoAriaLabel}
controls
className={`w-full h-full object-cover rounded-lg ${mediaClassName}`}
/>
) : imageSrc ? (
<img
src={imageSrc}
alt={imageAlt}
className={`w-full h-full object-cover rounded-lg ${mediaClassName}`}
/>
) : null}
</div>
)}
</div>
</div>
</div>
</div>
);
};
);
}
);
ContactSplit.displayName = "ContactSplit";
export default ContactSplit;