Files
travelplanning/dist/TourDetailPage.js
T

50 lines
8.8 KiB
JavaScript

import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useEffect, useMemo } from 'react';
import { ItineraryTimeline } from './ItineraryTimeline.js';
import { ExpenseManager } from './ExpenseManager.js';
import { useTourStore } from './useTourStore.js';
import { AddLocationModal } from './AddLocationModal.js';
import { Map as MapIcon, Wallet, Image as ImageIcon, Calendar, Users, ChevronLeft, Settings, Quote, Plus } from 'lucide-react';
export const TourDetailPage = ({ onBack }) => {
const [activeTab, setActiveTab] = useState('plan');
const [isAddLocationOpen, setIsAddLocationOpen] = useState(false);
const { currentTour, fetchTour, fetchPublicTours, publicTours, userRole } = useTourStore();
useEffect(() => {
const loadData = async () => {
if (publicTours.length === 0) {
await fetchPublicTours();
}
};
loadData();
}, []);
useEffect(() => {
if (publicTours.length > 0 && !currentTour) {
fetchTour(publicTours[0].id);
}
}, [publicTours, currentTour, fetchTour]);
const tabs = [
{ id: 'plan', label: 'Lộ trình', icon: MapIcon, visible: true },
{ id: 'expense', label: 'Chi phí', icon: Wallet, visible: ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '') },
{ id: 'photo', label: 'Ảnh', icon: ImageIcon, visible: true },
{ id: 'settings', label: 'Cài đặt', icon: Settings, visible: ['OWNER', 'MANAGER'].includes(userRole || '') },
].filter(t => t.visible);
const hasFinanceAccess = ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '');
const travelQuotes = [
"Đừng nghe họ nói, hãy tự mình đi xem.",
"Thế giới là một cuốn sách, và ai không đi du lịch thì chỉ mới đọc được một trang.",
"Hành trình ngàn dặm bắt đầu từ một bước chân.",
"Đi là để trở về, nhưng với một tâm hồn mới."
];
const randomQuote = useMemo(() => travelQuotes[Math.floor(Math.random() * travelQuotes.length)], []);
const tourInfo = {
title: currentTour?.title || "Hành trình khám phá TP.HCM",
date: currentTour?.startDate ? `${new Date(currentTour.startDate).toLocaleDateString('vi-VN')} - ${new Date(currentTour.endDate).toLocaleDateString('vi-VN')}` : "Chưa xác định ngày",
membersCount: currentTour?.participants?.length || 0,
budget: currentTour?.totalCost ? `${Number(currentTour.totalCost).toLocaleString()} VND` : "0 VND",
coverImage: currentTour?.photos?.[0]?.imageUrl || "https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?q=80&w=2070&auto=format&fit=crop"
};
return (_jsxs("div", { className: "min-h-screen bg-gray-50 pb-20", children: [_jsxs("div", { className: "sticky top-0 z-30 bg-white/80 backdrop-blur-md border-b border-gray-100 px-4 py-3 flex items-center justify-between", children: [_jsx("button", { onClick: onBack, className: "p-2 hover:bg-gray-100 rounded-full transition-colors", children: _jsx(ChevronLeft, { className: "w-6 h-6 text-gray-600" }) }), _jsx("h1", { className: "text-lg font-bold text-gray-800 truncate px-4", children: tourInfo.title }), _jsx("div", { className: "w-10" }), " "] }), _jsxs("div", { className: "relative h-64 w-full bg-blue-900", children: [_jsx("img", { src: tourInfo.coverImage, className: "w-full h-full object-cover opacity-60", alt: "Tour Cover" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent" }), _jsx("div", { className: "absolute bottom-16 left-0 right-0 p-6 text-white", children: _jsxs("div", { className: "max-w-2xl mx-auto space-y-2", children: [_jsx("h2", { className: "text-3xl font-black tracking-tight drop-shadow-md", children: tourInfo.title }), _jsxs("div", { className: "flex flex-wrap gap-4 text-sm font-medium opacity-90", children: [_jsxs("div", { className: "flex items-center bg-black/20 backdrop-blur-sm px-3 py-1 rounded-full border border-white/10", children: [_jsx(Calendar, { className: "w-4 h-4 mr-1.5" }), tourInfo.date] }), _jsxs("div", { className: "flex items-center bg-black/20 backdrop-blur-sm px-3 py-1 rounded-full border border-white/10", children: [_jsx(Users, { className: "w-4 h-4 mr-1.5" }), tourInfo.membersCount, " th\u00E0nh vi\u00EAn"] })] }), _jsxs("div", { className: "flex items-center gap-2 mt-4", children: [_jsxs("div", { className: "flex -space-x-3", children: [currentTour?.participants?.slice(0, 5).map((p, i) => (_jsx("div", { className: "w-10 h-10 rounded-full border-2 border-white bg-blue-100 flex items-center justify-center text-blue-600 font-bold overflow-hidden shadow-lg", children: _jsx("img", { src: `https://i.pravatar.cc/100?u=${p.userId}`, alt: "Avatar" }) }, i))), tourInfo.membersCount > 5 && (_jsxs("div", { className: "w-10 h-10 rounded-full border-2 border-white bg-gray-800 flex items-center justify-center text-[10px] font-bold text-white shadow-lg", children: ["+", tourInfo.membersCount - 5] }))] }), _jsx("button", { className: "p-2 bg-white/10 hover:bg-white/20 rounded-full border border-white/20 backdrop-blur-sm transition-all ml-2", children: _jsx(Plus, { className: "w-4 h-4" }) })] })] }) })] }), _jsx("div", { className: "max-w-2xl mx-auto -mt-10 px-4 relative z-10", children: _jsx("div", { className: `rounded-3xl p-6 shadow-2xl transition-all duration-500 ${hasFinanceAccess ? 'bg-indigo-600 text-white shadow-indigo-200' : 'bg-white text-gray-600 border border-gray-100'}`, children: _jsx("div", { className: "flex justify-between items-center", children: hasFinanceAccess ? (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsx("p", { className: "text-indigo-100 text-xs font-black uppercase tracking-widest mb-1", children: "T\u1ED5ng chi ti\u00EAu hi\u1EC7n t\u1EA1i" }), _jsx("h3", { className: "text-3xl font-black", children: tourInfo.budget })] }), _jsx("div", { className: "p-4 bg-white/10 rounded-2xl backdrop-blur-md", children: _jsx(Wallet, { className: "w-8 h-8" }) })] })) : (_jsxs("div", { className: "flex items-start gap-4 py-2", children: [_jsx(Quote, { className: "w-8 h-8 text-blue-500 opacity-30 flex-shrink-0" }), _jsxs("p", { className: "italic text-lg font-medium leading-relaxed", children: ["\"", randomQuote, "\""] })] })) }) }) }), _jsxs("div", { className: "max-w-2xl mx-auto mt-6 px-4 pb-24", children: [_jsx("div", { className: "bg-white rounded-2xl shadow-lg border border-gray-100 p-1 flex mb-6 sticky top-20 z-20", children: tabs.map((tab) => (_jsxs("button", { onClick: () => setActiveTab(tab.id), className: `flex-1 flex items-center justify-center py-3 rounded-xl text-sm font-semibold transition-all ${activeTab === tab.id
? 'bg-blue-50 text-blue-600 shadow-sm'
: 'text-gray-400 hover:text-gray-500 hover:bg-gray-50'}`, children: [_jsx(tab.icon, { className: `w-4 h-4 mr-2 ${activeTab === tab.id ? 'scale-110' : ''}` }), tab.label] }, tab.id))) }), _jsxs("div", { className: "transition-opacity duration-300", children: [activeTab === 'plan' && (_jsx("div", { className: "animate-in fade-in slide-in-from-bottom-4", children: _jsx(ItineraryTimeline, {}) })), activeTab === 'expense' && (_jsx("div", { className: "animate-in fade-in slide-in-from-bottom-4", children: _jsx(ExpenseManager, {}) })), activeTab === 'photo' && (_jsx("div", { className: "grid grid-cols-3 gap-1.5 animate-in fade-in", children: [1, 2, 3, 4, 5, 6].map((i) => (_jsxs("div", { className: "aspect-square bg-gray-200 rounded-xl overflow-hidden relative group border border-white", children: [_jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors" }), _jsx("img", { src: `https://picsum.photos/seed/${i + 10}/400/400`, alt: "Tour photo", className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" })] }, i))) })), activeTab === 'settings' && (_jsxs("div", { className: "p-8 text-center bg-white rounded-3xl border border-dashed border-gray-200 animate-in zoom-in-95", children: [_jsx(Settings, { className: "w-12 h-12 text-gray-300 mx-auto mb-4" }), _jsx("p", { className: "text-gray-500 font-medium", children: "T\u00EDnh n\u0103ng qu\u1EA3n l\u00FD th\u00E0nh vi\u00EAn \u0111ang \u0111\u01B0\u1EE3c c\u1EADp nh\u1EADt..." })] }))] })] }), _jsx("div", { className: "fixed bottom-6 left-1/2 -translate-x-1/2 z-40", children: _jsx("button", { onClick: () => activeTab === 'plan' ? setIsAddLocationOpen(true) : null, className: "bg-blue-600 text-white px-6 py-3 rounded-full shadow-lg hover:bg-blue-700 transition-all flex items-center font-bold", children: activeTab === 'plan' ? 'Thêm địa điểm' : activeTab === 'expense' ? 'Thêm chi phí' : 'Đăng ảnh' }) }), currentTour && (_jsx(AddLocationModal, { isOpen: isAddLocationOpen, onClose: () => setIsAddLocationOpen(false), tourId: currentTour.id }))] }));
};
//# sourceMappingURL=TourDetailPage.js.map