feat: cập nhật giao diện tour hiển thị mô tả trên banner

This commit is contained in:
2026-06-15 21:28:41 +07:00
parent dcaf71032c
commit c5530f36df
+51 -8
View File
@@ -178,6 +178,8 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
const [selectedMember, setSelectedMember] = useState<any>(null); const [selectedMember, setSelectedMember] = useState<any>(null);
const [isMemberDetailOpen, setIsMemberDetailOpen] = useState(false); const [isMemberDetailOpen, setIsMemberDetailOpen] = useState(false);
const [joinRequests, setJoinRequests] = useState<any[]>([]); const [joinRequests, setJoinRequests] = useState<any[]>([]);
const [titleInput, setTitleInput] = useState(currentTour?.title ?? '');
const [descriptionInput, setDescriptionInput] = useState(currentTour?.description ?? '');
// State cho input số lượng người tham gia // State cho input số lượng người tham gia
const [adultCountInput, setAdultCountInput] = useState(currentTour?.adultCount ?? 0); const [adultCountInput, setAdultCountInput] = useState(currentTour?.adultCount ?? 0);
const [childCountInput, setChildCountInput] = useState(currentTour?.childCount ?? 0); const [childCountInput, setChildCountInput] = useState(currentTour?.childCount ?? 0);
@@ -340,18 +342,20 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
}; };
// Hàm xử lý cập nhật số lượng người tham gia // Hàm xử lý cập nhật số lượng người tham gia
const handleUpdateParticipantCounts = async () => { const handleUpdateTourInfo = async () => {
if (!currentTour) return; if (!currentTour) return;
try { try {
await updateTourDetails(currentTour.id, { await updateTourDetails(currentTour.id, {
title: titleInput,
description: descriptionInput,
adultCount: adultCountInput, adultCount: adultCountInput,
childCount: childCountInput, childCount: childCountInput,
childDiscount: childDiscountInput, childDiscount: childDiscountInput,
}); });
notificationModal.openModal('Thành công', 'Đã cập nhật số lượng người tham gia.', 'success'); notificationModal.openModal('Thành công', 'Đã cập nhật thông tin chuyến đi.', 'success');
fetchTour(currentTour.id); // Re-fetch tour để cập nhật lại các tính toán liên quan fetchTour(currentTour.id); // Re-fetch tour để cập nhật lại các tính toán liên quan
} catch (error: any) { } catch (error: any) {
notificationModal.openModal('Lỗi', error.message || 'Không thể cập nhật số lượng người tham gia.', 'error'); notificationModal.openModal('Lỗi', error.message || 'Không thể cập nhật thông tin.', 'error');
} }
}; };
// Xác định Điểm xuất phát và Điểm kết thúc hiển thị dưới widget tài chính // Xác định Điểm xuất phát và Điểm kết thúc hiển thị dưới widget tài chính
@@ -428,6 +432,14 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
<div className="relative z-10 p-6 text-white pt-28 pb-20"> <div className="relative z-10 p-6 text-white pt-28 pb-20">
<div className="max-w-2xl mx-auto space-y-4"> <div className="max-w-2xl mx-auto space-y-4">
<h2 className="text-3xl font-black tracking-tight drop-shadow-md">{tourInfo.title}</h2> <h2 className="text-3xl font-black tracking-tight drop-shadow-md">{tourInfo.title}</h2>
{currentTour?.description && (
<p className="text-sm md:text-base text-white/90 max-w-xl line-clamp-3 md:line-clamp-none bg-black/20 backdrop-blur-sm p-4 rounded-2xl border border-white/10 italic leading-relaxed">
<Quote className="w-4 h-4 inline-block mr-2 opacity-50" />
{currentTour.description}
</p>
)}
{/* Dòng tóm tắt Lộ trình */} {/* Dòng tóm tắt Lộ trình */}
<div className="mt-3 text-[11px] sm:text-sm font-bold text-white bg-black/40 backdrop-blur-md px-4 py-2 rounded-xl border border-white/10 inline-flex items-center max-w-full"> <div className="mt-3 text-[11px] sm:text-sm font-bold text-white bg-black/40 backdrop-blur-md px-4 py-2 rounded-xl border border-white/10 inline-flex items-center max-w-full">
<span className="text-white/60 mr-1">Lộ trình:</span> <span className="text-white/60 mr-1">Lộ trình:</span>
@@ -819,13 +831,43 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
</div> </div>
</div> </div>
{canEdit && ( // Chỉ OWNER và MANAGER mới có thể chỉnh sửa phần này {canEdit && (
<div className="p-6 bg-white rounded-3xl border border-gray-100 shadow-sm animate-in zoom-in-95"> <div className="p-6 bg-white rounded-3xl border border-gray-100 shadow-sm animate-in zoom-in-95">
<div className="flex items-center gap-3 mb-6">
<Settings className="w-6 h-6 text-blue-500" />
<h3 className="text-lg font-bold text-gray-900">Thông tin bản</h3>
</div>
<div className="space-y-4 mb-8">
{isOwner && (
<>
<div>
<label className="block text-xs font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Tiêu đ Tour</label>
<input
type="text"
value={titleInput}
onChange={(e) => setTitleInput(e.target.value)}
className="w-full px-4 py-3 bg-gray-50 border border-gray-100 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm font-bold"
placeholder="Nhập tên chuyến đi..."
/>
</div>
<div>
<label className="block text-xs font-black text-gray-400 uppercase tracking-widest mb-2 ml-1"> tả chuyến đi</label>
<textarea
value={descriptionInput}
onChange={(e) => setDescriptionInput(e.target.value)}
className="w-full px-4 py-3 bg-gray-50 border border-gray-100 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm min-h-[100px] resize-none"
placeholder="Viết vài dòng giới thiệu về hành trình này..."
/>
</div>
</>
)}
<div className="flex items-center gap-3 mb-4"> <div className="flex items-center gap-3 mb-4">
<Users className="w-6 h-6 text-purple-500" /> <Users className="w-6 h-6 text-purple-500" />
<h3 className="text-lg font-bold text-gray-900">Quản s lượng người tham gia</h3> <h3 className="text-md font-bold text-gray-800">S lượng người tham gia</h3>
</div> </div>
<div className="space-y-4"> <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div> <div>
<label htmlFor="adultCount" className="block text-sm font-medium text-gray-700 mb-1">Số lượng người lớn</label> <label htmlFor="adultCount" className="block text-sm font-medium text-gray-700 mb-1">Số lượng người lớn</label>
<input <input
@@ -860,9 +902,10 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-blue-500 focus:border-blue-500" className="w-full px-4 py-2 border border-gray-200 rounded-xl focus:ring-blue-500 focus:border-blue-500"
/> />
</div> </div>
</div>
<button <button
onClick={handleUpdateParticipantCounts} onClick={handleUpdateTourInfo}
className="w-full px-4 py-3 bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-xl transition-all shadow-md" className="w-full mt-6 px-4 py-4 bg-blue-600 hover:bg-blue-700 text-white font-black uppercase tracking-widest rounded-2xl transition-all shadow-lg shadow-blue-100 active:scale-95"
> >
Lưu thay đi Lưu thay đi
</button> </button>