Files
worldshine-redesign/client/src/components/trans-routes/ViewDailyTemplate.js
Lixian Zhou e39f1c8fa1
All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 32s
fix
2026-03-11 14:08:34 -04:00

230 lines
7.6 KiB
JavaScript

import React, {useState, useEffect} from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
import { AuthService, DailyRoutesTemplateService } from "../../services";
import { Breadcrumb, Modal, Button, Spinner } from "react-bootstrap";
import { PencilSquare, Trash } from "react-bootstrap-icons";
import RoutesSection from "./RoutesSection";
import { selectAllActiveDrivers, selectAllActiveVehicles } from "./../../store";
const ViewDailyTemplate = () => {
const params = useParams();
const navigate = useNavigate();
const drivers = useSelector(selectAllActiveDrivers);
const vehicles = useSelector(selectAllActiveVehicles);
const [template, setTemplate] = useState(null);
const [inboundRoutes, setInboundRoutes] = useState([]);
const [outboundRoutes, setOutboundRoutes] = useState([]);
const [showEditNameModal, setShowEditNameModal] = useState(false);
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [newName, setNewName] = useState('');
const [saving, setSaving] = useState(false);
const [deleting, setDeleting] = useState(false);
const canEditTemplateRoutes = AuthService.canEditRouteTemplates();
useEffect(() => {
fetchTemplate();
}, [params.id]);
const fetchTemplate = () => {
DailyRoutesTemplateService.getDailyRoutesTemplate(params.id).then(data => {
setTemplate(data.data);
setNewName(data.data.name);
// Separate routes by type
const inbound = data.data.routes?.filter(route => route.type === 'inbound') || [];
const outbound = data.data.routes?.filter(route => route.type === 'outbound') || [];
setInboundRoutes(inbound);
setOutboundRoutes(outbound);
});
};
const goBack = () => {
navigate('/trans-routes/daily-templates/list');
};
const openEditNameModal = () => {
if (!canEditTemplateRoutes) return;
setShowEditNameModal(true);
};
const closeEditNameModal = () => {
setShowEditNameModal(false);
setNewName(template.name);
};
const saveName = () => {
if (!newName || newName.trim() === '') {
alert('Please enter a template name');
return;
}
setSaving(true);
DailyRoutesTemplateService.updateDailyRoutesTemplate(params.id, {
...template,
name: newName
}).then(() => {
setSaving(false);
setShowEditNameModal(false);
fetchTemplate();
}).catch(err => {
setSaving(false);
alert('Failed to update template name');
});
};
const handleRouteClick = (routeId) => {
navigate(`/trans-routes/daily-templates/${params.id}/view-route/${routeId}`);
};
const confirmDelete = () => {
if (!canEditTemplateRoutes) return;
setShowDeleteModal(true);
};
const deleteTemplate = () => {
setDeleting(true);
DailyRoutesTemplateService.deleteDailyRoutesTemplate(params.id).then(() => {
setDeleting(false);
setShowDeleteModal(false);
navigate('/trans-routes/daily-templates/list');
}).catch(err => {
setDeleting(false);
alert('Failed to delete template');
});
};
const goToCreateRoute = (type) => {
if (!canEditTemplateRoutes) return;
navigate(`/trans-routes/daily-templates/${params.id}/create-route?type=${type}`);
};
if (!template) {
return (
<div className="list row mb-4">
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
</div>
);
}
return (
<>
<div className="list row mb-4">
<Breadcrumb>
<Breadcrumb.Item href="/trans-routes/dashboard">Transportation</Breadcrumb.Item>
<Breadcrumb.Item href="/trans-routes/daily-templates/list">
Daily Route Templates
</Breadcrumb.Item>
<Breadcrumb.Item active>
{template.name}
</Breadcrumb.Item>
</Breadcrumb>
<div className="col-md-12 text-primary">
<h4>
{template.name}
{canEditTemplateRoutes && <PencilSquare
size={20}
className="clickable ms-2"
onClick={openEditNameModal}
title="Edit template name"
/>}
<button className="btn btn-link btn-sm" onClick={goBack}>Back to List</button>
{canEditTemplateRoutes && <button className="btn btn-danger btn-sm ms-2" onClick={confirmDelete}>
<Trash size={14} className="me-1" />Delete Template
</button>}
</h4>
<div className="text-muted">
<small>Template Date: {template.template_date} | Created by: {template.create_by}</small>
</div>
</div>
</div>
<div className="app-main-content-list-container">
<div className="list row">
<div className="col-md-12 mb-4">
<RoutesSection
transRoutes={inboundRoutes.map(route => ({...route, id: route._id}))}
sectionName="Inbound Routes"
drivers={drivers}
vehicles={vehicles}
onRouteClick={handleRouteClick}
isTemplate={true}
templateId={params.id}
canAddNew={canEditTemplateRoutes}
addText="+Add Route"
redirect={goToCreateRoute}
routeType="inbound"
showCheckedInText={false}
/>
</div>
<div className="col-md-12 mb-4">
<RoutesSection
transRoutes={outboundRoutes.map(route => ({...route, id: route._id}))}
sectionName="Outbound Routes"
drivers={drivers}
vehicles={vehicles}
onRouteClick={handleRouteClick}
isTemplate={true}
templateId={params.id}
canAddNew={canEditTemplateRoutes}
addText="+Add Route"
redirect={goToCreateRoute}
routeType="outbound"
showCheckedInText={false}
/>
</div>
</div>
</div>
<Modal show={showEditNameModal} onHide={closeEditNameModal}>
<Modal.Header closeButton>
<Modal.Title>Edit Template Name</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="mb-3">
<label className="form-label">Template Name</label>
<input
type="text"
className="form-control"
value={newName}
onChange={(e) => setNewName(e.target.value)}
disabled={saving}
/>
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={closeEditNameModal} disabled={saving}>
Cancel
</Button>
<Button variant="primary" onClick={saveName} disabled={saving}>
{saving ? <><Spinner size="sm" className="me-2" />Saving...</> : 'Save'}
</Button>
</Modal.Footer>
</Modal>
<Modal show={showDeleteModal} onHide={() => setShowDeleteModal(false)}>
<Modal.Header closeButton>
<Modal.Title>Delete Template</Modal.Title>
</Modal.Header>
<Modal.Body>
Are you sure you want to delete the template "{template?.name}"? This action cannot be undone.
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={() => setShowDeleteModal(false)} disabled={deleting}>
Cancel
</Button>
<Button variant="danger" onClick={deleteTemplate} disabled={deleting}>
{deleting ? <><Spinner size="sm" className="me-2" />Deleting...</> : 'Delete'}
</Button>
</Modal.Footer>
</Modal>
</>
);
};
export default ViewDailyTemplate;