Sửa lỗi khi click vào dấu + để thêm chặng

This commit is contained in:
2026-06-14 09:37:40 +07:00
parent 14bf43487e
commit 4545bde8ec
13 changed files with 139 additions and 133 deletions
+44 -57
View File
@@ -35,8 +35,8 @@ const formatTravelTime = (minutes: number) => {
return mins > 0 ? `${hours} giờ ${mins} phút` : `${hours} giờ`;
};
export const ItineraryTimeline = () => {
const { currentTour, legs, optimizeRouting, userRole, activeLegId, setActiveLegId, addLeg, updateLeg, deleteLeg, initializeLegs } = useTourStore();
export const ItineraryTimeline = ({ onAddLocation }: { onAddLocation?: (legId: string) => void }) => {
const { currentTour, legs, optimizeRouting, userRole, addLeg, updateLeg, deleteLeg, initializeLegs } = useTourStore();
const toggleComplete = async (locationId: string) => {
// Gọi API PATCH /api/v1/locations/:id để cập nhật trạng thái
@@ -75,51 +75,16 @@ export const ItineraryTimeline = () => {
}
};
const activeLeg = legs.find(l => l.id === activeLegId) || legs[0];
return (
<div className="max-w-2xl mx-auto p-0 bg-gray-50 min-h-screen">
{/* Tầng 1: Horizontal Leg Picker (6.3-A) */}
<div className="sticky top-[136px] z-20 bg-gray-50/80 backdrop-blur-sm pb-4 mb-4">
<div className="flex overflow-x-auto gap-2 px-2 no-scrollbar py-2">
{legs.map((leg) => (
<button
key={leg.id}
onClick={() => setActiveLegId(leg.id)}
className={`flex-shrink-0 px-6 py-2.5 rounded-2xl text-xs font-black uppercase tracking-widest transition-all border ${
activeLegId === leg.id
? 'bg-blue-600 text-white border-blue-600 shadow-lg shadow-blue-100 scale-105'
: 'bg-white text-gray-400 border-gray-100 hover:border-gray-200'
}`}
>
Chặng {leg.sequence}
</button>
))}
{['OWNER', 'MANAGER'].includes(userRole || '') && (
<button
onClick={handleDeclareLegs}
className="flex-shrink-0 px-4 py-2.5 rounded-2xl bg-blue-50 text-blue-600 border border-dashed border-blue-200 hover:bg-blue-100 transition-all flex items-center gap-2 text-xs font-bold"
title="Khai báo nhanh số lượng chặng"
>
<List className="w-4 h-4" /> Khai báo số chặng
</button>
)}
{['OWNER', 'MANAGER'].includes(userRole || '') && (
<button
onClick={handleAddLeg}
className="flex-shrink-0 p-2.5 rounded-2xl bg-white text-blue-600 border border-dashed border-blue-200 hover:bg-blue-50 transition-all flex items-center justify-center w-12"
>
<Plus className="w-5 h-5" />
</button>
)}
</div>
</div>
<div className="px-2">
{activeLeg && (
<div className="relative animate-in fade-in slide-in-from-right-4 duration-300">
{/* Leg Info Summary */}
{(() => {
const leg = activeLeg;
<div className="px-2 pt-4">
{legs.length === 0 ? (
<div className="text-center py-20 bg-white rounded-3xl border-2 border-dashed border-gray-200">
<List className="w-12 h-12 text-gray-300 mx-auto mb-4" />
<p className="text-gray-500 font-medium">Chưa chặng nào trong lộ trình.</p>
</div>
) : (
legs.map((leg, legIdx) => {
const totalDwellMinutes = leg.locations.reduce((acc: number, loc: any) => {
if (loc.plannedStart && loc.plannedEnd) {
return acc + differenceInMinutes(parseISO(loc.plannedEnd), parseISO(loc.plannedStart));
@@ -128,15 +93,25 @@ export const ItineraryTimeline = () => {
}, 0);
return (
<>
<div key={leg.id} className="relative mb-12 animate-in fade-in slide-in-from-bottom-4 duration-300">
{/* Leg Header */}
<div className="flex items-center mb-4 px-2">
<div className="font-black text-gray-900 text-lg truncate flex-1">
<div className="sticky top-[136px] z-20 bg-gray-50/90 backdrop-blur-sm flex items-center mb-6 py-2 px-2">
<div className="font-black text-blue-600 text-xl truncate flex-1 flex items-center gap-2">
<span className="bg-blue-600 text-white w-8 h-8 rounded-lg flex items-center justify-center text-sm">
{leg.sequence}
</span>
{leg.note || `Chi tiết Chặng ${leg.sequence}`}
</div>
<div className="flex items-center gap-2 ml-4">
{['OWNER', 'MANAGER'].includes(userRole || '') && (
<>
<button
onClick={() => onAddLocation?.(leg.id)}
className="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-xl transition-all"
title="Thêm địa điểm vào chặng này"
>
<Plus className="w-4 h-4" />
</button>
<button
onClick={() => handleEditLeg(leg)}
className="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-xl transition-all"
@@ -181,7 +156,7 @@ export const ItineraryTimeline = () => {
</div>
{/* Vertical Line for the whole leg */}
<div className="absolute left-6 top-10 bottom-0 w-0.5 bg-gray-200 -z-0" />
<div className="absolute left-6 top-16 bottom-0 w-0.5 bg-blue-100 -z-0" />
<div className="ml-2">
{leg.locations.map((location, idx) => {
@@ -282,15 +257,27 @@ export const ItineraryTimeline = () => {
);
})}
</div>
{leg.note && (
<p className="ml-14 mt-4 text-sm text-gray-400 italic">
* {leg.note}
</p>
)}
</>
</div>
);
})()}
})
)}
{/* Actions at the bottom of the list */}
{['OWNER', 'MANAGER'].includes(userRole || '') && (
<div className="flex flex-col gap-3 pb-20 mt-8">
<button
onClick={handleDeclareLegs}
className="w-full py-4 rounded-2xl bg-white text-blue-600 border-2 border-dashed border-blue-200 hover:bg-blue-50 transition-all flex items-center justify-center gap-2 text-sm font-bold"
>
<List className="w-5 h-5" />
{legs.length > 0 ? "Khai báo lại số lượng chặng" : "Bắt đầu bằng việc khai báo số chặng"}
</button>
<button
onClick={handleAddLeg}
className="w-full py-4 rounded-2xl bg-blue-600 text-white shadow-lg shadow-blue-100 hover:bg-blue-700 transition-all flex items-center justify-center gap-2 text-sm font-bold"
>
<Plus className="w-5 h-5" /> Thêm chặng lẻ vào cuối
</button>
</div>
)}
</div>