FairRelay / ops /backend-dm /controllers /dashboardController.js
MouleeswaranM's picture
Upload folder using huggingface_hub
fcf8749 verified
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
// ====== Mock Data for Demo Mode (when DB is unavailable) ======
const MOCK_STATS = {
pendingRequests: "12",
activeShipments: "34",
activeDrivers: "18",
fleetUtilization: "87%",
totalVehicles: 24,
totalCapacity: 48000,
activeCapacity: 41760,
unit: 'kg',
dispatchRuns: 48,
giniToday: 0.12,
co2SavedToday: 14.2,
aiHoursSaved: 3.2,
trends: {
pendingRequests: "+8 today",
activeShipments: "+12 today",
activeDrivers: "+5 today",
fleetUtilization: "+3% today"
}
};
const MOCK_ACTIVITY = [
{ day: 'Mon', requests: 14 },
{ day: 'Tue', requests: 22 },
{ day: 'Wed', requests: 18 },
{ day: 'Thu', requests: 31 },
{ day: 'Fri', requests: 27 },
{ day: 'Sat', requests: 19 },
{ day: 'Sun', requests: 11 },
];
const MOCK_LIVE_TRACKING = [
{ id: '1', name: 'MH-12-AB-1234 • Rajesh Kumar', status: 'In Transit' },
{ id: '2', name: 'DL-01-XY-9876 • Priya Sharma', status: 'Loading' },
{ id: '3', name: 'KA-05-CD-4567 • Amit Patel', status: 'Unloading' },
{ id: '4', name: 'TN-07-EF-3210 • Hub Transfer', status: 'Active' },
];
const MOCK_ABSORPTIONS = [
{ id: 'abs-001', type: 'Absorption', route: 'MH-12-AB-1234 ↔ DL-01-XY-9876', weight: '450.0 kg', priority: 'HIGH' },
{ id: 'abs-002', type: 'Backhaul', route: 'KA-05-CD-4567 ↔ TN-07-EF-3210', weight: '280.5 kg', priority: 'MEDIUM' },
{ id: 'abs-003', type: 'Absorption', route: 'GJ-18-PQ-5678 ↔ MH-12-AB-1234', weight: '120.0 kg', priority: 'LOW' },
];
exports.getStats = async (req, res) => {
try {
const pendingRequests = await prisma.shipment.count({ where: { status: 'PENDING' } });
const activeShipments = await prisma.shipment.count({
where: { status: { in: ['IN_TRANSIT', 'DISPATCHER_APPROVED', 'DRIVER_ACCEPTED', 'DRIVER_NOTIFIED'] } }
});
const activeDriversCount = await prisma.user.count({ where: { role: 'DRIVER', status: 'ON_DUTY' } });
const totalVehicles = await prisma.truck.count();
const totalCapacityResult = await prisma.truck.aggregate({ _sum: { capacity: true } });
const activeCapacityResult = await prisma.truck.aggregate({
_sum: { capacity: true },
where: { owner: { status: 'ON_DUTY' } }
});
res.json({
pendingRequests: pendingRequests.toString(),
activeShipments: activeShipments.toString(),
activeDrivers: activeDriversCount.toString(),
fleetUtilization: "87%",
totalVehicles,
totalCapacity: totalCapacityResult._sum.capacity || 0,
activeCapacity: activeCapacityResult._sum.capacity || 0,
unit: 'kg',
dispatchRuns: 48,
giniToday: 0.12,
co2SavedToday: 14.2,
aiHoursSaved: 3.2,
trends: {
pendingRequests: "+8 today",
activeShipments: "+12 today",
activeDrivers: "+5 today",
fleetUtilization: "+3% today"
}
});
} catch (error) {
console.warn('[Demo Mode] getStats using mock data:', error.message);
res.json(MOCK_STATS);
}
};
exports.getActivity = async (req, res) => {
try {
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 6);
sevenDaysAgo.setHours(0, 0, 0, 0);
const deliveries = await prisma.delivery.findMany({
where: { createdAt: { gte: sevenDaysAgo } },
select: { createdAt: true }
});
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const counts = {};
for (let i = 6; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
counts[dayNames[date.getDay()]] = 0;
}
deliveries.forEach(d => {
const day = dayNames[d.createdAt.getDay()];
if (counts[day] !== undefined) counts[day]++;
});
const today = new Date().getDay();
const orderedDays = [];
for (let i = 6; i >= 0; i--) {
orderedDays.push(dayNames[(today - i + 7) % 7]);
}
res.json(orderedDays.map(day => ({ day, requests: counts[day] || 0 })));
} catch (error) {
console.warn('[Demo Mode] getActivity using mock data:', error.message);
res.json(MOCK_ACTIVITY);
}
};
exports.getLiveTracking = async (req, res) => {
try {
const drivers = await prisma.user.findMany({ where: { role: 'DRIVER', status: 'IN_TRANSIT' }, take: 4 });
const trackingData = drivers.length > 0
? drivers.map(d => ({ id: d.id, name: d.homeBaseCity || 'Unknown Route', status: 'In Transit' }))
: MOCK_LIVE_TRACKING;
res.json(trackingData);
} catch (error) {
console.warn('[Demo Mode] getLiveTracking using mock data');
res.json(MOCK_LIVE_TRACKING);
}
};
exports.getLiveTrackingWeb = async (req, res) => {
try {
const trucks = await prisma.truck.findMany({ where: { isAvailable: false }, include: { owner: true }, take: 4 });
const trackingData = trucks.length > 0
? trucks.map(t => ({ id: t.id, name: `${t.licensePlate}${t.owner?.name || 'Unassigned'}`, status: 'Active' }))
: MOCK_LIVE_TRACKING;
res.json(trackingData);
} catch (error) {
console.warn('[Demo Mode] getLiveTrackingWeb using mock data');
res.json(MOCK_LIVE_TRACKING);
}
};
exports.getLiveTrackingGPS = async (req, res) => {
try {
const trucks = await prisma.truck.findMany({ where: { isAvailable: false }, include: { owner: true }, take: 20 });
const trackingData = trucks.map(t => ({
id: t.id,
name: `${t.licensePlate}${t.owner?.name || 'Unassigned'}`,
status: 'Active',
location: { lat: t.currentLat || 19.0760, lng: t.currentLng || 72.8777, heading: 0, speed: 60 }
}));
res.json(trackingData.length > 0 ? trackingData : [
{ id: '1', name: 'MH-12-AB-1234 • Rajesh Kumar', status: 'Active', location: { lat: 19.0760, lng: 72.8777, heading: 45, speed: 65 } },
{ id: '2', name: 'KA-05-CD-4567 • Priya Sharma', status: 'Active', location: { lat: 12.9716, lng: 77.5946, heading: 90, speed: 55 } },
{ id: '3', name: 'DL-01-XY-9876 • Amit Patel', status: 'Active', location: { lat: 28.6139, lng: 77.2090, heading: 180, speed: 70 } },
]);
} catch (error) {
console.warn('[Demo Mode] getLiveTrackingGPS using mock data');
res.json([
{ id: '1', name: 'MH-12-AB-1234 • Rajesh Kumar', status: 'Active', location: { lat: 19.0760, lng: 72.8777, heading: 45, speed: 65 } },
{ id: '2', name: 'KA-05-CD-4567 • Priya Sharma', status: 'Active', location: { lat: 12.9716, lng: 77.5946, heading: 90, speed: 55 } },
{ id: '3', name: 'DL-01-XY-9876 • Amit Patel', status: 'Active', location: { lat: 28.6139, lng: 77.2090, heading: 180, speed: 70 } },
]);
}
};
exports.getRecentAbsorptions = async (req, res) => {
try {
const startOfDay = new Date(); startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date(); endOfDay.setHours(23, 59, 59, 999);
const absorptions = await prisma.absorptionOpportunity.findMany({
where: { createdAt: { gte: startOfDay, lte: endOfDay } },
include: {
route1: { select: { id: true, truck: { select: { licensePlate: true } } } },
route2: { select: { id: true, truck: { select: { licensePlate: true } } } }
},
orderBy: { createdAt: 'desc' },
take: 3
});
if (absorptions.length === 0) return res.json(MOCK_ABSORPTIONS);
res.json(absorptions.map(abs => ({
id: abs.id,
type: 'Absorption',
route: `${abs.route1.truck?.licensePlate || 'Route 1'}${abs.route2.truck?.licensePlate || 'Route 2'}`,
weight: `${abs.spaceRequiredWeight.toFixed(1)} kg`,
priority: abs.totalDistanceSaved > 50 ? 'HIGH' : (abs.totalDistanceSaved > 20 ? 'MEDIUM' : 'LOW')
})));
} catch (error) {
console.warn('[Demo Mode] getRecentAbsorptions using mock data');
res.json(MOCK_ABSORPTIONS);
}
};