Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 40e8157

Browse files
committed
Revised drivermanagement
1 parent 92854cb commit 40e8157

9 files changed

Lines changed: 115 additions & 81 deletions

File tree

client/hash.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const bcryptjs = require('bcryptjs')
22

3-
const plainPassword = 'test12345'
3+
const plainPassword = 'bananas47!'
44

55
bcryptjs.hash(plainPassword, 10, (err, hashedPassword) => {
66
if (err) {

client/src/views/dashboard/ShipmentInfo/ShipmentInfo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const ShipmentInfo = ({ data }) => {
99
const [showDetails, setShowDetails] = useState(false)
1010

1111
useEffect(() => {
12-
const socket = new WebSocket('wss://backend-core2.axleshift.com')
12+
const socket = new WebSocket('wss://backend-core2.axleshift.com/ws')
1313

1414
socket.addEventListener('open', () => {
1515
// Join tracking when socket opens

client/src/views/driver/driverlogin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ const DriverLogin = () => {
139139
color="primary"
140140
className="rounded"
141141
onClick={() => navigate('/signup')}
142+
disabled
142143
>
143144
Signup
144145
</CButton>

client/src/views/driver/drivermanagement.js

Lines changed: 44 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState, useRef } from 'react'
1+
import React, { useEffect, useState } from 'react'
22
import {
33
CCard,
44
CCardBody,
@@ -11,110 +11,81 @@ import {
1111
CTableRow,
1212
CTableDataCell,
1313
CSpinner,
14+
CFormInput,
1415
} from '@coreui/react'
1516

1617
const DriverManagement = () => {
17-
const [shipments, setShipments] = useState([])
18+
const [drivers, setDrivers] = useState([])
1819
const [loading, setLoading] = useState(true)
19-
const socketRef = useRef(null)
20+
const [filterTerm, setFilterTerm] = useState('')
2021

2122
useEffect(() => {
22-
const fetchShipments = async () => {
23+
const fetchDrivers = async () => {
2324
try {
24-
const res = await fetch('https://backend-core2.axleshift.com/driver/shipments')
25+
const res = await fetch('https//backend-core2.axleshift.com/api/drivers')
2526
const data = await res.json()
26-
setShipments(data)
27+
setDrivers(data)
2728
} catch (error) {
28-
console.error('Failed to fetch shipments:', error)
29+
console.error('Failed to fetch drivers:', error)
2930
} finally {
3031
setLoading(false)
3132
}
3233
}
3334

34-
fetchShipments()
35+
fetchDrivers()
36+
const intervalId = setInterval(fetchDrivers, 2000)
3537

36-
// Connect to WebSocket
37-
socketRef.current = new WebSocket('wss://backend-core2.axleshift.com')
38-
39-
socketRef.current.onopen = () => {
40-
console.log('WebSocket connected (DriverManagement)')
41-
}
42-
43-
socketRef.current.onmessage = (event) => {
44-
const message = JSON.parse(event.data)
45-
46-
if (message.type === 'shipmentLocationUpdate') {
47-
const { trackingNumber, latitude, longitude, updated_at, driverUsername } = message.data
48-
49-
setShipments((prevShipments) =>
50-
prevShipments.map((shipment) =>
51-
shipment.trackingNumber === trackingNumber
52-
? {
53-
...shipment,
54-
latitude,
55-
longitude,
56-
updated_at,
57-
driverUsername,
58-
}
59-
: shipment,
60-
),
61-
)
62-
}
63-
}
64-
65-
socketRef.current.onerror = (error) => {
66-
console.error('WebSocket error:', error)
67-
}
38+
return () => clearInterval(intervalId)
39+
}, [])
40+
const filteredDrivers = drivers.filter((d) => {
41+
const term = filterTerm.toLowerCase()
6842

69-
socketRef.current.onclose = () => {
70-
console.log('WebSocket disconnected')
71-
}
43+
const matchesName = d.name.toLowerCase().includes(term)
44+
const matchesPlate = d.vehicle?.number?.toLowerCase().includes(term)
45+
const matchesLicense = d.licenseNumber?.toLowerCase().includes(term)
46+
const matchesVehicleType = d.vehicle?.type?.toLowerCase().includes(term)
47+
const matchesOnDuty = (d.onDuty ? 'Yes' : 'No').includes(term)
7248

73-
// Cleanup
74-
return () => {
75-
socketRef.current?.close()
76-
}
77-
}, [])
49+
return matchesName || matchesPlate || matchesLicense || matchesVehicleType || matchesOnDuty
50+
})
7851

7952
return (
8053
<CRow>
8154
<CCol>
8255
<CCard className="mb-4 shadow-sm">
8356
<CCardBody>
84-
<h4 className="mb-3">Active Shipments</h4>
57+
<div className="d-flex justify-content-between align-items-center mb-3">
58+
<h4>Driver Management</h4>
59+
<CFormInput
60+
type="text"
61+
placeholder="Search name, plate, or license"
62+
value={filterTerm}
63+
onChange={(e) => setFilterTerm(e.target.value)}
64+
className="form-control"
65+
style={{ maxWidth: '250px' }}
66+
/>
67+
</div>
8568
{loading ? (
8669
<CSpinner color="primary" />
8770
) : (
8871
<CTable striped responsive bordered hover>
8972
<CTableHead>
9073
<CTableRow>
91-
<CTableHeaderCell>Tracking Number</CTableHeaderCell>
92-
<CTableHeaderCell>Status</CTableHeaderCell>
93-
<CTableHeaderCell>Driver</CTableHeaderCell>
94-
<CTableHeaderCell>Delivery Address</CTableHeaderCell>
95-
<CTableHeaderCell>Live Location</CTableHeaderCell>
74+
<CTableHeaderCell>Name</CTableHeaderCell>
75+
<CTableHeaderCell>Vehicle Type</CTableHeaderCell>
76+
<CTableHeaderCell>On Duty</CTableHeaderCell>
77+
<CTableHeaderCell>Plate Number</CTableHeaderCell>
78+
<CTableHeaderCell>License Number</CTableHeaderCell>
9679
</CTableRow>
9780
</CTableHead>
9881
<CTableBody>
99-
{shipments.map((s) => (
100-
<CTableRow key={s.trackingNumber}>
101-
<CTableDataCell>{s.trackingNumber}</CTableDataCell>
102-
<CTableDataCell>{s.status || 'Unknown'}</CTableDataCell>
103-
<CTableDataCell>{s.driverUsername || 'Unassigned'}</CTableDataCell>
104-
<CTableDataCell>{s.deliveryAddress}</CTableDataCell>
105-
<CTableDataCell>
106-
{s.latitude && s.longitude ? (
107-
<a
108-
href={`https://www.google.com/maps?q=${s.latitude},${s.longitude}`}
109-
target="_blank"
110-
rel="noopener noreferrer"
111-
>
112-
View on Map
113-
</a>
114-
) : (
115-
'Not Available'
116-
)}
117-
</CTableDataCell>
82+
{filteredDrivers.map((d) => (
83+
<CTableRow key={d._id}>
84+
<CTableDataCell>{d.name}</CTableDataCell>
85+
<CTableDataCell>{d.vehicle?.type}</CTableDataCell>
86+
<CTableDataCell>{d.onDuty ? 'Yes' : 'No'}</CTableDataCell>
87+
<CTableDataCell>{d.vehicle?.number || 'Unassigned'}</CTableDataCell>
88+
<CTableDataCell>{d.licenseNumber}</CTableDataCell>
11889
</CTableRow>
11990
))}
12091
</CTableBody>

client/src/views/driver/drivertracking.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,18 @@ const DriverTracking = () => {
148148
}
149149
}, [location])
150150

151-
const handleLogout = () => {
152-
sessionStorage.removeItem('driverToken')
153-
window.dispatchEvent(new Event('storage'))
154-
navigate('/driverlogin')
151+
const handleLogout = async () => {
152+
const driverUsername = sessionStorage.getItem('driverUsername')
153+
154+
try {
155+
await axios.post('https://backend-core2.axleshift.com/logout', { driverUsername })
156+
sessionStorage.removeItem('driverToken')
157+
sessionStorage.removeItem('driverUsername')
158+
window.dispatchEvent(new Event('storage'))
159+
navigate('/driverlogin')
160+
} catch (err) {
161+
console.error('Logout failed:', err)
162+
}
155163
}
156164

157165
const handleShipmentSelect = (trackingNumber) => {

server/index.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const admin = require("firebase-admin");
1313
const rateLimit = require('express-rate-limit');
1414
const serviceAccount = require("./firebase-service-account.json");
1515
const shipmentsRoutes = require('./routes/shipments');
16+
const driversRoutes = require('./routes/drivers');
1617
const User = require('./models/User');
1718
const Driver = require('./models/Driver');
1819
const TrackData = require('./models/TrackData');
@@ -38,6 +39,7 @@ app.use(cors({
3839
app.use(express.json());
3940

4041
app.use('/api/shipments', shipmentsRoutes);
42+
app.use('/api/drivers', driversRoutes);
4143
// MongoDB Connection
4244
const mongoURI = process.env.mongoURIProduction;
4345
mongoose.connect(mongoURI)
@@ -388,19 +390,39 @@ app.post('/driverlogin', async (req, res) => {
388390
// Check password
389391
const isMatch = await bcryptjs.compare(password, driver.password);
390392
if (!isMatch) return res.status(400).json({ success: false, message: 'Invalid credentials' });
393+
driver.onDuty = true;
394+
await driver.save();
391395

392396
// Generate JWT token
393397
const token = jwt.sign(
394398
{ id: driver._id, userRole: 'driver' },
395399
process.env.JWT_SECRET,
396-
{ expiresIn: '7d' } // Token valid for 7 days
400+
{ expiresIn: '1h' }
397401
);
398-
res.json({ success: true, token, driver: { id: driver._id, username: driver.username, email: driver.email } });
402+
res.json({ success: true, token, driver: { id: driver._id, username: driver.username, email: driver.email, onDuty: driver.onDuty } });
399403
} catch (error) {
400404
console.error("Driver login error:", error);
401405
res.status(500).json({ success: false, message: 'Server error' });
402406
}
403407
});
408+
// Driver logout
409+
app.post('/logout', async (req, res) => {
410+
try {
411+
const { driverUsername } = req.body;
412+
413+
const driver = await Driver.findOne({username: driverUsername});
414+
if (!driver) {
415+
return res.status(404).json({ success: false, message: 'Driver not found' });
416+
}
417+
driver.onDuty = false;
418+
await driver.save();
419+
420+
res.status(200).json({ success: true, message: 'Logged out successfully' });
421+
} catch (err) {
422+
console.error('Logout error:', err);
423+
res.status(500).json({ success: false, message: 'Logout failed' });
424+
}
425+
});
404426

405427
//Driver get shipments
406428
app.get('/driver/shipments', async (req, res) => {

server/models/Driver.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ const DriverSchema = new mongoose.Schema({
77
password: { type: String, required: true },
88
userRole: { type: String, default: 'driver' },
99
assignedShipments: [String],
10+
phone: { type: String },
11+
licenseNumber: { type: String },
12+
status: { type: String, enum: ['Active', 'Inactive'], default: 'Active' },
13+
onDuty: { type: Boolean, default: false },
14+
vehicle: { type: mongoose.Schema.Types.ObjectId, ref: 'Vehicle'},
1015
});
1116

1217
DriverSchema.pre("save", async function(next) {

server/models/Vehicle.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const mongoose = require('mongoose')
2+
3+
const VehicleSchema = new mongoose.Schema({
4+
number: { type: String, required: true },
5+
model: { type: String },
6+
type: { type: String },
7+
assignedDriver: { type: mongoose.Schema.Types.ObjectId,ref: 'Driver' },
8+
createdAt: { type: Date, default: Date.now }
9+
})
10+
11+
module.exports = mongoose.model('Vehicle', VehicleSchema)

server/routes/drivers.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const express = require('express')
2+
const router = express.Router()
3+
const Driver = require('../models/Driver')
4+
require('../models/Vehicle')
5+
6+
router.get('/', async (req, res) => {
7+
try {
8+
const drivers = await Driver.find().populate('vehicle')
9+
res.status(200).json(drivers)
10+
} catch (err) {
11+
console.error('Error fetching drivers:', err)
12+
res.status(500).json({ error: 'Failed to fetch drivers' })
13+
}
14+
})
15+
16+
module.exports = router

0 commit comments

Comments
 (0)