569 lines
27 KiB
JavaScript
569 lines
27 KiB
JavaScript
import React, {useEffect, useState, useRef} 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, Breadcrumb, Tabs, Tab } from "react-bootstrap";
|
|
import RouteCustomerEditor from "./RouteCustomerEditor";
|
|
import { AuthService, TransRoutesService, CustomerService } from "../../services";
|
|
import TimePicker from 'react-time-picker';
|
|
import 'react-time-picker/dist/TimePicker.css';
|
|
import moment from 'moment';
|
|
import { Archive, GripVertical } from "react-bootstrap-icons";
|
|
import { PERSONAL_ROUTE_STATUS } from "../../shared";
|
|
import { DndProvider } from 'react-dnd';
|
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
import { useDrag } from 'react-dnd';
|
|
|
|
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 [allCustomers, setAllCustomers] = useState([]);
|
|
const [unassignedCustomers, setUnassignedCustomers] = useState([]);
|
|
const [addCustomerToRoute, setAddCustomerToRoute] = useState(null);
|
|
const paramsQuery = new URLSearchParams(window.location.search);
|
|
const scheduleDate = paramsQuery.get('dateSchedule');
|
|
const editSection = paramsQuery.get('editSection')
|
|
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 = () => {
|
|
if (!window.confirm('Are you sure you want to archive this route? This action cannot be undone.')) {
|
|
return;
|
|
}
|
|
const data = Object.assign({}, currentRoute, {status: ['disabled']})
|
|
dispatch(updateRoute({ id: currentRoute?.id, data, callback: redirectToDashboard }));
|
|
// redirectToDashboard();
|
|
}
|
|
|
|
const validateRoute = () => {
|
|
const errors = [];
|
|
|
|
// Required fields validation
|
|
if (!routeName || routeName.trim() === '') {
|
|
errors.push('Route Name');
|
|
}
|
|
if (!newRouteType || newRouteType === '') {
|
|
errors.push('Route Type');
|
|
}
|
|
if (!newDriver || newDriver === '') {
|
|
errors.push('Driver');
|
|
}
|
|
if (!newVehicle || newVehicle === '') {
|
|
errors.push('Vehicle');
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
window.alert(`Please fill in the following required fields:\n${errors.join('\n')}`);
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
const updateCurrentRoute = () => {
|
|
try {
|
|
if (!validateRoute()) {
|
|
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;
|
|
}
|
|
|
|
const calculateUnassignedCustomers = (customers, routes) => {
|
|
if (!customers || !routes) return [];
|
|
|
|
// Get all customer IDs that are assigned to any route today
|
|
const assignedCustomerIds = new Set();
|
|
routes.forEach(route => {
|
|
route.route_customer_list?.forEach(customer => {
|
|
assignedCustomerIds.add(customer.customer_id);
|
|
});
|
|
});
|
|
|
|
// Filter out customers that are not assigned to any route
|
|
// Also exclude discharged customers (type is 'discharged' or name contains 'discharged')
|
|
return customers.filter(customer => {
|
|
const isDischarged = customer.type === 'discharged' ||
|
|
(customer.name && customer.name.toLowerCase().includes('discharged')) ||
|
|
(customer.status !== 'active');
|
|
return customer.status === 'active' &&
|
|
!assignedCustomerIds.has(customer.id) &&
|
|
!isDischarged;
|
|
});
|
|
}
|
|
|
|
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);
|
|
})
|
|
|
|
// Fetch all customers
|
|
CustomerService.getAllCustomers().then(data => {
|
|
setAllCustomers(data?.data || []);
|
|
});
|
|
}, []);
|
|
|
|
// Calculate unassigned customers when allCustomers or routes change
|
|
useEffect(() => {
|
|
if (!currentRoute?.schedule_date) return;
|
|
|
|
const routeDate = currentRoute.schedule_date;
|
|
|
|
// Get routes from the same date as the current route (excluding current route which we'll handle separately)
|
|
const sameDateRoutes = [
|
|
...allRoutes.filter(route => route.schedule_date === routeDate && route.id !== currentRoute.id),
|
|
...tomorrowRoutes.filter(route => route.schedule_date === routeDate && route.id !== currentRoute.id),
|
|
...historyRoutes.filter(route => route.schedule_date === routeDate && route.id !== currentRoute.id)
|
|
];
|
|
|
|
// Add a virtual route with the current newCustomerList (to include customers being added in the editor)
|
|
const routesWithCurrentEdits = [
|
|
...sameDateRoutes,
|
|
{ route_customer_list: newCustomerList || [] }
|
|
];
|
|
|
|
const unassigned = calculateUnassignedCustomers(allCustomers, routesWithCurrentEdits);
|
|
setUnassignedCustomers(unassigned);
|
|
}, [allCustomers, allRoutes, tomorrowRoutes, historyRoutes, currentRoute, newCustomerList]);
|
|
|
|
// 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])
|
|
|
|
// Draggable component for unassigned customers
|
|
const DraggableUnassignedCustomer = ({ customer }) => {
|
|
const [{ isDragging }, drag] = useDrag({
|
|
type: 'UNASSIGNED_CUSTOMER',
|
|
item: () => customer,
|
|
collect: (monitor) => ({
|
|
isDragging: monitor.isDragging(),
|
|
}),
|
|
});
|
|
|
|
const opacity = isDragging ? 0.5 : 1;
|
|
|
|
return (
|
|
<div ref={drag} style={{ opacity }} className="customers-dnd-item-container-absent">
|
|
<GripVertical className="me-4" size={14}></GripVertical>
|
|
<div className="customer-dnd-item">
|
|
<span>{customer.name} </span>
|
|
<small className="me-2">{customer.address1}</small>
|
|
<small className="me-2">{customer.type}</small>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="list row mb-4">
|
|
<Breadcrumb>
|
|
<Breadcrumb.Item href="/">Transportation</Breadcrumb.Item>
|
|
<Breadcrumb.Item href="/trans-routes/dashboard">
|
|
Transportation Routes
|
|
</Breadcrumb.Item>
|
|
<Breadcrumb.Item active>
|
|
Edit Route
|
|
</Breadcrumb.Item>
|
|
</Breadcrumb>
|
|
<div className="col-md-12 text-primary">
|
|
<h4>
|
|
Edit Route Information <button className="btn btn-link btn-sm" onClick={() => {redirectToView()}}>Back</button>
|
|
</h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="app-main-content-list-container form-page">
|
|
<div className="app-main-content-list-func-container">
|
|
<Tabs defaultActiveKey="routeOverview" id="route-view-tab">
|
|
<Tab eventKey="routeOverview" title="Route Information">
|
|
{ editSection === 'info' && <div className="multi-columns-container">
|
|
<div className="column-container">
|
|
<div className="column-card">
|
|
<h6 className="text-primary">Route Details</h6>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Route Name
|
|
<span className="required">*</span>
|
|
</div>
|
|
<input type="text" value={routeName || ''} onChange={e => setRouteName(e.target.value)}/>
|
|
</div>
|
|
<div className="me-4">
|
|
<div className="field-label">Vechile
|
|
<span className="required">*</span>
|
|
</div>
|
|
<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>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Driver
|
|
<span className="required">*</span>
|
|
</div>
|
|
<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="me-4">
|
|
<div className="field-label">Route Type
|
|
<span className="required">*</span>
|
|
</div>
|
|
<select value={newRouteType} onChange={e => setNewRouteType(e.target.value)}>
|
|
<option value="inbound">Inbound</option>
|
|
<option value="outbound">Outbound</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
{ newRouteType === 'outbound' && <div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Estimated Start Time
|
|
</div>
|
|
<TimePicker disableClock={true} format={'HH:mm'} value={estimatedStartTime} onChange={setEstimatedStartTime} />
|
|
</div>
|
|
</div>}
|
|
<div className="app-main-content-fields-section">
|
|
<div className="me-4">
|
|
<div className="field-label">Vehicle Checklist
|
|
</div>
|
|
{ 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>
|
|
<div className="list row mb-5">
|
|
<div className="col-md-12 col-sm-12 col-xs-12">
|
|
<button className="btn btn-default btn-sm float-right" onClick={() => redirectToView()}> Cancel </button>
|
|
<button className="btn btn-primary btn-sm float-right" onClick={() => updateCurrentRoute()}> Save </button>
|
|
</div>
|
|
{errorMessage && <div className="col-md-12 col-sm-12 col-xs-12 alert alert-danger mt-4">{errorMessage}</div>}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="column-container">
|
|
{ newVehicle && newVehicle !== '' && <div className="column-card mb-4">
|
|
<h6 className="text-primary">Vehicle Information</h6>
|
|
<div className="app-main-content-fields-section short">
|
|
<div className="field-body">
|
|
<div className="field-label">Vehicle Number</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.vehicle_number}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Seating Capacity</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.capacity}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Mileage</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.mileage}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Make</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.make}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Model</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.model}</div>
|
|
</div>
|
|
</div>
|
|
<div className="app-main-content-fields-section short">
|
|
<div className="field-body">
|
|
<div className="field-label">License Plate</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.tag}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Year</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.year}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">GPS ID</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.gps_tag}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">EZPass</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.ezpass}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Vin</div>
|
|
<div className="field-value">{vehicles.find(item => item.id === newVehicle)?.vin || ''}</div>
|
|
</div>
|
|
</div>
|
|
</div>}
|
|
{
|
|
newDriver && newDriver !== '' && <div className="column-card">
|
|
<h6 className="text-primary">Driver Information</h6>
|
|
<small className="text-primary">Personal Details</small>
|
|
<div className="app-main-content-fields-section short">
|
|
<div className="field-body">
|
|
<div className="field-label">Driver Name</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.name}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Preferred Name</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.name_cn}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Job Title</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.title}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Job Type</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.employment_status}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">License Type</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.license_type}</div>
|
|
</div>
|
|
</div>
|
|
<div className="app-main-content-fields-section short">
|
|
<div className="field-body">
|
|
<div className="field-label">Phone Number</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.phone}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Email</div>
|
|
<div className="field-value">{drivers.find(item => item.id === newDriver)?.email}</div>
|
|
</div>
|
|
<div className="field-body"></div>
|
|
<div className="field-body"></div>
|
|
<div className="field-body"></div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div> }
|
|
|
|
{
|
|
editSection === 'assignment' && <DndProvider backend={HTML5Backend}>
|
|
<div className="multi-columns-container">
|
|
<div className="column-container">
|
|
<div className="column-card adjust" style={{paddingRight: '30px'}}>
|
|
<div className="col-md-12 mb-4">
|
|
<RouteCustomerEditor
|
|
currentRoute={currentRoute ? {
|
|
...currentRoute,
|
|
route_customer_list: currentRoute.route_customer_list?.filter(
|
|
customer => customer?.customer_route_status !== PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT
|
|
) || []
|
|
} : undefined}
|
|
setNewCustomerList={setNewCustomerList}
|
|
onAddCustomer={(addFn) => setAddCustomerToRoute(() => addFn)}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="column-container">
|
|
<div className="column-card adjust">
|
|
<h6 className="text-primary">Scheduled Absences ({currentRoute?.route_customer_list?.filter(item => item?.customer_route_status === PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT)?.length || 0})</h6>
|
|
<div className="customers-container mb-4">
|
|
{
|
|
currentRoute?.route_customer_list.filter(customer => customer?.customer_route_status === PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT)?.map((abItem) => {
|
|
return <div key={abItem.customer_id} className="customers-dnd-item-container-absent">
|
|
<GripVertical className="me-4" size={14}></GripVertical>
|
|
<div className="customer-dnd-item">
|
|
<span>{abItem.customer_name} </span>
|
|
<small className="me-2">{abItem.customer_address}</small>
|
|
<small className="me-2">{abItem.customer_pickup_status}</small>
|
|
</div>
|
|
|
|
</div>
|
|
})
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="column-container">
|
|
<div className="column-card adjust">
|
|
<h6 className="text-primary">Unassigned Customers ({unassignedCustomers?.length || 0})</h6>
|
|
<div className="customers-container mb-4">
|
|
{
|
|
unassignedCustomers?.map((customer) => {
|
|
return <DraggableUnassignedCustomer key={customer.id} customer={customer} />
|
|
})
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DndProvider>
|
|
}
|
|
</Tab>
|
|
</Tabs>
|
|
<div className="list-func-panel">
|
|
<button className="btn btn-primary" onClick={() => softDeleteCurrentRoute()}><Archive size={16} className="me-2"></Archive>Delete</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; |