From 743462d088ab14f73b2c465d9bae2150933874ad Mon Sep 17 00:00:00 2001 From: aryabenade Date: Wed, 15 Apr 2026 11:07:13 +0530 Subject: [PATCH] make the card comparison section in selected city page dynamic --- src/Redux/services/cities.service.ts | 6 +- src/components/MelbourneCardComparison.tsx | 156 ++++++++++++++------- src/components/Navbar.tsx | 19 ++- src/pages/MelbournePage.tsx | 26 ++-- 4 files changed, 137 insertions(+), 70 deletions(-) diff --git a/src/Redux/services/cities.service.ts b/src/Redux/services/cities.service.ts index e1dfb06..9754016 100644 --- a/src/Redux/services/cities.service.ts +++ b/src/Redux/services/cities.service.ts @@ -23,8 +23,12 @@ export const citiesApi = createApi({ query: (listType) => `/cities/list/all?listType=${listType}`, + }), + + getSelectedCityDetails:builder.query({ + query: (cityId) => `/website/${cityId}`, }) }), }); -export const { useGetCityListWithBannerQuery,useGetUpcomingCitiesQuery } = citiesApi; \ No newline at end of file +export const { useGetCityListWithBannerQuery,useGetUpcomingCitiesQuery,useGetSelectedCityDetailsQuery } = citiesApi; \ No newline at end of file diff --git a/src/components/MelbourneCardComparison.tsx b/src/components/MelbourneCardComparison.tsx index d12ac03..e32bdaa 100644 --- a/src/components/MelbourneCardComparison.tsx +++ b/src/components/MelbourneCardComparison.tsx @@ -3,52 +3,52 @@ import { Check, X, Star, Users, MapPin, Calendar, Clock, Zap, Eye } from 'lucide import { Button } from './ui/button'; import { motion } from 'motion/react'; -const cardOptions = [ - { - id: 'selective', - name: 'Flexi Card', - subtitle: 'Pick 5-10 things to do from a choice of 102 attractions tours and activities', - priceRange: '$89-159', - duration: '3-7 days', - popular: false, - color: 'from-blue-500 to-cyan-500', - features: { - passCategory: 'Selective Card', - accessToAttractions: true, - entryToAttractions: true, - accessToExperiences: true, - entryToSites: true, - accessToVenues: false, - entryToEvents: 'Pass Category', - accessToLocations: 'Pass Category', - entryToActivities: true, - accessToExhibits: true, - entryToActivitiesSecond: true - } - }, - { - id: 'unlimited', - name: 'Melbourne Unlimited Card', - subtitle: 'Pick 5-30 things to do from a choice of 102 attractions tours and activities', - priceRange: '$159-299', - duration: '3-7 days', - popular: true, - color: 'from-purple-500 to-pink-500', - features: { - passCategory: 'Pass Category', - accessToAttractions: true, - entryToAttractions: true, - accessToExperiences: true, - entryToSites: true, - accessToVenues: true, - entryToEvents: 'Pass Category', - accessToLocations: 'Pass Category', - entryToActivities: true, - accessToExhibits: true, - entryToActivitiesSecond: true - } - } -]; +// const cardOptions = [ +// { +// id: 'selective', +// name: 'Flexi Card', +// subtitle: 'Pick 5-10 things to do from a choice of 102 attractions tours and activities', +// priceRange: '$89-159', +// duration: '3-7 days', +// popular: false, +// color: 'from-blue-500 to-cyan-500', +// features: { +// passCategory: 'Selective Card', +// accessToAttractions: true, +// entryToAttractions: true, +// accessToExperiences: true, +// entryToSites: true, +// accessToVenues: false, +// entryToEvents: 'Pass Category', +// accessToLocations: 'Pass Category', +// entryToActivities: true, +// accessToExhibits: true, +// entryToActivitiesSecond: true +// } +// }, +// { +// id: 'unlimited', +// name: 'Melbourne Unlimited Card', +// subtitle: 'Pick 5-30 things to do from a choice of 102 attractions tours and activities', +// priceRange: '$159-299', +// duration: '3-7 days', +// popular: true, +// color: 'from-purple-500 to-pink-500', +// features: { +// passCategory: 'Pass Category', +// accessToAttractions: true, +// entryToAttractions: true, +// accessToExperiences: true, +// entryToSites: true, +// accessToVenues: true, +// entryToEvents: 'Pass Category', +// accessToLocations: 'Pass Category', +// entryToActivities: true, +// accessToExhibits: true, +// entryToActivitiesSecond: true +// } +// } +// ]; const features = [ { key: 'passCategory', label: 'Pass Category', icon: Star }, @@ -71,11 +71,59 @@ const FeatureIcon = ({ feature }: { feature: typeof features[0] }) => { interface MelbourneCardComparisonProps { onCheckoutClick?: () => void; + cards: any[] } -export function MelbourneCardComparison({ onCheckoutClick }: MelbourneCardComparisonProps) { +export function MelbourneCardComparison({ onCheckoutClick,cards }: MelbourneCardComparisonProps) { const [selectedCard, setSelectedCard] = useState('unlimited'); + const cardOptions = [ + { + id: cards[0]?.id, + name: cards[0]?.title, + subtitle: cards[0]?.description, + priceRange: `$${cards[0]?.adultPrice}`, + duration: '3-7 days', + popular: false, + color: 'from-blue-500 to-cyan-500', + features: { + passCategory: 'Selective Card', + accessToAttractions: true, + entryToAttractions: true, + accessToExperiences: true, + entryToSites: true, + accessToVenues: false, + entryToEvents: 'Pass Category', + accessToLocations: 'Pass Category', + entryToActivities: true, + accessToExhibits: true, + entryToActivitiesSecond: true + } + }, + { + id: cards[1]?.id, + name: cards[1]?.title, + subtitle: cards[1]?.description, + priceRange: `$${cards[1]?.adultPrice}`, + duration: '3-7 days', + popular: true, + color: 'from-purple-500 to-pink-500', + features: { + passCategory: 'Pass Category', + accessToAttractions: true, + entryToAttractions: true, + accessToExperiences: true, + entryToSites: true, + accessToVenues: true, + entryToEvents: 'Pass Category', + accessToLocations: 'Pass Category', + entryToActivities: true, + accessToExhibits: true, + entryToActivitiesSecond: true + } + } + ]; + const renderFeatureValue = (value: boolean | string, cardId: string) => { if (typeof value === 'boolean') { return value ? ( @@ -92,7 +140,7 @@ export function MelbourneCardComparison({ onCheckoutClick }: MelbourneCardCompar ); } - + return (
{value} @@ -122,17 +170,17 @@ export function MelbourneCardComparison({ onCheckoutClick }: MelbourneCardCompar Choose Your Adventure
- +

Buy {' '} Now

- +

- Melbourne is a must-visit cultural epicenter, and this spectacular trip unlocks - your access around the city in one easy. Save over the cost of visiting Melbourne's + Melbourne is a must-visit cultural epicenter, and this spectacular trip unlocks + your access around the city in one easy. Save over the cost of visiting Melbourne's landmarks, have lunch at Phi Phi Leh, snorkel at Bamboo Island, and visit Monkey Beach.

@@ -179,7 +227,7 @@ export function MelbourneCardComparison({ onCheckoutClick }: MelbourneCardCompar {feature.label} - + {cardOptions.map((card) => (
{renderFeatureValue(card.features[feature.key as keyof typeof card.features], card.id)} @@ -196,7 +244,7 @@ export function MelbourneCardComparison({ onCheckoutClick }: MelbourneCardCompar
Ready to explore?
Compare features above
- + {cardOptions.map((card) => (
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 36980ca..9190dfc 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -91,6 +91,10 @@ export default function Navbar({ const { user, login, logout } = useAuth(); // from AuthContext + const cityLogo = sessionStorage.getItem("cityLogo") || "" + + const baseUrl = import.meta.env.VITE_BASE_URL; + const protectedPaths = ["/passes", "/whats-included", "/", "/melbourne"]; const handleOpenLoginModal = () => { @@ -563,8 +567,7 @@ export default function Navbar({ >
{/* Enhanced Navigation Items with source tracking */} {navigationItems.map((item) => { @@ -625,12 +628,13 @@ export default function Navbar({ onClick={handleOpenCityDialogFromNavbar} > - {!activeCity || activeCity === 'shared' + {/* {!activeCity || activeCity === 'shared' ? 'City' : ['landing', 'landingpage'].includes(activeCity.toLowerCase()) ? 'City' : activeCity.charAt(0).toUpperCase() + activeCity.slice(1) - } + } */} + {cityName ? cityName : "City"} @@ -786,10 +790,11 @@ export default function Navbar({ trigger={
- {activeCity && activeCity !== 'shared' ? + {/* {activeCity && activeCity !== 'shared' ? activeCity.charAt(0).toUpperCase() + activeCity.slice(1) : currentSource === 'melbourne' ? 'Melbourne' : 'Select City' - } + } */} + {cityName ? cityName : "City"}
diff --git a/src/pages/MelbournePage.tsx b/src/pages/MelbournePage.tsx index a4dbe82..64c8c11 100644 --- a/src/pages/MelbournePage.tsx +++ b/src/pages/MelbournePage.tsx @@ -1,8 +1,7 @@ import { motion, useAnimationControls, AnimatePresence } from 'motion/react'; import { Button } from '../components/ui/button'; import { ArrowRight, Calendar, Thermometer, Eye, MapPin, Clock, Users, Ticket, Wand2, Plane, Sparkles } from 'lucide-react'; -import { useEffect, useRef, useState } from 'react'; -import Navbar from '../components/Navbar'; +import { useState } from 'react'; import { ImageWithFallback } from '../components/figma/ImageWithFallback'; import { MelbourneAttractions } from '../components/MelbourneAttractions'; import { MelbourneCardComparison } from '../components/MelbourneCardComparison'; @@ -12,11 +11,10 @@ import { CustomPostcards } from '../components/CustomPostcards'; import { EnhancedTestimonials } from '../components/EnhancedTestimonials'; import { MobileAppPromotion } from '../components/MobileAppPromotion'; import { MelbourneFAQ } from '../components/MelbourneFAQ'; -import { Footer } from '../components/Footer'; -// import { MinimalHeroBanner } from './MinimalHeroBanner'; import { Layout } from '../Layout'; import { HeroBannerCarousel } from '../components/HeroBannerCarousel'; import { HotelEsimOffers } from '../components/HotelEsimOffers'; +import { useGetSelectedCityDetailsQuery } from '../Redux/services/cities.service'; interface User { email: string; @@ -149,6 +147,18 @@ export function MelbournePage({ const [currentCardIndex, setCurrentCardIndex] = useState(0); const [isAnimating, setIsAnimating] = useState(false); + const cityId = localStorage.getItem("cityId") + + const { data: cityDetails, isLoading: loadingCityDetails } = useGetSelectedCityDetailsQuery(cityId) + + + if (loadingCityDetails) { + return
Loading...
+ } + + const cards = cityDetails?.city?.cards + sessionStorage.setItem("cityLogo", String(cityDetails?.city?.cityIconPath)) + const currentCard = itineraryCards[currentCardIndex]; const nextCard = itineraryCards[(currentCardIndex + 1) % itineraryCards.length]; const thirdCard = itineraryCards[(currentCardIndex + 2) % itineraryCards.length]; @@ -257,12 +267,12 @@ export function MelbournePage({ {/* Attractions Section */}
- +
{/* Pass Comparison */}
- +
{/* Tour Overview */} @@ -740,8 +750,8 @@ export function MelbournePage({ }, 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' + ? '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 }}