94 lines
3.8 KiB
JavaScript
94 lines
3.8 KiB
JavaScript
const nocodbService = require('../services/nocodb');
|
|
const logger = require('../utils/logger');
|
|
const config = require('../config');
|
|
|
|
class DashboardController {
|
|
async getStats(req, res) {
|
|
try {
|
|
// Get all locations using the paginated method
|
|
const locationsResponse = await nocodbService.getAllPaginated(config.nocodb.tableId);
|
|
const locations = locationsResponse.list || [];
|
|
|
|
logger.info(`Processing ${locations.length} locations for dashboard stats`);
|
|
|
|
// Calculate support level distribution
|
|
const supportLevels = { '1': 0, '2': 0, '3': 0, '4': 0 };
|
|
let signDelivered = 0;
|
|
|
|
// Track sign sizes for requested signs
|
|
const signSizes = { 'Regular': 0, 'Large': 0, 'Unsure': 0 };
|
|
|
|
locations.forEach(loc => {
|
|
// Support levels
|
|
if (loc['Support Level']) {
|
|
supportLevels[loc['Support Level']]++;
|
|
}
|
|
|
|
// Signs delivered (where Sign checkbox is checked)
|
|
if (loc.Sign || loc.sign) {
|
|
signDelivered++;
|
|
}
|
|
|
|
// Sign sizes for requested signs (count all with sign size, regardless of delivery)
|
|
if (loc['Sign Size']) {
|
|
const size = loc['Sign Size'];
|
|
if (signSizes.hasOwnProperty(size)) {
|
|
signSizes[size]++;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Calculate overall score (weighted average)
|
|
const totalResponses = Object.values(supportLevels).reduce((a, b) => a + b, 0);
|
|
const weightedScore = (supportLevels['1'] * 4 + supportLevels['2'] * 3 +
|
|
supportLevels['3'] * 2 + supportLevels['4'] * 1) /
|
|
(totalResponses || 1);
|
|
|
|
// Get all users using the paginated method
|
|
let users = [];
|
|
if (config.nocodb.loginSheetId) {
|
|
const usersResponse = await nocodbService.getAllPaginated(config.nocodb.loginSheetId);
|
|
users = usersResponse.list || [];
|
|
logger.info(`Processing ${users.length} users for dashboard stats`);
|
|
} else {
|
|
logger.warn('Login sheet ID not configured, skipping user stats');
|
|
}
|
|
|
|
// Get daily entry counts for the last 30 days
|
|
const thirtyDaysAgo = new Date();
|
|
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
|
|
|
const dailyEntries = {};
|
|
locations.forEach(loc => {
|
|
const createdAt = new Date(loc.CreatedAt || loc.created_at || loc.createdAt);
|
|
if (!isNaN(createdAt.getTime()) && createdAt >= thirtyDaysAgo) {
|
|
const dateKey = createdAt.toISOString().split('T')[0];
|
|
dailyEntries[dateKey] = (dailyEntries[dateKey] || 0) + 1;
|
|
}
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
supportLevels,
|
|
signDelivered,
|
|
signSizes,
|
|
totalLocations: locations.length,
|
|
overallScore: weightedScore.toFixed(2),
|
|
totalUsers: users.length,
|
|
dailyEntries
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
logger.error('Error fetching dashboard stats:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Failed to fetch dashboard statistics'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = new DashboardController();
|