feat: cập nhật giao diện tour hiển thị mô tả trên banner
This commit is contained in:
@@ -178,6 +178,8 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
|
||||
const [selectedMember, setSelectedMember] = useState<any>(null);
|
||||
const [isMemberDetailOpen, setIsMemberDetailOpen] = useState(false);
|
||||
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
|
||||
const [adultCountInput, setAdultCountInput] = useState(currentTour?.adultCount ?? 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
|
||||
const handleUpdateParticipantCounts = async () => {
|
||||
const handleUpdateTourInfo = async () => {
|
||||
if (!currentTour) return;
|
||||
try {
|
||||
await updateTourDetails(currentTour.id, {
|
||||
title: titleInput,
|
||||
description: descriptionInput,
|
||||
adultCount: adultCountInput,
|
||||
childCount: childCountInput,
|
||||
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
|
||||
} 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
|
||||
@@ -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="max-w-2xl mx-auto space-y-4">
|
||||
<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 */}
|
||||
<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>
|
||||
@@ -819,13 +831,43 @@ export const TourDetailPage = ({ onBack }: { onBack: () => void }) => {
|
||||
</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="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 cơ 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">Mô 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">
|
||||
<Users className="w-6 h-6 text-purple-500" />
|
||||
<h3 className="text-lg font-bold text-gray-900">Quản lý 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 className="space-y-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<label htmlFor="adultCount" className="block text-sm font-medium text-gray-700 mb-1">Số lượng người lớn</label>
|
||||
<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"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleUpdateParticipantCounts}
|
||||
className="w-full px-4 py-3 bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-xl transition-all shadow-md"
|
||||
onClick={handleUpdateTourInfo}
|
||||
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
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user