|
|
@@ -0,0 +1,472 @@
|
|
|
+import React, { useState, useEffect } from 'react';
|
|
|
+import Navbar from '@/src/components/Navbar.tsx';
|
|
|
+import Sidebar from '@/src/components/Sidebar.tsx';
|
|
|
+import Footer from '@/src/components/Footer.tsx';
|
|
|
+import { CONTENT } from '../constants.ts';
|
|
|
+import { ChevronRight, MapPin, Calendar, DollarSign, X, ChevronDown, Info } from 'lucide-react';
|
|
|
+import { useLanguage } from '@/src/contexts/LanguageContext.tsx';
|
|
|
+import { useTheme } from '@/src/contexts/ThemeContext.tsx';
|
|
|
+import { Itinerary } from '../types.ts';
|
|
|
+import { useLocation } from 'react-router-dom';
|
|
|
+
|
|
|
+const Itineraries: React.FC = () => {
|
|
|
+ const { language } = useLanguage();
|
|
|
+ const { itineraries } = useTheme();
|
|
|
+ const [selectedItinerary, setSelectedItinerary] = useState<Itinerary | null>(null);
|
|
|
+ const [selectedDays, setSelectedDays] = useState<number[]>([]);
|
|
|
+ const [sortBy, setSortBy] = useState<string>('default');
|
|
|
+ const location = useLocation();
|
|
|
+
|
|
|
+ const t = CONTENT[language];
|
|
|
+
|
|
|
+ // Get section from query parameters
|
|
|
+ const section = new URLSearchParams(location.search).get('section');
|
|
|
+
|
|
|
+ // Scroll to section when section parameter changes
|
|
|
+ useEffect(() => {
|
|
|
+ if (section) {
|
|
|
+ const element = document.getElementById(`itinerary-${section}`);
|
|
|
+ if (element) {
|
|
|
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [section]);
|
|
|
+
|
|
|
+ // Filter itineraries by selected days
|
|
|
+ const filteredItineraries = itineraries.filter((itinerary) => {
|
|
|
+ if (selectedDays.length === 0) return true;
|
|
|
+ return selectedDays.includes(itinerary.days);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Sort itineraries
|
|
|
+ const sortedItineraries = [...filteredItineraries].sort((a, b) => {
|
|
|
+ switch (sortBy) {
|
|
|
+ case 'price-low':
|
|
|
+ return parseInt(a.price.replace(/[^0-9]/g, '')) - parseInt(b.price.replace(/[^0-9]/g, ''));
|
|
|
+ case 'price-high':
|
|
|
+ return parseInt(b.price.replace(/[^0-9]/g, '')) - parseInt(a.price.replace(/[^0-9]/g, ''));
|
|
|
+ case 'days-low':
|
|
|
+ return a.days - b.days;
|
|
|
+ case 'days-high':
|
|
|
+ return b.days - a.days;
|
|
|
+ default:
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // Toggle day filter
|
|
|
+ const toggleDayFilter = (days: number) => {
|
|
|
+ setSelectedDays(prev => {
|
|
|
+ if (prev.includes(days)) {
|
|
|
+ return prev.filter(d => d !== days);
|
|
|
+ } else {
|
|
|
+ return [...prev, days];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // Clear all filters
|
|
|
+ const clearFilters = () => {
|
|
|
+ setSelectedDays([]);
|
|
|
+ setSortBy('default');
|
|
|
+ };
|
|
|
+
|
|
|
+ // Itinerary details are now directly available in the itineraries data
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className="min-h-screen bg-white font-sans text-vista-darkblue overflow-x-hidden">
|
|
|
+ <Navbar />
|
|
|
+ <Sidebar />
|
|
|
+
|
|
|
+ {/* Hero Section */}
|
|
|
+ <section className="relative h-[60vh] md:h-[70vh] w-full overflow-hidden bg-vista-darkblue">
|
|
|
+ <div className="absolute inset-0 bg-gradient-to-br from-vista-darkblue/95 to-vista-darkblue/60 z-10"></div>
|
|
|
+ <div className="absolute inset-0 bg-cover bg-center opacity-40" style={{ backgroundImage: `url(https://picsum.photos/1920/1080?random=20)` }}></div>
|
|
|
+ <div className="absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXR0ZXJuIGlkPSJwYXR0ZXJuIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cGF0aCBkPSJNMTAgMTBoMjB2MjBIMTB6TTMwIDEwaDIwdjIwSDMweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAuNSIvPjwvcGF0dGVybj48L3N2Zz4=')] opacity-10 z-20"></div>
|
|
|
+ <div className="relative z-30 h-full flex flex-col justify-center items-center text-center px-4 py-12">
|
|
|
+ <span className="text-vista-gold uppercase tracking-widest text-xs sm:text-sm font-bold mb-4">{t.nav.menu[2].title}</span>
|
|
|
+ <h1 className="text-3xl sm:text-4xl md:text-5xl lg:text-7xl font-serif text-white mb-4 sm:mb-6 leading-tight">探索长江精选航线</h1>
|
|
|
+ <p className="text-white/90 max-w-2xl sm:max-w-3xl text-base sm:text-lg md:text-xl mb-6 sm:mb-8 leading-relaxed">体验无与伦比的奢华旅程,欣赏长江三峡的壮丽风光和人文历史</p>
|
|
|
+ <a href="#itinerary-routes" className="px-8 sm:px-10 py-3 sm:py-4 bg-vista-gold text-white font-bold tracking-widest uppercase text-xs sm:text-sm hover:bg-opacity-90 transition-all duration-300 shadow-lg hover:shadow-xl">
|
|
|
+ {t.nav.book}
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ {/* Main Content */}
|
|
|
+ <section className="py-24 bg-white" id="itinerary-routes">
|
|
|
+ <div className="max-w-7xl mx-auto px-6">
|
|
|
+ {/* Section Title */}
|
|
|
+ <div className="text-center mb-12">
|
|
|
+ <div className="inline-block relative mb-4">
|
|
|
+ <span className="text-vista-gold uppercase tracking-widest text-sm font-bold">{t.nav.menu[2].submenu?.[0].title}</span>
|
|
|
+ <div className="absolute -bottom-2 left-1/2 transform -translate-x-1/2 w-16 h-1 bg-vista-gold/30"></div>
|
|
|
+ </div>
|
|
|
+ <h2 className="text-4xl md:text-5xl font-serif text-vista-darkblue mt-3 mb-6">精选航线</h2>
|
|
|
+ <p className="text-vista-darkblue/70 max-w-3xl mx-auto text-lg">
|
|
|
+ 选择您理想的长江游轮之旅,每一条航线都经过精心设计,带您探索长江的自然美景和人文历史
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Filters and Sorting */}
|
|
|
+ <div className="mb-12 bg-gray-50 rounded-lg p-6 shadow-sm">
|
|
|
+ <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-6">
|
|
|
+ {/* Day Filter */}
|
|
|
+ <div>
|
|
|
+ <div className="flex items-center gap-4 mb-3">
|
|
|
+ <span className="text-sm font-bold uppercase tracking-wider text-vista-darkblue">天数</span>
|
|
|
+ {selectedDays.length > 0 && (
|
|
|
+ <button
|
|
|
+ className="text-xs text-vista-gold hover:text-vista-darkblue transition-colors"
|
|
|
+ onClick={clearFilters}
|
|
|
+ >
|
|
|
+ 清除筛选
|
|
|
+ </button>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <div className="flex flex-wrap gap-3">
|
|
|
+ {[4, 5, 8].map((days) => (
|
|
|
+ <button
|
|
|
+ key={days}
|
|
|
+ className={`px-4 py-2 rounded-full text-sm font-medium transition-all duration-300 ${selectedDays.includes(days) ? 'bg-vista-gold text-white shadow-md' : 'bg-white border border-gray-200 text-vista-darkblue hover:border-vista-gold hover:text-vista-gold'}`}
|
|
|
+ onClick={() => toggleDayFilter(days)}
|
|
|
+ >
|
|
|
+ {days} {t.home.days}
|
|
|
+ </button>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Sort By */}
|
|
|
+ <div>
|
|
|
+ <div className="flex items-center gap-2 mb-3">
|
|
|
+ <span className="text-sm font-bold uppercase tracking-wider text-vista-darkblue">排序</span>
|
|
|
+ </div>
|
|
|
+ <select
|
|
|
+ className="bg-white border border-gray-200 rounded-lg px-4 py-2 pr-10 text-sm text-vista-darkblue focus:outline-none focus:border-vista-gold focus:ring-2 focus:ring-vista-gold/20"
|
|
|
+ value={sortBy}
|
|
|
+ onChange={(e) => setSortBy(e.target.value)}
|
|
|
+ >
|
|
|
+ <option value="default">默认排序</option>
|
|
|
+ <option value="price-low">价格从低到高</option>
|
|
|
+ <option value="price-high">价格从高到低</option>
|
|
|
+ <option value="days-low">天数从少到多</option>
|
|
|
+ <option value="days-high">天数从多到少</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Results Count */}
|
|
|
+ <div className="mt-6 pt-4 border-t border-gray-200 text-sm text-vista-darkblue/60">
|
|
|
+ 找到 {sortedItineraries.length} 条航线
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Itinerary Grid */}
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-12">
|
|
|
+ {sortedItineraries.map((item) => (
|
|
|
+ <div
|
|
|
+ key={item.id}
|
|
|
+ className="group bg-white border border-gray-100 shadow-sm hover:shadow-xl transition-all duration-300 cursor-pointer rounded-lg overflow-hidden transform hover:-translate-y-2"
|
|
|
+ onClick={() => setSelectedItinerary(item)}
|
|
|
+ >
|
|
|
+ <div className="relative overflow-hidden h-72">
|
|
|
+ {item.video ? (
|
|
|
+ <video
|
|
|
+ src={item.video}
|
|
|
+ poster={item.image}
|
|
|
+ className="w-full h-full object-cover transform group-hover:scale-105 transition-transform duration-700"
|
|
|
+ autoPlay
|
|
|
+ muted
|
|
|
+ loop
|
|
|
+ playsInline
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ <img
|
|
|
+ src={item.image}
|
|
|
+ alt={item.title}
|
|
|
+ className="w-full h-full object-cover transform group-hover:scale-105 transition-transform duration-700"
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ <div className="absolute top-4 left-4 bg-white/95 backdrop-blur-sm px-4 py-2 rounded-full text-xs font-bold tracking-widest uppercase z-10 text-vista-darkblue shadow-sm">
|
|
|
+ {item.days} {t.home.days}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="p-8">
|
|
|
+ <div className="flex items-center text-xs text-vista-darkblue/50 uppercase tracking-widest mb-3">
|
|
|
+ <MapPin size={14} className="mr-1" />
|
|
|
+ {item.route}
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-5 group-hover:text-vista-gold transition-colors leading-tight">{item.title}</h3>
|
|
|
+
|
|
|
+ <div className="space-y-4 mb-7">
|
|
|
+ <div className="flex items-center text-sm text-vista-darkblue/80">
|
|
|
+ <Calendar size={16} className="mr-2 text-vista-gold" />
|
|
|
+ <span>{item.days}天{item.days - 1}晚</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center text-sm text-vista-darkblue/80">
|
|
|
+ <DollarSign size={16} className="mr-2 text-vista-gold" />
|
|
|
+ <span className="text-vista-gold font-bold">{item.price}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <button className="w-full flex items-center justify-center gap-2 px-6 py-3 bg-vista-darkblue text-white font-bold tracking-widest uppercase text-xs hover:bg-vista-gold transition-all duration-300 shadow-md hover:shadow-lg">
|
|
|
+ {t.home.details} <Info size={14} />
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ {/* 产品亮点 Section */}
|
|
|
+ <section className="py-24 bg-gray-50" id="itinerary-highlights">
|
|
|
+ <div className="max-w-7xl mx-auto px-6">
|
|
|
+ {/* Section Title */}
|
|
|
+ <div className="text-center mb-16">
|
|
|
+ <div className="inline-block relative mb-4">
|
|
|
+ <span className="text-vista-gold uppercase tracking-widest text-sm font-bold">{t.nav.menu[2].submenu?.[1].title}</span>
|
|
|
+ <div className="absolute -bottom-2 left-1/2 transform -translate-x-1/2 w-16 h-1 bg-vista-gold/30"></div>
|
|
|
+ </div>
|
|
|
+ <h2 className="text-4xl md:text-5xl font-serif text-vista-darkblue mt-3 mb-6">产品亮点</h2>
|
|
|
+ <p className="text-vista-darkblue/70 max-w-3xl mx-auto text-lg">
|
|
|
+ 我们的游轮航线为您提供无与伦比的旅行体验,每一个细节都经过精心设计
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Highlights Grid */}
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-10">
|
|
|
+ <div className="bg-white rounded-lg p-8 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="w-16 h-16 bg-vista-gold rounded-full flex items-center justify-center mb-6">
|
|
|
+ <MapPin size={32} className="text-white" />
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-4">精选航线</h3>
|
|
|
+ <p className="text-vista-darkblue/70 leading-relaxed">
|
|
|
+ 精心设计的航线,带您探索长江的自然美景和人文历史,每一处都值得细细品味
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="bg-white rounded-lg p-8 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="w-16 h-16 bg-vista-gold rounded-full flex items-center justify-center mb-6">
|
|
|
+ <Calendar size={32} className="text-white" />
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-4">灵活选择</h3>
|
|
|
+ <p className="text-vista-darkblue/70 leading-relaxed">
|
|
|
+ 提供4天、5天、8天等多种行程选择,满足不同旅行者的需求和时间安排
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="bg-white rounded-lg p-8 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="w-16 h-16 bg-vista-gold rounded-full flex items-center justify-center mb-6">
|
|
|
+ <DollarSign size={32} className="text-white" />
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-4">性价比高</h3>
|
|
|
+ <p className="text-vista-darkblue/70 leading-relaxed">
|
|
|
+ 价格包含住宿、餐饮、景点门票和导游服务,让您的旅行更加省心省力
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="bg-white rounded-lg p-8 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="w-16 h-16 bg-vista-gold rounded-full flex items-center justify-center mb-6">
|
|
|
+ <ChevronRight size={32} className="text-white" />
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-4">专业服务</h3>
|
|
|
+ <p className="text-vista-darkblue/70 leading-relaxed">
|
|
|
+ 经验丰富的导游和船员团队,为您提供贴心周到的服务,确保旅途愉快
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="bg-white rounded-lg p-8 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="w-16 h-16 bg-vista-gold rounded-full flex items-center justify-center mb-6">
|
|
|
+ <Info size={32} className="text-white" />
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-4">深度体验</h3>
|
|
|
+ <p className="text-vista-darkblue/70 leading-relaxed">
|
|
|
+ 不仅仅是观光,更是一次深度体验长江文化和当地风土人情的机会
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="bg-white rounded-lg p-8 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="w-16 h-16 bg-vista-gold rounded-full flex items-center justify-center mb-6">
|
|
|
+ <ChevronDown size={32} className="text-white" />
|
|
|
+ </div>
|
|
|
+ <h3 className="text-2xl font-serif text-vista-darkblue mb-4">舒适体验</h3>
|
|
|
+ <p className="text-vista-darkblue/70 leading-relaxed">
|
|
|
+ 豪华游轮设施齐全,为您提供舒适的住宿和餐饮体验,让您的旅途更加惬意
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ {/* 游轮航期 Section */}
|
|
|
+ <section className="py-24 bg-white" id="itinerary-schedules">
|
|
|
+ <div className="max-w-7xl mx-auto px-6">
|
|
|
+ {/* Section Title */}
|
|
|
+ <div className="text-center mb-16">
|
|
|
+ <div className="inline-block relative mb-4">
|
|
|
+ <span className="text-vista-gold uppercase tracking-widest text-sm font-bold">{t.nav.menu[2].submenu?.[2].title}</span>
|
|
|
+ <div className="absolute -bottom-2 left-1/2 transform -translate-x-1/2 w-16 h-1 bg-vista-gold/30"></div>
|
|
|
+ </div>
|
|
|
+ <h2 className="text-4xl md:text-5xl font-serif text-vista-darkblue mt-3 mb-6">游轮航期</h2>
|
|
|
+ <p className="text-vista-darkblue/70 max-w-3xl mx-auto text-lg">
|
|
|
+ 查看我们的游轮航期,选择最适合您的出行时间
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Schedules Table */}
|
|
|
+ <div className="overflow-x-auto">
|
|
|
+ <table className="w-full border-collapse">
|
|
|
+ <thead>
|
|
|
+ <tr className="bg-vista-darkblue text-white">
|
|
|
+ <th className="px-8 py-6 text-left text-sm font-bold uppercase tracking-wider">航线名称</th>
|
|
|
+ <th className="px-8 py-6 text-left text-sm font-bold uppercase tracking-wider">天数</th>
|
|
|
+ <th className="px-8 py-6 text-left text-sm font-bold uppercase tracking-wider">出发日期</th>
|
|
|
+ <th className="px-8 py-6 text-left text-sm font-bold uppercase tracking-wider">价格</th>
|
|
|
+ <th className="px-8 py-6 text-left text-sm font-bold uppercase tracking-wider">操作</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ {itineraries.map((item, index) => (
|
|
|
+ <tr key={item.id} className={`${index % 2 === 0 ? 'bg-gray-50' : 'bg-white'} border-b border-gray-100 hover:bg-vista-gold/5 transition-colors`}>
|
|
|
+ <td className="px-8 py-6">
|
|
|
+ <div className="font-serif text-vista-darkblue font-medium">{item.title}</div>
|
|
|
+ <div className="text-xs text-vista-darkblue/50 mt-1">{item.route}</div>
|
|
|
+ </td>
|
|
|
+ <td className="px-8 py-6 text-vista-darkblue">{item.days} {t.home.days}</td>
|
|
|
+ <td className="px-8 py-6 text-vista-darkblue">
|
|
|
+ <div className="space-y-1">
|
|
|
+ {['2025-12-25', '2025-12-30', '2026-01-05'].map((date, idx) => (
|
|
|
+ <div key={idx} className="text-sm">{date}</div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+ <td className="px-8 py-6">
|
|
|
+ <span className="text-vista-gold font-bold">{item.price}</span>
|
|
|
+ </td>
|
|
|
+ <td className="px-8 py-6">
|
|
|
+ <button
|
|
|
+ className="px-4 py-2 bg-vista-gold text-white font-bold tracking-widest uppercase text-xs rounded-full hover:bg-vista-darkblue transition-all duration-300"
|
|
|
+ onClick={() => setSelectedItinerary(item)}
|
|
|
+ >
|
|
|
+ {t.home.details}
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ ))}
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ {/* Itinerary Details Modal */}
|
|
|
+ {selectedItinerary && (
|
|
|
+ <div className="fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4 overflow-y-auto">
|
|
|
+ <div className="bg-white rounded-lg max-w-4xl w-full max-h-[90vh] overflow-y-auto transform transition-all duration-500 ease-out scale-100 opacity-100">
|
|
|
+ <div className="relative h-80 overflow-hidden">
|
|
|
+ <img
|
|
|
+ src={selectedItinerary.image}
|
|
|
+ alt={selectedItinerary.title}
|
|
|
+ className="w-full h-full object-cover transition-transform duration-500 hover:scale-105"
|
|
|
+ />
|
|
|
+ <button
|
|
|
+ className="absolute top-4 right-4 bg-white/90 backdrop-blur-sm rounded-full p-3 hover:bg-white transition-all duration-300 shadow-lg hover:shadow-xl"
|
|
|
+ onClick={() => setSelectedItinerary(null)}
|
|
|
+ >
|
|
|
+ <X size={24} className="text-vista-darkblue" />
|
|
|
+ </button>
|
|
|
+ <div className="absolute top-4 left-4 bg-white/95 backdrop-blur-sm px-4 py-2 rounded-full text-xs font-bold tracking-widest uppercase z-10 text-vista-darkblue shadow-sm">
|
|
|
+ {selectedItinerary.days} {t.home.days}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="p-8">
|
|
|
+ <div className="flex flex-col md:flex-row md:items-center justify-between mb-8">
|
|
|
+ <div>
|
|
|
+ <h2 className="text-3xl md:text-4xl font-serif text-vista-darkblue mb-2 leading-tight">{selectedItinerary.title}</h2>
|
|
|
+ <div className="flex items-center text-xs text-vista-darkblue/50 uppercase tracking-widest">
|
|
|
+ <MapPin size={14} className="mr-1" />
|
|
|
+ {selectedItinerary.route}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className="mt-4 md:mt-0 flex items-center gap-8">
|
|
|
+ <div className="flex items-center gap-2">
|
|
|
+ <Calendar size={20} className="text-vista-gold" />
|
|
|
+ <span className="text-vista-darkblue font-bold">{selectedItinerary.days}天{selectedItinerary.days - 1}晚</span>
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center gap-2">
|
|
|
+ <DollarSign size={20} className="text-vista-gold" />
|
|
|
+ <span className="text-vista-gold font-serif italic text-2xl">{selectedItinerary.price}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="space-y-10">
|
|
|
+ <div>
|
|
|
+ <h3 className="text-xl font-serif text-vista-darkblue mb-5 uppercase tracking-wider">{t.features[2].title}</h3>
|
|
|
+ <p className="text-vista-darkblue/80 leading-relaxed text-lg">
|
|
|
+ {selectedItinerary.description}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <h3 className="text-xl font-serif text-vista-darkblue mb-5 uppercase tracking-wider">行程亮点</h3>
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
+ {selectedItinerary.highlights.map((highlight: string, index: number) => (
|
|
|
+ <div key={index} className="flex items-start gap-3 p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
|
|
|
+ <div className="w-3 h-3 bg-vista-gold rounded-full mt-2 flex-shrink-0"></div>
|
|
|
+ <span className="text-vista-darkblue/80 leading-relaxed">{highlight}</span>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <h3 className="text-xl font-serif text-vista-darkblue mb-5 uppercase tracking-wider">每日行程</h3>
|
|
|
+ <div className="relative space-y-12">
|
|
|
+ {/* Timeline line */}
|
|
|
+ <div className="absolute left-1/2 transform -translate-x-1/2 w-1 bg-vista-gold/20 h-full"></div>
|
|
|
+
|
|
|
+ {selectedItinerary.itinerary.map((day: any, index: number) => (
|
|
|
+ <div key={index} className={`relative flex ${index % 2 === 0 ? 'md:flex-row' : 'md:flex-row-reverse'} items-center gap-8`}>
|
|
|
+ {/* Timeline dot */}
|
|
|
+ <div className="absolute left-1/2 transform -translate-x-1/2 w-6 h-6 rounded-full bg-vista-gold border-4 border-white shadow-lg z-10 flex items-center justify-center">
|
|
|
+ <span className="text-white text-xs font-bold">{day.day}</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Content card */}
|
|
|
+ <div className="w-full md:w-5/12 bg-white border border-gray-100 rounded-lg p-6 shadow-md hover:shadow-xl transition-all duration-300">
|
|
|
+ <div className="flex items-center justify-between mb-3">
|
|
|
+ <h4 className="text-lg font-bold text-vista-darkblue">{day.title}</h4>
|
|
|
+ <span className="text-xs font-bold text-vista-gold uppercase tracking-wider">第 {day.day} 天</span>
|
|
|
+ </div>
|
|
|
+ <p className="text-vista-darkblue/80 leading-relaxed">{day.description}</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Empty space for alternating layout */}
|
|
|
+ <div className="hidden md:block w-5/12"></div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-12 flex justify-center">
|
|
|
+ <button className="px-12 py-5 bg-vista-gold text-white font-bold tracking-widest uppercase text-sm hover:bg-vista-darkblue transition-all duration-300 shadow-lg hover:shadow-xl transform hover:-translate-y-1">
|
|
|
+ {t.nav.book}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <Footer />
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default Itineraries;
|