100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
import { ClientModel, ProjectModel, VAModel } from "../../../models/vaModel.js";
|
|
import jwt from "jsonwebtoken";
|
|
|
|
function formatHoursToReadable(hours) {
|
|
const wholeHours = Math.floor(hours);
|
|
const decimalMinutes = (hours - wholeHours) * 60;
|
|
const wholeMinutes = Math.round(decimalMinutes);
|
|
|
|
if (wholeHours > 0 && wholeMinutes > 0) {
|
|
return `${wholeHours}h ${wholeMinutes}m`;
|
|
} else if (wholeHours > 0) {
|
|
return `${wholeHours}h`;
|
|
} else {
|
|
return `${wholeMinutes}m`;
|
|
}
|
|
}
|
|
|
|
// Getting client dashboard data - all VAs and projects
|
|
async function client_dashboard_projects(req, res) {
|
|
try {
|
|
const accessToken = req.headers.token;
|
|
|
|
if (!accessToken) {
|
|
return res.status(401).json({ success: false, message: "Missing token" });
|
|
}
|
|
|
|
const decoded = jwt.verify(accessToken, process.env.JWT_SECRET_ACCESS_TOKEN);
|
|
|
|
if (!decoded || !decoded.email) {
|
|
return res.status(401).json({ success: false, message: "Invalid token" });
|
|
}
|
|
|
|
const clientEmail = decoded.email;
|
|
const clientUser = await ClientModel.findOne({ "userDetails.email": clientEmail });
|
|
if (!clientUser) {
|
|
return res.status(404).json({ success: false, message: "Client not found" });
|
|
}
|
|
|
|
// Get all VA IDs and Project IDs assigned to this client
|
|
const clientVaIds = clientUser.vaIds || [];
|
|
const clientProjectIds = clientUser.projectIds || [];
|
|
|
|
// Get all VAs assigned to this client (with required fields only)
|
|
const allAssignedVAs = await VAModel.find({
|
|
_id: { $in: clientVaIds }
|
|
})
|
|
.select('userDetails.firstName userDetails.lastName userDetails.email status')
|
|
.lean()
|
|
.exec();
|
|
|
|
// Get All Projects of client with required fields
|
|
const clientProjects = await ProjectModel.find({
|
|
_id: { $in: clientProjectIds }
|
|
})
|
|
.select('name hourlyRate vaAssigned dedicatedHours status')
|
|
.lean()
|
|
.exec();
|
|
|
|
// Format VAs with only required fields
|
|
const vasFormatted = allAssignedVAs.map((va) => ({
|
|
id: va._id,
|
|
firstName: va.userDetails?.firstName || '',
|
|
lastName: va.userDetails?.lastName || '',
|
|
email: va.userDetails?.email || '',
|
|
status: va.status || ''
|
|
}));
|
|
|
|
// Format projects with only required fields
|
|
const projectsFormatted = clientProjects.map((project) => ({
|
|
id: project._id,
|
|
name: project.name,
|
|
hourlyRate: project.hourlyRate,
|
|
vaAssigned: project.vaAssigned.length || 0,
|
|
dedicatedHours: formatHoursToReadable(project.dedicatedHours) || 0,
|
|
status: project.status || ''
|
|
}));
|
|
|
|
return res.status(200).json({
|
|
success: true,
|
|
data: {
|
|
vas: vasFormatted,
|
|
projects: projectsFormatted
|
|
},
|
|
counts: {
|
|
totalVAs: vasFormatted.length,
|
|
totalProjects: projectsFormatted.length
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Client dashboard error:", error);
|
|
return res.status(500).json({
|
|
success: false,
|
|
message: "Internal Server Error",
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
export { client_dashboard_projects }; |