Files
CityCards-Website/src/pages/PassesPage.tsx
2026-04-27 11:22:54 +05:30

821 lines
40 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from 'react';
import { Check, X, Star, Shield, Clock, Smartphone, Download, QrCode, Heart, Users, Award, Headphones } from 'lucide-react';
import { Button } from '../components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card';
import { RadioGroup, RadioGroupItem } from '../components/ui/radio-group';
import { Badge } from '../components/ui/badge';
import { EnhancedTestimonials } from '../components/EnhancedTestimonials';
import { ReviewsSection } from '../components/ReviewsSection';
import { Layout } from '../Layout';
import { LoginModal } from '../components/LoginModal';
import { ImageWithFallback } from '../components/figma/ImageWithFallback';
import { useAuth } from '../context/AuthContext';
import { useNavigate } from 'react-router-dom';
import { useGetSelectedCityDetailsQuery } from '../Redux/services/cities.service';
import LoadingSpinner from '../components/LoadingSpinner';
interface PassesPageProps {
onCheckoutClick?: () => void;
onSignInClick: () => void;
onSignOutClick?: () => void;
}
interface PassType {
id: string;
name: string;
title: string;
description: string;
price: string;
originalPrice?: string;
period: string;
popular?: boolean;
features: string[];
tableFeatures: {
freeDelivery: boolean | string;
attractionsIncluded: string;
validityPeriod: string;
audioGuide: boolean;
skipTheLine: boolean | string;
mobileApp: boolean;
cancellationPolicy: string;
customerSupport: string;
additionalPerks: string;
};
}
const passTypes: PassType[] = [
{
id: 'selective',
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',
originalPrice: '$89.99',
period: 'per person',
features: [
'Access to selected attractions',
'Limited number of attractions per pass',
'Flexible validity period',
'Priority entry where available',
'Mobile ticket delivery'
],
tableFeatures: {
freeDelivery: true,
attractionsIncluded: '3, 5, or 7 attractions',
validityPeriod: '30 days',
audioGuide: false,
skipTheLine: 'Selected venues',
mobileApp: true,
cancellationPolicy: '24 hours free cancellation',
customerSupport: 'Email support',
additionalPerks: 'Basic travel tips'
}
},
{
id: 'unlimited',
name: 'Unlimited Pass',
title: 'UNLIMITED CARD',
description: 'The ultimate experience for adventure seekers who want unlimited access to all attractions with premium features.',
price: '$89.99',
originalPrice: '$149.99',
period: 'per person',
popular: true,
features: [
'Unlimited access to all attractions',
'Time-limited validity (7 days)',
'Skip-the-line access',
'Expert guide inclusion',
'Mobile app access',
'Premium customer support'
],
tableFeatures: {
freeDelivery: true,
attractionsIncluded: 'All attractions (50+)',
validityPeriod: '2, 3, 5, or 7 days',
audioGuide: true,
skipTheLine: 'All venues',
mobileApp: true,
cancellationPolicy: '24 hours free cancellation',
customerSupport: '24/7 Phone & Email',
additionalPerks: 'Exclusive discounts & priority booking'
}
}
];
const featureComparison = [
{ key: 'freeDelivery', label: 'Free Delivery' },
{ key: 'attractionsIncluded', label: 'Attractions Included' },
{ key: 'validityPeriod', label: 'Validity Period' },
{ key: 'audioGuide', label: 'Audio Guide' },
{ key: 'skipTheLine', label: 'Skip-the-Line Access' },
{ key: 'mobileApp', label: 'Mobile App' },
{ key: 'cancellationPolicy', label: 'Cancellation Policy' },
{ key: 'customerSupport', label: 'Customer Support' },
{ key: 'additionalPerks', label: 'Additional Perks' }
];
const trustFeatures = [
{
icon: Star,
title: 'Unique Benefits',
description: 'Exclusive access to premium attractions and experiences',
stat: '50+ Partner Venues',
color: 'from-yellow-400 to-orange-500'
},
{
icon: Users,
title: 'Proven Performance',
description: 'Trusted by thousands of satisfied travelers worldwide',
stat: '4.8/5 Rating',
color: 'from-blue-400 to-cyan-500'
},
{
icon: Shield,
title: 'Quality Assurance',
description: 'Safety-first approach with verified partners and secure booking',
stat: '100% Secure',
color: 'from-green-400 to-emerald-500'
},
{
icon: Headphones,
title: 'Award-winning Support',
description: 'Round-the-clock assistance for seamless travel experience',
stat: '24/7 Available',
color: 'from-purple-400 to-pink-500'
}
];
export function PassesPage({
onCheckoutClick,
onSignInClick,
onSignOutClick,
}: PassesPageProps) {
const [selectedPass, setSelectedPass] = useState<string>(passTypes[1].id);
const [isLoginOpen, setIsLoginOpen] = useState(false);
const { user } = useAuth(); // from AuthContext
const navigate = useNavigate()
const cityId = localStorage.getItem("cityId")
const cityName = localStorage.getItem("cityName")
const { data: cityDetails, isLoading: loadingCityDetails } = useGetSelectedCityDetailsQuery(cityId)
const cards = cityDetails?.city?.cards ?? []
if (loadingCityDetails) {
return (<LoadingSpinner />)
}
const handleCheckoutClick = (cardTypeName:string) => {
console.log('Proceeding to checkout for user:', user);
// Add your checkout logic here
navigate('/checkout', { state: { selectedCard: cardTypeName } });
};
const handleSignInClick = () => {
setIsLoginOpen(true);
};
const renderFeatureValue = (value: boolean | string) => {
if (typeof value === 'boolean') {
return value ? (
<Check className="w-5 h-5 text-green-500 mx-auto" />
) : (
<X className="w-5 h-5 text-red-400 mx-auto" />
);
}
return <span className="text-gray-700">{value}</span>;
};
return (
<Layout
activeCity={sessionStorage.getItem("lastKnownCity") || "shared"}
onSignInClick={onSignInClick}
onSignOutClick={onSignOutClick}
user={user} // ✅ Pass the updated user data
>
<div className="container mx-auto px-4 pt-52 pb-12 relative z-10">
{/* Page Header */}
<div className="text-center mb-16">
<div className="mb-6">
<h1 className="font-merchant font-light text-4xl md:text-5xl lg:text-6xl mb-4">
Buy <span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-1.5">Cards</span>
</h1>
<p className="font-poppins text-xl leading-relaxed font-normal text-gray-600 max-w-3xl mx-auto">
Skip the lines, save money, and explore more with our flexible city cards designed for modern travelers
</p>
</div>
</div>
{/* Pass Comparison Section */}
<div className="mb-20">
<RadioGroup
className="grid md:grid-cols-2 gap-8 max-w-6xl mx-auto"
>
{/* Flexi Pass Card */}
<div className="relative h-full">
<Card
className={`relative h-full flex flex-col transition-all duration-300 cursor-pointer ${selectedPass === passTypes[0].id
? "ring-2 ring-red-500 shadow-lg" // 🔴 red border when selected
: "border-gray-200 shadow-md hover:shadow-lg hover:border-primary/30"
}`}
onClick={() => setSelectedPass(passTypes[0].id)}
>
<div className="absolute top-5 right-5 z-10">
{/* <RadioGroupItem value={passTypes[0].id} id={passTypes[0].id} className="w-5 h-5" /> */}
</div>
<CardHeader className="text-center pb-4 pt-8 flex-shrink-0">
<CardTitle className="font-merchant text-2xl leading-tight mb-3 text-gray-900">
{cards[0]?.title}
</CardTitle>
<CardDescription className="font-poppins text-sm text-gray-600 leading-relaxed font-normal min-h-[48px] flex items-center justify-center px-4">
{cards[0]?.description}
</CardDescription>
</CardHeader>
{/* Pricing */}
<div className="px-6 pb-6 flex-shrink-0">
<div className="flex items-baseline justify-center gap-2 mb-2">
<span className="text-5xl font-bold text-gray-900 font-poppins">
${cards[0]?.adultPrice}
</span>
<span className="text-gray-500 font-poppins text-base">
/ {passTypes[0].period}
</span>
</div>
<div className="h-5 flex items-center justify-center">
{cards[0]?.adultPrice && (
<div className="text-sm text-gray-500 font-poppins">
{/* Strikethrough price = originalPrice + $5 */}
<span className="line-through mr-2">
${parseFloat(cards[0]?.adultPrice) + 5}
</span>
<span className="text-green-600 font-medium">
Save{" "}
{Math.round(
((5) / (parseFloat(cards[0]?.adultPrice) + 5)) * 100
)}
%
</span>
</div>
)}
</div>
</div>
<CardContent className="pt-0 pb-6 px-6 flex-grow flex flex-col">
<div className="flex-grow mb-6">
<div className="space-y-3">
{passTypes[0].features.map((feature, index) => (
<div key={index} className="flex items-start gap-3">
<Check className="w-4 h-4 text-green-500 mt-1 flex-shrink-0" />
<span className="text-sm text-gray-700 font-poppins leading-relaxed font-normal">{feature}</span>
</div>
))}
</div>
</div>
<div className="flex-shrink-0 space-y-3">
<Button
className={`w-full h-12 rounded-lg font-semibold transition-all cursor-pointer duration-300 font-poppins ${selectedPass === passTypes[0].id
? "bg-primary hover:bg-primary/90 text-white hover:shadow-lg"
: "bg-gray-400 hover:bg-gray-400 text-white hover:shadow-md"
}`}
onClick={() => user ? handleCheckoutClick(cards[0]?.cardType?.cardTypeName) : handleSignInClick}
disabled={selectedPass !== passTypes[0].id}
>
{user ? 'PURCHASE NOW' : 'LOGIN TO BUY PASS'}
</Button>
<p className="text-xs text-gray-500 text-center font-poppins font-normal leading-tight">
Free cancellation up to 24 hours Instant delivery
</p>
</div>
</CardContent>
</Card>
</div>
{/* Unlimited Pass Card */}
<div className="relative h-full">
<Card
className={`relative h-full flex flex-col transition-all duration-300 cursor-pointer ${selectedPass === passTypes[1]?.id
? "ring-2 ring-red-500 shadow-lg" // 🔴 red border when selected
: "border-gray-200 shadow-md hover:shadow-lg hover:border-primary/30"
}`}
onClick={() => setSelectedPass(passTypes[1]?.id)}
>
{passTypes[1]?.popular && (
<div className="absolute -top-3 left-1/2 transform -translate-x-1/2 z-10">
<Badge className="bg-gradient-to-r from-yellow-400 to-orange-500 text-black px-6 py-1.5 font-semibold shadow-lg font-poppins">
Most Popular
</Badge>
</div>
)}
<div className="absolute top-5 right-5 z-10">
{/* <RadioGroupItem value={passTypes[1].id} id={passTypes[1].id} className="w-5 h-5" /> */}
</div>
<CardHeader className="text-center pb-4 pt-8 flex-shrink-0">
<CardTitle className="font-merchant text-2xl leading-tight mb-3 text-gray-900">
{cards[1]?.title}
</CardTitle>
<CardDescription className="font-poppins text-sm text-gray-600 leading-relaxed font-normal min-h-[48px] flex items-center justify-center px-4">
{cards[1]?.description}
</CardDescription>
</CardHeader>
{/* Pricing */}
<div className="px-6 pb-6 flex-shrink-0">
<div className="flex items-baseline justify-center gap-2 mb-2">
<span className="text-5xl font-bold text-gray-900 font-poppins">${cards[1]?.adultPrice}</span>
<span className="text-gray-500 font-poppins text-base">/ {passTypes[1]?.period}</span>
</div>
<div className="h-5 flex items-center justify-center">
{cards[1]?.adultPrice && (
<div className="text-sm text-gray-500 font-poppins">
{/* Strikethrough price = originalPrice + $5 */}
<span className="line-through mr-2">
${parseFloat(cards[1]?.adultPrice) + 5}
</span>
<span className="text-green-600 font-medium">
Save{" "}
{Math.round(
((5) / (parseFloat(cards[1]?.adultPrice) + 5)) * 100
)}
%
</span>
</div>
)}
</div>
</div>
<CardContent className="pt-0 pb-6 px-6 flex-grow flex flex-col">
<div className="flex-grow mb-6">
<div className="space-y-3">
{passTypes[1]?.features.map((feature, index) => (
<div key={index} className="flex items-start gap-3">
<Check className="w-4 h-4 text-green-500 mt-1 flex-shrink-0" />
<span className="text-sm text-gray-700 font-poppins leading-relaxed font-normal">{feature}</span>
</div>
))}
</div>
</div>
<div className="flex-shrink-0 space-y-3">
<Button
className={`w-full h-12 rounded-lg font-semibold transition-all cursor-pointer duration-300 font-poppins ${selectedPass === passTypes[1].id
? "bg-primary hover:bg-primary/90 text-white hover:shadow-lg"
: "bg-gray-400 hover:bg-gray-400 text-white hover:shadow-md"
}`}
disabled={selectedPass !== passTypes[1].id}
onClick={() => user ? handleCheckoutClick(cards[1]?.cardType?.cardTypeName) : handleSignInClick}
>
{user ? 'PURCHASE NOW' : 'LOGIN TO BUY PASS'}
</Button>
<p className="text-xs text-gray-500 text-center font-poppins font-normal leading-tight">
Free cancellation up to 24 hours Instant delivery
</p>
</div>
</CardContent>
</Card>
</div>
</RadioGroup>
</div>
{/* Good to Know Section */}
<div className="mb-24">
<div className="text-center mb-16">
<h2 className="font-merchant text-4xl md:text-5xl text-gray-900 mb-6">
<span className="font-light">Good to</span>{' '}
<span className="font-bold italic bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pr-2">Know</span>
</h2>
<p className="font-poppins text-lg text-gray-600 font-light max-w-2xl mx-auto leading-relaxed">
Simple tips to help you get the most out of your CityCard experience
</p>
</div>
<div className="max-w-7xl mx-auto">
<div className="grid lg:grid-cols-12 gap-8 items-start">
{/* Left Column: The Rules */}
<div className="lg:col-span-7 space-y-6">
{/* Rule 1: Calendar Days */}
<div className="bg-white rounded-[2rem] p-8 border border-gray-100 shadow-[0_8px_30px_rgb(0,0,0,0.04)] hover:shadow-[0_8px_30px_rgb(0,0,0,0.08)] transition-all duration-500 relative overflow-hidden">
<div className="absolute top-0 right-0 w-64 h-64 bg-blue-50/50 rounded-full blur-3xl -mr-32 -mt-32 pointer-events-none"></div>
<div className="flex flex-col sm:flex-row items-start gap-6 relative z-10">
<div className="w-14 h-14 bg-blue-100/50 rounded-2xl flex items-center justify-center shrink-0 text-blue-600">
<Clock className="w-7 h-7" strokeWidth={1.5} />
</div>
<div className="flex-1 w-full">
<h3 className="font-merchant text-xl text-gray-900 mb-3">Calendar Days Policy</h3>
<p className="font-poppins text-gray-600 leading-relaxed mb-6">
Unlimited passes work on a <span className="font-medium text-gray-900">consecutive calendar day basis</span>, not 24-hour periods. Your pass expires at 11:59 PM on your final day.
</p>
{/* Visual Timeline Example */}
<div className="bg-blue-50/30 rounded-xl p-5 border border-blue-100/50 flex flex-col sm:flex-row gap-4 sm:items-center justify-between w-full">
<div className="flex-1">
<div className="text-xs font-bold text-blue-800 uppercase tracking-wider mb-1">Start</div>
<div className="font-poppins font-medium text-gray-900 text-sm sm:text-base">Monday 4:30 PM</div>
<div className="text-xs text-gray-500 mt-1">First scan</div>
</div>
<div className="hidden sm:flex flex-col items-center px-4 shrink-0">
<div className="text-[10px] font-medium text-blue-400 mb-1">3 Days</div>
<div className="w-24 h-0.5 bg-blue-200 relative">
<div className="absolute inset-0 bg-blue-400 w-1/2 animate-pulse"></div>
</div>
</div>
<div className="flex-1 text-left sm:text-right">
<div className="text-xs font-bold text-blue-800 uppercase tracking-wider mb-1">End</div>
<div className="font-poppins font-medium text-gray-900 text-sm sm:text-base">Wednesday 11:59 PM</div>
<div className="text-xs text-gray-500 mt-1">Expiration</div>
</div>
</div>
</div>
</div>
</div>
{/* Rule 2: Fair Use */}
<div className="bg-white rounded-[2rem] p-8 border border-gray-100 shadow-[0_8px_30px_rgb(0,0,0,0.04)] hover:shadow-[0_8px_30px_rgb(0,0,0,0.08)] transition-all duration-500 relative overflow-hidden">
<div className="absolute top-0 right-0 w-64 h-64 bg-orange-50/50 rounded-full blur-3xl -mr-32 -mt-32 pointer-events-none"></div>
<div className="flex flex-col sm:flex-row items-start gap-6 relative z-10">
<div className="w-14 h-14 bg-orange-100/50 rounded-2xl flex items-center justify-center shrink-0 text-orange-600">
<Shield className="w-7 h-7" strokeWidth={1.5} />
</div>
<div className="flex-1">
<h3 className="font-merchant text-xl text-gray-900 mb-3">60-Minute Adventure Gap</h3>
<p className="font-poppins text-gray-600 leading-relaxed">
To keep the journey smooth for everyone, there's a simple <span className="font-medium text-gray-900">60-minute wait</span> between scanning your pass at attractions.
</p>
<div className="mt-4 flex flex-wrap items-center gap-3 text-sm text-orange-800 bg-orange-50/50 py-2 px-4 rounded-full w-fit">
<span className="w-2 h-2 bg-orange-400 rounded-full animate-pulse shrink-0"></span>
Perfect for grabbing a coffee or traveling to your next stop!
</div>
</div>
</div>
</div>
</div>
{/* Right Column: The "Card Types" Summary */}
<div className="lg:col-span-5 h-full min-h-[400px]">
<div className="bg-gradient-to-br from-[#F95F62] to-[#ff8f92] rounded-[2rem] p-8 border border-white/20 shadow-[0_8px_30px_rgb(249,95,98,0.3)] h-full relative overflow-hidden flex flex-col justify-center text-white">
{/* Abstract Shapes */}
<div className="absolute top-0 right-0 w-64 h-64 bg-white/10 rounded-full blur-3xl -mr-10 -mt-10 pointer-events-none"></div>
<div className="absolute bottom-0 left-0 w-64 h-64 bg-black/5 rounded-full blur-3xl -ml-10 -mb-10 pointer-events-none"></div>
<div className="relative z-10">
<h3 className="font-merchant text-3xl mb-2 text-white">Your Pass, Your Way</h3>
<p className="text-white/90 font-poppins mb-8 font-light leading-relaxed">Choose the flexibility that matches your travel style.</p>
<div className="space-y-4">
{/* Flex Option - White Card */}
<div className="bg-white rounded-2xl p-5 shadow-lg border border-white/50 hover:scale-[1.02] transition-transform duration-300 cursor-default group relative overflow-hidden">
<div className="absolute left-0 top-0 bottom-0 w-1.5 bg-[#F95FAF]"></div>
<div className="flex justify-between items-center mb-2 pl-3">
<span className="font-poppins font-semibold text-lg text-gray-900 group-hover:text-[#F95FAF] transition-colors">Flexi Card</span>
<span className="text-[10px] uppercase tracking-wider bg-[#F95FAF]/10 px-2 py-1 rounded-md text-[#F95FAF] font-bold">Casual</span>
</div>
<p className="text-sm text-gray-600 font-light mb-4 pl-3">Best for visiting specific attractions at your own pace.</p>
<div className="flex gap-2 pl-3">
{[3, 5, 7].map(n => (
<div key={n} className="text-xs border border-[#F95FAF]/30 text-[#F95FAF] rounded-lg px-3 py-1.5 font-medium bg-[#F95FAF]/5">{n}</div>
))}
<span className="text-xs flex items-center text-gray-400 ml-1">Attractions</span>
</div>
</div>
{/* Unlimited Option - White Card with Highlight */}
<div className="bg-white rounded-2xl p-5 shadow-lg border border-white/50 hover:scale-[1.02] transition-transform duration-300 cursor-default group relative overflow-hidden">
<div className="absolute top-0 right-0 bg-[#F95F62] text-white text-[10px] font-bold px-3 py-1 rounded-bl-xl shadow-sm z-10">POPULAR</div>
<div className="absolute left-0 top-0 bottom-0 w-1.5 bg-[#F95F62]"></div>
<div className="flex justify-between items-center mb-2 pl-3">
<span className="font-poppins font-semibold text-lg text-gray-900 group-hover:text-[#F95F62] transition-colors">Unlimited Card</span>
<span className="text-[10px] uppercase tracking-wider bg-[#F95F62]/10 px-2 py-1 rounded-md text-[#F95F62] border border-[#F95F62]/20 font-bold">Power User</span>
</div>
<p className="text-sm text-gray-600 font-light mb-4 pl-3">Unlimited access for full days of exploration.</p>
<div className="flex gap-2 flex-wrap pl-3">
{[2, 3, 5, 7].map(n => (
<div key={n} className="text-xs bg-white text-[#F95F62] border border-[#F95F62]/20 rounded-lg px-3 py-1.5 font-medium shadow-sm">{n}</div>
))}
<span className="text-xs flex items-center text-gray-500 ml-1">Days</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Detailed Features Comparison Table */}
<Card className="overflow-hidden mb-20 bg-white shadow-lg">
<CardHeader className="text-center">
<CardTitle className="font-merchant text-3xl font-bold text-gray-900 mb-2">
Detailed Feature Comparison
</CardTitle>
<CardDescription className="text-lg text-gray-600 font-light">
See exactly what's included with each pass type
</CardDescription>
</CardHeader>
<CardContent className="p-0">
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b border-gray-200 bg-gray-50">
<th className="text-left p-6 font-semibold text-gray-900 min-w-[200px]">Features</th>
<th className="text-center p-6 font-semibold text-gray-900 min-w-[200px]">Flexi Pass</th>
<th className="text-center p-6 font-semibold text-gray-900 min-w-[200px] bg-primary/5">Unlimited Pass</th>
</tr>
</thead>
<tbody>
{featureComparison.map((feature, index) => (
<tr key={feature.key} className={`border-b border-gray-100 ${index % 2 === 0 ? 'bg-white' : 'bg-gray-50/50'}`}>
<td className="p-6 font-medium text-gray-900">
<div className="flex items-center">
<span className="w-2 h-2 bg-primary rounded-full mr-3"></span>
{feature.label}
</div>
</td>
<td className="p-6 text-center">
{renderFeatureValue(passTypes[0].tableFeatures[feature.key as keyof typeof passTypes[0]['tableFeatures']])}
</td>
<td className="p-6 text-center bg-primary/5">
{renderFeatureValue(passTypes[1].tableFeatures[feature.key as keyof typeof passTypes[1]['tableFeatures']])}
</td>
</tr>
))}
</tbody>
</table>
</div>
</CardContent>
</Card>
{/* Mobile App Promotion Banner */}
<div className="mb-20">
<Card className="bg-gray-50 overflow-hidden shadow-lg">
<CardContent className="p-0">
<div className="grid lg:grid-cols-2 gap-12 items-center">
{/* Smartphone Mockup */}
<div className="relative flex justify-center p-8 lg:p-16">
<div className="relative">
{/* Phone Frame */}
<div className="w-64 h-[520px] bg-black rounded-[2.5rem] p-2 shadow-2xl">
<div className="w-full h-full bg-white rounded-[2rem] relative overflow-hidden">
{/* Screen Content */}
<div className="absolute inset-0 bg-gradient-to-b from-primary/90 to-secondary/90">
{/* Status Bar */}
<div className="flex justify-between items-center px-6 pt-4 pb-2 text-white text-sm">
<span>9:41</span>
<div className="flex gap-1">
<div className="w-4 h-2 bg-white rounded-sm opacity-80"></div>
<div className="w-4 h-2 bg-white rounded-sm opacity-60"></div>
<div className="w-4 h-2 bg-white rounded-sm opacity-40"></div>
</div>
</div>
{/* App Header */}
<div className="px-6 py-4">
<div className="flex items-center gap-3 mb-6">
<div className="w-12 h-12 bg-white/20 rounded-xl flex items-center justify-center backdrop-blur-sm">
<span className="text-xl">🏙</span>
</div>
<div>
<h3 className="text-white font-semibold text-lg">CityCards</h3>
<p className="text-white/70 text-sm">{cityName} Explorer</p>
</div>
</div>
</div>
{/* Active Pass Card */}
<div className="mx-6 mb-6">
<div className="bg-white/15 backdrop-blur-md rounded-2xl p-4 border border-white/20">
<div className="flex justify-between items-center mb-3">
<span className="text-white font-semibold">Premium Pass</span>
<Badge className="bg-green-400 text-green-900 text-xs">Active</Badge>
</div>
<div className="h-2 bg-white/20 rounded-full mb-3">
<div className="h-2 bg-gradient-to-r from-yellow-400 to-orange-500 rounded-full w-3/4"></div>
</div>
<p className="text-white/80 text-xs">18 of 24 attractions visited</p>
</div>
</div>
{/* Quick Actions */}
<div className="px-6 mb-6">
<div className="grid grid-cols-3 gap-3">
{[
{ icon: '🗺️', label: 'Map' },
{ icon: '📍', label: 'Near Me' },
{ icon: '⭐', label: 'Favorites' }
].map((action, index) => (
<div key={index} className="bg-white/10 backdrop-blur-sm rounded-xl p-3 text-center border border-white/20">
<span className="text-lg mb-1 block">{action.icon}</span>
<span className="text-white text-xs">{action.label}</span>
</div>
))}
</div>
</div>
{/* Featured Attraction */}
<div className="mx-6">
<div className="bg-white/10 backdrop-blur-sm rounded-xl p-4 border border-white/20">
<h4 className="text-white font-medium mb-2">Today's Highlight</h4>
<div className="flex items-center gap-3">
<div className="w-12 h-12 bg-white/20 rounded-lg"></div>
<div>
<p className="text-white text-sm font-medium">Royal Botanic Gardens</p>
<p className="text-white/70 text-xs">2.5km away • Open now</p>
</div>
</div>
</div>
</div>
{/* Bottom Tab Bar */}
<div className="absolute bottom-6 left-4 right-4">
<div className="bg-white/10 backdrop-blur-md rounded-2xl p-2 border border-white/20">
<div className="grid grid-cols-4 gap-2 text-center">
{['Home', 'Passes', 'Map', 'Profile'].map((tab, index) => (
<div key={index} className="py-2">
<span className="text-white text-xs">{tab}</span>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Content */}
<div className="p-8 lg:p-16">
<h2 className="heading-dynamic text-4xl text-gray-900 mb-6">
<span className="font-light">Access all your</span>{' '}
<span className="font-bold italic text-gradient-primary pr-2">city cards</span>{' '}
<span className="font-normal">on your</span>{' '}
<span className="font-semibold text-emphasis">phone</span>
</h2>
<p className="text-xl text-gray-600 mb-8 leading-relaxed font-light">
Download our mobile app for easy access to your passes, maps, and exclusive offers.
Never worry about losing your tickets again.
</p>
{/* App Features */}
<div className="space-y-4 mb-8">
{[
'Instant pass activation and QR code access',
'Offline maps and attraction information',
'Real-time updates and exclusive app-only offers',
'Track your progress and plan your journey'
].map((feature, index) => (
<div key={index} className="flex items-center gap-3">
<Check className="w-5 h-5 text-green-500" />
<span className="text-gray-700 font-light">{feature}</span>
</div>
))}
</div>
{/* Download Buttons */}
<div className="flex flex-col sm:flex-row gap-4 mb-8">
<Button className="bg-black text-white hover:bg-gray-800 flex items-center justify-center gap-3 px-6 py-4 rounded-xl font-semibold">
<Download className="w-5 h-5" />
Download for iOS
</Button>
<Button className="bg-black text-white hover:bg-gray-800 flex items-center justify-center gap-3 px-6 py-4 rounded-xl font-semibold">
<Download className="w-5 h-5" />
Get it on Google Play
</Button>
</div>
{/* QR Code */}
<div className="flex items-center gap-4">
<div className="w-16 h-16 bg-black rounded-xl p-2">
<div className="w-full h-full bg-white rounded-lg flex items-center justify-center">
<QrCode className="w-8 h-8 text-black" />
</div>
</div>
<div>
<p className="font-medium text-gray-900">Scan to download</p>
<p className="text-sm text-gray-600 font-light">Available on iOS and Android</p>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
{/* Why Choose Us Section */}
<div className="mb-20">
<div className="text-center mb-12">
<h2 className="heading-dynamic text-4xl text-gray-900 mb-4">
<span className="font-light">Why Choose</span>{' '}
<span className="font-bold italic text-gradient-primary pr-2">CityCards</span><span className="font-normal">?</span>
</h2>
<p className="text-xl text-gray-600 max-w-3xl mx-auto font-light">
We're committed to providing the best city exploration experience with unmatched value and service
</p>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
{trustFeatures.map((feature, index) => {
const IconComponent = feature.icon;
return (
<Card key={index} className="text-center p-8 border-gray-200 hover:shadow-lg transition-shadow duration-300">
<CardContent className="p-0">
<div className={`w-16 h-16 bg-gradient-to-r ${feature.color} rounded-2xl flex items-center justify-center mx-auto mb-6`}>
<IconComponent className="w-8 h-8 text-white" />
</div>
<h4 className="font-semibold text-gray-900 mb-3">{feature.title}</h4>
<p className="text-gray-600 mb-4 leading-relaxed font-light">{feature.description}</p>
<div className="text-2xl font-bold text-primary mb-1">{feature.stat}</div>
</CardContent>
</Card>
);
})}
</div>
</div>
{/* Enhanced Testimonials Section */}
<EnhancedTestimonials />
{/* Reviews Section */}
<ReviewsSection />
{/* Final CTA Section */}
<div className="text-center bg-gradient-to-r from-primary to-secondary rounded-3xl p-12 text-white relative overflow-hidden">
{/* Background Pattern */}
<div className="absolute inset-0 bg-gradient-to-br from-white/10 to-transparent"></div>
<div className="absolute top-10 right-10 w-32 h-32 bg-white/5 rounded-full"></div>
<div className="absolute bottom-10 left-10 w-24 h-24 bg-white/5 rounded-full"></div>
<div className="relative z-10">
<h3 className="heading-dynamic text-4xl mb-4">
<span className="font-light">Ready to</span>{' '}
<span className="font-bold italic text-emphasis">explore</span>{' '}
<span className="font-semibold">{cityName}?</span>
</h3>
<p className="text-xl mb-8 max-w-2xl mx-auto opacity-90 font-light">
Choose your pass and start discovering amazing attractions with skip-the-line access.
Money-back guarantee included.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center mb-8">
<Button
size="lg"
className="bg-white text-primary hover:bg-gray-100 py-4 px-8 rounded-2xl font-semibold text-lg shadow-lg hover:shadow-xl transition-all duration-200"
>
Choose Your Pass
</Button>
<div className="flex items-center gap-2 text-white/80">
<Check className="w-5 h-5" />
<span className="font-light">No hidden fees Instant confirmation</span>
</div>
</div>
<div className="flex justify-center items-center gap-8 text-sm text-white/70">
<span className="flex items-center gap-2 font-light">
<Shield className="w-4 h-4" />
SSL Secured
</span>
<span className="flex items-center gap-2 font-light">
<Heart className="w-4 h-4" />
Money Back Guarantee
</span>
<span className="flex items-center gap-2 font-light">
<Clock className="w-4 h-4" />
24/7 Support
</span>
</div>
</div>
</div>
</div>
<LoginModal
isOpen={isLoginOpen}
onClose={() => {
setIsLoginOpen(false);
}}
/>
</Layout>
);
}
export default PassesPage;