added admin features

This commit is contained in:
Deep Koluguri 2025-11-06 13:43:51 -05:00
parent 12d5968373
commit 493e79273f
4 changed files with 269 additions and 3 deletions

View File

@ -393,11 +393,111 @@ const updateProfile = async (req, res) => {
} }
}; };
// Update member details (Manager only)
const updateMemberDetails = async (req, res) => {
try {
const { memberId } = req.params;
const { full_name, mobile_number, email, address, emergency_contact } = req.body;
const managerId = req.user.id;
// Find the member
const member = await User.findByPk(memberId);
if (!member) {
return res.status(404).json({
success: false,
message: 'Member not found'
});
}
// Check if the logged-in user is a manager
const manager = await User.findByPk(managerId);
if (manager.role !== 'manager') {
return res.status(403).json({
success: false,
message: 'Only managers can update member details'
});
}
// Prepare updates
const updates = {};
if (full_name) {
updates.full_name = full_name;
}
if (mobile_number) {
// Validate mobile number format
if (!/^[0-9]{10}$/.test(mobile_number)) {
return res.status(400).json({
success: false,
message: 'Mobile number must be exactly 10 digits'
});
}
// Check if mobile number is already taken by another user
const existingUser = await User.findOne({
where: { mobile_number }
});
if (existingUser && existingUser.id !== memberId) {
return res.status(400).json({
success: false,
message: 'Mobile number is already in use'
});
}
updates.mobile_number = mobile_number;
}
if (email !== undefined) {
if (email && !/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email)) {
return res.status(400).json({
success: false,
message: 'Please provide a valid email address'
});
}
updates.email = email;
}
if (address !== undefined) {
updates.address = address;
}
if (emergency_contact !== undefined) {
if (emergency_contact && !/^[0-9]{10}$/.test(emergency_contact)) {
return res.status(400).json({
success: false,
message: 'Emergency contact must be exactly 10 digits'
});
}
updates.emergency_contact = emergency_contact;
}
// Update member
await member.update(updates);
res.json({
success: true,
message: 'Member details updated successfully',
data: {
user: member.toJSON()
}
});
} catch (error) {
console.error('Update member details error:', error);
res.status(500).json({
success: false,
message: 'Internal server error'
});
}
};
module.exports = { module.exports = {
signup, signup,
login, login,
createMember, createMember,
changePassword, changePassword,
getProfile, getProfile,
updateProfile updateProfile,
updateMemberDetails
}; };

View File

@ -510,10 +510,167 @@ const getDrawStatistics = async (req, res) => {
} }
}; };
// Delete monthly draw (manager only, for mistakes)
const deleteMonthlyDraw = async (req, res) => {
try {
const { draw_id } = req.params;
const managerId = req.user.id;
// Find the draw
const monthlyDraw = await MonthlyDraw.findOne({
where: { id: draw_id },
include: [
{
model: ChitGroup,
attributes: ['id', 'manager_id', 'name']
}
]
});
if (!monthlyDraw) {
return res.status(404).json({
success: false,
message: 'Monthly draw not found'
});
}
// Check if user is the manager
if (monthlyDraw.ChitGroup.manager_id !== managerId) {
return res.status(403).json({
success: false,
message: 'Only the group manager can delete draws'
});
}
// Store draw info for response
const drawInfo = {
month: monthlyDraw.month,
year: monthlyDraw.year,
groupName: monthlyDraw.ChitGroup.name
};
// Delete the draw
await monthlyDraw.destroy();
res.json({
success: true,
message: `Draw for ${drawInfo.month}/${drawInfo.year} deleted successfully`,
data: drawInfo
});
} catch (error) {
console.error('Delete monthly draw error:', error);
res.status(500).json({
success: false,
message: 'Internal server error'
});
}
};
// Update monthly draw (manager only, for corrections)
const updateMonthlyDraw = async (req, res) => {
try {
const { draw_id } = req.params;
const { winner_id, prize_amount, notes } = req.body;
const managerId = req.user.id;
// Find the draw
const monthlyDraw = await MonthlyDraw.findOne({
where: { id: draw_id },
include: [
{
model: ChitGroup,
attributes: ['id', 'manager_id', 'name']
}
]
});
if (!monthlyDraw) {
return res.status(404).json({
success: false,
message: 'Monthly draw not found'
});
}
// Check if user is the manager
if (monthlyDraw.ChitGroup.manager_id !== managerId) {
return res.status(403).json({
success: false,
message: 'Only the group manager can update draws'
});
}
const updates = {};
// Update winner if provided
if (winner_id) {
// Verify the winner is a member of the group
const member = await GroupMember.findOne({
where: {
group_id: monthlyDraw.ChitGroup.id,
user_id: winner_id,
status: 'active'
},
include: [{ model: User, attributes: ['id', 'full_name'] }]
});
if (!member) {
return res.status(400).json({
success: false,
message: 'Winner must be an active member of this group'
});
}
updates.winner_id = winner_id;
if (!notes) {
updates.notes = `Winner updated to: ${member.User.full_name}`;
}
}
// Update prize amount if provided
if (prize_amount) {
updates.prize_amount = prize_amount;
}
// Update notes if provided
if (notes) {
updates.notes = notes;
}
// Perform update
await monthlyDraw.update(updates);
// Fetch updated draw with winner details
const updatedDraw = await MonthlyDraw.findOne({
where: { id: draw_id },
include: [
{
model: User,
as: 'winner',
attributes: ['id', 'full_name', 'mobile_number']
}
]
});
res.json({
success: true,
message: 'Monthly draw updated successfully',
data: updatedDraw
});
} catch (error) {
console.error('Update monthly draw error:', error);
res.status(500).json({
success: false,
message: 'Internal server error'
});
}
};
module.exports = { module.exports = {
createMonthlyDraw, createMonthlyDraw,
getGroupMonthlyDraws, getGroupMonthlyDraws,
getMonthlyDrawDetails, getMonthlyDrawDetails,
verifyDrawResult, verifyDrawResult,
getDrawStatistics getDrawStatistics,
deleteMonthlyDraw,
updateMonthlyDraw
}; };

View File

@ -17,5 +17,6 @@ router.put('/change-password', authController.changePassword);
// Manager only routes // Manager only routes
router.post('/create-member', requireManager, authController.createMember); router.post('/create-member', requireManager, authController.createMember);
router.put('/member/:memberId', requireManager, authController.updateMemberDetails);
module.exports = router; module.exports = router;

View File

@ -6,7 +6,9 @@ const {
getGroupMonthlyDraws, getGroupMonthlyDraws,
getMonthlyDrawDetails, getMonthlyDrawDetails,
verifyDrawResult, verifyDrawResult,
getDrawStatistics getDrawStatistics,
deleteMonthlyDraw,
updateMonthlyDraw
} = require('../controllers/monthlyDrawController'); } = require('../controllers/monthlyDrawController');
// All routes require authentication // All routes require authentication
@ -21,6 +23,12 @@ router.get('/group/:group_id', getGroupMonthlyDraws);
// Get monthly draw details // Get monthly draw details
router.get('/:draw_id', getMonthlyDrawDetails); router.get('/:draw_id', getMonthlyDrawDetails);
// Update monthly draw (manager only)
router.put('/:draw_id', updateMonthlyDraw);
// Delete monthly draw (manager only)
router.delete('/:draw_id', deleteMonthlyDraw);
// Verify provably fair result // Verify provably fair result
router.post('/:draw_id/verify', verifyDrawResult); router.post('/:draw_id/verify', verifyDrawResult);