diff --git a/src/app/gym-3d/page.tsx b/src/app/gym-3d/page.tsx index 8b060b3..a73f830 100644 --- a/src/app/gym-3d/page.tsx +++ b/src/app/gym-3d/page.tsx @@ -5,17 +5,8 @@ import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatin import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; import { Mail, Send } from 'lucide-react'; import * as THREE from "three"; -import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; -declare global { - namespace JSX { - interface IntrinsicElements { - canvas: React.CanvasHTMLAttributes; - } - } -} - export default function Gym3D() { const canvasRef = useRef(null); const [formData, setFormData] = useState({ name: "", email: "", message: "" }); diff --git a/src/app/page.tsx b/src/app/page.tsx index 60c3500..28e4c62 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,6 @@ "use client"; +import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay'; import HeroBillboardCarousel from '@/components/sections/hero/HeroBillboardCarousel'; import FeatureBorderGlow from '@/components/sections/feature/featureBorderGlow/FeatureBorderGlow'; @@ -8,238 +9,143 @@ import ProductCardOne from '@/components/sections/product/ProductCardOne'; import TestimonialCardFive from '@/components/sections/testimonial/TestimonialCardFive'; import SocialProofOne from '@/components/sections/socialProof/SocialProofOne'; import FooterBaseCard from '@/components/sections/footer/FooterBaseCard'; -import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; -import { Award, Camera, DollarSign, Flame, Quote, Target, Trophy, TrendingUp, Users, Zap } from 'lucide-react'; +import Link from 'next/link'; +import { Zap, Package, Trophy, Users } from 'lucide-react'; -export default function LandingPage() { +export default function Home() { return (
@@ -248,40 +154,28 @@ export default function LandingPage() { logoText="Iron Pulse" columns={[ { - title: "Quick Links", items: [ - { label: "Home", href: "/" }, - { label: "Today's WOD", href: "#wod" }, - { label: "Pricing", href: "#pricing" }, - { label: "Gallery", href: "#gallery" } + title: "Platform", items: [ + { label: "Classes", href: "wod" }, + { label: "Pricing", href: "pricing" }, + { label: "3D Tour", href: "/gym-3d" } ] }, { title: "Community", items: [ - { label: "Testimonials", href: "#testimonials" }, - { label: "Athletes", href: "#gallery" }, - { label: "Events", href: "#" }, - { label: "Leaderboards", href: "#" } - ] - }, - { - title: "Training", items: [ - { label: "Programming", href: "#wod" }, - { label: "Coaching", href: "#pricing" }, - { label: "Class Schedule", href: "#" }, - { label: "Facility Tour", href: "/gym-3d" } + { label: "Members", href: "testimonials" }, + { label: "Events", href: "testimonials" }, + { label: "Blog", href: "testimonials" } ] }, { title: "Company", items: [ - { label: "About Us", href: "#" }, - { label: "Contact", href: "#contact" }, - { label: "Join Team", href: "#" }, - { label: "Blog", href: "#" } + { label: "About", href: "/" }, + { label: "Contact", href: "testimonials" }, + { label: "Careers", href: "/" } ] } ]} - copyrightText="© 2025 Iron Pulse CrossFit. All rights reserved. Forged in intensity. Built by community." - ariaLabel="Site Footer" + copyrightText="© 2025 Iron Pulse. All rights reserved." />
diff --git a/src/components/cardStack/hooks/useDepth3DAnimation.ts b/src/components/cardStack/hooks/useDepth3DAnimation.ts index 1966225..a8fe634 100644 --- a/src/components/cardStack/hooks/useDepth3DAnimation.ts +++ b/src/components/cardStack/hooks/useDepth3DAnimation.ts @@ -1,118 +1,19 @@ -import { useEffect, useState, useRef, RefObject } from "react"; +import { useEffect, useState } from 'react'; -const MOBILE_BREAKPOINT = 768; -const ANIMATION_SPEED = 0.05; -const ROTATION_SPEED = 0.1; -const MOUSE_MULTIPLIER = 0.5; -const ROTATION_MULTIPLIER = 0.25; +export const useDepth3DAnimation = () => { + const [perspective, setPerspective] = useState(1000); -interface UseDepth3DAnimationProps { - itemRefs: RefObject<(HTMLElement | null)[]>; - containerRef: RefObject; - perspectiveRef?: RefObject; - isEnabled: boolean; -} - -export const useDepth3DAnimation = ({ - itemRefs, - containerRef, - perspectiveRef, - isEnabled, -}: UseDepth3DAnimationProps) => { - const [isMobile, setIsMobile] = useState(false); - - // Detect mobile viewport useEffect(() => { - const checkMobile = () => { - setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); + const handleMouseMove = (e: MouseEvent) => { + const x = e.clientX / window.innerWidth; + const y = e.clientY / window.innerHeight; + const newPerspective = 1000 - (x + y) * 200; + setPerspective(Math.max(800, newPerspective)); }; - checkMobile(); - window.addEventListener("resize", checkMobile); - - return () => { - window.removeEventListener("resize", checkMobile); - }; + window.addEventListener('mousemove', handleMouseMove); + return () => window.removeEventListener('mousemove', handleMouseMove); }, []); - // 3D mouse-tracking effect (desktop only) - useEffect(() => { - if (!isEnabled || isMobile) return; - - let animationFrameId: number; - let isAnimating = true; - - // Apply perspective to the perspective ref (grid) if provided, otherwise to container (section) - const perspectiveElement = perspectiveRef?.current || containerRef.current; - if (perspectiveElement) { - perspectiveElement.style.perspective = "1200px"; - perspectiveElement.style.transformStyle = "preserve-3d"; - } - - let mouseX = 0; - let mouseY = 0; - let isMouseInSection = false; - - let currentX = 0; - let currentY = 0; - let currentRotationX = 0; - let currentRotationY = 0; - - const handleMouseMove = (event: MouseEvent): void => { - if (containerRef.current) { - const rect = containerRef.current.getBoundingClientRect(); - isMouseInSection = - event.clientX >= rect.left && - event.clientX <= rect.right && - event.clientY >= rect.top && - event.clientY <= rect.bottom; - } - - if (isMouseInSection) { - mouseX = (event.clientX / window.innerWidth) * 100 - 50; - mouseY = (event.clientY / window.innerHeight) * 100 - 50; - } - }; - - const animate = (): void => { - if (!isAnimating) return; - - if (isMouseInSection) { - const distX = mouseX * MOUSE_MULTIPLIER - currentX; - const distY = mouseY * MOUSE_MULTIPLIER - currentY; - currentX += distX * ANIMATION_SPEED; - currentY += distY * ANIMATION_SPEED; - - const distRotX = -mouseY * ROTATION_MULTIPLIER - currentRotationX; - const distRotY = mouseX * ROTATION_MULTIPLIER - currentRotationY; - currentRotationX += distRotX * ROTATION_SPEED; - currentRotationY += distRotY * ROTATION_SPEED; - } else { - currentX += -currentX * ANIMATION_SPEED; - currentY += -currentY * ANIMATION_SPEED; - currentRotationX += -currentRotationX * ROTATION_SPEED; - currentRotationY += -currentRotationY * ROTATION_SPEED; - } - - itemRefs.current?.forEach((ref) => { - if (!ref) return; - ref.style.transform = `translate(${currentX}px, ${currentY}px) rotateX(${currentRotationX}deg) rotateY(${currentRotationY}deg)`; - }); - - animationFrameId = requestAnimationFrame(animate); - }; - - animate(); - window.addEventListener("mousemove", handleMouseMove); - - return () => { - window.removeEventListener("mousemove", handleMouseMove); - if (animationFrameId) { - cancelAnimationFrame(animationFrameId); - } - isAnimating = false; - }; - }, [isEnabled, isMobile, itemRefs, containerRef]); - - return { isMobile }; + return { perspective }; }; diff --git a/src/components/cardStack/layouts/timelines/TimelineBase.tsx b/src/components/cardStack/layouts/timelines/TimelineBase.tsx index 6c3930a..c2ef2e8 100644 --- a/src/components/cardStack/layouts/timelines/TimelineBase.tsx +++ b/src/components/cardStack/layouts/timelines/TimelineBase.tsx @@ -1,149 +1,32 @@ -"use client"; - -import React, { Children, useCallback } from "react"; -import { cls } from "@/lib/utils"; -import CardStackTextBox from "../../CardStackTextBox"; -import { useCardAnimation } from "../../hooks/useCardAnimation"; -import type { LucideIcon } from "lucide-react"; -import type { ButtonConfig, CardAnimationType, TitleSegment, ButtonAnimationType } from "../../types"; -import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; - -type TimelineVariant = "timeline"; +import React from 'react'; interface TimelineBaseProps { - children: React.ReactNode; - variant?: TimelineVariant; - uniformGridCustomHeightClasses?: string; - animationType: CardAnimationType; - title?: string; - titleSegments?: TitleSegment[]; - description?: string; - tag?: string; - tagIcon?: LucideIcon; - tagAnimation?: ButtonAnimationType; - buttons?: ButtonConfig[]; - buttonAnimation?: ButtonAnimationType; - textboxLayout?: TextboxLayout; - useInvertedBackground?: InvertedBackground; - className?: string; - containerClassName?: string; - textBoxClassName?: string; - titleClassName?: string; - titleImageWrapperClassName?: string; - titleImageClassName?: string; - descriptionClassName?: string; - tagClassName?: string; - buttonContainerClassName?: string; - buttonClassName?: string; - buttonTextClassName?: string; - ariaLabel?: string; + id: string; + title: string; + description: string; + isActive: boolean; + isPast: boolean; } -const TimelineBase = ({ - children, - variant = "timeline", - uniformGridCustomHeightClasses = "min-h-80 2xl:min-h-90", - animationType, +export const TimelineBase: React.FC = ({ + id, title, - titleSegments, description, - tag, - tagIcon, - tagAnimation, - buttons, - buttonAnimation, - textboxLayout = "default", - useInvertedBackground, - className = "", - containerClassName = "", - textBoxClassName = "", - titleClassName = "", - titleImageWrapperClassName = "", - titleImageClassName = "", - descriptionClassName = "", - tagClassName = "", - buttonContainerClassName = "", - buttonClassName = "", - buttonTextClassName = "", - ariaLabel = "Timeline section", -}: TimelineBaseProps) => { - const childrenArray = Children.toArray(children); - const { itemRefs } = useCardAnimation({ - animationType, - itemCount: childrenArray.length, - isGrid: false - }); - - const getItemClasses = useCallback((index: number) => { - // Timeline variant - scattered/organic pattern - const alignmentClass = - index % 2 === 0 ? "self-start ml-0" : "self-end mr-0"; - - const marginClasses = cls( - index % 4 === 0 && "md:ml-0", - index % 4 === 1 && "md:mr-20", - index % 4 === 2 && "md:ml-15", - index % 4 === 3 && "md:mr-30" - ); - - return cls(alignmentClass, marginClasses); - }, []); + isActive, + isPast, +}) => { + const opacity = isActive ? 'opacity-100' : isPast ? 'opacity-75' : 'opacity-50'; + const scale = isActive ? 'scale-100' : 'scale-95'; return ( -
-
- {(title || titleSegments || description) && ( - - )} -
- {Children.map(childrenArray, (child, index) => ( -
{ itemRefs.current[index] = el; }} - > - {child} -
- ))} -
+
+

{title}

+

{description}

-
+ ); }; - -TimelineBase.displayName = "TimelineBase"; - -export default React.memo(TimelineBase); diff --git a/src/components/sections/contact/ContactCenter.tsx b/src/components/sections/contact/ContactCenter.tsx index e0cae92..f2bf60b 100644 --- a/src/components/sections/contact/ContactCenter.tsx +++ b/src/components/sections/contact/ContactCenter.tsx @@ -1,131 +1,102 @@ "use client"; -import ContactForm from "@/components/form/ContactForm"; -import HeroBackgrounds, { type HeroBackgroundVariantProps } from "@/components/background/HeroBackgrounds"; -import { cls } from "@/lib/utils"; -import { LucideIcon } from "lucide-react"; -import { sendContactEmail } from "@/utils/sendContactEmail"; -import type { ButtonAnimationType } from "@/types/button"; +import React, { useState } from 'react'; +import { Mail, Phone, MapPin } from 'lucide-react'; -type ContactCenterBackgroundProps = 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" } ->; - -interface ContactCenterProps { - title: string; - description: string; - tag: string; - tagIcon?: LucideIcon; - tagAnimation?: ButtonAnimationType; - background: ContactCenterBackgroundProps; - useInvertedBackground: boolean; - tagClassName?: string; - inputPlaceholder?: string; - buttonText?: string; - termsText?: string; - onSubmit?: (email: string) => void; - ariaLabel?: string; - className?: string; - containerClassName?: string; - contentClassName?: string; - titleClassName?: string; - descriptionClassName?: string; - formWrapperClassName?: string; - formClassName?: string; - inputClassName?: string; - buttonClassName?: string; - buttonTextClassName?: string; - termsClassName?: string; +interface ContactFormData { + name: string; + email: string; + message: string; } -const ContactCenter = ({ - title, - description, - tag, - tagIcon, - tagAnimation, - background, - useInvertedBackground, - tagClassName = "", - 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 = "", - titleClassName = "", - descriptionClassName = "", - formWrapperClassName = "", - formClassName = "", - inputClassName = "", - buttonClassName = "", - buttonTextClassName = "", - termsClassName = "", -}: ContactCenterProps) => { +export const ContactCenter: React.FC = () => { + const [formData, setFormData] = useState({ + name: '', + email: '', + message: '', + }); + const [isSubmitted, setIsSubmitted] = useState(false); - const handleSubmit = async (email: string) => { - try { - await sendContactEmail({ email }); - console.log("Email send successfully"); - } catch (error) { - console.error("Failed to send email:", error); - } - }; + const handleChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ ...prev, [name]: value })); + }; - return ( -
-
-
-
- -
-
- -
-
+ const handleFormSubmit = (e: React.FormEvent) => { + e.preventDefault(); + setIsSubmitted(true); + setFormData({ name: '', email: '', message: '' }); + setTimeout(() => setIsSubmitted(false), 3000); + }; + + return ( +
+
+

Get in Touch

+

We'd love to hear from you. Send us a message!

+
+ +
+
+
+ +
+

Email

+

hello@company.com

-
- ); + +
+ +
+

Phone

+

+1 (555) 123-4567

+
+
+
+ +
+

Address

+

123 Main Street, City, State 12345

+
+
+ + +
+ + +