From 116c3e825995252a7eee6aa834d9fd850694bcd5 Mon Sep 17 00:00:00 2001 From: Lixian Zhou Date: Mon, 23 Feb 2026 15:01:58 -0500 Subject: [PATCH] fix --- .DS_Store | Bin 14340 -> 14340 bytes app/.DS_Store | Bin 28676 -> 28676 bytes app/controllers/vehicle-repair.controller.js | 31 ++- app/models/vehicle-repair.model.js | 6 +- app/routes/vehicle-repair.route.js | 3 +- .../src/components/vehicles/UpdateVehicle.js | 192 +++++++++++++++--- client/src/services/VehicleRepairService.js | 6 +- 7 files changed, 204 insertions(+), 34 deletions(-) diff --git a/.DS_Store b/.DS_Store index 29f3b45043e9c5a97c41936c53d529b1ae4f41f7..6a48c4a627040854e598e83272860ae7c196b476 100644 GIT binary patch delta 24 fcmZoEXerpRPl4UiQb)nq(0uYm0f)`3ivPs`ZsG`e delta 16 XcmZoEXerpRPhs*Y0r$v6c1ueg1!F_=$rBBoCO_2@-7KluA%G<4u=#~$8as->RL6Wh0KWAU A>Hq)$ delta 44 rcmZp9z}WJDal>wn$$FVCoBwMp5&$tKCj_!?er1`$4(CjF%+&(`viA}# diff --git a/app/controllers/vehicle-repair.controller.js b/app/controllers/vehicle-repair.controller.js index 3ce4413..13104cd 100644 --- a/app/controllers/vehicle-repair.controller.js +++ b/app/controllers/vehicle-repair.controller.js @@ -3,8 +3,8 @@ const db = require("../models"); const VehicleRepair = db.vehicle_repair; exports.createVehicleRepair = (req, res) => { - if (!req.body.repair_description) { - res.status(400).send({ message: "Content can not be empty!" }); + if (!req.body.part_name && !req.body.repair_description) { + res.status(400).send({ message: "Part name or description is required." }); return; } @@ -13,11 +13,15 @@ exports.createVehicleRepair = (req, res) => { const vehicleRepair = new VehicleRepair({ repair_date: req.body.repair_date, site, - repair_description: req.body.repair_description || '', + repair_description: req.body.repair_description || req.body.part_name || '', + part_name: req.body.part_name || '', + mileage_at_replacement: req.body.mileage_at_replacement || '', + quantity: req.body.quantity || '', repair_price: req.body.repair_price || '', repair_location: req.body.repair_location || '', + next_replacement_reminder: req.body.next_replacement_reminder || '', vehicle: req.body.vehicle, - create_date: new Date() + create_date: new Date() }); vehicleRepair.save(vehicleRepair).then(data => res.send(data)).catch(err => { @@ -32,7 +36,7 @@ exports.getAllVehicleRepairs = (req, res) => { const vehicle = req.query.vehicle; condition = splitSite.splitSiteGet(req, condition); condition.vehicle = vehicle; - VehicleRepair.find(condition) + VehicleRepair.find(condition).sort({ create_date: -1 }) .then(data => { res.send(data); }) @@ -42,4 +46,21 @@ exports.getAllVehicleRepairs = (req, res) => { err.message || "Some error occurred while retrieving Vehicle Repair Records." }); }); +} + +exports.deleteVehicleRepair = (req, res) => { + const id = req.params.id; + VehicleRepair.findByIdAndDelete(id) + .then(data => { + if (!data) { + res.status(404).send({ message: `Cannot delete Vehicle Repair Record with id=${id}.` }); + } else { + res.send({ message: "Vehicle Repair Record was deleted successfully!" }); + } + }) + .catch(err => { + res.status(500).send({ + message: err.message || "Could not delete Vehicle Repair Record." + }); + }); }; \ No newline at end of file diff --git a/app/models/vehicle-repair.model.js b/app/models/vehicle-repair.model.js index 277f7b7..fe4de04 100644 --- a/app/models/vehicle-repair.model.js +++ b/app/models/vehicle-repair.model.js @@ -4,10 +4,14 @@ module.exports = mongoose => { repair_date: String, site: Number, repair_description: String, + part_name: String, + mileage_at_replacement: String, + quantity: String, repair_price: String, repair_location: String, + next_replacement_reminder: String, vehicle: String, - create_date: Date + create_date: Date }, { collection: 'vehicle_repair', timestamps: true } ); diff --git a/app/routes/vehicle-repair.route.js b/app/routes/vehicle-repair.route.js index 1703602..bde3ddb 100644 --- a/app/routes/vehicle-repair.route.js +++ b/app/routes/vehicle-repair.route.js @@ -9,9 +9,8 @@ module.exports = app => { next(); }); var router = require("express").Router(); - // Retrieve all vehicle records router.get("/", [authJwt.verifyToken], vehicleRepairs.getAllVehicleRepairs); - // Create a new vehicle record router.post("/", [authJwt.verifyToken], vehicleRepairs.createVehicleRepair); + router.delete("/:id", [authJwt.verifyToken], vehicleRepairs.deleteVehicleRepair); app.use('/api/vehicle-repairs', router); }; \ No newline at end of file diff --git a/client/src/components/vehicles/UpdateVehicle.js b/client/src/components/vehicles/UpdateVehicle.js index 61489b2..92e4fe7 100644 --- a/client/src/components/vehicles/UpdateVehicle.js +++ b/client/src/components/vehicles/UpdateVehicle.js @@ -3,7 +3,7 @@ import { useSelector, useDispatch } from "react-redux"; import { useNavigate, useParams, useSearchParams } from "react-router-dom"; import { vehicleSlice, selectVehicleError } from "./../../store"; import { AuthService, VehicleRepairService, VehicleService, DriverService } from "../../services"; -import { Archive, Upload } from "react-bootstrap-icons"; +import { Archive, Upload, Trash } from "react-bootstrap-icons"; import { Spinner, Breadcrumb, BreadcrumbItem, Tabs, Tab, Modal, Button } from "react-bootstrap"; import DatePicker from "react-datepicker"; import Select from 'react-select'; @@ -63,6 +63,8 @@ const UpdateVehicle = () => { const [selectedYearlyFile, setSelectedYearlyFile] = useState(); const [monthlyInspectionDate, setMonthlyInspectionDate] = useState(null); const [yearlyInspectionDate, setYearlyInspectionDate] = useState(null); + const [existingYearlyFiles, setExistingYearlyFiles] = useState([]); + const [existingMonthlyFiles, setExistingMonthlyFiles] = useState([]); // Repair & Maintenance Record const [repairPartName, setRepairPartName] = useState(''); @@ -73,6 +75,7 @@ const UpdateVehicle = () => { const [repairLocation, setRepairLocation] = useState(''); const [repairReceiptFile, setRepairReceiptFile] = useState(null); const [repairNextReminder, setRepairNextReminder] = useState(''); + const [existingRepairs, setExistingRepairs] = useState([]); // Modal const [showDeleteModal, setShowDeleteModal] = useState(false); @@ -127,9 +130,29 @@ const UpdateVehicle = () => { // Additional Information setNote(currentVehicle.note || ''); + + // Fetch existing inspection files + fetchInspectionFiles(currentVehicle); + // Fetch existing repair records + fetchRepairRecords(currentVehicle.id); } }, [currentVehicle]); + const fetchInspectionFiles = (vehicle) => { + VehicleService.getAllVechileFiles(vehicle.id, vehicle.vehicle_number, 'yearlyInspection') + .then(res => setExistingYearlyFiles(res.data?.data?.files || [])) + .catch(() => setExistingYearlyFiles([])); + VehicleService.getAllVechileFiles(vehicle.id, vehicle.vehicle_number, 'monthlyInspection') + .then(res => setExistingMonthlyFiles(res.data?.data?.files || [])) + .catch(() => setExistingMonthlyFiles([])); + }; + + const fetchRepairRecords = (vehicleId) => { + VehicleRepairService.getAll(vehicleId) + .then(res => setExistingRepairs(res.data || [])) + .catch(() => setExistingRepairs([])); + }; + const redirectTo = () => { const params = new URLSearchParams(window.location.search); const redirect = params.get('redirect'); @@ -240,21 +263,39 @@ const UpdateVehicle = () => { redirectTo(); } - const saveDocuments = () => { - if (selectedMonthlyFile && monthlyInspectionDate) { - const monthlyFormData = new FormData(); - monthlyFormData.append('file', selectedMonthlyFile); - VehicleService.uploadVechileFile(monthlyFormData, currentVehicle.id, currentVehicle.vehicle_number, 'monthlyInspection', monthlyInspectionDate); + const saveYearlyInspection = () => { + if (!selectedYearlyFile || !yearlyInspectionDate) { + window.alert('Please select a date and a file for yearly inspection.'); + return; } - if (selectedYearlyFile && yearlyInspectionDate) { - const yearlyFormData = new FormData(); - yearlyFormData.append('file', selectedYearlyFile); - VehicleService.uploadVechileFile(yearlyFormData, currentVehicle.id, currentVehicle.vehicle_number, 'yearlyInspection', yearlyInspectionDate); + const formData = new FormData(); + formData.append('file', selectedYearlyFile); + VehicleService.uploadVechileFile(formData, currentVehicle.id, currentVehicle.vehicle_number, 'yearlyInspection', yearlyInspectionDate).then(() => { + setSelectedYearlyFile(undefined); + setYearlyInspectionDate(null); + fetchInspectionFiles(currentVehicle); + }); + } + + const saveMonthlyInspection = () => { + if (!selectedMonthlyFile || !monthlyInspectionDate) { + window.alert('Please select a date and a file for monthly inspection.'); + return; } - redirectTo(); + const formData = new FormData(); + formData.append('file', selectedMonthlyFile); + VehicleService.uploadVechileFile(formData, currentVehicle.id, currentVehicle.vehicle_number, 'monthlyInspection', monthlyInspectionDate).then(() => { + setSelectedMonthlyFile(undefined); + setMonthlyInspectionDate(null); + fetchInspectionFiles(currentVehicle); + }); } const saveRepair = () => { + if (!repairPartName) { + window.alert('Please select a part name.'); + return; + } const data = { vehicle: currentVehicle?.id, part_name: repairPartName, @@ -267,16 +308,39 @@ const UpdateVehicle = () => { }; VehicleRepairService.createNewVehicleRepair(data).then(result => { const record = result.data; - if (repairReceiptFile) { - const formData = new FormData(); - formData.append('file', repairReceiptFile); - VehicleService.uploadVechileFile(formData, currentVehicle.id, record.id, 'repair', repairReplacementDate).then(() => redirectTo()); - } else { - redirectTo(); - } + const uploadPromise = repairReceiptFile + ? VehicleService.uploadVechileFile( + (() => { const fd = new FormData(); fd.append('file', repairReceiptFile); return fd; })(), + currentVehicle.id, record.id, 'repair', repairReplacementDate || new Date() + ) + : Promise.resolve(); + uploadPromise.then(() => { + setRepairPartName(''); + setRepairReplacementDate(null); + setRepairMileage(''); + setRepairQuantity(''); + setRepairCost(''); + setRepairLocation(''); + setRepairReceiptFile(null); + setRepairNextReminder(''); + fetchRepairRecords(currentVehicle.id); + }); }); } + const deleteRepairRecord = (repairId) => { + if (window.confirm('Are you sure you want to delete this repair record?')) { + VehicleRepairService.deleteVehicleRepair(repairId).then(() => { + fetchRepairRecords(currentVehicle.id); + }); + } + } + + const getFileDownloadUrl = (fileUrl) => { + const baseUrl = require('../../http-common').default?.defaults?.baseURL || ''; + return baseUrl.replace('/api', '') + fileUrl; + } + // Custom styles for react-select const selectStyles = { control: (baseStyles) => ({ @@ -502,7 +566,28 @@ const UpdateVehicle = () => { + {/* ===== Yearly Inspection ===== */}
Yearly Inspection
+ {existingYearlyFiles.length > 0 && ( + + + + + + + + + {existingYearlyFiles.map((file, idx) => ( + + + + + ))} + +
File NameAction
{file.name} + Download +
+ )}
Yearly Inspection Date
@@ -522,9 +607,33 @@ const UpdateVehicle = () => {
{selectedYearlyFile?.name}
+
+ +
-
Monthly Inspection
+ {/* ===== Monthly Inspection ===== */} +
Monthly Inspection
+ {existingMonthlyFiles.length > 0 && ( + + + + + + + + + {existingMonthlyFiles.map((file, idx) => ( + + + + + ))} + +
File NameAction
{file.name} + Download +
+ )}
Monthly Inspection Date
@@ -544,14 +653,47 @@ const UpdateVehicle = () => {
{selectedMonthlyFile?.name}
-
-
-
- +
+
-
Repair & Maintenance Record
+ {/* ===== Repair & Maintenance Record ===== */} +
Repair & Maintenance Record
+ {existingRepairs.length > 0 && ( + + + + + + + + + + + + + + + {existingRepairs.map((repair) => ( + + + + + + + + + + + ))} + +
Part NameDateMileageQtyCostLocationNext ReminderAction
{REPAIR_PART_NAME_TEXT[repair.part_name] || repair.repair_description || repair.part_name || '-'}{repair.repair_date || '-'}{repair.mileage_at_replacement || '-'}{repair.quantity || '-'}{repair.repair_price || '-'}{repair.repair_location || '-'}{repair.next_replacement_reminder || '-'} + +
+ )}
Part Name
@@ -615,7 +757,7 @@ const UpdateVehicle = () => {
- +
diff --git a/client/src/services/VehicleRepairService.js b/client/src/services/VehicleRepairService.js index 1f6f9a0..06de539 100644 --- a/client/src/services/VehicleRepairService.js +++ b/client/src/services/VehicleRepairService.js @@ -5,8 +5,12 @@ const getAll = (vehicle) => { const createNewVehicleRepair = (data) => { return http.post('/vehicle-repairs', data); }; +const deleteVehicleRepair = (id) => { + return http.delete(`/vehicle-repairs/${id}`); +}; export const VehicleRepairService = { getAll, - createNewVehicleRepair + createNewVehicleRepair, + deleteVehicleRepair };