import React, { useEffect, useState } from 'react';
import { Formik, Form, Field, FieldArray } from 'formik';
import { FIRST_NAME, LAST_NAME, USER_ID } from '../constants';
import { createResourceCombination, createTrip, fetchCustomers, fetchDrivers } from '../services/api';
import InitialDateTime from '../components/InitialDateTime';
import { v4 as uuidv4 } from 'uuid';
import '../styles/AddTrip.css';
// Interfaces
interface Customer {
id: number;
name: string;
}
interface Driver {
id: number;
first_name: string;
last_name: string;
}
interface Trip {
trip_number: string;
start_location: string;
start_location_activity: string;
start_time: string;
end_time: string;
end_location: string;
end_location_activity: string;
start_km: number;
end_km: number;
break_time: string;
editable: boolean;
}
interface FormValues {
trip_number: string;
break_time: string;
date: string;
customer: string;
truck: string;
trailer: string;
ept: boolean;
trips: Trip[];
}
const initialValues: FormValues = {
trip_number: '',
break_time: '',
date: '',
customer: '',
truck: '',
trailer: '',
ept: false,
trips: [
{
trip_number: '',
start_location: '',
start_location_activity: '',
start_time: '',
end_time: '',
end_location: '',
end_location_activity: '',
start_km: 0,
end_km: 0,
break_time: '',
editable: true,
},
],
};
const AddTripPage: React.FC = () => {
const [customers, setCustomers] = useState<Customer[]>([]);
const [drivers, setDrivers] = useState<Driver[]>([]);
const [currentDriver, setCurrentDriver] = useState<Driver | null>(null);
const [savedTrips, setSavedTrips] = useState<Trip[]>([]);
useEffect(() => {
fetchCustomers()
.then((data) => {
setCustomers(data);
})
.catch((error) => {
console.error('Failed to fetch customers:', error);
});
fetchDrivers()
.then((data) => {
setDrivers(data);
setCurrentDriver(data[0]); // Assuming the first driver in the list is the current user
})
.catch((error) => {
console.error('Failed to fetch drivers:', error);
});
// Retrieve saved trips from localStorage
const savedTripsData = localStorage.getItem('savedTrips');
if (savedTripsData) {
setSavedTrips(JSON.parse(savedTripsData));
}
}, []);
// Save trips to localStorage when the component unmounts
useEffect(() => {
return () => {
localStorage.setItem('savedTrips', JSON.stringify(savedTrips));
};
}, [savedTrips]);
const handleAddTrip = (push: (trip: Trip) => void) => {
const newTrip: Trip = {
trip_number: '',
start_location: '',
start_location_activity: '',
start_time: '',
end_time: '',
end_location: '',
end_location_activity: '',
start_km: 0,
end_km: 0,
break_time: '',
editable: true,
};
push(newTrip);
};
const handleRemoveTrip = (remove: (index: number) => void, index: number) => {
remove(index);
};
const handleSubmit = async (values: FormValues, actions: any) => {
try {
const userIdString = localStorage.getItem(USER_ID);
const userId = userIdString ? parseInt(userIdString, 10) : null;
if (userId === null || isNaN(userId)) {
throw new Error('Invalid user ID');
}
const resourceCombinationData = {
rc_id: uuidv4(),
driver: userId,
truck: values.truck,
trailer: values.trailer,
date: values.date,
ept: values.ept,
};
const resourceCombinationResponse = await createResourceCombination(resourceCombinationData);
const rcId = resourceCombinationResponse.rc_id;
const validatedTrips = values.trips.reduce((acc, trip) => {
const {
resource_combination,
customer,
trip_number,
start_location,
start_location_activity,
start_time,
start_km,
end_location,
end_location_activity,
end_time,
end_km,
} = trip;
const missingFields = [];
if (!resource_combination) missingFields.push('resource_combination');
if (!customer) missingFields.push('customer');
if (!trip_number) missingFields.push('trip_number');
if (!start_location) missingFields.push('start_location');
if (!start_location_activity) missingFields.push('start_location_activity');
if (!start_time) missingFields.push('start_time');
if (!start_km) missingFields.push('start_km');
if (!end_location) missingFields.push('end_location');
if (!end_location_activity) missingFields.push('end_location_activity');
if (!end_time) missingFields.push('end_time');
if (!end_km) missingFields.push('end_km');
if (missingFields.length > 0) {
console.warn(`Skipping trip ${trip_number} due to missing fields: ${missingFields.join(', ')}`);
return acc;
}
// Calculate Total Kilometers (total_km)
const europeanStyleTotalKm = (end_km - start_km).toFixed(2).replace('.', ',');
// Calculate Total Hours (total_hours)
let total_hours = (new Date(end_time).getTime() - new Date(start_time).getTime()) / (1000 * 60 * 60);
if (new Date(end_time).getTime() < new Date(start_time).getTime()) {
// Trip went over time, add 24 hours to end_time
total_hours += 24;
}
total_hours -= new Date(trip.break_time).getHours();
if (total_hours < 0) {
throw new Error(`Total hours cannot be negative for trip: ${trip_number}`);
}
// Fix Time Display Issue (Time Server)
const formattedStartTime = new Date(start_time).toLocaleString();
const formattedEndTime = new Date(end_time).toLocaleString();
acc.push({
resource_combination: rcId,
customer: parseInt(customer, 10),
trip_number,
start_location,
start_location_activity,
start_time: formattedStartTime,
start_km,
end_location,
end_location_activity,
end_time: formattedEndTime,
end_km,
break_time: trip.break_time,
total_km: europeanStyleTotalKm,
total_hours,
});
return acc;
}, []);
console.log('POST Request Payload:', { trips: validatedTrips });
if (validatedTrips.length === 0) {
throw new Error('No valid trips found');
}
await createTrip({ trips: validatedTrips });
actions.setSubmitting(false);
actions.resetForm();
} catch (error) {
console.error('Failed to submit:', error);
actions.setSubmitting(false);
}
};