This commit is contained in:
@@ -15,6 +15,7 @@ exports.createVehicleRepair = (req, res) => {
|
||||
site,
|
||||
repair_description: req.body.repair_description || req.body.part_name || '',
|
||||
part_name: req.body.part_name || '',
|
||||
part_name_other: req.body.part_name_other || '',
|
||||
mileage_at_replacement: req.body.mileage_at_replacement || '',
|
||||
quantity: req.body.quantity || '',
|
||||
repair_price: req.body.repair_price || '',
|
||||
|
||||
@@ -5,6 +5,7 @@ module.exports = mongoose => {
|
||||
site: Number,
|
||||
repair_description: String,
|
||||
part_name: String,
|
||||
part_name_other: String,
|
||||
mileage_at_replacement: String,
|
||||
quantity: String,
|
||||
repair_price: String,
|
||||
|
||||
@@ -299,14 +299,7 @@ const DashboardCustomersList = ({ additionalButtons, showBreadcrumb = false, tit
|
||||
}
|
||||
|
||||
const table = <div className="list row mb-4">
|
||||
<div
|
||||
className="col-md-12"
|
||||
style={{
|
||||
overflow: 'auto',
|
||||
minHeight: isAllCustomersPage ? 'calc(100vh - 360px)' : undefined,
|
||||
paddingBottom: isAllCustomersPage ? '24px' : undefined
|
||||
}}
|
||||
>
|
||||
<div className="col-md-12" style={{ overflow: 'auto'}}>
|
||||
<table className="personnel-info-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -27,7 +27,7 @@ const RouteView = () => {
|
||||
const [routeStatusValue, setRouteStatusValue] = useState('');
|
||||
const [isSavingRouteStatus, setIsSavingRouteStatus] = useState(false);
|
||||
const [latestRouteForStatus, setLatestRouteForStatus] = useState(undefined);
|
||||
const [customerMetaById, setCustomerMetaById] = useState(new Map());
|
||||
const [routeSnapshot, setRouteSnapshot] = useState(undefined);
|
||||
const paramsQuery = new URLSearchParams(window.location.search);
|
||||
const scheduleDate = paramsQuery.get('dateSchedule');
|
||||
|
||||
@@ -42,22 +42,8 @@ const RouteView = () => {
|
||||
{ value: ROUTE_STATUS.SIGN_OFF, label: 'Signed Off' },
|
||||
{ value: ROUTE_STATUS.UNEXPECTED_ABSENT, label: 'Unexpected Absent' },
|
||||
];
|
||||
const getRouteWithLatestCustomerMeta = (route) => {
|
||||
if (!route || !Array.isArray(route?.route_customer_list) || customerMetaById.size === 0) {
|
||||
return route;
|
||||
}
|
||||
return Object.assign({}, route, {
|
||||
route_customer_list: route.route_customer_list.map((customerInRoute) => {
|
||||
const customerMeta = customerMetaById.get(customerInRoute?.customer_id);
|
||||
if (!customerMeta) return customerInRoute;
|
||||
return Object.assign({}, customerInRoute, {
|
||||
customer_program_type: customerMeta.program_type || '',
|
||||
customer_pay_source: customerMeta.pay_source || ''
|
||||
});
|
||||
})
|
||||
});
|
||||
};
|
||||
const routeForStatusView = getRouteWithLatestCustomerMeta(latestRouteForStatus || currentRoute);
|
||||
const routeForStatusView = latestRouteForStatus || currentRoute;
|
||||
const routeForAssignmentView = routeSnapshot || currentRoute;
|
||||
const closeModal = () => {
|
||||
setShowVehicleDetails(false);
|
||||
}
|
||||
@@ -146,6 +132,20 @@ const RouteView = () => {
|
||||
setLatestRouteForStatus(undefined);
|
||||
}, [currentRoute?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
const routeId = currentRoute?.id || params?.id;
|
||||
if (!routeId) return;
|
||||
TransRoutesService.getRoute(routeId)
|
||||
.then((response) => {
|
||||
if (response?.data) {
|
||||
setRouteSnapshot(response.data);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setRouteSnapshot(undefined);
|
||||
});
|
||||
}, [currentRoute?.id, params?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentRoute?.driver || currentDriver?.id) {
|
||||
setFallbackDriver(undefined);
|
||||
@@ -160,23 +160,6 @@ const RouteView = () => {
|
||||
});
|
||||
}, [currentRoute?.driver, currentDriver?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
CustomerService.getAllCustomers()
|
||||
.then((res) => {
|
||||
const nextMap = new Map();
|
||||
(res?.data || []).forEach((customer) => {
|
||||
nextMap.set(customer?.id, {
|
||||
program_type: customer?.program_type || '',
|
||||
pay_source: customer?.pay_source || ''
|
||||
});
|
||||
});
|
||||
setCustomerMetaById(nextMap);
|
||||
})
|
||||
.catch(() => {
|
||||
setCustomerMetaById(new Map());
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const dateArr = moment(currentRoute?.schedule_date)?.format('MM/DD/YYYY')?.split('/') || [];
|
||||
|
||||
@@ -283,7 +266,7 @@ const RouteView = () => {
|
||||
{currentRoute && currentRoute?.checklist_result.length === 0 && <>No Checklist found</>}</div>
|
||||
</div>
|
||||
</div>
|
||||
<RouteCustomerEditor currentRoute={currentRoute} viewMode={true} editFun={edit}></RouteCustomerEditor>
|
||||
<RouteCustomerEditor currentRoute={routeForAssignmentView} viewMode={true} editFun={edit}></RouteCustomerEditor>
|
||||
</Tab>
|
||||
<Tab eventKey="routeStatus" title="Route Status">
|
||||
<div className="list row">
|
||||
|
||||
@@ -19,6 +19,7 @@ const AddRepairRecord = () => {
|
||||
const [existingRepairs, setExistingRepairs] = useState([]);
|
||||
|
||||
const [partName, setPartName] = useState('');
|
||||
const [partNameOther, setPartNameOther] = useState('');
|
||||
const [replacementDate, setReplacementDate] = useState(null);
|
||||
const [mileage, setMileage] = useState('');
|
||||
const [quantity, setQuantity] = useState('');
|
||||
@@ -60,9 +61,14 @@ const AddRepairRecord = () => {
|
||||
window.alert('Please select a part name.');
|
||||
return;
|
||||
}
|
||||
if (partName === REPAIR_PART_NAME.OTHER && !partNameOther.trim()) {
|
||||
window.alert('Please specify Other Parts.');
|
||||
return;
|
||||
}
|
||||
const data = {
|
||||
vehicle: currentVehicle?.id,
|
||||
part_name: partName,
|
||||
part_name_other: partName === REPAIR_PART_NAME.OTHER ? partNameOther.trim() : '',
|
||||
repair_date: formatDateForBackend(replacementDate),
|
||||
mileage_at_replacement: mileage,
|
||||
quantity,
|
||||
@@ -80,6 +86,7 @@ const AddRepairRecord = () => {
|
||||
: Promise.resolve();
|
||||
uploadPromise.then(() => {
|
||||
setPartName('');
|
||||
setPartNameOther('');
|
||||
setReplacementDate(null);
|
||||
setMileage('');
|
||||
setQuantity('');
|
||||
@@ -138,7 +145,11 @@ const AddRepairRecord = () => {
|
||||
<tbody>
|
||||
{existingRepairs.map((repair) => (
|
||||
<tr key={repair.id}>
|
||||
<td>{REPAIR_PART_NAME_TEXT[repair.part_name] || repair.repair_description || repair.part_name || '-'}</td>
|
||||
<td>
|
||||
{repair.part_name === REPAIR_PART_NAME.OTHER
|
||||
? (repair.part_name_other || REPAIR_PART_NAME_TEXT[repair.part_name] || '-')
|
||||
: (REPAIR_PART_NAME_TEXT[repair.part_name] || repair.repair_description || repair.part_name || '-')}
|
||||
</td>
|
||||
<td>{repair.repair_date || '-'}</td>
|
||||
<td>{repair.mileage_at_replacement || '-'}</td>
|
||||
<td>{repair.quantity || '-'}</td>
|
||||
@@ -168,6 +179,17 @@ const AddRepairRecord = () => {
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{partName === REPAIR_PART_NAME.OTHER && (
|
||||
<div className="me-4">
|
||||
<div className="field-label">Other Parts-Please Specify</div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="e.g., Door handle bracket"
|
||||
value={partNameOther}
|
||||
onChange={e => setPartNameOther(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="me-4">
|
||||
<div className="field-label">Replacement Date</div>
|
||||
<DatePicker
|
||||
|
||||
@@ -17,6 +17,7 @@ const EditRepairRecord = () => {
|
||||
|
||||
const [currentVehicle, setCurrentVehicle] = useState(null);
|
||||
const [partName, setPartName] = useState('');
|
||||
const [partNameOther, setPartNameOther] = useState('');
|
||||
const [replacementDate, setReplacementDate] = useState(null);
|
||||
const [mileage, setMileage] = useState('');
|
||||
const [quantity, setQuantity] = useState('');
|
||||
@@ -38,6 +39,7 @@ const EditRepairRecord = () => {
|
||||
const repair = (res.data || []).find(r => r.id === params.repairId);
|
||||
if (repair) {
|
||||
setPartName(repair.part_name || '');
|
||||
setPartNameOther(repair.part_name_other || '');
|
||||
if (repair.repair_date) {
|
||||
const parsed = moment(repair.repair_date, 'MM/DD/YYYY');
|
||||
if (parsed.isValid()) setReplacementDate(parsed.toDate());
|
||||
@@ -61,8 +63,13 @@ const EditRepairRecord = () => {
|
||||
window.alert('Please select a part name.');
|
||||
return;
|
||||
}
|
||||
if (partName === REPAIR_PART_NAME.OTHER && !partNameOther.trim()) {
|
||||
window.alert('Please specify Other Parts.');
|
||||
return;
|
||||
}
|
||||
const data = {
|
||||
part_name: partName,
|
||||
part_name_other: partName === REPAIR_PART_NAME.OTHER ? partNameOther.trim() : '',
|
||||
repair_date: formatDateForBackend(replacementDate),
|
||||
mileage_at_replacement: mileage,
|
||||
quantity,
|
||||
@@ -113,6 +120,17 @@ const EditRepairRecord = () => {
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{partName === REPAIR_PART_NAME.OTHER && (
|
||||
<div className="me-4">
|
||||
<div className="field-label">Other Parts-Please Specify</div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="e.g., Door handle bracket"
|
||||
value={partNameOther}
|
||||
onChange={e => setPartNameOther(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="me-4">
|
||||
<div className="field-label">Replacement Date</div>
|
||||
<DatePicker
|
||||
|
||||
@@ -407,7 +407,9 @@ const ViewVehicle = () => {
|
||||
<td className="td-index">{index + 1}</td>
|
||||
<td>
|
||||
<PencilSquare size={14} className="clickable me-2" onClick={() => navigate(`/vehicles/${currentVehicle?.id}/repairs/edit/${repair?.id}`)} />
|
||||
{REPAIR_PART_NAME_TEXT[repair?.part_name] || repair?.part_name || repair?.repair_description}
|
||||
{repair?.part_name === 'other'
|
||||
? (repair?.part_name_other || REPAIR_PART_NAME_TEXT[repair?.part_name] || repair?.repair_description)
|
||||
: (REPAIR_PART_NAME_TEXT[repair?.part_name] || repair?.part_name || repair?.repair_description)}
|
||||
</td>
|
||||
<td>{repair?.repair_date}</td>
|
||||
<td>{repair?.mileage_at_replacement}</td>
|
||||
|
||||
Reference in New Issue
Block a user