diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index e110ee0..48a19d1 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -33,6 +33,7 @@ import ComingSoonPage from './pages/ComingSoonPage'; import { SuperSavingsPage } from './components/SuperSavingsPage'; import { WhatsIncluded } from './components/WhatsIncluded'; import { LandingMagicItineraryPage } from './components/LandingMagicItineraryPage'; +import { DiscoverPage } from './components/DiscoverPage'; // User type definition interface User { @@ -160,6 +161,12 @@ export function AppRouter({ } /> + + + + } /> + diff --git a/src/assets/citycards-vid.mp4 b/src/assets/citycards-vid.mp4 new file mode 100644 index 0000000..4d0574b Binary files /dev/null and b/src/assets/citycards-vid.mp4 differ diff --git a/src/components/AttractionsPage.tsx b/src/components/AttractionsPage.tsx index cec7791..66fea7c 100644 --- a/src/components/AttractionsPage.tsx +++ b/src/components/AttractionsPage.tsx @@ -211,7 +211,7 @@ const filterCategories = [ ]; const passTypeCategories = [ - { value: 'selective', label: 'Selective Pass', count: 6 }, + { value: 'selective', label: 'Flexi Pass', count: 6 }, { value: 'unlimited', label: 'Unlimited Pass', count: 6 } ]; @@ -441,7 +441,7 @@ export function AttractionsPage({ ) : ( - Selective Pass + Flexi Pass )} diff --git a/src/components/CityCardsPage.tsx b/src/components/CityCardsPage.tsx index 079d42f..1ae32fa 100644 --- a/src/components/CityCardsPage.tsx +++ b/src/components/CityCardsPage.tsx @@ -138,7 +138,7 @@ export function CityCardsPage({
- {/* Selective Pass */} + {/* Flexi Pass */} - SELECTIVE PASS + Flexi Pass Perfect for travelers who want to explore selected attractions at their own pace with essential features. diff --git a/src/components/CustomPostcards.tsx b/src/components/CustomPostcards.tsx index 85f9779..6562bfe 100644 --- a/src/components/CustomPostcards.tsx +++ b/src/components/CustomPostcards.tsx @@ -999,7 +999,7 @@ export function CustomPostcards() {
+ + + )} + + ) : ( + <> + +
+ + {currentSlideData.subtitle} + +
+

+ {currentSlideData.title === 'AI-Powered Magic Itinerary' ? 'Intelligent Magic Itinerary' : currentSlideData.title} +

+ + {currentSlideData.description} + +
+ {currentSlideData.showButtons && ( + + + + + )} + + )} +
+
+ + + + + {/* How It Works Section */} + {/* How It Works Section - Travel Journal Style */} +
+ {/* Background Texture */} +
+ + {/* Decorative Blobs */} +
+
+ +
+ +
+ Process +
+

+ Start Your + Journey + + + + +

+

+ Three simple steps to unlock the city's best experiences. It's like having a local guide in your pocket. +

+
+ +
+ {/* Central Connecting Line (Desktop) */} +
+ + {steps.map((step, index) => { + const isEven = index % 2 === 0; + + return ( + + {/* Image Side - Polaroid Style - Always on left for odd, right for even */} +
+
+ {/* Washi Tape */} +
+ + {/* Polaroid Frame */} +
+
+
+ +
+
+ + Step {step.number} • {step.title} +
+
+ + {/* Stamp Decoration */} +
+
+
APPROVED
+
CityCards
+
+
+
+
+ + {/* Center Marker (Desktop) */} +
+
+
+ + {/* Text Side - Always on right for odd, left for even */} +
+
+ +
+

+ 0{index + 1}. + {step.title} +

+

+ {step.description} +

+
+
+ ); + })} +
+
+
+ + {/* Why Choose City Cards Section */} +
+ {/* Background Map Decoration */} +
+ +
+ + {/* Floating Travel Icons Background */} +
+ +
+
+ +
+ +
+ +
+ + Why Travelers Choose Us +
+ + Unlock Your + Adventure + + + Travel smarter, not harder. We've curated the ultimate toolkit for modern explorers to experience cities like a local. + +
+ + + {[ + { + type: 'feature', + icon: DollarSign, + title: "Maximum Savings", + subtitle: "Budget Friendly", + desc: "Keep your travel funds for what matters. Save up to 43% compared to buying individual tickets.", + color: "emerald", + badge: "BEST VALUE" + }, + { + type: 'feature', + icon: Zap, + title: "Priority Access", + subtitle: "Skip The Line", + desc: "Feel like a VIP. Walk past the long queues at the most popular landmarks and museums.", + color: "amber", + badge: "TIME SAVER" + }, + { + type: 'image', + image: "https://images.unsplash.com/photo-1768639401082-f45f9241c768?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxoaWRkZW4lMjBnZW0lMjB0cmF2ZWwlMjBzcG90JTIwYmVhdXRpZnVsfGVufDF8fHx8MTc2OTY3MDgzOHww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral", + title: "Hidden Gems", + desc: "Discover secret spots only locals know about.", + badge: "INSIDER TIP" + }, + { + type: 'image', + image: "https://images.unsplash.com/photo-1574178508948-d01c15d33e76?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxkZWxpY2lvdXMlMjBmb29kJTIwdHJhdmVsJTIwZGluaW5nJTIwYWVzdGhldGljfGVufDF8fHx8MTc2OTY3MDgzOHww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral", + title: "Culinary Journey", + desc: "Taste your way through the city with exclusive dining perks.", + badge: "DELICIOUS" + }, + { + type: 'feature', + icon: Palette, + title: "Cultural Deep Dive", + subtitle: "Immersive Tours", + desc: "Connect with the soul of the city through expert-led art, history, and cultural experiences.", + color: "violet", + }, + { + type: 'feature', + icon: Ticket, + title: "All-Digital Pass", + subtitle: "Eco-Friendly", + desc: "Travel light. Your entire trip fits in your pocket with our seamless mobile pass system.", + color: "blue", + } + ].map((item, index) => ( + + {item.type === 'feature' ? ( + <> +
+ +
+
+
+ +
+ {item.badge && ( + + {item.badge} + + )} +
+ +

{item.title}

+

+ {item.subtitle} +

+

+ {item.desc} +

+
+ + ) : ( + <> +
+ +
+
+ +
+ {item.badge && ( +
+ + {item.badge} + +
+ )} +

{item.title}

+

+ {item.desc} +

+
+ + )} +
+ ))} +
+
+
+ + {/* Pass Options Overview - Refactored with RadioGroup and Card Design */} +
+
+ +
+ PRICING PLANS +
+

