225 lines
11 KiB
JavaScript
225 lines
11 KiB
JavaScript
import React, {useState, useEffect} from "react";
|
|
import { useSelector } from "react-redux";
|
|
import { useParams, useNavigate } from "react-router-dom";
|
|
import { selectAllRoutes, selectTomorrowAllRoutes, selectAllActiveDrivers, selectAllActiveVehicles, selectHistoryRoutes } from "./../../store";
|
|
import PersonnelSection from "./PersonnelSection";
|
|
import { AuthService, CustomerService, SignatureRequestService } from "../../services";
|
|
import moment from 'moment';
|
|
import { Breadcrumb, Tabs, Tab, Dropdown, Spinner, Modal, Button } from "react-bootstrap";
|
|
import { Download, Pencil } from "react-bootstrap-icons";
|
|
import RouteCustomerEditor from "./RouteCustomerEditor";
|
|
|
|
const RouteView = () => {
|
|
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 currentDriver = drivers.find(item => item.id === currentRoute?.driver);
|
|
const [showVehicleDetails, setShowVehicleDetails] = useState(false);
|
|
const [signature, setSignature] = useState(undefined);
|
|
const [signatureRequest, setSignatureRequest] = useState(undefined);
|
|
const paramsQuery = new URLSearchParams(window.location.search);
|
|
const scheduleDate = paramsQuery.get('dateSchedule');
|
|
|
|
const navigate = useNavigate();
|
|
const closeModal = () => {
|
|
setShowVehicleDetails(false);
|
|
}
|
|
const openModal = () => {
|
|
setShowVehicleDetails(true);
|
|
}
|
|
const getRelatedOutboundRoutesForThisView = () => {
|
|
if (allRoutes.find(item => item.id === params.id)) {
|
|
return allRoutes.filter(item => item.type==='outbound');
|
|
}
|
|
if (tomorrowRoutes.find(item => item.id === params.id)) {
|
|
return tomorrowRoutes.filter(item => item.type==='outbound');
|
|
}
|
|
if (historyRoutes.find(item => item.id === params.id)) {
|
|
return historyRoutes.filter(item => item.type==='outbound');
|
|
}
|
|
}
|
|
const directToDashboad = () => {
|
|
navigate(`/trans-routes/dashboard?dateSchedule=${moment(currentRoute?.schedule_date).format('YYYY-MM-DD')}`);
|
|
}
|
|
const edit = (editSection) => {
|
|
if (scheduleDate) {
|
|
navigate(`/trans-routes/edit/${currentRoute?.id}?dateSchedule=${scheduleDate}&editSection=${editSection}`)
|
|
} else {
|
|
navigate(`/trans-routes/edit/${currentRoute?.id}?editSection=${editSection}`)
|
|
}
|
|
}
|
|
const deleteFile = () => {
|
|
if (signature) {
|
|
const dateArr = moment(currentRoute?.schedule_date)?.format('MM/DD/YYYY')?.split('/') || [];
|
|
CustomerService.deleteFile({name: `${currentRoute?.id}_${currentRoute?.driver}_${dateArr[0]}_${dateArr[1]}`}).then(data => {
|
|
setSignature(undefined);
|
|
})
|
|
}
|
|
}
|
|
const generateSignatureRequest = () => {
|
|
SignatureRequestService.createNewSignatureRequest({
|
|
driver_id: currentDriver?.id,
|
|
driver_name: currentDriver?.name,
|
|
route_id: currentRoute?.id,
|
|
route_date: currentRoute?.schedule_date,
|
|
route_name: currentRoute?.name,
|
|
status: 'active',
|
|
}).then((data) => {
|
|
setSignatureRequest(data.data);
|
|
})
|
|
}
|
|
useEffect(() => {
|
|
const dateArr = moment(currentRoute?.schedule_date)?.format('MM/DD/YYYY')?.split('/') || [];
|
|
|
|
CustomerService.getAvatar(`${currentRoute?.id}_${currentRoute?.driver}_${dateArr[0]}_${dateArr[1]}`).then(data => {
|
|
setSignature(data.data);
|
|
});
|
|
SignatureRequestService.getAllSignatureRequests({driver_id: currentDriver?.id, route_id: currentRoute?.id, route_date: currentRoute?.scheduleDate}).then((data) => {
|
|
if (data?.data?.length > 0) {
|
|
setSignatureRequest(data?.data[0]);
|
|
}
|
|
})
|
|
}, [currentRoute]);
|
|
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>
|
|
View Route
|
|
</Breadcrumb.Item>
|
|
</Breadcrumb>
|
|
<div className="col-md-12 text-primary">
|
|
<h4>
|
|
View Route Information <button className="btn btn-link btn-sm" onClick={() => {directToDashboad()}}>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">
|
|
<h6 className="text-primary">Route Details <button className="btn btn-sm btn-primary" onClick={() => edit('info')}><Pencil size={16} className="me-2"></Pencil>Edit </button></h6>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="field-body">
|
|
<div className="field-label">Route Name</div>
|
|
<div className="field-value">{currentRoute?.name}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Vehicle</div>
|
|
<div className="field-value">{currentVehicle?.vehicle_number}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Driver</div>
|
|
<div className="field-value">{currentDriver?.name}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Route Type</div>
|
|
<div className="field-value">{currentRoute?.type}</div>
|
|
</div>
|
|
</div>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="field-body">
|
|
<div className="field-label">Route Start Time</div>
|
|
<div className="field-value">{currentRoute?.start_time && (new Date(currentRoute?.start_time))?.toLocaleTimeString()}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">Route End Time</div>
|
|
<div className="field-value">{currentRoute?.end_time && (new Date(currentRoute?.end_time))?.toLocaleTimeString()}</div>
|
|
</div>
|
|
{currentRoute?.type === 'outbound' &&<div className="field-body">
|
|
<div className="field-label">Leave Center Time</div>
|
|
<div className="field-value">{currentRoute?.start_time && (new Date(currentRoute?.start_time))?.toLocaleTimeString()}</div>
|
|
</div>}
|
|
{currentRoute?.type === 'outbound' &&<div className="field-body">
|
|
<div className="field-label">Estimated Start Time</div>
|
|
<div className="field-value">{currentRoute?.estimated_start_time && (new Date(currentRoute?.estimated_start_time))?.toLocaleTimeString()}</div>
|
|
</div>}
|
|
</div>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="field-body">
|
|
<div className="field-label">Start Mileage</div>
|
|
<div className="field-value">{ currentRoute?.start_mileage}</div>
|
|
</div>
|
|
<div className="field-body">
|
|
<div className="field-label">End Mileage</div>
|
|
<div className="field-value">{ currentRoute?.end_mileage}</div>
|
|
</div>
|
|
</div>
|
|
<div className="app-main-content-fields-section">
|
|
{signature &&<div className="field-body">
|
|
<div className="field-label">Driver Signature</div>
|
|
<div className="field-value">
|
|
{signature && <img width="100px" src={`data:image/jpg;base64, ${signature}`}/>}
|
|
|
|
</div>
|
|
</div>}
|
|
{!signature && !signatureRequest && <div className="field-body">
|
|
<div className="field-label">Signature Request</div>
|
|
<div className="field-value"><button className="btn btn-sm btn-primary" onClick={() => generateSignatureRequest()}>Generate Signature Link For Driver</button></div>
|
|
</div>}
|
|
{!signature && signatureRequest && <div className="alert alert-success fade show mb-2 mt-2" role="alert">
|
|
<div>Please send this to the driver to get signature:</div>
|
|
<div>{`${window.location.origin}/signature/${signatureRequest?.id}`}</div>
|
|
</div>}
|
|
</div>
|
|
<div className="app-main-content-fields-section">
|
|
<div className="field-body">
|
|
<div className="field-label">Checklist</div>
|
|
<div className="field-value">
|
|
{currentRoute && currentRoute?.checklist_result?.map(item => <div>{`${item?.item}: ${item?.result ? 'Yes': "No"}`}</div>)}
|
|
{currentRoute && currentRoute?.checklist_result.length === 0 && <>No Checklist found</>}</div>
|
|
</div>
|
|
</div>
|
|
<RouteCustomerEditor currentRoute={currentRoute} viewMode={true} editFun={edit}></RouteCustomerEditor>
|
|
</Tab>
|
|
<Tab eventKey="routeStatus" title="Route Status">
|
|
<div className="list row">
|
|
<div className="col-md-12 mb-4">
|
|
{currentRoute && <PersonnelSection transRoutes={[currentRoute]} showCompletedInfo={true} showGroupInfo={true} isInbound={currentRoute?.type === 'inbound' } allowForceEdit={AuthService.canViewRoutes()} sectionName="Personnel Status (click on each user to edit)" relatedOutbound={getRelatedOutboundRoutesForThisView()} vehicle={currentVehicle} driverName={currentDriver?.name} deleteFile={deleteFile}/>}
|
|
</div>
|
|
</div>
|
|
</Tab>
|
|
</Tabs>
|
|
{/* <div className="list-func-panel">
|
|
<button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button>
|
|
</div> */}
|
|
</div>
|
|
<Modal show={showVehicleDetails} onHide={() => closeModal()}>
|
|
<Modal.Header closeButton>
|
|
<Modal.Title>Vehicle Info</Modal.Title>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<>
|
|
<div className="mb-2">Vehicle Number: {currentVehicle?.vehicle_number}</div>
|
|
<div className="mb-2">Tag: {currentVehicle?.tag}</div>
|
|
<div className="mb-2">EzPass: {currentVehicle?.ezpass}</div>
|
|
<div className="mb-2">GPS: {currentVehicle?.gps_tag}</div>
|
|
<div className="mb-2">Capacity: {currentVehicle?.capacity}</div>
|
|
<div className="mb-2">Status: {currentVehicle?.status}</div>
|
|
<div className="mb-2">Mileage: {currentVehicle?.mileage}</div>
|
|
</>
|
|
</Modal.Body>
|
|
<Modal.Footer>
|
|
<Button variant="secondary" onClick={() => closeModal()}>
|
|
Close
|
|
</Button>
|
|
</Modal.Footer>
|
|
</Modal>
|
|
</div>
|
|
|
|
|
|
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default RouteView; |