|
|
|
|
@@ -3,102 +3,103 @@ import { ImageWithFallback } from './figma/ImageWithFallback';
|
|
|
|
|
import { Button } from './ui/button';
|
|
|
|
|
import { useRef, useState, useEffect } from 'react';
|
|
|
|
|
import Image592Traced from '../imports/Image592Traced-5025-559';
|
|
|
|
|
import { useGetUpcomingCitiesQuery } from '../Redux/services/cities.service';
|
|
|
|
|
|
|
|
|
|
const upcomingCities = [
|
|
|
|
|
{
|
|
|
|
|
id: 1,
|
|
|
|
|
name: 'Boston',
|
|
|
|
|
country: 'USA',
|
|
|
|
|
launchDate: 'Spring 2025',
|
|
|
|
|
attractions: 65,
|
|
|
|
|
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1568271667303-14b2a1a36da1?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
name: 'Rome',
|
|
|
|
|
country: 'Italy',
|
|
|
|
|
launchDate: 'Summer 2025',
|
|
|
|
|
attractions: 80,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1552832230-c0197dd311b5?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
name: 'Paris',
|
|
|
|
|
country: 'France',
|
|
|
|
|
launchDate: 'Fall 2025',
|
|
|
|
|
attractions: 95,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1502602898536-47ad22581b52?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 4,
|
|
|
|
|
name: 'Dubai',
|
|
|
|
|
country: 'UAE',
|
|
|
|
|
launchDate: 'Winter 2025',
|
|
|
|
|
attractions: 70,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1512453979798-5ea266f8880c?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false,
|
|
|
|
|
badge: 'New'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 5,
|
|
|
|
|
name: 'Tokyo',
|
|
|
|
|
country: 'Japan',
|
|
|
|
|
launchDate: 'Early 2026',
|
|
|
|
|
attractions: 120,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1540959733332-eab4deabeeaf?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 6,
|
|
|
|
|
name: 'Sydney',
|
|
|
|
|
country: 'Australia',
|
|
|
|
|
launchDate: 'Spring 2026',
|
|
|
|
|
attractions: 85,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 7,
|
|
|
|
|
name: 'New York',
|
|
|
|
|
country: 'USA',
|
|
|
|
|
launchDate: 'Summer 2026',
|
|
|
|
|
attractions: 150,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false,
|
|
|
|
|
badge: 'Most Requested'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 8,
|
|
|
|
|
name: 'Singapore',
|
|
|
|
|
country: 'Singapore',
|
|
|
|
|
launchDate: 'Fall 2026',
|
|
|
|
|
attractions: 75,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1525625293386-3f8f99389edd?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 9,
|
|
|
|
|
name: 'Amsterdam',
|
|
|
|
|
country: 'Netherlands',
|
|
|
|
|
launchDate: 'Winter 2026',
|
|
|
|
|
attractions: 90,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1534351590666-13e3e96b5017?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 10,
|
|
|
|
|
name: 'Barcelona',
|
|
|
|
|
country: 'Spain',
|
|
|
|
|
launchDate: 'Early 2027',
|
|
|
|
|
attractions: 110,
|
|
|
|
|
image: 'https://images.unsplash.com/photo-1583422409516-2895a77efded?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
showHoverState: false
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
// const upcomingCities = [
|
|
|
|
|
// {
|
|
|
|
|
// id: 1,
|
|
|
|
|
// name: 'Boston',
|
|
|
|
|
// country: 'USA',
|
|
|
|
|
// launchDate: 'Spring 2025',
|
|
|
|
|
// attractions: 65,
|
|
|
|
|
// description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1568271667303-14b2a1a36da1?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: true
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 2,
|
|
|
|
|
// name: 'Rome',
|
|
|
|
|
// country: 'Italy',
|
|
|
|
|
// launchDate: 'Summer 2025',
|
|
|
|
|
// attractions: 80,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1552832230-c0197dd311b5?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 3,
|
|
|
|
|
// name: 'Paris',
|
|
|
|
|
// country: 'France',
|
|
|
|
|
// launchDate: 'Fall 2025',
|
|
|
|
|
// attractions: 95,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1502602898536-47ad22581b52?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 4,
|
|
|
|
|
// name: 'Dubai',
|
|
|
|
|
// country: 'UAE',
|
|
|
|
|
// launchDate: 'Winter 2025',
|
|
|
|
|
// attractions: 70,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1512453979798-5ea266f8880c?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false,
|
|
|
|
|
// badge: 'New'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 5,
|
|
|
|
|
// name: 'Tokyo',
|
|
|
|
|
// country: 'Japan',
|
|
|
|
|
// launchDate: 'Early 2026',
|
|
|
|
|
// attractions: 120,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1540959733332-eab4deabeeaf?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 6,
|
|
|
|
|
// name: 'Sydney',
|
|
|
|
|
// country: 'Australia',
|
|
|
|
|
// launchDate: 'Spring 2026',
|
|
|
|
|
// attractions: 85,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 7,
|
|
|
|
|
// name: 'New York',
|
|
|
|
|
// country: 'USA',
|
|
|
|
|
// launchDate: 'Summer 2026',
|
|
|
|
|
// attractions: 150,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1496442226666-8d4d0e62e6e9?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false,
|
|
|
|
|
// badge: 'Most Requested'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 8,
|
|
|
|
|
// name: 'Singapore',
|
|
|
|
|
// country: 'Singapore',
|
|
|
|
|
// launchDate: 'Fall 2026',
|
|
|
|
|
// attractions: 75,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1525625293386-3f8f99389edd?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 9,
|
|
|
|
|
// name: 'Amsterdam',
|
|
|
|
|
// country: 'Netherlands',
|
|
|
|
|
// launchDate: 'Winter 2026',
|
|
|
|
|
// attractions: 90,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1534351590666-13e3e96b5017?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 10,
|
|
|
|
|
// name: 'Barcelona',
|
|
|
|
|
// country: 'Spain',
|
|
|
|
|
// launchDate: 'Early 2027',
|
|
|
|
|
// attractions: 110,
|
|
|
|
|
// image: 'https://images.unsplash.com/photo-1583422409516-2895a77efded?ixlib=rb-4.0.3&auto=format&fit=crop&w=600&q=80',
|
|
|
|
|
// showHoverState: false
|
|
|
|
|
// }
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
export function LandingUpcomingCities() {
|
|
|
|
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
@@ -107,6 +108,15 @@ export function LandingUpcomingCities() {
|
|
|
|
|
const [scrollLeft, setScrollLeft] = useState(0);
|
|
|
|
|
const [showDragHint, setShowDragHint] = useState(false);
|
|
|
|
|
|
|
|
|
|
const listType = "upcomingCity"
|
|
|
|
|
// const[listType,setListType]=useState("upcomingCity")
|
|
|
|
|
|
|
|
|
|
const { data, isLoading } = useGetUpcomingCitiesQuery(listType)
|
|
|
|
|
|
|
|
|
|
if(isLoading){
|
|
|
|
|
return <div>Loading...</div>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleMouseDown = (e: React.MouseEvent) => {
|
|
|
|
|
if (!scrollContainerRef.current) return;
|
|
|
|
|
// Only start dragging if not clicking on a button or interactive element
|
|
|
|
|
@@ -143,11 +153,11 @@ export function LandingUpcomingCities() {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleGlobalMouseUp = () => setIsDragging(false);
|
|
|
|
|
document.addEventListener('mouseup', handleGlobalMouseUp);
|
|
|
|
|
return () => document.removeEventListener('mouseup', handleGlobalMouseUp);
|
|
|
|
|
}, []);
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
// const handleGlobalMouseUp = () => setIsDragging(false);
|
|
|
|
|
// document.addEventListener('mouseup', handleGlobalMouseUp);
|
|
|
|
|
// return () => document.removeEventListener('mouseup', handleGlobalMouseUp);
|
|
|
|
|
// }, []);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<section className="py-20 bg-gray-50">
|
|
|
|
|
@@ -172,11 +182,11 @@ export function LandingUpcomingCities() {
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
<div
|
|
|
|
|
ref={scrollContainerRef}
|
|
|
|
|
className={`flex gap-6 overflow-x-auto scrollbar-hide pb-2 ${isDragging ? 'cursor-grabbing dragging select-none' : 'cursor-grab'}`}
|
|
|
|
|
style={{
|
|
|
|
|
scrollbarWidth: 'none',
|
|
|
|
|
style={{
|
|
|
|
|
scrollbarWidth: 'none',
|
|
|
|
|
msOverflowStyle: 'none',
|
|
|
|
|
scrollBehavior: isDragging ? 'auto' : 'smooth',
|
|
|
|
|
paddingLeft: 'max(1rem, calc((100vw - 1280px) / 2 + 1rem))',
|
|
|
|
|
@@ -188,112 +198,112 @@ export function LandingUpcomingCities() {
|
|
|
|
|
onMouseMove={handleMouseMove}
|
|
|
|
|
onMouseEnter={handleMouseEnter}
|
|
|
|
|
>
|
|
|
|
|
{upcomingCities.map((city) => (
|
|
|
|
|
<div
|
|
|
|
|
key={city.id}
|
|
|
|
|
className="flex-shrink-0 w-72 md:w-80 group relative h-[420px] rounded-3xl overflow-hidden shadow-lg hover:shadow-xl transition-all duration-500"
|
|
|
|
|
>
|
|
|
|
|
{/* Background - Either solid color or image */}
|
|
|
|
|
{city.showHoverState ? (
|
|
|
|
|
// Boston card with image background and same layout as other cards
|
|
|
|
|
<>
|
|
|
|
|
<ImageWithFallback
|
|
|
|
|
src={city.image!}
|
|
|
|
|
alt={city.name}
|
|
|
|
|
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* Dark overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent group-hover:from-black/80 transition-all duration-500" />
|
|
|
|
|
|
|
|
|
|
{/* City name overlay - matching Rome card layout */}
|
|
|
|
|
<div className="absolute bottom-6 left-6 right-6 text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.name}</h3>
|
|
|
|
|
<div className="flex items-center justify-between text-sm text-white/80">
|
|
|
|
|
<span>{city.country}</span>
|
|
|
|
|
<span>{city.launchDate}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{data && data?.upcomingCities?.map((city: any) => (
|
|
|
|
|
<div
|
|
|
|
|
key={city.id}
|
|
|
|
|
className="flex-shrink-0 w-72 md:w-80 group relative h-[420px] rounded-3xl overflow-hidden shadow-lg hover:shadow-xl transition-all duration-500"
|
|
|
|
|
>
|
|
|
|
|
{/* Background - Either solid color or image */}
|
|
|
|
|
{true ? (
|
|
|
|
|
// Boston card with image background and same layout as other cards
|
|
|
|
|
<>
|
|
|
|
|
<ImageWithFallback
|
|
|
|
|
src={city.imgPathName!}
|
|
|
|
|
alt={city.cityName}
|
|
|
|
|
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* Hover state overlay - same as other cards */}
|
|
|
|
|
<div className="absolute inset-0 bg-warm-coral/90 opacity-0 group-hover:opacity-100 transition-all duration-500 flex items-center justify-center">
|
|
|
|
|
<div className="text-center text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.name}</h3>
|
|
|
|
|
<p className="text-white/90 mb-4">{city.attractions}+ attractions</p>
|
|
|
|
|
<p className="text-sm text-white/80 mb-6">Coming {city.launchDate}</p>
|
|
|
|
|
<Button
|
|
|
|
|
variant="secondary"
|
|
|
|
|
className="bg-white/20 hover:bg-white/30 text-white border-white/30 hover:border-white/50 backdrop-blur-sm"
|
|
|
|
|
onMouseDown={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setIsDragging(false);
|
|
|
|
|
}}
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
console.log('Notify Me button clicked');
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Notify Me
|
|
|
|
|
<ArrowRight className="w-4 h-4 ml-2" />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
// Image background for other cards
|
|
|
|
|
<>
|
|
|
|
|
<ImageWithFallback
|
|
|
|
|
src={city.image!}
|
|
|
|
|
alt={city.name}
|
|
|
|
|
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* Dark overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent group-hover:from-black/80 transition-all duration-500" />
|
|
|
|
|
|
|
|
|
|
{/* Badge (if present) */}
|
|
|
|
|
{city.badge && (
|
|
|
|
|
<div className="absolute top-4 right-4 bg-white text-gray-900 px-3 py-1 rounded-full text-sm font-medium shadow-lg">
|
|
|
|
|
{city.badge}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{/* Dark overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent group-hover:from-black/80 transition-all duration-500" />
|
|
|
|
|
|
|
|
|
|
{/* City name overlay */}
|
|
|
|
|
<div className="absolute bottom-6 left-6 right-6 text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.name}</h3>
|
|
|
|
|
<div className="flex items-center justify-between text-sm text-white/80">
|
|
|
|
|
<span>{city.country}</span>
|
|
|
|
|
<span>{city.launchDate}</span>
|
|
|
|
|
</div>
|
|
|
|
|
{/* City name overlay - matching Rome card layout */}
|
|
|
|
|
<div className="absolute bottom-6 left-6 right-6 text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.cityName}</h3>
|
|
|
|
|
<div className="flex items-center justify-between text-sm text-white/80">
|
|
|
|
|
{/* <span>{city.country}</span>
|
|
|
|
|
<span>{city.launchDate}</span> */}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Hover state overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/90 to-secondary/90 opacity-0 group-hover:opacity-100 transition-all duration-500 flex items-center justify-center">
|
|
|
|
|
<div className="text-center text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.name}</h3>
|
|
|
|
|
<p className="text-white/90 mb-4">{city.attractions}+ attractions</p>
|
|
|
|
|
<p className="text-sm text-white/80 mb-6">Coming {city.launchDate}</p>
|
|
|
|
|
<Button
|
|
|
|
|
variant="secondary"
|
|
|
|
|
className="bg-white/20 hover:bg-white/30 text-white border-white/30 hover:border-white/50 backdrop-blur-sm"
|
|
|
|
|
onMouseDown={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setIsDragging(false);
|
|
|
|
|
}}
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
console.log('Notify Me button clicked');
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Notify Me
|
|
|
|
|
<ArrowRight className="w-4 h-4 ml-2" />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
{/* Hover state overlay - same as other cards */}
|
|
|
|
|
<div className="absolute inset-0 bg-warm-coral/90 opacity-0 group-hover:opacity-100 transition-all duration-500 flex items-center justify-center">
|
|
|
|
|
<div className="text-center text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.cityName}</h3>
|
|
|
|
|
{/* <p className="text-white/90 mb-4">{city.attractions}+ attractions</p>
|
|
|
|
|
<p className="text-sm text-white/80 mb-6">Coming {city.launchDate}</p> */}
|
|
|
|
|
<Button
|
|
|
|
|
variant="secondary"
|
|
|
|
|
className="bg-white/20 hover:bg-white/30 text-white border-white/30 hover:border-white/50 backdrop-blur-sm"
|
|
|
|
|
onMouseDown={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setIsDragging(false);
|
|
|
|
|
}}
|
|
|
|
|
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
console.log('Notify Me button clicked');
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Notify Me
|
|
|
|
|
<ArrowRight className="w-4 h-4 ml-2" />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
// Image background for other cards
|
|
|
|
|
<>
|
|
|
|
|
<ImageWithFallback
|
|
|
|
|
src={city.image!}
|
|
|
|
|
alt={city.name}
|
|
|
|
|
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* Dark overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent group-hover:from-black/80 transition-all duration-500" />
|
|
|
|
|
|
|
|
|
|
{/* Badge (if present) */}
|
|
|
|
|
{/* {city.badge && (
|
|
|
|
|
<div className="absolute top-4 right-4 bg-white text-gray-900 px-3 py-1 rounded-full text-sm font-medium shadow-lg">
|
|
|
|
|
{city.badge}
|
|
|
|
|
</div>
|
|
|
|
|
)} */}
|
|
|
|
|
|
|
|
|
|
{/* City name overlay */}
|
|
|
|
|
{/* <div className="absolute bottom-6 left-6 right-6 text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.name}</h3>
|
|
|
|
|
<div className="flex items-center justify-between text-sm text-white/80">
|
|
|
|
|
<span>{city.country}</span>
|
|
|
|
|
<span>{city.launchDate}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div> */}
|
|
|
|
|
|
|
|
|
|
{/* Hover state overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/90 to-secondary/90 opacity-0 group-hover:opacity-100 transition-all duration-500 flex items-center justify-center">
|
|
|
|
|
<div className="text-center text-white">
|
|
|
|
|
<h3 className="text-2xl font-bold mb-2">{city.cityName}</h3>
|
|
|
|
|
{/* <p className="text-white/90 mb-4">{city.attractions}+ attractions</p> */}
|
|
|
|
|
{/* <p className="text-sm text-white/80 mb-6">Coming {city.launchDate}</p> */}
|
|
|
|
|
<Button
|
|
|
|
|
variant="secondary"
|
|
|
|
|
className="bg-white/20 hover:bg-white/30 text-white border-white/30 hover:border-white/50 backdrop-blur-sm"
|
|
|
|
|
onMouseDown={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setIsDragging(false);
|
|
|
|
|
}}
|
|
|
|
|
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
console.log('Notify Me button clicked');
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Notify Me
|
|
|
|
|
<ArrowRight className="w-4 h-4 ml-2" />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|