+ Choose Your + Perfect Pass +

+

+ Flexible options designed to match your travel style. Compare our two pass types and find the perfect fit. +

+
+ +
+ {/* Flexi Card */} + +
+

+ FLEXI CARD +

+

+ Perfect for travelers who want to explore selected attractions at their own pace with essential features. +

+
+ +
    + {[ + 'Access to selected attractions', + 'Limited number of attractions per pass', + 'Flexible validity period', + 'Priority entry where available', + 'Mobile ticket delivery' + ].map((feature) => ( +
  • +
    + +
    + {feature} +
  • + ))} +
+ +
+

+ ✓ Free cancellation up to 24 hours • Instant delivery +

+
+ + +
+ + {/* Unlimited Card */} + + {/* Popular Badge */} +
+
+ Most Popular +
+
+ +
+

+ UNLIMITED CARD +

+

+ The ultimate experience for adventure seekers who want unlimited access to all attractions with premium features. +

+
+ +
    + {[ + 'Unlimited access to all attractions', + 'Time-limited validity (7 days)', + 'Skip-the-line access', + 'Expert guide inclusion', + 'Mobile app access', + 'Premium customer support' + ].map((feature) => ( +
  • +
    + +
    + {feature} +
  • + ))} +
+ +
+

+ ✓ Free cancellation up to 24 hours • Instant delivery +

+
+ + +
+
+
+
+ + + + + {/* CTA Section */} +
+
+
+
+
+ +
+ +

+ Ready to Start Your Adventure? +

+

+ Join millions of travelers who've discovered the smarter way to explore cities +

