All files / emp_audit_system/controllers dashboardController.js

28.57% Statements 8/28
0% Branches 0/8
0% Functions 0/5
28.57% Lines 8/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126  6x 6x 6x 6x         6x                                                                                               6x                                                           6x                             6x                                              
// controllers/dashboardController.js
const Audit = require('../models/Audit');
const Establishment = require('../models/Establishment');
const User = require('../models/User');
const { formatDate } = require('../utils/helpers');
 
/**
 * Get dashboard overview
 */
exports.getDashboard = async (req, res) => {
  try {
    const userId = req.user.id;
    const userRole = req.user.role;
 
    // Get data based on user role
    const query = userRole === 'admin' 
      ? {} 
      : { user: userId };
 
    const [audits, establishments, stats, recentActivity] = await Promise.all([
      // Last 5 audits
      Audit.find(query)
        .sort({ createdAt: -1 })
        .limit(5)
        .populate('establishment user'),
      
      // Establishments for quick audit creation
      Establishment.find().limit(5),
      
      // Dashboard statistics
      this.getDashboardStats(userId, userRole),
      
      // Recent system activity
      this.getRecentActivity(userId, userRole)
    ]);
 
    res.render('dashboard', {
      user: req.user,
      audits,
      establishments,
      stats,
      recentActivity,
      helpers: { formatDate }
    });
 
  } catch (error) {
    console.error('Dashboard Error:', error);
    res.status(500).render('error', { 
      message: 'Failed to load dashboard',
      error
    });
  }
};
 
/**
 * Get dashboard statistics
 */
exports.getDashboardStats = async (userId, userRole) => {
  const query = userRole === 'admin' ? {} : { user: userId };
  
  const [
    totalAudits,
    pendingAudits,
    completedAudits,
    avgCompliance
  ] = await Promise.all([
    Audit.countDocuments(query),
    Audit.countDocuments({ ...query, status: 'submitted' }),
    Audit.countDocuments({ ...query, status: 'approved' }),
    Audit.aggregate([
      { $match: query },
      { $group: { _id: null, avg: { $avg: "$complianceScore" } } }
    ])
  ]);
 
  return {
    totalAudits,
    pendingAudits,
    completedAudits,
    complianceRate: avgCompliance[0]?.avg ? Math.round(avgCompliance[0].avg) : 0,
    establishments: await Establishment.countDocuments()
  };
};
 
/**
 * Get recent system activity
 */
exports.getRecentActivity = async (userId, userRole) => {
  const query = userRole === 'admin' 
    ? {} 
    : { $or: [{ user: userId }, { public: true }] };
 
  return Audit.find(query)
    .sort({ updatedAt: -1 })
    .limit(8)
    .select('status updatedAt establishment complianceScore')
    .populate('establishment', 'name');
};
 
/**
 * API Endpoint for dashboard data (used by frontend JS)
 */
exports.getDashboardData = async (req, res) => {
  try {
    const stats = await this.getDashboardStats(req.user.id, req.user.role);
    const recentActivity = await this.getRecentActivity(req.user.id, req.user.role);
 
    res.json({
      success: true,
      stats,
      recentActivity: recentActivity.map(item => ({
        id: item._id,
        establishment: item.establishment.name,
        status: item.status,
        date: item.updatedAt,
        compliance: item.complianceScore
      }))
    });
  } catch (error) {
    console.error('Dashboard API Error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to load dashboard data'
    });
  }
};