trip-planner/frontend/src/components/timeline/TripTimeline.jsx

98 lines
2.6 KiB
React
Raw Normal View History

import { useState, useEffect } from 'react';
import DaySection from './DaySection';
import axios from 'axios';
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
function TripTimeline({ trip, plannableItems, onScheduleSuccess }) {
const [calendarSlots, setCalendarSlots] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchCalendarSlots();
}, [trip.id]);
const fetchCalendarSlots = async () => {
try {
const token = localStorage.getItem('token');
const response = await axios.get(`${API_URL}/api/trips/${trip.id}/calendar-slots`, {
headers: { Authorization: `Bearer ${token}` }
});
setCalendarSlots(response.data.data || []);
} catch (error) {
console.error('Error fetching calendar slots:', error);
} finally {
setLoading(false);
}
};
const handleScheduleItem = async (plannableItemId, startDatetime, endDatetime) => {
try {
const token = localStorage.getItem('token');
await axios.post(
`${API_URL}/api/planned-items`,
{
plannable_item_id: plannableItemId,
trip_id: trip.id,
start_datetime: startDatetime,
end_datetime: endDatetime,
},
{
headers: { Authorization: `Bearer ${token}` }
}
);
await fetchCalendarSlots();
if (onScheduleSuccess) {
onScheduleSuccess();
}
} catch (error) {
console.error('Error scheduling item:', error);
throw error;
}
};
const generateDays = () => {
const days = [];
const start = new Date(trip.start_date);
const end = new Date(trip.end_date);
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
days.push(new Date(d));
}
return days;
};
const getSlotsForDay = (date) => {
const dateString = date.toISOString().split('T')[0];
return calendarSlots.filter(slot => slot.slot_date === dateString);
};
if (loading) {
return <div className="p-4 text-gray-500">Loading timeline...</div>;
}
const days = generateDays();
return (
<div className="trip-timeline">
<h3 className="text-xl font-semibold mb-4">Trip Timeline</h3>
<div className="space-y-8">
{days.map((day, index) => (
<DaySection
key={day.toISOString()}
date={day}
dayNumber={index + 1}
slots={getSlotsForDay(day)}
plannableItems={plannableItems}
onScheduleItem={handleScheduleItem}
/>
))}
</div>
</div>
);
}
export default TripTimeline;