+ +
+ + +
+
+
+
+ + + + ); +} + +function StepSection({ step, index, onInView }: { step: any, index: number, onInView: (i: number) => void }) { + const isEven = index % 2 === 0; + + return ( + onInView(index)} + > +
+
+ {step.number} +
+

{step.title}

+

{step.description}

+ +
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ ); +} diff --git a/src/components/FAQPage.tsx b/src/components/FAQPage.tsx index 0bab334..58e7197 100644 --- a/src/components/FAQPage.tsx +++ b/src/components/FAQPage.tsx @@ -70,7 +70,7 @@ const faqData: FAQItem[] = [ { id: '2', question: 'What\'s the difference between Selective and Unlimited passes?', - answer: 'Our Selective pass allows you to choose specific attractions you want to visit, perfect for targeted exploration. The Unlimited pass gives you access to all participating attractions in the city during your pass validity period, ideal for comprehensive city discovery.', + answer: 'Our Flexi Pass allows you to choose specific attractions you want to visit, perfect for targeted exploration. The Unlimited pass gives you access to all participating attractions in the city during your pass validity period, ideal for comprehensive city discovery.', category: 'Passes' }, { diff --git a/src/components/HeroBannerCarousel.tsx b/src/components/HeroBannerCarousel.tsx new file mode 100644 index 0000000..af7fb62 --- /dev/null +++ b/src/components/HeroBannerCarousel.tsx @@ -0,0 +1,234 @@ +import { useState, useEffect } from 'react'; +import { motion } from 'motion/react'; +import { ArrowRight } from 'lucide-react'; +import { ImageWithFallback } from './figma/ImageWithFallback'; + +interface HeroBannerCarouselProps { + onCheckoutClick?: () => void; + onPassesClick?: () => void; + onEsimsClick?: () => void; + onHotelDiscountsClick?: () => void; +} + +export function HeroBannerCarousel({ + onCheckoutClick, + onPassesClick, + onEsimsClick, + onHotelDiscountsClick +}: HeroBannerCarouselProps) { + const [currentSlide, setCurrentSlide] = useState(0); + const [isPaused, setIsPaused] = useState(false); + + const slides = [ + { + id: 1, + title: "Discover", + highlight: "Melbourne", + subtitle: "Ultimate Guide to Iconic City", + description: "From Flinders Street to St Kilda Beach: explore the best of Melbourne's landmarks, culture, food and more!", + image: "https://images.unsplash.com/photo-1757470238279-0e9f331d02c9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBza3lsaW5lJTIwc3Vuc2V0fGVufDF8fHx8MTc2MDUwOTIyMHww&ixlib=rb-4.1.0&q=80&w=1080", + cta: "Get Started", + onClick: onCheckoutClick + }, + { + id: 2, + title: "Unlock", + highlight: "City Passes", + subtitle: "Save More, Experience More", + description: "Get unlimited access to top attractions with our flexible city passes. Choose from 1, 2, 3, or 5-day options!", + image: "https://images.unsplash.com/photo-1743441914096-e8f9aaded6f8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxjaXR5JTIwYXR0cmFjdGlvbiUyMHBhc3N8ZW58MXx8fHwxNzYwNTA5MjIxfDA&ixlib=rb-4.1.0&q=80&w=1080", + cta: "Explore Passes", + onClick: onPassesClick + }, + { + id: 3, + title: "Stay", + highlight: "Connected", + subtitle: "Travel eSIMs for Every Journey", + description: "Never lose touch while traveling. Get instant data connectivity in over 190 countries with our eSIM solutions!", + image: "https://images.unsplash.com/photo-1755286218783-5b8334109336?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtb2JpbGUlMjBwaG9uZSUyMHJvYW1pbmd8ZW58MXx8fHwxNzYwNTA5MjIxfDA&ixlib=rb-4.1.0&q=80&w=1080", + cta: "Get eSIM", + onClick: onEsimsClick + }, + { + id: 4, + title: "Exclusive", + highlight: "Hotel Deals", + subtitle: "Luxury Stays at Best Prices", + description: "Book premium hotels at unbeatable rates. Enjoy exclusive discounts on handpicked accommodations worldwide!", + image: "https://images.unsplash.com/photo-1634041441461-a1789d008830?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxsdXh1cnklMjBob3RlbCUyMGV4dGVyaW9yfGVufDF8fHx8MTc2MDQ5NzY1MXww&ixlib=rb-4.1.0&q=80&w=1080", + cta: "View Hotels", + onClick: onHotelDiscountsClick + } + ]; + + // Auto-scroll effect + useEffect(() => { + if (isPaused) return; + + const interval = setInterval(() => { + setCurrentSlide((prev) => (prev + 1) % slides.length); + }, 5000); // Change slide every 5 seconds + + return () => clearInterval(interval); + }, [isPaused, slides.length]); + + const goToSlide = (index: number) => { + setCurrentSlide(index); + }; + + return ( +
setIsPaused(true)} + onMouseLeave={() => setIsPaused(false)} + > + {/* Slides */} + {slides.map((slide, index) => { + return ( + + {/* Left Side - Content Panel (60% width) */} + +
+

+
+ {slide.title} + + {slide.highlight} + +
+
+ {slide.subtitle} +
+

+ +

+ {slide.description} +

+ + +
+
+ + {/* Right Side - Full Height Image (40% width) */} + + + + {/* Subtle overlay for depth */} +
+ + + ); + })} + + {/* Slide Indicators - Bottom Center (All Screens) */} +
+ {slides.map((_, index) => ( + + ))} +
+ + {/* Numbered Slide Navigation - Bottom Left (Desktop) */} +
+
+ {slides.map((slide, index) => ( + + ))} +
+
+
+ ); +} \ No newline at end of file diff --git a/src/components/HotelEsimOffers.tsx b/src/components/HotelEsimOffers.tsx new file mode 100644 index 0000000..09d2085 --- /dev/null +++ b/src/components/HotelEsimOffers.tsx @@ -0,0 +1,325 @@ +import { motion } from 'motion/react'; +import { ArrowRight, Wifi, Hotel } from 'lucide-react'; + +interface HotelEsimOffersProps { + onEsimsClick?: () => void; + onHotelDiscountsClick?: () => void; +} + +export function HotelEsimOffers({ onEsimsClick, onHotelDiscountsClick }: HotelEsimOffersProps) { + return ( +
+
+ + {/* e-SIM Offers Section */} + + {/* Subtle Background Elements */} +
+ + +
+ +
+
+ {/* Header */} + + + + + Stay Connected in Melbourne + + +

+ Travel + Connected +

+

+ Get instant e-SIM connectivity across Australia. Stay online from the moment you land in Melbourne. +

+
+ + {/* Main Card */} + + + +
+ {/* Left Content */} +
+
+ 🇦🇺 AUSTRALIA-WIDE COVERAGE +
+

+ Exclusive e-SIM Offers for Melbourne Visitors +

+

+ No more hunting for local SIM cards at the airport. Activate your e-SIM instantly and explore Melbourne with seamless connectivity. +

+ + + Explore Plans + + + + +
+ + {/* Right Features */} +
+ {[ + { icon: '🌐', label: 'Australia Coverage', value: '100%', unit: 'nationwide' }, + { icon: '⚡', label: 'Instant Setup', value: '< 1', unit: 'minute' }, + { icon: '💰', label: 'Save Up To', value: '85%', unit: 'vs roaming' }, + { icon: '🔒', label: 'Secure', value: '100%', unit: 'encrypted' } + ].map((item, index) => ( + +
{item.icon}
+
{item.value}
+
{item.unit}
+
+ ))} +
+
+
+
+
+
+ + {/* Hotel Discounts Section */} + + {/* Animated Background Elements */} +
+ + +
+ +
+
+ {/* Header */} + + + + + Premium Melbourne Hotels + + +

+ Sleep in + Luxury +

+

+ Unlock exclusive rates at Melbourne's finest hotels. Your CityCard membership opens doors to premium CBD and waterfront stays. +

+
+ + {/* Main Card */} + +
+ {/* Left Content */} +
+
+ 🔥 MARRIOTT BONVOY PARTNER +
+

+ Melbourne Premium Stays at Unbeatable Prices +

+

+ Access exclusive member rates at Melbourne's top hotels including Crown Towers, W Melbourne, and premium CBD properties. Enjoy complimentary upgrades and special amenities. +

+
+ + {/* Right - Savings Badge */} +
+ +
+
25%
+
Average Savings
+
on Melbourne hotels
+
+ + NEW + +
+
+
+ + {/* Features Grid */} +
+ {[ + { icon: '🏆', title: 'Premium Locations', desc: 'CBD, Southbank & St Kilda' }, + { icon: '💎', title: 'Member Perks', desc: 'Free upgrades included' }, + { icon: '⚡', title: 'Instant Booking', desc: 'Confirm in seconds' } + ].map((feature, index) => ( + +
{feature.icon}
+
+

{feature.title}

+

{feature.desc}

+
+
+ ))} +
+ + {/* CTA */} +
+ + View Hotel Deals + + + + +

+ Limited time offer • No booking fees • Best price guarantee +

+
+
+
+
+
+ +
+
+ ); +} diff --git a/src/components/LandingNewsletterSection.tsx b/src/components/LandingNewsletterSection.tsx index bbddb17..d9a4abb 100644 --- a/src/components/LandingNewsletterSection.tsx +++ b/src/components/LandingNewsletterSection.tsx @@ -96,14 +96,14 @@ export function LandingNewsletterSection() {
exclusive offers.
- - We recommend you to subscribe, drop your email below to get daily update about us + Subscribe now and receive 10% off your first purchase! We'll send your exclusive discount code directly to your inbox. diff --git a/src/components/MelbournePage.tsx b/src/components/MelbournePage.tsx index ff44cad..64abd05 100644 --- a/src/components/MelbournePage.tsx +++ b/src/components/MelbournePage.tsx @@ -1,6 +1,6 @@ -import { motion, useAnimationControls } from 'motion/react'; +import { motion, useAnimationControls, AnimatePresence } from 'motion/react'; import { Button } from './ui/button'; -import { ArrowRight, Calendar, Thermometer, Eye } from 'lucide-react'; +import { ArrowRight, Calendar, Thermometer, Eye, MapPin, Clock, Users, Ticket, Wand2, Plane, Sparkles } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; import Navbar from './Navbar'; import { ImageWithFallback } from './figma/ImageWithFallback'; @@ -8,264 +8,116 @@ import { MelbourneAttractions } from './MelbourneAttractions'; import { MelbourneCardComparison } from './MelbourneCardComparison'; import { MelbourneTourOverview } from './MelbourneTourOverview'; import { MelbourneBlogs } from './MelbourneBlogs'; +import { CustomPostcards } from './CustomPostcards'; import { EnhancedTestimonials } from './EnhancedTestimonials'; import { MobileAppPromotion } from './MobileAppPromotion'; import { MelbourneFAQ } from './MelbourneFAQ'; import { Footer } from './Footer'; +import { MinimalHeroBanner } from './MinimalHeroBanner'; import { Layout } from '../Layout'; -import { PersonalizedTourHero } from './PersonalizedTourHero'; +import { HeroBannerCarousel } from './HeroBannerCarousel'; +import { HotelEsimOffers } from './HotelEsimOffers'; interface User { email: string; name: string; } -// Hero Banner Carousel Component -function HeroBannerCarousel({ onCheckoutClick, onPassesClick, onEsimsClick, onHotelDiscountsClick }: { - onCheckoutClick?: () => void; - onPassesClick?: () => void; - onEsimsClick?: () => void; - onHotelDiscountsClick?: () => void; -}) { - const [currentSlide, setCurrentSlide] = useState(0); - const [isPaused, setIsPaused] = useState(false); - - const slides = [ - { - id: 1, - title: "Discover", - highlight: "Melbourne", - subtitle: "Ultimate Guide to Iconic City", - description: "From Flinders Street to St Kilda Beach: explore the best of Melbourne's landmarks, culture, food and more!", - image: "https://images.unsplash.com/photo-1757470238279-0e9f331d02c9?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBza3lsaW5lJTIwc3Vuc2V0fGVufDF8fHx8MTc2MDUwOTIyMHww&ixlib=rb-4.1.0&q=80&w=1080", - cta: "Get Started", - onClick: onCheckoutClick - }, - { - id: 2, - title: "Unlock", - highlight: "City Passes", - subtitle: "Save More, Experience More", - description: "Get unlimited access to top attractions with our flexible city passes. Choose from 1, 2, 3, or 5-day options!", - image: "https://images.unsplash.com/photo-1743441914096-e8f9aaded6f8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxjaXR5JTIwYXR0cmFjdGlvbiUyMHBhc3N8ZW58MXx8fHwxNzYwNTA5MjIxfDA&ixlib=rb-4.1.0&q=80&w=1080", - cta: "Explore Passes", - onClick: onPassesClick - }, - { - id: 3, - title: "Stay", - highlight: "Connected", - subtitle: "Travel eSIMs for Every Journey", - description: "Never lose touch while traveling. Get instant data connectivity in over 190 countries with our eSIM solutions!", - image: "https://images.unsplash.com/photo-1755286218783-5b8334109336?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtb2JpbGUlMjBwaG9uZSUyMHJvYW1pbmd8ZW58MXx8fHwxNzYwNTA5MjIxfDA&ixlib=rb-4.1.0&q=80&w=1080", - cta: "Get eSIM", - onClick: onEsimsClick - }, - { - id: 4, - title: "Exclusive", - highlight: "Hotel Deals", - subtitle: "Luxury Stays at Best Prices", - description: "Book premium hotels at unbeatable rates. Enjoy exclusive discounts on handpicked accommodations worldwide!", - image: "https://images.unsplash.com/photo-1634041441461-a1789d008830?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxsdXh1cnklMjBob3RlbCUyMGV4dGVyaW9yfGVufDF8fHx8MTc2MDQ5NzY1MXww&ixlib=rb-4.1.0&q=80&w=1080", - cta: "View Hotels", - onClick: onHotelDiscountsClick - } - ]; - - // Auto-scroll effect - useEffect(() => { - if (isPaused) return; - - const interval = setInterval(() => { - setCurrentSlide((prev) => (prev + 1) % slides.length); - }, 5000); // Change slide every 5 seconds - - return () => clearInterval(interval); - }, [isPaused, slides.length]); - - const goToSlide = (index: number) => { - setCurrentSlide(index); - }; - - return ( -
setIsPaused(true)} - onMouseLeave={() => setIsPaused(false)} - > - {/* Slides */} - {slides.map((slide, index) => { - return ( - - {/* Left Side - Content Panel (60% width) */} - -
-

-
- {slide.title} - - {slide.highlight} - -
-
- {slide.subtitle} -
-

- -

- {slide.description} -

- - -
-
- - {/* Right Side - Full Height Image (40% width) */} - - - - {/* Subtle overlay for depth */} -
- - - ); - })} - - {/* Slide Indicators - Bottom Center (All Screens) */} -
- {slides.map((_, index) => ( - - ))} -
- - {/* Numbered Slide Navigation - Bottom Left (Desktop) */} -
-
- {slides.map((slide, index) => ( - - ))} -
-
-
- ); -} - interface MelbournePageProps { - onBackClick?: () => void; - onHomeClick?: () => void; - onAttractionsClick?: () => void; - onPassesClick?: () => void; + onBackClick: () => void; + onHomeClick: () => void; + onAttractionsClick: () => void; + onPassesClick: () => void; onCheckoutClick?: () => void; - onSignInClick?: () => void; + onSignInClick: () => void; onSignOutClick?: () => void; - onBlogsClick?: () => void; - onHowItWorksClick?: () => void; - onFAQClick?: () => void; - onPrivacyPolicyClick?: () => void; - onAboutUsClick?: () => void; + onBlogsClick: () => void; + onHowItWorksClick: () => void; + onFAQClick: () => void; + onPrivacyPolicyClick: () => void; + onAboutUsClick: () => void; onProfileClick?: () => void; onCityCardsClick?: () => void; onMagicItineraryClick?: () => void; + onSuperSavingsClick?: () => void; onPostCardsClick?: () => void; onOffersClick?: () => void; onEsimsClick?: () => void; onHotelDiscountsClick?: () => void; onContactUsClick?: () => void; + onCreateItineraryClick?: () => void; currentPage?: string; user?: User | null; } +interface ItineraryCard { + id: number; + city: string; + country: string; + days: number; + image: string; + highlights: string[]; + activities: { name: string; time: string }[]; +} + +const itineraryCards: ItineraryCard[] = [ + { + id: 1, + city: 'Melbourne', + country: 'Australia', + days: 3, + image: 'https://images.unsplash.com/photo-1720044282356-e319c686d209?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBjaXR5JTIwbGFuZG1hcmt8ZW58MXx8fHwxNzY5MTUwMzA5fDA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral', + highlights: ['Coffee Culture', 'Street Art', 'Rooftop Bars'], + activities: [ + { name: 'Breakfast at Higher Ground', time: '09:00 AM' }, + { name: 'Explore Hosier Lane', time: '11:00 AM' }, + { name: 'Royal Botanic Gardens', time: '02:00 PM' }, + { name: 'Sunset at Eureka Skydeck', time: '06:00 PM' } + ] + }, + { + id: 2, + city: 'Sydney', + country: 'Australia', + days: 4, + image: 'https://images.unsplash.com/photo-1523059623039-a9ed027e7fad?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxTeWRuZXklMjBvcGVyYSUyMGhvdXNlfGVufDF8fHx8MTc2OTE1MDMwOXww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral', + highlights: ['Opera House', 'Bondi Beach', 'Harbour Bridge'], + activities: [ + { name: 'Opera House Tour', time: '10:00 AM' }, + { name: 'Walk the Harbour Bridge', time: '01:00 PM' }, + { name: 'Ferry to Manly', time: '03:30 PM' }, + { name: 'Dinner at The Rocks', time: '07:00 PM' } + ] + }, + { + id: 3, + city: 'Gold Coast', + country: 'Australia', + days: 5, + image: 'https://images.unsplash.com/photo-1611473247871-8a4ef64d17ee?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxHb2xkJTIwQ29hc3QlMjBiZWFjaCUyMGF1c3RyYWxpYXxlbnwxfHx8fDE3NjkxNTAzMDl8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral', + highlights: ['Surfers Paradise', 'Theme Parks', 'Rainforest'], + activities: [ + { name: 'Surf Lesson', time: '08:00 AM' }, + { name: 'Q1 Observation Deck', time: '12:00 PM' }, + { name: 'Currumbin Sanctuary', time: '02:00 PM' }, + { name: 'Sunset Cruise', time: '05:30 PM' } + ] + }, + { + id: 4, + city: 'Cairns', + country: 'Australia', + days: 4, + image: 'https://images.unsplash.com/photo-1710171781154-678ede6f39a3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxDYWlybnMlMjBncmVhdCUyMGJhcnJpZXIlMjByZWVmfGVufDF8fHx8MTc2OTE1MDMwOXww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral', + highlights: ['Great Barrier Reef', 'Daintree', 'Esplanade'], + activities: [ + { name: 'Reef Snorkeling', time: '09:00 AM' }, + { name: 'Lunch on the Boat', time: '01:00 PM' }, + { name: 'Esplanade Lagoon', time: '04:00 PM' }, + { name: 'Night Market', time: '07:00 PM' } + ] + } +]; export function MelbournePage({ onBackClick, @@ -283,100 +135,674 @@ export function MelbournePage({ onProfileClick, onCityCardsClick, onMagicItineraryClick, + onSuperSavingsClick, onPostCardsClick, onOffersClick, onEsimsClick, onHotelDiscountsClick, onContactUsClick, + onCreateItineraryClick, currentPage, user }: MelbournePageProps) { + // Magic Itinerary state + const [currentCardIndex, setCurrentCardIndex] = useState(0); + const [isAnimating, setIsAnimating] = useState(false); + + const currentCard = itineraryCards[currentCardIndex]; + const nextCard = itineraryCards[(currentCardIndex + 1) % itineraryCards.length]; + const thirdCard = itineraryCards[(currentCardIndex + 2) % itineraryCards.length]; + return ( - -
+
+ {/* Navigation */} + {/* Hero Banner Carousel */} - - {/* */} + + {/* Main Content */} -
-
+
+ {/* Sticky Page Navigation */} +
+
+ {/* horizontal scroll wrapper */} +
+ {/* actual flex row */} +
+ {[ + { id: 'overview', label: 'Overview', icon: MapPin }, + { id: 'attractions', label: 'Attractions', icon: Eye }, + { id: 'passes', label: 'City Pass', icon: Ticket }, + { id: 'tours', label: 'Tours', icon: Plane }, + { id: 'itinerary', label: 'Itinerary', icon: Wand2 }, + { id: 'faq', label: 'FAQ', icon: Sparkles } + ].map((item) => ( + + ))} +
+
+
+
+ + +
{/* Features Grid */} {[ { - title: "50+ Attractions", - description: "Access to Melbourne's top museums, galleries, and experiences", - icon: "🏛️" + title: "50+ Top Attractions", + description: "Unlimited access to Melbourne's finest museums, zoos, and observation decks.", + icon: MapPin, + color: "text-blue-500", + bg: "bg-blue-50" }, { - title: "Instant QR Access", - description: "Skip the lines with digital tickets on your phone", - icon: "📱" + title: "Instant Digital Entry", + description: "Skip the ticket lines with a simple scan of your mobile pass.", + icon: Ticket, + color: "text-primary", + bg: "bg-primary/10" }, { - title: "Save up to 50%", - description: "Exclusive discounts and special offers for cardholders", - icon: "💰" + title: "Save over 50%", + description: "Enjoy massive savings compared to buying individual attraction tickets.", + icon: Sparkles, + color: "text-emerald-500", + bg: "bg-emerald-50" } ].map((feature, index) => ( -
{feature.icon}
-

- {feature.title} -

-

- {feature.description} -

+
+ +
+

{feature.title}

+

{feature.description}

))}
+ + {/* Attractions Section */} +
+ { }} /> +
+ + {/* Pass Comparison */} +
+ { }} /> +
+ + {/* Tour Overview */} +
+ +
+ + {/* Hotel & eSIM Offers */} +
+ +
+ + {/* Blogs */} +
+ { }} /> +
+ + {/* Custom Postcards */} + +
+ + {/* Magic Itinerary Section */} +
+
+ {/* Dynamic City Background */} + + + {/* City Background Image */} +
+ +
+ + {/* Lightened Multi-layer Gradient Overlay - Reduced opacity to show city */} +
+
+
+ + + + {/* White Readability Overlay - 42% Opacity */} +
+ + {/* Simplified Decorative Elements - Optimized */} +
+ {/* Single Coral Gradient Blob - Optimized */} + + + {/* Simplified Floating Icons - Reduced from 8 to 4 */} + {[...Array(4)].map((_, i) => ( + + {i % 2 === 0 ? ( + + ) : ( + + )} + + ))} +
+ +
+ {/* Header */} +
+ + + + + AI-Powered Magic Itinerary + + + + + Plan Your{' '} + + Dream Journey + +
+ in Just{' '} + 3 Seconds + + ✨ + +
+ + + Our AI creates personalized itineraries with + perfectly timed activities, optimized routes, and curated experiences tailored + just for you. + +
+ + {/* Card Stack Display */} +
+
+ {/* Card Stack Container */} +
+ {/* Visible Card Stack - Third Card */} + +
+ +
+
+

