2025-04-14 16:29:36 -04:00

297 lines
14 KiB
JavaScript

import React, {useEffect, useState} from "react";
import { useSelector,useDispatch } from "react-redux";
import { useParams, useNavigate } from "react-router-dom";
import { selectAllRoutes, transRoutesSlice, vehicleSlice, selectTomorrowAllRoutes, selectAllActiveDrivers, selectAllActiveVehicles, selectHistoryRoutes } from "./../../store";
import { Modal, Button } from "react-bootstrap";
import RouteCustomerEditor from "./RouteCustomerEditor";
import { AuthService, TransRoutesService } from "../../services";
import TimePicker from 'react-time-picker';
import 'react-time-picker/dist/TimePicker.css';
import moment from 'moment';
const RouteEdit = () => {
const params = useParams();
const allRoutes = useSelector(selectAllRoutes);
const tomorrowRoutes = useSelector(selectTomorrowAllRoutes);
const historyRoutes = useSelector(selectHistoryRoutes);
const drivers = useSelector(selectAllActiveDrivers);
const vehicles = useSelector(selectAllActiveVehicles);
// const currentRoute = (allRoutes.find(item => item.id === params.id)) || (tomorrowRoutes.find(item => item.id === params.id)) || (historyRoutes.find(item => item.id === params.id)) || {};
const currentVehicle = vehicles.find(item => item.id === currentRoute?.vehicle ) || [];
const navigate = useNavigate();
const dispatch = useDispatch();
const { updateRoute} = transRoutesSlice.actions;
const { updateVehicle} = vehicleSlice.actions;
const [routeName, setRouteName] = useState('');
const [newDriver, setNewDriver] = useState('');
const [newVehicle, setNewVehicle] = useState('');
const [newRouteType, setNewRouteType] = useState('');
const [showAddCheckItem, setShowAddCheckItem] = useState(false);
const [showCopyCheckItem, setShowCopyCheckItem] = useState(false);
const [newChecklistItems, setNewChecklistItems] = useState([]);
const [selectedRouteChecklistToCopy, setSelectedRouteChecklistToCopy] = useState({});
const [newCustomerList, setNewCustomerList] = useState([]);
const [errorMessage, setErrorMessage] = useState(undefined);
const [estimatedStartTime, setEstimatedStartTime] = useState(undefined);
const [currentRoute, setCurrentRoute] = useState(undefined);
const paramsQuery = new URLSearchParams(window.location.search);
const scheduleDate = paramsQuery.get('dateSchedule');
const redirectToView = () => {
if (scheduleDate) {
navigate(`/trans-routes/${params.id}?dateSchedule=${scheduleDate}`);
} else {
navigate(`/trans-routes/${params.id}`);
}
}
const redirectToDashboard = () => {
navigate(`/trans-routes/dashboard`);
}
const softDeleteCurrentRoute = () => {
const data = Object.assign({}, currentRoute, {status: ['disabled']})
dispatch(updateRoute({ id: currentRoute?.id, data, callback: redirectToDashboard }));
// redirectToDashboard();
}
const updateCurrentRoute = () => {
try {
if (!routeName || routeName === '') { setErrorMessage('Route Name is Required'); return;}
if (!newRouteType || newRouteType === '') {setErrorMessage('Route Type is Required'); return;}
if (!newDriver || newDriver === '') {setErrorMessage('Driver is Required'); return;}
if (!newVehicle || newVehicle === '') {setErrorMessage('Vehicle is Required'); return;}
let data = Object.assign({}, currentRoute, {name: routeName, driver: newDriver, vehicle: newVehicle, type: newRouteType, route_customer_list: newCustomerList});
if (estimatedStartTime && estimatedStartTime !== '') {
data = Object.assign({}, data, {estimated_start_time: combineDateAndTime(currentRoute.schedule_date, estimatedStartTime)})
}
let payload = { id: currentRoute?.id, data };
if ((historyRoutes.find(item => item.id === params.id)) || (scheduleDate && new Date(data.schedule_date) > new Date())) {
payload = Object.assign({}, payload, {dateText: data.schedule_date});
if (scheduleDate && new Date(data.schedule_date) > new Date()) {
payload = Object.assign({}, payload, {fromSchedule: true});
}
}
payload.callback = redirectToView;
dispatch(updateRoute(payload));
// TransRoutesService.updateInProgress(data);
// setTimeout(() => {
// redirectToView();
// }, 5000);
} catch(ex) {
}
}
const addItemToArray = () => {
const arr = [...newChecklistItems, ''];
setNewChecklistItems(arr);
}
const saveChecklistItems = () => {
const data = Object.assign({}, currentVehicle, {checklist: newChecklistItems});
dispatch(updateVehicle({ id: currentVehicle.id, data }));
setShowAddCheckItem(false);
}
const copyChecklistItems = () => {
const data = Object.assign({}, currentVehicle, {checklist: vehicles.find(vehicle => vehicle.id === selectedRouteChecklistToCopy.vehicle)?.checklist});
dispatch(updateVehicle({ id: currentVehicle.id, data }));
setShowCopyCheckItem(false);
}
const closeAddCheckItemModal = () => {
setNewChecklistItems([])
setShowAddCheckItem(false);
}
const showAddCheckItemModal = () => {
setNewChecklistItems(currentVehicle.checklist)
setShowAddCheckItem(true);
}
const closeCopyCheckItemModal = () => {
setSelectedRouteChecklistToCopy({});
setShowCopyCheckItem(false);
}
const showCopyCheckItemModal = () => {
setShowCopyCheckItem(true);
}
const combineDateAndTime = (date, time) => {
const dateObj = moment(date);
const timeObj = moment(time, 'HH:mm');
dateObj.set({
hour: timeObj.get('hour'),
minute: timeObj.get('minute'),
second: timeObj.get('second')
})
return dateObj;
}
useEffect(() => {
if (!AuthService.canAddOrEditRoutes()) {
window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
AuthService.logout();
navigate(`/login`);
}
TransRoutesService.getRoute(params.id).then(data => {
setCurrentRoute(data?.data);
setRouteName(data?.data?.name);
setNewDriver(data?.data?.driver);
setNewVehicle(data?.data?.vehicle);
setNewRouteType(data?.data?.type);
setEstimatedStartTime(data?.data?.estimated_start_time && new Date(data?.data?.estimated_start_time));
setNewCustomerList(data?.data?.route_customer_list);
setErrorMessage(undefined);
})
}, []);
// useEffect(() => {
// if (currentRoute) {
// setRouteName(currentRoute.name);
// setNewDriver(currentRoute.driver);
// setNewVehicle(currentRoute.vehicle);
// setNewRouteType(currentRoute.type);
// setEstimatedStartTime(currentRoute.estimated_start_time && new Date(currentRoute.estimated_start_time));
// setNewCustomerList(currentRoute.route_customer_list);
// }
// setErrorMessage(undefined);
// }, [currentRoute])
return (
<>
<div className="list row mb-4">
<div className="col-md-12 text-primary">
<h5>{currentRoute?.name} <button className="btn btn-link btn-sm" onClick={() => {redirectToView()}}>Back To View</button></h5>
</div>
</div>
<div className="list row mb-5">
<div className="col-md-7 col-sm-7 col-xs-12">
<button className="btn btn-primary btn-sm me-4" onClick={() => updateCurrentRoute()}> Save Route </button>
<button className="btn btn-default btn-sm" onClick={() => redirectToView()}> Cancel </button>
<button className="btn btn-danger btn-sm float-end" onClick={() => softDeleteCurrentRoute()}>Delete Route</button>
</div>
{errorMessage && <div className="col-md-6 col-sm-6 col-xs-12 alert alert-danger mt-4">{errorMessage}</div>}
</div>
<div className="list row mb-4">
<div className="col-md-6 mb-4">
Name(*): <input type="text" value={routeName || ''} onChange={e => setRouteName(e.target.value)}/>
</div>
<div className="col-md-6 mb-4">Vehicle(*): <select value={newVehicle} onChange={e => setNewVehicle(e.target.value)}>
{vehicles.map((vehicle) => (<option key={vehicle.id} value={vehicle.id}>{vehicle.vehicle_number}</option>))}
</select>
</div>
<div className="col-md-6 mb-4">Driver(*): <select value={newDriver} onChange={e => setNewDriver(e.target.value)}>
{drivers.map((driver) => <option key={driver.id} value={driver.id}>{driver.name}</option>)}
</select>
</div>
<div className="col-md-6 mb-4">Type(*): <select value={newRouteType} onChange={e => setNewRouteType(e.target.value)}>
<option value="inbound">Inbound</option>
<option value="outbound">Outbound</option>
</select>
</div>
{
newRouteType === 'outbound' && (<div className="col-md-6 mb-4">
Estimated Start TIme: <TimePicker disableClock={true} format={'HH:mm'} value={estimatedStartTime} onChange={setEstimatedStartTime} />
</div>)
}
</div>
<div className="list row mb-4">
<div className="col-md-12 mb-4">
<RouteCustomerEditor currentRoute={currentRoute} setNewCustomerList={setNewCustomerList}></RouteCustomerEditor>
</div>
</div>
{ newVehicle && newVehicle !== '' && (<div className="list row mb-4">
<div className="col-md-12 create-route-container">
<h6>Vehicle Info</h6>
<div className="list row">
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Vehicle Number: {vehicles.find(item => item.id === newVehicle)?.vehicle_number}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Tag: {vehicles.find(item => item.id === newVehicle)?.tag}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">EzPass: {vehicles.find(item => item.id === newVehicle)?.ezpass}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">GPS: {vehicles.find(item => item.id === newVehicle)?.gps_tag}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Capacity: {vehicles.find(item => item.id === newVehicle)?.capacity}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Status: {vehicles.find(item => item.id === newVehicle)?.status}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Mileage: {vehicles.find(item => item.id === newVehicle)?.mileage}</div>
</div>
</div>
</div>)}
{ newDriver && newDriver !== '' && (<div className="list row mb-4">
<div className="col-md-12 create-route-container">
<h6>Driver Info</h6>
<div className="list row">
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Name: {drivers.find(item => item.id === newDriver)?.name}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Preferred Name: {drivers.find(item => item.id === newDriver)?.name_cn}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Driver Capacity: {drivers.find(item => item.id === newDriver)?.driver_capacity}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Roles: {drivers.find(item => item.id === newDriver)?.roles}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Phone: {drivers.find(item => item.id === newDriver)?.phone}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Email: {drivers.find(item => item.id === newDriver)?.email}</div>
<div className="col-md-4 col-sm-6 col-xs-12 mb-2">Employment Status: {drivers.find(item => item.id === newDriver)?.employment_status}</div>
</div>
</div>
</div>)}
<div className="list row mb-4">
<div className="col-md-6">
<h6>Vehicle Checklist</h6>
{ currentVehicle?.checklist?.length > 0 && (<table className="mb-4">
<tbody>
{currentVehicle.checklist.map((item, index) => (<tr key={index}><td>{item}</td></tr>))}
</tbody>
</table>) }
<div className="mb-4"><button className="btn btn-link btn-sm" onClick={() => showAddCheckItemModal()}>+Add Check Items</button></div>
<div className="mb-4"><button className="btn btn-link btn-sm" onClick={() => showCopyCheckItemModal()}>Copy Checklist From Other Route</button></div>
</div>
</div>
<Modal show={showAddCheckItem} onHide={() => closeAddCheckItemModal()}>
<Modal.Header closeButton>
<Modal.Title>Add New Checklist Item</Modal.Title>
</Modal.Header>
<Modal.Body>
<>
{newChecklistItems.map((item, index) => (<div className="mb-4" key={index}><input type="text" value={item} onChange={(e) => setNewChecklistItems([...newChecklistItems].map((a, index1) => {if (index1 === index) {return e.target.value;} return a;}))}/>
<button className="btn btn-link btn-sm" onClick={(e) => setNewChecklistItems([...newChecklistItems].filter((value, index1) => index1 != index))}>Remove</button>
</div>))}
<button className="btn btn-link" onClick={() => addItemToArray()}>+Add New Item</button>
</>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => closeAddCheckItemModal()}>
Close
</Button>
<Button variant="primary" onClick={() => saveChecklistItems()}>
Save Checklist Items
</Button>
</Modal.Footer>
</Modal>
<Modal show={showCopyCheckItem} onHide={() => closeCopyCheckItemModal()}>
<Modal.Header closeButton>
<Modal.Title> Click on Route to Select</Modal.Title>
</Modal.Header>
<Modal.Body>
<>
{[...allRoutes, ...tomorrowRoutes].filter(r => r.id !== currentRoute?.id).map((route) => {
return (<div className={`card-container ${route.id === selectedRouteChecklistToCopy.id ? 'selected': ''}`} key={route.id} onClick={() => setSelectedRouteChecklistToCopy(route)}>
<div>{route.name}</div>
<div>
{vehicles.find((a) => a.id === route.vehicle)?.checklist?.map((item, index) => <small key={index} className="me-2">{item}</small>)}
</div>
</div>);
})}
</>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => closeCopyCheckItemModal()}>
Close
</Button>
<Button variant="primary" onClick={() => copyChecklistItems()}>
Copy Checklist Items
</Button>
</Modal.Footer>
</Modal>
</>
);
};
export default RouteEdit;