From 5933e33d6d68487f6dddb3f3be97786cd541acd4 Mon Sep 17 00:00:00 2001 From: aryabenade Date: Mon, 20 Apr 2026 19:34:20 +0530 Subject: [PATCH] refactor the code in checkout2Page --- src/pages/CartPageDesign.tsx | 878 +++++++++++++++++++++++++++++++ src/pages/CheckoutPage2.tsx | 838 +++++++++++++++-------------- src/pages/PaymentDetailsPage.tsx | 2 +- 3 files changed, 1320 insertions(+), 398 deletions(-) create mode 100644 src/pages/CartPageDesign.tsx diff --git a/src/pages/CartPageDesign.tsx b/src/pages/CartPageDesign.tsx new file mode 100644 index 0000000..e51725c --- /dev/null +++ b/src/pages/CartPageDesign.tsx @@ -0,0 +1,878 @@ +import React, { useState } from 'react'; +import { motion, AnimatePresence } from 'motion/react'; +import { + Users, Baby, ShoppingBag, Trash2, Check, CreditCard, Mail, + ChevronRight, ChevronDown, Minus, Plus, Calendar, ArrowLeft, MapPin, + Zap, Shield, Clock, Percent, Sparkles +} from 'lucide-react'; +import Navbar from '../components/Navbar'; +import { Footer } from '../components/Footer'; +import { ImageWithFallback } from '../components/figma/ImageWithFallback'; +import { useNavigate } from 'react-router-dom'; +import { useGetCardsinCartQuery } from '../Redux/services/cards.service'; +import LoadingSpinner from '../components/LoadingSpinner' + +/* ─── Types ─── */ +export interface CartItem { + id: string; + city: string; + cardType: 'Flexi' | 'Unlimited'; + days: number; + adults: number; + children: number; + quantity: number; + pricePerUnit: number; + image: string; +} + +interface Attraction { + id: string; + name: string; + image: string; + category: string; + included: boolean; +} + +interface CartPageDesignProps { + onBackClick: () => void; + onHomeClick: () => void; + onPassesClick: () => void; + onCheckoutClick?: () => void; + onSecureCheckoutClick?: (item: CartItem) => void; + onSignInClick: () => void; + onSignOutClick?: () => void; + onAttractionsClick?: () => void; + onBlogsClick?: () => void; + onHowItWorksClick?: () => void; + onFAQClick?: () => void; + onPrivacyPolicyClick?: () => void; + onAboutUsClick?: () => void; + onProfileClick?: () => void; + onCityCardsClick?: () => void; + onMagicItineraryClick?: () => void; + onPostCardsClick?: () => void; + onOffersClick?: () => void; + onSuperSavingsClick?: () => void; + onEsimsClick?: () => void; + onHotelDiscountsClick?: () => void; + onContactUsClick?: () => void; + onCartClick?: () => void; + currentPage?: string; + user?: { email: string; name: string } | null; +} + +/* ─── Data ─── */ +const initialCartItems: CartItem[] = [ + { + id: '1', city: 'Melbourne', cardType: 'Flexi', days: 3, adults: 3, children: 3, quantity: 2, pricePerUnit: 49.50, + image: 'https://images.unsplash.com/photo-1655963754904-2cf2b562a681?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBmbGluZGVycyUyMHN0YXRpb24lMjBzdW5zZXR8ZW58MXx8fHwxNzc2MzE5NDgzfDA&ixlib=rb-4.1.0&q=80&w=1080', + }, + { + id: '2', city: 'Sydney', cardType: 'Flexi', days: 3, adults: 3, children: 3, quantity: 2, pricePerUnit: 49.50, + image: 'https://images.unsplash.com/photo-1695018228065-2e0026c654af?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxTeWRuZXklMjBvcGVyYSUyMGhvdXNlJTIwaGFyYm91ciUyMGJyaWRnZXxlbnwxfHx8fDE3NzYzMTk0ODN8MA&ixlib=rb-4.1.0&q=80&w=1080', + }, + { + id: '3', city: 'Melbourne', cardType: 'Unlimited', days: 6, adults: 2, children: 1, quantity: 1, pricePerUnit: 79.00, + image: 'https://images.unsplash.com/photo-1705120624704-0970afc29fea?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBzdHJlZXQlMjBhcnQlMjBsYW5ld2F5c3xlbnwxfHx8fDE3NzYzMTk0ODR8MA&ixlib=rb-4.1.0&q=80&w=1080', + }, +]; + +const dayOptions = [3, 6, 12, 18, 24]; + +const attractionsData: Record> = { + Melbourne: { + Flexi: [ + { id: 'mel-1', name: 'SEA LIFE Aquarium', image: 'https://images.unsplash.com/photo-1536845111858-bb269af65cb6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBhcXVhcml1bSUyMHVuZGVyd2F0ZXJ8ZW58MXx8fHwxNzc2MzE5OTcwfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'mel-2', name: 'Melbourne Zoo', image: 'https://images.unsplash.com/photo-1730074888490-31239540bacf?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjB6b28lMjB3aWxkbGlmZXxlbnwxfHx8fDE3NzYzMTk5NzB8MA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'mel-3', name: 'Royal Botanic Gardens', image: 'https://images.unsplash.com/photo-1585894507208-eeead8cb9a56?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBib3RhbmljYWwlMjBnYXJkZW4lMjBncmVlbnxlbnwxfHx8fDE3NzYzMTk5NzF8MA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Nature', included: true }, + { id: 'mel-4', name: 'NGV Art Gallery', image: 'https://images.unsplash.com/photo-1752429242469-55ba7ec210d2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxhcnQlMjBnYWxsZXJ5JTIwbXVzZXVtJTIwaW50ZXJpb3J8ZW58MXx8fHwxNzc2MzE5OTczfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Culture', included: true }, + ], + Unlimited: [ + { id: 'mel-1', name: 'SEA LIFE Aquarium', image: 'https://images.unsplash.com/photo-1536845111858-bb269af65cb6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBhcXVhcml1bSUyMHVuZGVyd2F0ZXJ8ZW58MXx8fHwxNzc2MzE5OTcwfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'mel-2', name: 'Melbourne Zoo', image: 'https://images.unsplash.com/photo-1730074888490-31239540bacf?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjB6b28lMjB3aWxkbGlmZXxlbnwxfHx8fDE3NzYzMTk5NzB8MA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'mel-3', name: 'Royal Botanic Gardens', image: 'https://images.unsplash.com/photo-1585894507208-eeead8cb9a56?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBib3RhbmljYWwlMjBnYXJkZW4lMjBncmVlbnxlbnwxfHx8fDE3NzYzMTk5NzF8MA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Nature', included: true }, + { id: 'mel-4', name: 'NGV Art Gallery', image: 'https://images.unsplash.com/photo-1752429242469-55ba7ec210d2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxhcnQlMjBnYWxsZXJ5JTIwbXVzZXVtJTIwaW50ZXJpb3J8ZW58MXx8fHwxNzc2MzE5OTczfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Culture', included: true }, + { id: 'mel-5', name: 'Melbourne Star Wheel', image: 'https://images.unsplash.com/photo-1769880659692-fa77e04c5ffa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxvYnNlcnZhdGlvbiUyMHdoZWVsJTIwYW11c2VtZW50JTIwbmlnaHR8ZW58MXx8fHwxNzc2MzE5OTc2fDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Experience', included: true }, + { id: 'mel-6', name: 'Penguin Parade', image: 'https://images.unsplash.com/photo-1670391050251-d1cfbc3891c4?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxwZW5ndWlucyUyMHdpbGRsaWZlJTIwbmF0dXJlfGVufDF8fHx8MTc3NjMxOTk3Nnww&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'mel-7', name: 'Yarra River Cruise', image: 'https://images.unsplash.com/photo-1562003914-018a4a6c2171?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxyaXZlciUyMGNydWlzZSUyMGJvYXQlMjBjaXR5fGVufDF8fHx8MTc3NjMxOTk3M3ww&ixlib=rb-4.1.0&q=80&w=1080', category: 'Experience', included: true }, + ], + }, + Sydney: { + Flexi: [ + { id: 'syd-1', name: 'Harbour Bridge Climb', image: 'https://images.unsplash.com/photo-1767974062666-2685a670e353?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxTeWRuZXklMjBoYXJib3VyJTIwYnJpZGdlJTIwY2xpbWJ8ZW58MXx8fHwxNzc2MzE5OTcxfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Adventure', included: true }, + { id: 'syd-2', name: 'Taronga Zoo', image: 'https://images.unsplash.com/photo-1704852168456-b70e08441917?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxTeWRuZXklMjB0YXJvbmdhJTIwem9vJTIwYW5pbWFsc3xlbnwxfHx8fDE3NzYzMTk5NzJ8MA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'syd-3', name: 'Art Gallery NSW', image: 'https://images.unsplash.com/photo-1752429242469-55ba7ec210d2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxhcnQlMjBnYWxsZXJ5JTIwbXVzZXVtJTIwaW50ZXJpb3J8ZW58MXx8fHwxNzc2MzE5OTczfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Culture', included: true }, + ], + Unlimited: [ + { id: 'syd-1', name: 'Harbour Bridge Climb', image: 'https://images.unsplash.com/photo-1767974062666-2685a670e353?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxTeWRuZXklMjBoYXJib3VyJTIwYnJpZGdlJTIwY2xpbWJ8ZW58MXx8fHwxNzc2MzE5OTcxfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Adventure', included: true }, + { id: 'syd-2', name: 'Taronga Zoo', image: 'https://images.unsplash.com/photo-1704852168456-b70e08441917?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxTeWRuZXklMjB0YXJvbmdhJTIwem9vJTIwYW5pbWFsc3xlbnwxfHx8fDE3NzYzMTk5NzJ8MA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + { id: 'syd-3', name: 'Art Gallery NSW', image: 'https://images.unsplash.com/photo-1752429242469-55ba7ec210d2?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxhcnQlMjBnYWxsZXJ5JTIwbXVzZXVtJTIwaW50ZXJpb3J8ZW58MXx8fHwxNzc2MzE5OTczfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Culture', included: true }, + { id: 'syd-4', name: 'Sydney Harbour Cruise', image: 'https://images.unsplash.com/photo-1562003914-018a4a6c2171?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxyaXZlciUyMGNydWlzZSUyMGJvYXQlMjBjaXR5fGVufDF8fHx8MTc3NjMxOTk3M3ww&ixlib=rb-4.1.0&q=80&w=1080', category: 'Experience', included: true }, + { id: 'syd-5', name: 'SEA LIFE Aquarium', image: 'https://images.unsplash.com/photo-1536845111858-bb269af65cb6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxNZWxib3VybmUlMjBhcXVhcml1bSUyMHVuZGVyd2F0ZXJ8ZW58MXx8fHwxNzc2MzE5OTcwfDA&ixlib=rb-4.1.0&q=80&w=1080', category: 'Wildlife', included: true }, + ], + }, +}; + +const offersData: Record = { + Flexi: [ + { title: 'Astor Hotels Ultra Deluxe', description: '15% Discount on all treatments for first-time clients', image: 'https://images.unsplash.com/photo-1715191904112-4a5d9c3089fa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxsdXh1cnklMjBob3RlbCUyMHJlc29ydCUyMGV4dGVyaW9yfGVufDF8fHx8MTc3NjMyMTM2MXww&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'Green Valley Spa Lux', description: '20% Off on membership plans for new members', image: 'https://images.unsplash.com/photo-1759216853079-831ef8c8b327?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxzcGElMjB3ZWxsbmVzcyUyMHRyZWF0bWVudCUyMGludGVyaW9yfGVufDF8fHx8MTc3NjMyMTM2M3ww&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'Harbour Dining Co.', description: '10% Off your first dining experience at waterfront', image: 'https://images.unsplash.com/photo-1676471932681-45fa972d848a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxyZXN0YXVyYW50JTIwZmluZSUyMGRpbmluZ3xlbnwxfHx8fDE3NzYzMTkxNDl8MA&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'National Gallery Exhibition', description: 'Free audio guide with every gallery visit', image: 'https://images.unsplash.com/photo-1569342380852-035f42d9ca41?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtdXNldW0lMjBnYWxsZXJ5JTIwZXhoaWJpdGlvbnxlbnwxfHx8fDE3NzYyNDYwMjh8MA&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'Sunset Harbour Cruise', description: 'Complimentary drink on every sunset cruise booking', image: 'https://images.unsplash.com/photo-1765783800962-83d99ff7b158?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxjcnVpc2UlMjBib2F0JTIwaGFyYm9yJTIwdG91cnxlbnwxfHx8fDE3NzYzMjE2MDd8MA&ixlib=rb-4.1.0&q=80&w=1080' }, + ], + Unlimited: [ + { title: 'SkyView Ferris Wheel', description: 'Complimentary second ride for all pass holders', image: 'https://images.unsplash.com/photo-1626209025747-b41ee6ec191f?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxmZXJyaXMlMjB3aGVlbCUyMGFtdXNlbWVudCUyMHBhcmt8ZW58MXx8fHwxNzc2MzE3NDI2fDA&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'City Mall Boutique', description: '15% Off at select boutique stores with your pass', image: 'https://images.unsplash.com/photo-1567966689299-819568579d36?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxzaG9wcGluZyUyMG1hbGwlMjBib3V0aXF1ZSUyMHJldGFpbHxlbnwxfHx8fDE3NzYzMjEzNjN8MA&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'Adventure Outfitters', description: 'Free gear rental on outdoor adventure bookings', image: 'https://images.unsplash.com/photo-1761131221577-0716baffc6ef?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxhZHZlbnR1cmUlMjBzcG9ydHMlMjBvdXRkb29yJTIwYWN0aXZpdHl8ZW58MXx8fHwxNzc2MzIxMzYzfDA&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'Skyline Rooftop Lounge', description: 'Buy one get one free on signature cocktails', image: 'https://images.unsplash.com/photo-1642114955097-8f3d0e141641?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxyb29mdG9wJTIwYmFyJTIwY2l0eSUyMHNreWxpbmUlMjBuaWdodHxlbnwxfHx8fDE3NzYyNDU2NTl8MA&ixlib=rb-4.1.0&q=80&w=1080' }, + { title: 'Yarra Valley Wines', description: 'Exclusive wine tasting tour with pass holders discount', image: 'https://images.unsplash.com/photo-1764649841527-c8852b63cc53?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHx3aW5lJTIwdGFzdGluZyUyMHZpbmV5YXJkJTIwY2VsbGFyfGVufDF8fHx8MTc3NjMyMTYwOHww&ixlib=rb-4.1.0&q=80&w=1080' }, + ], +}; + +const priceTable: Record> = { + Flexi: { 3: 49.5, 6: 69, 12: 99, 18: 129, 24: 159 }, + Unlimited: { 3: 79, 6: 109, 12: 149, 18: 189, 24: 229 }, +}; + +/* ═══════════════════════════════════════════ + FIGMA CARD TYPE COMPONENTS + ═══════════════════════════════════════════ */ + +function FlexiCardPreview({ city, adultPrice, childPrice, isSelected }: { city: string; adultPrice: number; childPrice: number; isSelected: boolean }) { + return ( +
+ {/* Card bg */} +
+ {/* City image */} +
+ {/* */} +
+ {/* City name - left aligned */} +
+

{city}

+
+ {/* Pricing */} +
+
+ From + ${adultPrice} + /Adult +
+
+ and + ${childPrice} + /Child +
+
+ {/* Description */} +
+

+ Dive into an extensive selection of thrilling destinations! +

+
+ {/* Side tab - Flexi (pink) */} +
+ Card + Flexi +
+ {/* Selected checkmark */} + {isSelected && ( +
+ +
+ )} +
+ ); +} + +function UnlimitedCardPreview({ city, adultPrice, childPrice, isSelected }: { city: string; adultPrice: number; childPrice: number; isSelected: boolean }) { + return ( +
+ {/* Card bg */} +
+ {/* City image */} +
+ {/* */} +
+ {/* City name - left aligned */} +
+

{city}

+
+ {/* Pricing */} +
+
+ From + ${adultPrice} + /Adult +
+
+ and + ${childPrice} + /Child +
+
+ {/* Description */} +
+

+ Dive into an extensive selection of thrilling destinations! +

+
+ {/* Side tab - Unlimited (coral) */} +
+ Card + Unlimited +
+ {/* Selected checkmark */} + {isSelected && ( +
+ +
+ )} +
+ ); +} + +/* ═══════════════════════════════════════════ + CHECKOUT CONFIGURATION CARD (Mobile-first) + ═══════════════════════════════════════════ */ + +function CheckoutConfigCard({ + item, + onChange, + onProceed, +}: { + item: CartItem; + onChange: (updates: Partial) => void; + onProceed: () => void; +}) { + const [daysOpen, setDaysOpen] = useState(false); + const originalPrice = (item.pricePerUnit * item.quantity * 1.35); + const totalPrice = item.pricePerUnit * item.quantity; + + return ( +
+ {/* City header */} +
+

{item.city}

+
+ + {item.cardType} Card + +
+
+ + {/* Configuration rows */} +
+ {/* No. of Adults */} +
+ No. of Adults +
+ + {item.adults} + +
+
+ + {/* No. of Children */} +
+ No. of Children +
+ + {item.children} + +
+
+ + {/* No. of Days (dropdown) */} +
+ + {item.cardType === 'Flexi' ? 'No. of Attractions' : 'No. of Days'} + +
+ + + {daysOpen && ( + + {dayOptions.map((d) => ( + + ))} + + )} + +
+
+ + {/* You Pay */} +
+ You Pay +
+ + ${originalPrice.toFixed(0)} + + + ${totalPrice.toFixed(0)} + +
+
+
+ + {/* Proceed button */} +
+ + Proceed to Pay + +
+
+ ); +} + +/* ═══════════════════════════════════════════ + MAIN CART PAGE + ═══════════════════════════════════════════ */ + +export function CartPageDesign({ + onBackClick, + onHomeClick, + onPassesClick, + onCheckoutClick, + onSecureCheckoutClick, + onSignInClick, + onSignOutClick, + onAttractionsClick, + onBlogsClick, + onHowItWorksClick, + onFAQClick, + onPrivacyPolicyClick, + onAboutUsClick, + onProfileClick, + onCityCardsClick, + onMagicItineraryClick, + onPostCardsClick, + onOffersClick, + onSuperSavingsClick, + onEsimsClick, + onHotelDiscountsClick, + onContactUsClick, + onCartClick, + currentPage, + user, +}: CartPageDesignProps) { + const [activeTab, setActiveTab] = useState<'cards' | 'postcards'>('cards'); + const [cartItems, setCartItems] = useState(initialCartItems); + const [selectedCardId, setSelectedCardId] = useState(null); + const [view, setView] = useState<'cart' | 'checkout'>('cart'); + const [checkoutItem, setCheckoutItem] = useState(null); + + const handleRemoveItem = (id: string) => { + setCartItems(prev => prev.filter(item => item.id !== id)); + if (selectedCardId === id) setSelectedCardId(null); + }; + + const handleSelectCard = (id: string) => { + setSelectedCardId(prev => (prev === id ? null : id)); + }; + + const handleGoToCheckout = () => { + const item = cartItems.find(i => i.id === selectedCardId); + if (item) { + setCheckoutItem({ ...item }); + setView('checkout'); + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + }; + + const handleBackToCart = () => { + setView('cart'); + setCheckoutItem(null); + }; + + const handleCheckoutItemChange = (updates: Partial) => { + if (!checkoutItem) return; + const updated = { ...checkoutItem, ...updates }; + const prices = priceTable[updated.cardType]; + if (prices && prices[updated.days] !== undefined) { + updated.pricePerUnit = prices[updated.days]; + } + setCheckoutItem(updated); + }; + + const isEmpty = cartItems.length === 0; + const selectedItem = cartItems.find(i => i.id === selectedCardId); + const attractions = checkoutItem ? (attractionsData[checkoutItem.city]?.[checkoutItem.cardType] || []) : []; + const offers = checkoutItem ? (offersData[checkoutItem.cardType] || []) : []; + + return ( +
+ {}} onSignInClick={onSignInClick} onSignOutClick={onSignOutClick} + onPassesClick={onPassesClick} onCheckoutClick={onCheckoutClick} onHomeClick={onHomeClick} + onAttractionsClick={onAttractionsClick} onBlogsClick={onBlogsClick} onHowItWorksClick={onHowItWorksClick} + onFAQClick={onFAQClick} onPrivacyPolicyClick={onPrivacyPolicyClick} onAboutUsClick={onAboutUsClick} + onProfileClick={onProfileClick} onCityCardsClick={onCityCardsClick} onMagicItineraryClick={onMagicItineraryClick} + onPostCardsClick={onPostCardsClick} onOffersClick={onOffersClick} onSuperSavingsClick={onSuperSavingsClick} + onEsimsClick={onEsimsClick} onHotelDiscountsClick={onHotelDiscountsClick} onCartClick={onCartClick} + currentPage={currentPage as any} user={user} + /> + + + {view === 'cart' ? ( + /* ─── CART VIEW ─── */ + + {/* Header */} +
+

+ Your{' '} + Cart +

+

+ {isEmpty ? 'Your cart is empty' : `${cartItems.length} ${cartItems.length === 1 ? 'item' : 'items'} in your cart`} +

+
+ + {/* Tab switcher */} + {/* Cards listed directly below */} + + {/* Content */} + + {activeTab === 'cards' ? ( + + {isEmpty ? ( + } title="No cards in your cart" description="Browse our city passes to unlock amazing experiences and savings on your next adventure" actionLabel="Explore Passes" onAction={onPassesClick} /> + ) : ( +
+ {/* Table header (desktop) */} +
+
City Cards
+
Travellers
+
Qty
+
Price
+
+
+ + + {cartItems.map((item) => { + const isSelected = selectedCardId === item.id; + const totalPrice = item.pricePerUnit * item.quantity; + + return ( + handleSelectCard(item.id)} + className={`relative bg-white rounded-2xl overflow-hidden cursor-pointer transition-all duration-300 ${ + isSelected ? 'ring-2 ring-[#F95F62] shadow-lg shadow-[#F95F62]/8' : 'ring-1 ring-gray-100 hover:ring-gray-200 hover:shadow-md' + }`} + > + {/* Selected badge */} + + {isSelected && ( + + + + )} + + + {/* Mobile layout */} +
+
+ +
+
+
+
+
{item.city}
+
+ {item.cardType} + {item.days}d +
+
+ +
+
+ {item.adults}A · {item.children}C · Qty {item.quantity} +
+ ${totalPrice.toFixed(2)} + {item.quantity > 1 && ${item.pricePerUnit.toFixed(2)}/ea} +
+
+
+
+ + {/* Desktop layout */} +
+
+
+ +
+
+
{item.city}
+
+ {item.cardType} Card + {item.days} days +
+
+
+
+
+ {item.adults} + {item.children} +
+
+
+ {item.quantity} +
+
+ ${totalPrice.toFixed(2)} + {item.quantity > 1 && ${item.pricePerUnit.toFixed(2)} per unit} +
+
+ +
+
+
+ ); + })} +
+ + {/* Bottom checkout bar */} + +
+ {selectedItem ? ( + <> +

+ Selected: {selectedItem.city} {selectedItem.cardType} · {selectedItem.days}d · Qty {selectedItem.quantity} +

+

+ ${(selectedItem.pricePerUnit * selectedItem.quantity).toFixed(2)} +

+ + ) : ( +

Tap a card above to select it for checkout

+ )} +
+ + Secure Checkout + +
+
+ )} + + ) : ( + + } title="No post cards yet" description="Send beautiful digital post cards to friends and family from your favourite destinations around the world" actionLabel="Browse Post Cards" onAction={onPostCardsClick} /> + + )} + + + ) : ( + /* ─── CHECKOUT VIEW ─── */ + + {checkoutItem && ( + <> + {/* Back */} + + + {/* Stepper */} + {/* */} + + {/* Checkout heading */} +
+

+ Checkout{' '} + {checkoutItem.city} +

+ +
+ +
+ {/* Left column */} +
+ + {/* ── Card Type Selection (Figma cards) ── */} +
+

+ Choose Your Card +

+

+ Select the card type that best suits your travel style +

+
+ {/* Flexi */} + + + {/* Unlimited */} + +
+ + {/* ── Config Card (mobile only) — right after card selection ── */} +
+ checkoutItem && onSecureCheckoutClick?.(checkoutItem)} + /> +
+ + {/* Features Comparison */} +
+
+ {/* Header */} +

Features

+

Flexi

+

Unlimited

+ {[ + { feature: 'Access to attractions', flexi: true, unlimited: true }, + { feature: 'Entry to attractions', flexi: true, unlimited: true }, + { feature: 'Access to experiences', flexi: true, unlimited: true }, + { feature: 'Entry to sites', flexi: false, unlimited: true }, + { feature: 'Access to venues', flexi: true, unlimited: true }, + { feature: 'Entry to events', flexi: true, unlimited: true }, + { feature: 'Access to experiences', flexi: false, unlimited: true }, + { feature: 'Access to Itinerary creation', flexi: false, unlimited: true }, + { feature: 'Access to postcard creation', flexi: false, unlimited: true }, + ].map((row, i) => ( + +

+ {row.feature} +

+
+ {row.flexi ? ( +
+ +
+ ) : ( + + )} +
+
+ {row.unlimited ? ( +
+ +
+ ) : ( + + )} +
+
+ ))} +
+
+
+ + {/* ── Offers ── */} +
+

+ {checkoutItem.cardType} Card Offers +

+

+ Exclusive deals and discounts included with your {checkoutItem.cardType} pass +

+
+ {offers.map((offer, idx) => ( +
+
+
+ +
+
+

+ {offer.title} +

+
+
+

+ {offer.description} +

+
+
+
+
+ ))} +
+
+ + {/* ── Available Attractions ── */} +
+
+

Available Attractions

+ {attractions.length} included +
+

+ Explore all the experiences you can enjoy with your pass +

+
+ {attractions.map((a) => ( +
+
+ +
+
+ {a.category} +
+
+
{a.name}
+
+ +
+
+ ))} +
+
+
+ + {/* Right column: Config card (desktop only, sticky) */} +
+
+ checkoutItem && onSecureCheckoutClick?.(checkoutItem)} + /> +
+
+
+ + )} + + )} + + +
+
+ ); +} + +/* ─── Empty state ─── */ +function EmptyState({ icon, title, description, actionLabel, onAction }: { + icon: React.ReactNode; title: string; description: string; actionLabel: string; onAction?: () => void; +}) { + return ( + + {icon} +

{title}

+

{description}

+ {actionLabel} +
+ ); +} \ No newline at end of file diff --git a/src/pages/CheckoutPage2.tsx b/src/pages/CheckoutPage2.tsx index 32bff5b..7f8f136 100644 --- a/src/pages/CheckoutPage2.tsx +++ b/src/pages/CheckoutPage2.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { motion, AnimatePresence } from 'motion/react'; import { ArrowLeft, Check, Minus, Plus, ChevronDown @@ -91,15 +91,21 @@ const offersData: Record +
+ {/* Card bg */}
-
- {/* */} + {/* City image */} +
+ +
+ {/* City name - left aligned */}

{city}

+ {/* Pricing */}
From @@ -112,15 +118,18 @@ function FlexiCardPreview({ city, adultPrice, childPrice, isSelected }: { city: /Child
+ {/* Description */}

Dive into an extensive selection of thrilling destinations!

+ {/* Side tab - Flexi (pink) */}
Card Flexi
+ {/* Selected checkmark */} {isSelected && (
@@ -130,15 +139,21 @@ function FlexiCardPreview({ city, adultPrice, childPrice, isSelected }: { city: ); } -function UnlimitedCardPreview({ city, adultPrice, childPrice, isSelected }: { city: string; adultPrice: number; childPrice: number; isSelected: boolean }) { +function UnlimitedCardPreview({ city, adultPrice, childPrice, isSelected, image }: { city: string; adultPrice: number; childPrice: number; isSelected: boolean, image: string; }) { return ( -
+
+ {/* Card bg */}
-
- {/* */} + {/* City image */} +
+ +
+ {/* City name - left aligned */}

{city}

+ {/* Pricing */}
From @@ -151,15 +166,18 @@ function UnlimitedCardPreview({ city, adultPrice, childPrice, isSelected }: { ci /Child
+ {/* Description */}

Dive into an extensive selection of thrilling destinations!

+ {/* Side tab - Unlimited (coral) */}
Card Unlimited
+ {/* Selected checkmark */} {isSelected && (
@@ -172,25 +190,39 @@ function UnlimitedCardPreview({ city, adultPrice, childPrice, isSelected }: { ci /* ─── CheckoutConfigCard (Exact Copy) ─── */ function CheckoutConfigCard({ item, - onChange, onProceed, }: { - item: CartItem; - onChange: (updates: Partial) => void; + item: any; onProceed: () => void; }) { - const [daysOpen, setDaysOpen] = useState(false); - const originalPrice = (item.pricePerUnit * item.quantity * 1.35); - const totalPrice = item.pricePerUnit * item.quantity; + const [dropdownOpen, setDropdownOpen] = useState(false); + const [noOfAdults, setNoOfAdults] = useState(1) + const [noOfChildren, setNoOfChildren] = useState(0) + const [noOfAttractions, setNoOfAttractions] = useState(item?.minNumber); + + const adultPrice = item?.adultPrice * noOfAdults + const childPrice = item?.childPrice * noOfChildren + const originalPrice = adultPrice + childPrice + const totalPrice = originalPrice - 20 + + useEffect(() => { + setNoOfAttractions(item?.minNumber) + }, [item]) + + const numberArray = Array.from( + { length: item?.maxNumber - item?.minNumber + 1 }, + (_, i) => item?.minNumber + i + ); + const navigate = useNavigate(); return (
-

{item.city}

+

{item?.city}

- - {item.cardType}3 + + {item?.cardType?.displayName}
@@ -198,11 +230,11 @@ function CheckoutConfigCard({
No. of Adults
- - {item.adults} -
@@ -211,11 +243,11 @@ function CheckoutConfigCard({
No. of Children
- - {item.children} -
@@ -223,19 +255,35 @@ function CheckoutConfigCard({
- {item.cardType === 'Flexi' ? 'No. of Attractions' : 'No. of Days'} + {item?.cardType?.name === 'selective_pass' ? 'No. of Attractions' : 'No. of Days'}
- - {daysOpen && ( - - {dayOptions.map((d) => ( - ))} @@ -247,8 +295,8 @@ function CheckoutConfigCard({
You Pay
- ${originalPrice.toFixed(0)} - ${totalPrice.toFixed(0)} + ${originalPrice} + ${totalPrice}
@@ -263,6 +311,233 @@ function CheckoutConfigCard({ } /* ─── MAIN CHECKOUT PAGE 2 ─── */ +export function CheckoutPage2({ + onHomeClick, + onPassesClick, + onAttractionsClick, + onBlogsClick, + onHowItWorksClick, + onFAQClick, + onPrivacyPolicyClick, + onAboutUsClick, + onContactUsClick, + onSignInClick, + onSignOutClick, + onProfileClick, + user, + currentPage, +}: any) { + const navigate = useNavigate(); + + // Default item (you can pass via props later) + + const cityId = localStorage.getItem("cityId") + const { data: checkoutPageData, isLoading } = useGetCheckoutPageDataQuery(cityId) + + const cityName = checkoutPageData?.city?.name ?? "" + const cityImage = checkoutPageData?.city?.heroBanner?.image ?? "" + const cards = checkoutPageData?.cards ?? [] + const flexiCard = checkoutPageData?.cards[0] ?? null + const unlimitedCard = checkoutPageData?.cards[1] ?? null + + const [checkoutItem, setCheckoutItem] = useState(flexiCard); + + useEffect(() => { + setCheckoutItem(flexiCard) + }, [cards]) + + console.log(checkoutItem) + + if (isLoading) { + return + } else { + console.log(flexiCard) + } + + const handleCheckoutItemChange = (cardObject: any) => { + setCheckoutItem(cardObject); + }; + + // const attractions = attractionsData[checkoutItem.city]?.[checkoutItem.cardType] || []; + // const offers = offersData[checkoutItem.cardType] || []; + + return ( +
+ { }} + onSignInClick={onSignInClick} + onSignOutClick={onSignOutClick} + onPassesClick={onPassesClick} + onCheckoutClick={() => { }} + onHomeClick={onHomeClick} + onAttractionsClick={onAttractionsClick} + onBlogsClick={onBlogsClick} + onHowItWorksClick={onHowItWorksClick} + onFAQClick={onFAQClick} + onPrivacyPolicyClick={onPrivacyPolicyClick} + onAboutUsClick={onAboutUsClick} + onProfileClick={onProfileClick} + onCityCardsClick={() => { }} + onMagicItineraryClick={() => { }} + onPostCardsClick={() => { }} + onOffersClick={() => { }} + onSuperSavingsClick={() => { }} + onEsimsClick={() => { }} + onHotelDiscountsClick={() => { }} + onCartClick={() => { }} + currentPage={currentPage} + user={user} + /> + +
+ + +
+

+ Checkout{' '} + {cityName} +

+
+ +
+ {/* Left Column */} +
+ {/* Card Type Selection */} +
+

Choose Your Card

+

Select the card type that best suits your travel style

+
+ + +
+ + {/* Features Comparison (Exact Copy) */} +
+
+

Features

+

Flexi

+

Unlimited

+ {[ + { feature: 'Access to attractions', flexi: true, unlimited: true }, + { feature: 'Entry to attractions', flexi: true, unlimited: true }, + { feature: 'Access to experiences', flexi: true, unlimited: true }, + { feature: 'Entry to sites', flexi: false, unlimited: true }, + { feature: 'Access to venues', flexi: true, unlimited: true }, + { feature: 'Entry to events', flexi: true, unlimited: true }, + { feature: 'Access to experiences', flexi: false, unlimited: true }, + { feature: 'Access to Itinerary creation', flexi: false, unlimited: true }, + { feature: 'Access to postcard creation', flexi: false, unlimited: true }, + ].map((row, i) => ( + +

+ {row.feature} +

+
+ {row.flexi ?
: } +
+
+ {row.unlimited ?
: } +
+
+ ))} +
+
+
+ + {/* Offers Section (Exact) */} + {/*
+

{checkoutItem.cardType} Card Offers

+

Exclusive deals and discounts included with your {checkoutItem.cardType} pass

+
+ {offers.map((offer, idx) => ( +
+
+
+ +
+
+

{offer.title}

+
+
+

{offer.description}

+
+
+
+
+ ))} +
+
*/} + + {/* Attractions Section (Exact) */} + {/*
+
+

Available Attractions

+ {attractions.length} included +
+

Explore all the experiences you can enjoy with your pass

+
+ {attractions.map((a) => ( +
+
+ +
+
+ {a.category} +
+
+
{a.name}
+
+
+
+ ))} +
+
*/} +
+ + {/* Right Column - Config Card */} +
+
+ navigate("/payment")} + /> +
+
+ + {/* Mobile Config Card */} + {/*
+ navigate("/payment")} + /> +
*/} +
+
+ +
+
+ ); +} + // export function CheckoutPage2({ // onHomeClick, // onPassesClick, @@ -281,46 +556,68 @@ function CheckoutConfigCard({ // }: any) { // const navigate = useNavigate(); -// // Default item (you can pass via props later) +// const cityId = localStorage.getItem("cityId"); +// const { data: checkoutPageData, isLoading } = useGetCheckoutPageDataQuery(cityId); + +// const city = checkoutPageData?.city; +// const allCards = checkoutPageData?.cards ?? []; +// const allAttractions = checkoutPageData?.attractions ?? []; +// const allOffers = checkoutPageData?.offers ?? []; + +// const baseUrl = import.meta.env.VITE_BASE_URL; + + +// // Initialize with first card (Flexi) as default +// const defaultCard = allCards[0] || null; + // const [checkoutItem, setCheckoutItem] = useState({ -// id: '1', -// city: 'Melbourne', -// cardType: 'Flexi', -// days: 3, +// id: defaultCard?.id?.toString() || '1', +// city: city?.name || 'Melbourne', +// cardType: defaultCard?.cardType?.displayName || 'Flexi', +// days: defaultCard?.validityDuration || 3, // adults: 2, // children: 1, // quantity: 1, -// pricePerUnit: 49.5, -// image: '', +// pricePerUnit: defaultCard?.adultPrice || 49.5, +// image: city?.heroBanner?.image || '', // }); -// const cityId = localStorage.getItem("cityId") -// const { data: checkoutPageData, isLoading } = useGetCheckoutPageDataQuery(cityId) - -// const cards = checkoutPageData?.cards ?? [] - // if (isLoading) { -// return -// } else { -// console.log(checkoutPageData) +// return ; // } // const handleCheckoutItemChange = (updates: Partial) => { // const updated = { ...checkoutItem, ...updates }; -// const prices = priceTable[updated.cardType]; -// if (prices && prices[updated.days] !== undefined) { -// updated.pricePerUnit = prices[updated.days]; + +// // If card type changes, update with real card data +// if (updates.cardType) { +// const selectedCard = allCards.find( +// c => c.cardType?.displayName === updates.cardType +// ); +// if (selectedCard) { +// updated.id = selectedCard.id.toString(); +// updated.days = selectedCard.validityDuration; +// updated.pricePerUnit = selectedCard.adultPrice; +// } // } + // setCheckoutItem(updated); // }; -// const attractions = attractionsData[checkoutItem.city]?.[checkoutItem.cardType] || []; -// const offers = offersData[checkoutItem.cardType] || []; +// // Get currently selected card +// const selectedCard = allCards.find(c => +// c.cardType?.displayName === checkoutItem.cardType +// ) || allCards[0]; + +// // Offers for selected card (fallback to global offers) +// const currentOffers = selectedCard?.offers?.length +// ? selectedCard.offers +// : allOffers; // return ( //
// { }} // onSignInClick={onSignInClick} // onSignOutClick={onSignOutClick} @@ -347,14 +644,19 @@ function CheckoutConfigCard({ // /> //
-// //
//

// Checkout{' '} -// {checkoutItem.city} +// +// {city?.name || checkoutItem.city} +// //

//
@@ -364,19 +666,40 @@ function CheckoutConfigCard({ // {/* Card Type Selection */} //
//

Choose Your Card

-//

Select the card type that best suits your travel style

+//

+// Select the card type that best suits your travel style +//

//
-// -// +// {allCards.map((card) => ( +// +// ))} //
-// {/* Features Comparison (Exact Copy) */} +// {/* Features Comparison - Kept as is (no CSS change) */} //
//
+// {/* Header */} //

Features

//

Flexi

//

Unlimited

@@ -396,10 +719,22 @@ function CheckoutConfigCard({ // {row.feature} //

//
-// {row.flexi ?
: } +// {row.flexi ? ( +//
+// +//
+// ) : ( +// +// )} //
//
-// {row.unlimited ?
: } +// {row.unlimited ? ( +//
+// +//
+// ) : ( +// +// )} //
// // ))} @@ -407,22 +742,34 @@ function CheckoutConfigCard({ //
//
-// {/* Offers Section (Exact) */} +// {/* Offers Section */} //
-//

{checkoutItem.cardType} Card Offers

-//

Exclusive deals and discounts included with your {checkoutItem.cardType} pass

+//

+// {checkoutItem.cardType} Card Offers +//

+//

+// Exclusive deals and discounts included with your {checkoutItem.cardType} pass +//

//
-// {offers.map((offer, idx) => ( +// {currentOffers.map((offer, idx) => ( //
//
//
-// +// //
//
-//

{offer.title}

+//

+// {offer.title} +//

//
//
-//

{offer.description}

+//

+// {offer.description} +//

//
//
//
@@ -431,24 +778,31 @@ function CheckoutConfigCard({ //
//
-// {/* Attractions Section (Exact) */} +// {/* Attractions Section */} //
//
//

Available Attractions

-// {attractions.length} included +// +// {allAttractions.length} included +// //
-//

Explore all the experiences you can enjoy with your pass

+//

+// Explore all the experiences you can enjoy with your pass +//

//
-// {attractions.map((a) => ( -//
+// {allAttractions.map((attraction) => ( +//
//
-// +// //
-//
-// {a.category} -//
//
-//
{a.name}
+//
+// {attraction.title} +//
//
//
//
@@ -492,314 +846,4 @@ function CheckoutConfigCard({ // /> //
// ); -// } - -export function CheckoutPage2({ - onHomeClick, - onPassesClick, - onAttractionsClick, - onBlogsClick, - onHowItWorksClick, - onFAQClick, - onPrivacyPolicyClick, - onAboutUsClick, - onContactUsClick, - onSignInClick, - onSignOutClick, - onProfileClick, - user, - currentPage, -}: any) { - const navigate = useNavigate(); - - const cityId = localStorage.getItem("cityId"); - const { data: checkoutPageData, isLoading } = useGetCheckoutPageDataQuery(cityId); - - const city = checkoutPageData?.city; - const allCards = checkoutPageData?.cards ?? []; - const allAttractions = checkoutPageData?.attractions ?? []; - const allOffers = checkoutPageData?.offers ?? []; - - const baseUrl = import.meta.env.VITE_BASE_URL; - - - // Initialize with first card (Flexi) as default - const defaultCard = allCards[0] || null; - - const [checkoutItem, setCheckoutItem] = useState({ - id: defaultCard?.id?.toString() || '1', - city: city?.name || 'Melbourne', - cardType: defaultCard?.cardType?.displayName || 'Flexi', - days: defaultCard?.validityDuration || 3, - adults: 2, - children: 1, - quantity: 1, - pricePerUnit: defaultCard?.adultPrice || 49.5, - image: city?.heroBanner?.image || '', - }); - - if (isLoading) { - return ; - } - - const handleCheckoutItemChange = (updates: Partial) => { - const updated = { ...checkoutItem, ...updates }; - - // If card type changes, update with real card data - if (updates.cardType) { - const selectedCard = allCards.find( - c => c.cardType?.displayName === updates.cardType - ); - if (selectedCard) { - updated.id = selectedCard.id.toString(); - updated.days = selectedCard.validityDuration; - updated.pricePerUnit = selectedCard.adultPrice; - } - } - - setCheckoutItem(updated); - }; - - // Get currently selected card - const selectedCard = allCards.find(c => - c.cardType?.displayName === checkoutItem.cardType - ) || allCards[0]; - - // Offers for selected card (fallback to global offers) - const currentOffers = selectedCard?.offers?.length - ? selectedCard.offers - : allOffers; - - return ( -
- { }} - onSignInClick={onSignInClick} - onSignOutClick={onSignOutClick} - onPassesClick={onPassesClick} - onCheckoutClick={() => { }} - onHomeClick={onHomeClick} - onAttractionsClick={onAttractionsClick} - onBlogsClick={onBlogsClick} - onHowItWorksClick={onHowItWorksClick} - onFAQClick={onFAQClick} - onPrivacyPolicyClick={onPrivacyPolicyClick} - onAboutUsClick={onAboutUsClick} - onProfileClick={onProfileClick} - onCityCardsClick={() => { }} - onMagicItineraryClick={() => { }} - onPostCardsClick={() => { }} - onOffersClick={() => { }} - onSuperSavingsClick={() => { }} - onEsimsClick={() => { }} - onHotelDiscountsClick={() => { }} - onCartClick={() => { }} - currentPage={currentPage} - user={user} - /> - -
- - -
-

- Checkout{' '} - - {city?.name || checkoutItem.city} - -

-
- -
- {/* Left Column */} -
- {/* Card Type Selection */} -
-

Choose Your Card

-

- Select the card type that best suits your travel style -

-
- {allCards.map((card) => ( - - ))} -
- - {/* Features Comparison - Kept as is (no CSS change) */} -
-
- {/* Header */} -

Features

-

Flexi

-

Unlimited

- {[ - { feature: 'Access to attractions', flexi: true, unlimited: true }, - { feature: 'Entry to attractions', flexi: true, unlimited: true }, - { feature: 'Access to experiences', flexi: true, unlimited: true }, - { feature: 'Entry to sites', flexi: false, unlimited: true }, - { feature: 'Access to venues', flexi: true, unlimited: true }, - { feature: 'Entry to events', flexi: true, unlimited: true }, - { feature: 'Access to experiences', flexi: false, unlimited: true }, - { feature: 'Access to Itinerary creation', flexi: false, unlimited: true }, - { feature: 'Access to postcard creation', flexi: false, unlimited: true }, - ].map((row, i) => ( - -

- {row.feature} -

-
- {row.flexi ? ( -
- -
- ) : ( - - )} -
-
- {row.unlimited ? ( -
- -
- ) : ( - - )} -
-
- ))} -
-
-
- - {/* Offers Section */} -
-

- {checkoutItem.cardType} Card Offers -

-

- Exclusive deals and discounts included with your {checkoutItem.cardType} pass -

-
- {currentOffers.map((offer, idx) => ( -
-
-
- -
-
-

- {offer.title} -

-
-
-

- {offer.description} -

-
-
-
-
- ))} -
-
- - {/* Attractions Section */} -
-
-

Available Attractions

- - {allAttractions.length} included - -
-

- Explore all the experiences you can enjoy with your pass -

-
- {allAttractions.map((attraction) => ( -
-
- -
-
-
- {attraction.title} -
-
-
-
- ))} -
-
-
- - {/* Right Column - Config Card */} -
-
- navigate("/payment")} - /> -
-
- - {/* Mobile Config Card */} -
- navigate("/payment")} - /> -
-
-
- -
- ); -} \ No newline at end of file +// } \ No newline at end of file diff --git a/src/pages/PaymentDetailsPage.tsx b/src/pages/PaymentDetailsPage.tsx index 0f22825..08b5ad3 100644 --- a/src/pages/PaymentDetailsPage.tsx +++ b/src/pages/PaymentDetailsPage.tsx @@ -11,7 +11,7 @@ import { Separator } from '../components/ui/separator'; import { useGetUserProfileDetailsQuery } from '../Redux/services/profile.service'; import LoadingSpinner from '../components/LoadingSpinner'; import { useNavigate, useParams } from 'react-router-dom'; -import { useGetCardBookingDetailsQuery, useStoreRecepientDetailsMutation, useStoreRecipientDetailsMutation } from '../Redux/services/cards.service'; +import { useGetCardBookingDetailsQuery, useStoreRecipientDetailsMutation } from '../Redux/services/cards.service'; import { toast } from 'sonner'; export interface CheckoutOrderItem {