+ {thirdCard.city} +

+
+
+ + + {/* Visible Card Stack - Second Card */} + +
+ +
+
+

+ {nextCard.city} +

+
+
+ + + {/* Animated Front Card */} + + + {/* Card Image */} +
+ +
+ + {/* City Info Overlay */} + +

+ {currentCard.city} +

+

+ + {currentCard.country} +

+
+ + {/* Duration Badge */} + +
+ + {currentCard.days} Days +
+
+ + {/* Top Left Journey Icon */} + + + +
+ + {/* Card Content */} + + {/* Highlights - Compact */} + + {currentCard.highlights.map((highlight, idx) => ( + + {highlight} + + ))} + + + {/* Day 1 Header */} + +
+ + Day 1 +
+
+ + + {/* Day 1 Activities - Compact */} + + {currentCard.activities.slice(0, 2).map((activity, idx) => ( +
+ {idx < 1 && ( +
+ )} + +
+
+ {idx + 1} +
+
+
+ +
+

{activity.name}

+
+ + {activity.time} +
+
+
+ ))} + + + {/* Day 2 Header */} + +
+ + Day 2 +
+
+ + + {/* Day 2 Activities - Compact */} + + {currentCard.activities.slice(2, 4).map((activity, idx) => ( +
+ {idx < 1 && ( +
+ )} + +
+
+ {idx + 1} +
+
+
+ +
+

{activity.name}

+
+ + {activity.time} +
+
+
+ ))} + + + + + + {/* Optimized Floating Sparkles */} + {[...Array(3)].map((_, i) => ( + + + + ))} +
+
+ + {/* Card Indicators with City Names */} + + {itineraryCards.map((card, idx) => ( + { + setIsAnimating(true); + setTimeout(() => { + setCurrentCardIndex(idx); + setIsAnimating(false); + }, 400); + }} + className={`font-poppins group relative transition-all duration-300 px-4 py-2 rounded-full font-medium ${idx === currentCardIndex + ? 'bg-gradient-to-r from-primary to-orange-500 text-white shadow-lg scale-110' + : 'bg-white/80 backdrop-blur-sm text-gray-600 hover:text-primary hover:bg-white border border-gray-200 hover:border-primary/30 hover:scale-105' + }`} + whileHover={{ y: -2 }} + whileTap={{ scale: 0.95 }} + > + {card.city} + {idx === currentCardIndex && ( + + )} + + ))} + + + {/* CTA Button */} + + + +

