import { useState, useEffect, useRef, forwardRef } from "react"; import { Star, Menu, X, ShoppingBag, ChevronDown, Globe, } from "lucide-react"; import { motion, AnimatePresence } from "motion/react"; import { ImageWithFallback } from "./figma/ImageWithFallback"; import { Button } from "./ui/button"; import { CitySubmenu } from "./CitySubmenu"; import imgRectangle4429 from "figma:asset/43f3bc1f9c8cc5b8f60f3f6be0bc1ad29eded0d7.png"; import cityCardsLogo from "figma:asset/e961451f70697dd054c4240fc1dcad81e08ce31e.png"; // City list data for right sidebar const cityList = [ { id: 1, name: "Sydney", attractions: 65, image: "https://images.unsplash.com/photo-1695018228065-2e0026c654af?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxzeWRuZXklMjBoYXJib3IlMjBicmlkZ2UlMjBvcGVyYSUyMGhvdXNlfGVufDF8fHx8MTc1NjEyNDA2NXww&ixlib=rb-4.1.0&q=80&w=1080", }, { id: 2, name: "Melbourne", attractions: 48, image: "https://images.unsplash.com/photo-1679731980101-503d93bbec27?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjBjb2ZmZWUlMjBsYW5ld2F5c3xlbnwxfHx8fDE3NTYxMjQwNzN8MA&ixlib=rb-4.1.0&q=80&w=1080", }, { id: 3, name: "Brisbane", attractions: 32, image: "https://images.unsplash.com/photo-1548661625-a30d197ce439?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxicmlzYmFuZSUyMHJpdmVyJTIwY2l0eSUyMHNreWxpbmV8ZW58MXx8fHwxNzU2MTI0MDc3fDA&ixlib=rb-4.1.0&q=80&w=1080", }, ]; // Interface for dropdown items interface DropdownItem { id: string; label: string; badge?: string; icon?: React.ReactNode; action?: () => void; } // Forward ref for dropdown component const Dropdown = forwardRef< HTMLDivElement, { isOpen: boolean; onToggle: () => void; items: DropdownItem[]; title: string; trigger: React.ReactNode; } >(({ isOpen, onToggle, items, title, trigger }, ref) => { return (
{trigger}
{isOpen && (

{title}

{items.map((item) => (
{item.icon} {item.label}
{item.badge && ( {item.badge} )}
))}
)}
); }); Dropdown.displayName = "Dropdown"; interface HeroSectionProps { onSignInClick?: () => void; onPassesClick?: () => void; onMelbourneClick?: () => void; onAttractionsClick?: () => void; onHomeClick?: () => void; onBlogsClick?: () => void; onHowItWorksClick?: () => void; currentPage?: string; } export function HeroSection({ onSignInClick, onPassesClick, onMelbourneClick, onAttractionsClick, onHomeClick, onBlogsClick, onHowItWorksClick, currentPage, }: HeroSectionProps) { const [hoveredCity, setHoveredCity] = useState( null, ); const [isScrolled, setIsScrolled] = useState(false); const [activeLanguageDropdown, setActiveLanguageDropdown] = useState(false); const [activeCartDropdown, setActiveCartDropdown] = useState(false); const [scrollY, setScrollY] = useState(0); // Refs for dropdowns and parallax const languageRef = useRef(null); const cartRef = useRef(null); const heroRef = useRef(null); // Sample cart data const [cartItems] = useState([ { id: "1", name: "Melbourne City Card", price: "$49", quantity: 1, }, { id: "2", name: "Sydney City Card", price: "$59", quantity: 1, }, ]); const cartTotal = cartItems.reduce( (sum, item) => sum + parseFloat(item.price.replace("$", "")), 0, ); // Language options const languages = [ { id: "en", label: "English", action: () => console.log("English selected"), }, { id: "es", label: "Español", action: () => console.log("Spanish selected"), }, { id: "fr", label: "Français", action: () => console.log("French selected"), }, { id: "de", label: "Deutsch", action: () => console.log("German selected"), }, ]; // Navigation handlers const handleNavClick = (action: string) => { switch (action) { case "about": console.log("Navigate to About Us"); break; case "products": console.log("Navigate to Cities"); break; case "attractions": if (onAttractionsClick) { onAttractionsClick(); } break; case "card": if (onPassesClick) onPassesClick(); break; case "offer": console.log("Navigate to Deals"); break; default: break; } }; const isNavItemActive = (action: string) => { if (action === "card" && currentPage === "passes") return true; if (action === "about" && currentPage === "home") return true; if (action === "attractions" && currentPage === "attractions") return true; return false; }; // Handle scroll effects with parallax (throttled for performance) useEffect(() => { let ticking = false; const handleScroll = () => { if (!ticking) { requestAnimationFrame(() => { const currentScrollY = window.scrollY; setIsScrolled(currentScrollY > 20); setScrollY(currentScrollY); ticking = false; }); ticking = true; } }; window.addEventListener("scroll", handleScroll, { passive: true, }); return () => window.removeEventListener("scroll", handleScroll); }, []); // Calculate parallax values const scrollProgress = Math.min( scrollY / window.innerHeight, 1, ); const backgroundScale = 1.2 - scrollProgress * 0.2; // Scale from 1.2 to 1 const backgroundY = scrollY * 0.5; // Parallax movement const borderOpacity = 1 - scrollProgress * 0.3; // Border fade effect // Close dropdowns when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( languageRef.current && !languageRef.current.contains(event.target as Node) ) { setActiveLanguageDropdown(false); } if ( cartRef.current && !cartRef.current.contains(event.target as Node) ) { setActiveCartDropdown(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener( "mousedown", handleClickOutside, ); }, []); return (
{/* Background Image with Parallax */} {/* Black Gradient Overlay */}
{/* Main Content Frame with Border Animation */} {/* Glassmorphism Navigation Bar with Menu */} {/* Navigation Content */}
{/* CityCards Logo Section */} onHomeClick?.()} > CityCards {/* Navigation Links */}
{[ { label: "About Us", action: "about" }, { label: "Cities", action: "products" }, { label: "Attractions", action: "attractions" }, { label: "Your Card", action: "card" }, { label: "Deals", action: "offer" }, ].map((item) => ( handleNavClick(item.action)} className={`relative px-0 py-2 text-base font-medium transition-all duration-200 whitespace-nowrap group capitalize ${ isNavItemActive(item.action) ? "text-white" : "text-white/80 hover:text-white" }`} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > {item.label} {/* Active indicator */} {/* Hover background */} ))}
{/* Right Section */}
{/* Language Dropdown */}
setActiveLanguageDropdown( !activeLanguageDropdown, ) } items={languages} title="Select Language" trigger={
ENG
} />
{/* Shopping Cart */}
setActiveCartDropdown(!activeCartDropdown) } items={[ ...cartItems.map((item) => ({ id: item.id, label: `${item.name} - ${item.price}`, badge: `${item.quantity}x`, })), { id: "total", label: `Total: $${cartTotal.toFixed(2)}`, icon: , }, { id: "checkout", label: "Proceed to Checkout", action: () => console.log("Checkout"), }, ]} title="Shopping Cart" trigger={
{cartItems.length}
} />
{/* Mobile Menu Button */}
{/* CTA Button */}
{/* City Submenu */} {}} // Empty function since it's always shown on homepage currentPage={currentPage} onHomeClick={onHomeClick} onMelbourneClick={onMelbourneClick} onAttractionsClick={onAttractionsClick} onPassesClick={onPassesClick} onBlogsClick={onBlogsClick} onHowItWorksClick={onHowItWorksClick} /> {/* Main Content Container */}
{/* Left Content */}
{/* Main Headline */}

Melbourne{' '} City{' '} Card.

See{' '} More{', '} Spend{' '} Less{'.'}

Instant QR access to 40+ attractions, exclusive perks, and savings up to 30%

{/* CTA Button */}
{/* Right Side City List */}
{cityList.map((city, index) => ( setHoveredCity(city.id)} onMouseLeave={() => setHoveredCity(null)} initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} transition={{ duration: 0.6, delay: 0.6 + index * 0.1, }} > {/* City Name */}
— {city.name}
{/* Hover Card */} {hoveredCity === city.id && (
{/* Image */}
{/* Content */}

{city.name}

{city.attractions} attractions

Discover the best experiences

{/* Arrow Pointer */}
)} ))}
); }