214 lines
11 KiB
TypeScript
214 lines
11 KiB
TypeScript
import { motion } from 'motion/react';
|
|
import {
|
|
HelpCircle,
|
|
Clock,
|
|
MapPin,
|
|
CreditCard,
|
|
Calendar,
|
|
Users,
|
|
Coffee,
|
|
Camera,
|
|
Train,
|
|
Smartphone
|
|
} from 'lucide-react';
|
|
import {
|
|
Accordion,
|
|
AccordionContent,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
} from "./ui/accordion";
|
|
|
|
const cityName = localStorage.getItem('cityName') || 'the city';
|
|
|
|
const faqData = [
|
|
// {
|
|
// id: "refund",
|
|
// question: "Can I get a refund on my Melbourne CityCard?",
|
|
// answer: "Yes, you can cancel your Melbourne CityCard and receive a full refund if you cancel at least 24 hours in advance of your selected start date. For cancellations within 24 hours, refunds are subject to our cancellation policy. Digital cards can be refunded instantly through your account.",
|
|
// icon: CreditCard
|
|
// },
|
|
{
|
|
id: "duration",
|
|
question: `How long is my ${cityName} CityCard valid?`,
|
|
answer: `${cityName} CityCards are available in 1, 2, 3, and 5-day options. Your card activates on the first attraction you visit and is valid for consecutive days only. The 5-day ${cityName} Unlimited Card provides the best value for extended stays with access to over 40 premium attractions.`,
|
|
icon: Calendar
|
|
},
|
|
{
|
|
id: "transportation",
|
|
question: `Does the ${cityName} CityCard include public transport?`,
|
|
answer: `The ${cityName} Unlimited Card includes a complimentary Myki card loaded with travel credit for trams, trains, and buses within ${cityName}'s CBD and inner suburbs. The Selective Card focuses on attractions only, but we provide detailed transport guides for each venue.`,
|
|
icon: Train
|
|
},
|
|
{
|
|
id: "attractions",
|
|
question: `What are the must-visit attractions included with my ${cityName} CityCard?`,
|
|
answer: `Your ${cityName} CityCard includes iconic experiences like Eureka Tower SkyDeck, Royal Botanic Gardens tours, ${cityName} Zoo, SEA LIFE ${cityName} Aquarium, and ${cityName} Star observation wheel. Plus unique local experiences like laneways art tours, coffee culture walks, and rooftop dining discounts.`,
|
|
icon: Camera
|
|
},
|
|
{
|
|
id: "best-time",
|
|
question: `When is the best time to visit ${cityName}?`,
|
|
answer: `${cityName} is fantastic year-round! Spring (Sep-Nov) offers perfect weather and blooming gardens. Summer (Dec-Feb) brings outdoor festivals and rooftop season. Autumn (Mar-May) showcases beautiful foliage and harvest events. Winter (Jun-Aug) is ideal for cozy cafes, indoor attractions, and cultural experiences.`,
|
|
icon: Clock
|
|
},
|
|
{
|
|
id: "coffee-culture",
|
|
question: `How can I experience ${cityName}'s famous coffee culture?`,
|
|
answer: `Your ${cityName} CityCard includes guided coffee tours through famous laneways, visits to historic coffee roasters, and discounts at award-winning cafes. We've partnered with local baristas to offer exclusive tastings and behind-the-scenes experiences at ${cityName}'s most beloved coffee institutions.`,
|
|
icon: Coffee
|
|
},
|
|
{
|
|
id: "group-bookings",
|
|
question: `Do you offer group discounts for families or friends?`,
|
|
answer: `Yes! Groups of 4+ receive automatic discounts, and families with children under 16 get special pricing. School groups and corporate bookings receive additional benefits. Contact our ${cityName} team for custom packages that can include private tours and exclusive venue access.`,
|
|
icon: Users
|
|
},
|
|
{
|
|
id: "mobile-app",
|
|
question: `Do I need the mobile app to use my ${cityName} CityCard?`,
|
|
answer: `While not required, our mobile app enhances your ${cityName} experience with interactive maps, real-time attraction wait times, insider tips from locals, and the ability to skip lines at participating venues. Download it for offline access to your itinerary and exclusive app-only deals.`,
|
|
icon: Smartphone
|
|
},
|
|
{
|
|
id: "neighborhoods",
|
|
question: `Which ${cityName} neighborhoods should I explore?`,
|
|
answer: `Your CityCard provides access to experiences across ${cityName}'s diverse neighborhoods: Fitzroy for street art and vintage shopping, St. Kilda for beaches and nightlife, Southbank for dining and culture, CBD for iconic attractions, and Richmond for authentic Vietnamese food and shopping.`,
|
|
icon: MapPin
|
|
}
|
|
];
|
|
|
|
export function MelbourneFAQ() {
|
|
return (
|
|
<section className="py-16 md:py-24 bg-gradient-to-br from-gray-50 via-white to-gray-50 relative overflow-hidden">
|
|
{/* Background Elements */}
|
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-secondary/5"></div>
|
|
<div className="absolute top-0 right-0 w-96 h-96 bg-gradient-to-br from-primary/10 to-transparent rounded-full -translate-y-48 translate-x-48 blur-2xl"></div>
|
|
<div className="absolute bottom-0 left-0 w-96 h-96 bg-gradient-to-tr from-secondary/10 to-transparent rounded-full translate-y-48 -translate-x-48 blur-2xl"></div>
|
|
|
|
<div className="container mx-auto px-4 relative z-10">
|
|
{/* Header */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 30 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6 }}
|
|
viewport={{ once: true }}
|
|
className="text-center mb-16"
|
|
>
|
|
<div className="inline-flex items-center gap-2 bg-gradient-to-r from-primary/10 to-secondary/10 px-4 py-2 rounded-full mb-6">
|
|
<HelpCircle className="w-4 h-4 text-primary" />
|
|
<span className="text-sm font-medium bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
|
|
{cityName} Guide
|
|
</span>
|
|
</div>
|
|
|
|
<h2 className="font-merchant text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-6">
|
|
<span className="font-normal">Frequently Asked</span>{' '}
|
|
<span className="pr-2 font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic">
|
|
Questions
|
|
</span>
|
|
</h2>
|
|
|
|
<p className="text-xl text-gray-600 max-w-4xl mx-auto leading-relaxed">
|
|
Everything you need to know about exploring {cityName} with your CityCard. From iconic attractions
|
|
to hidden local gems, we've got your {cityName} adventure covered.
|
|
</p>
|
|
</motion.div>
|
|
|
|
{/* FAQ Grid */}
|
|
<div className="max-w-4xl mx-auto">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 30 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6, delay: 0.2 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<Accordion type="single" collapsible className="space-y-4">
|
|
{faqData.map((faq, index) => {
|
|
const IconComponent = faq.icon;
|
|
return (
|
|
<motion.div
|
|
key={faq.id}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.4, delay: 0.3 + index * 0.05 }}
|
|
viewport={{ once: true }}
|
|
>
|
|
<AccordionItem
|
|
value={faq.id}
|
|
className="bg-white rounded-2xl shadow-sm border border-gray-100 hover:shadow-md transition-all duration-300 overflow-hidden group"
|
|
>
|
|
<AccordionTrigger className="px-6 py-5 hover:no-underline group-hover:bg-gray-50/50 transition-colors duration-200">
|
|
<div className="flex items-center gap-4 text-left">
|
|
<div className="flex-shrink-0 w-10 h-10 bg-gradient-to-br from-primary/10 to-secondary/10 rounded-xl flex items-center justify-center group-hover:from-primary/20 group-hover:to-secondary/20 transition-all duration-200">
|
|
<IconComponent className="w-5 h-5 text-primary" />
|
|
</div>
|
|
<span className="font-merchant font-semibold text-gray-900 group-hover:text-primary transition-colors duration-200">
|
|
{faq.question}
|
|
</span>
|
|
</div>
|
|
</AccordionTrigger>
|
|
<AccordionContent className="px-6 pb-6">
|
|
<div className="pl-14">
|
|
<p className="text-gray-600 leading-relaxed">
|
|
{faq.answer}
|
|
</p>
|
|
</div>
|
|
</AccordionContent>
|
|
</AccordionItem>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</Accordion>
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Call to Action */}
|
|
{/* <motion.div
|
|
initial={{ opacity: 0, y: 30 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6, delay: 0.5 }}
|
|
viewport={{ once: true }}
|
|
className="text-center mt-16"
|
|
>
|
|
<div className="bg-gradient-to-br from-primary/5 via-secondary/5 to-primary/5 rounded-3xl p-8 md:p-12 border border-gray-100 max-w-3xl mx-auto">
|
|
<div className="mb-6">
|
|
<div className="w-16 h-16 bg-gradient-to-br from-primary to-secondary rounded-2xl mx-auto flex items-center justify-center mb-4">
|
|
<HelpCircle className="w-8 h-8 text-white" />
|
|
</div>
|
|
<h3 className="font-merchant text-2xl md:text-3xl font-semibold text-gray-900 mb-4">
|
|
Still have questions?
|
|
</h3>
|
|
<p className="text-gray-600 text-lg mb-8 max-w-2xl mx-auto">
|
|
Our Melbourne experts are here to help you make the most of your visit.
|
|
Get personalized recommendations and insider tips.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
|
<motion.button
|
|
whileHover={{ scale: 1.05 }}
|
|
whileTap={{ scale: 0.95 }}
|
|
className="bg-gradient-to-r from-primary to-secondary text-white font-semibold px-8 py-4 rounded-2xl shadow-lg hover:shadow-xl transition-all duration-300 group"
|
|
>
|
|
<span className="flex items-center gap-2">
|
|
Contact Melbourne Support
|
|
<HelpCircle className="w-5 h-5 group-hover:rotate-12 transition-transform duration-200" />
|
|
</span>
|
|
</motion.button>
|
|
<motion.button
|
|
whileHover={{ scale: 1.05 }}
|
|
whileTap={{ scale: 0.95 }}
|
|
className="border-2 border-gray-300 text-gray-700 font-semibold px-8 py-4 rounded-2xl hover:border-primary hover:text-primary transition-all duration-300 group"
|
|
>
|
|
<span className="flex items-center gap-2">
|
|
Browse Melbourne Guide
|
|
<MapPin className="w-5 h-5 group-hover:bounce transition-all duration-200" />
|
|
</span>
|
|
</motion.button>
|
|
</div>
|
|
</div>
|
|
</motion.div> */}
|
|
</div>
|
|
</section>
|
|
);
|
|
} |