+ + Free to use • No credit card required + +

+
+
+
+
+
+ +
+ {/* Testimonials */} + + + {/* Mobile App Promotion */} + + + {/* FAQ */} +
+ +
- - {/* Melbourne Attractions Section */} - - - {/* Melbourne Card Comparison Section */} - - - {/* Melbourne Tour Overview Section */} - - - {/* Melbourne Blogs Section */} - - - {/* Enhanced Testimonials Section */} - - - {/* Mobile App Promotion Section */} - - - {/* Melbourne FAQ Section */} - -
- + +
); } \ No newline at end of file diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index fd75953..90bda91 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -93,7 +93,7 @@ export default function Navbar({ // Position 1 - Shared item { label: 'Discover', - path: '/how-it-works', + path: '/discover', isShared: true, landingLabel: 'Discover', melbourneLabel: 'How It Works' @@ -535,7 +535,7 @@ export default function Navbar({ ? 'Melbourne CityCards Logo' : 'CityCards Logo' } - className="h-10 w-auto" + className="h-14 w-auto" /> diff --git a/src/components/PassesPage.tsx b/src/components/PassesPage.tsx index 2b0b66f..dcc5f85 100644 --- a/src/components/PassesPage.tsx +++ b/src/components/PassesPage.tsx @@ -10,6 +10,7 @@ import { Footer } from './Footer'; import { ReviewsSection } from './ReviewsSection'; import { Layout } from '../Layout'; import { LoginModal } from './LoginModal'; +import { ImageWithFallback } from './figma/ImageWithFallback'; interface PassesPageProps { onCheckoutClick?: () => void; @@ -45,7 +46,7 @@ interface PassType { const passTypes: PassType[] = [ { id: 'selective', - name: 'Selective Pass', + name: 'Flexi Pass', title: 'Flexi Card', description: 'Perfect for travelers who want to explore selected attractions at their own pace with essential features.', price: '$59.99', @@ -211,20 +212,21 @@ export function PassesPage({ {/* Pass Comparison Section */}
- {passTypes.map((pass) => (
- - + + {/* Popular Badge */} {pass.popular && (
@@ -249,6 +251,40 @@ export function PassesPage({ + {/* Attraction Images Grid */} +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ {/* Pricing Section - Fixed Height */}
@@ -264,7 +300,7 @@ export function PassesPage({ )}
- + {/* Content - Flexible Height with Fixed Features Area */} {/* Features List - Fixed height */} @@ -279,18 +315,19 @@ export function PassesPage({
- {/* ✅ UPDATED: CTA Button with login logic */} + {/* CTA Button - Pushed to bottom */}
- - +

✓ Free cancellation up to 24 hours • Instant delivery

@@ -302,6 +339,136 @@ export function PassesPage({
+ {/* Good to Know Section */} +
+
+

+ Good to{' '} + Know +

+

+ Simple tips to help you get the most out of your CityCard experience +

+
+ +
+
+ + {/* Left Column: The Rules */} +
+ + {/* Rule 1: Calendar Days */} +
+
+ +
+
+ +
+
+

Calendar Days Policy

+

+ Unlimited passes work on a consecutive calendar day basis, not 24-hour periods. Your pass expires at 11:59 PM on your final day. +

+ + {/* Visual Timeline Example */} +
+
+
Start
+
Monday 4:30 PM
+
First scan
+
+
+
3 Days
+
+
+
+
+
+
End
+
Wednesday 11:59 PM
+
Expiration
+
+
+
+
+
+ + {/* Rule 2: Fair Use */} +
+
+ +
+
+ +
+
+

60-Minute Adventure Gap

+

+ To keep the journey smooth for everyone, there's a simple 60-minute wait between scanning your pass at attractions. +

+
+ + Perfect for grabbing a coffee or traveling to your next stop! +
+
+
+
+
+ + {/* Right Column: The "Card Types" Summary */} +
+
+ {/* Abstract Shapes */} +
+
+ +
+

Your Pass, Your Way

+

Choose the flexibility that matches your travel style.

+ +
+ {/* Flex Option - White Card */} +
+
+
+ Flexi Card + Casual +
+

Best for visiting specific attractions at your own pace.

+
+ {[3, 5, 7].map(n => ( +
{n}
+ ))} + Attractions +
+
+ + {/* Unlimited Option - White Card with Highlight */} +
+
POPULAR
+
+
+ Unlimited Card + Power User +
+

Unlimited access for full days of exploration.

+
+ {[2, 3, 5, 7].map(n => ( +
{n}
+ ))} + Days +
+
+
+
+
+
+ +
+
+
+ {/* Detailed Features Comparison Table */} @@ -319,8 +486,8 @@ export function PassesPage({ Features - Selective Pass - Premium Unlimited + Flexi Pass + Unlimited Pass diff --git a/src/components/PersonalizedTourHero.tsx b/src/components/PersonalizedTourHero.tsx index 104b783..e5026cf 100644 --- a/src/components/PersonalizedTourHero.tsx +++ b/src/components/PersonalizedTourHero.tsx @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'motion/react'; import { Sparkles, MapPin, Calendar, Wand2, Clock } from 'lucide-react'; // import { ImageWithFallback } from './figma/ImageWithFallback'; -import cityTourVideo from '../assets/itinenary-animation-vid.mp4'; +import cityTourVideo from '../assets/citycards-vid.mp4'; interface PersonalizedTourHeroProps { onCreateItineraryClick?: () => void; diff --git a/src/components/ProfilePage.tsx b/src/components/ProfilePage.tsx index 63894c2..02842d6 100644 --- a/src/components/ProfilePage.tsx +++ b/src/components/ProfilePage.tsx @@ -89,7 +89,7 @@ const mockPasses = [ id: '2', name: 'Melbourne Selective Card', city: 'Melbourne', - type: 'Selective Pass', + type: 'Flexi Pass', status: 'active', price: 89.00, originalPrice: 149.00, @@ -383,7 +383,7 @@ export function ProfilePage({ {(() => { // Determine which pass type to show const hasUnlimitedPass = activePasses.some(pass => pass.type === 'Unlimited Pass'); - const hasSelectivePass = activePasses.some(pass => pass.type === 'Selective Pass'); + const hasSelectivePass = activePasses.some(pass => pass.type === 'Flexi Pass'); if (hasUnlimitedPass) { return ( diff --git a/src/components/SuperSavingsPage.tsx b/src/components/SuperSavingsPage.tsx index 714d066..4124ccc 100644 --- a/src/components/SuperSavingsPage.tsx +++ b/src/components/SuperSavingsPage.tsx @@ -535,130 +535,196 @@ export function SuperSavingsPage({ {/* How It Works Section */} -
-
+
+ {/* Background decorative elements */} +
+
+ +
-

- How{' '} - - It Works - +
+
+ Simple Process +
+
+

+ Start Saving in Minutes

-

- Access massive discounts in three simple steps +

+ Your journey to smarter travel and bigger savings begins with three simple steps.

-
- {[ - { - step: '01', - title: 'Get Your Pass', - description: 'Purchase a CityCards pass and unlock instant access', - icon: '🎫' - }, - { - step: '02', - title: 'Browse Deals', - description: 'Explore hundreds of exclusive super savings across categories', - icon: '💎' - }, - { - step: '03', - title: 'Save Big', - description: 'Enjoy discounts up to 65% on premium experiences', - icon: '🎉' - } - ].map((item, index) => ( - - -
{item.icon}
-
- {item.step} +
+ {/* Connecting line for desktop */} +
+ +
+ {[ + { + step: '01', + title: 'Unlock Access', + description: 'Get your CityCards pass to instantly activate membership perks.', + icon: MapPinned + }, + { + step: '02', + title: 'Discover Deals', + description: 'Browse exclusive offers on hotels, flights, and experiences.', + icon: Search + }, + { + step: '03', + title: 'Enjoy Savings', + description: 'Redeem discounts instantly and watch your travel budget grow.', + icon: Percent + } + ].map((item, index) => ( + +
+ {/* Icon Container */} +
+
+
+ +
+
+ {index + 1} +
+
+ +

+ {item.title} +

+

+ {item.description} +

-

- {item.title} -

-

- {item.description} -

- -
- ))} + + ))} +
+ +
{/* Categories Section */} -
-
- -

- - Top Categories - {' '} - to Save -

-

- From luxury hotels to exciting tours, find massive savings on everything you love -

-
+
+ {/* Abstract Travel Patterns */} +
-
+
+ {/* Section Header */} +
+ +
+
+ Explore Collections +
+

+ Curated for the Modern Traveler +

+

+ Discover exclusive savings across our most sought-after travel categories. +

+
+ + + + +
+ + {/* Bento Grid Layout */} +
{categoriesData.map((category, index) => ( - -
- +
+ {/* Background Gradient Hover */} +
+ + {/* Large Watermark Icon for visual depth */} + + +
+
+
+ +
+ + {category.savings} + +
+ +

+ {category.title} +

+

+ {category.description} +

-

- {category.title} -

-

- {category.description} -

-
- - {category.savings} - - + +
+ Explore Deals +
- +
))}
-
+ {/* Mobile View All Button */} +
diff --git a/src/pages/landingPage.tsx b/src/pages/landingPage.tsx index 3e7b8d2..fc9a777 100644 --- a/src/pages/landingPage.tsx +++ b/src/pages/landingPage.tsx @@ -107,79 +107,60 @@ export function LandingPage({ onSignInClick, onClose={() => { }} /> */} {/* Hero Section */} -
+
+ - {/* Overlay */} -
+ {/* Main Headline */} +
+

+ CityCards. + See More, Spend Less. +

+
-
- - {/* Main Headline */} -
-

- CityCards. - See More, Spend Less. -

-
+ {/* Subheading */} +
+

+ Instant QR access to 40+ attractions, +
+ exclusive perks, and save up to 50-60% +

+
- {/* Subheading */} -
-

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

-
- - {/* CTA Button */} - - - - - -
-
- - {/* Scroll Indicator */} - + - -
+ Explore Cities + + + +
+
{/* Features Section */} @@ -194,7 +175,6 @@ export function LandingPage({ onSignInClick, {/* CustomPostcards Section */} - {/* */} {/* UpcomingCities Section */}