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?.()}
>
{/* 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 */}
console.log('Mobile menu toggled')}
className="text-white/80 hover:text-white p-2"
>
{/* CTA Button */}
GET A CITY CARD
{/* 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 */}
Explore Melbourne
{/* 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 */}
)}
))}
);
}