Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions backend/controllers/admin.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const adminService = require("../services/admin.service");
const { safeArray, safeNumber, sanitizeString, getPagination, buildPaginationMeta } = require("../utils/helpers");

const getDashboardStats = async (req, res) => {
try {
const data = await adminService.getDashboardStats();
return res.status(200).json({ success: true, data });
} catch (error) {
console.error("ADMIN DASHBOARD ERROR:", error);
return res.status(500).json({ success: false, message: "Server error" });
}
};

const getUsers = async (req, res) => {
try {
const { page, limit } = getPagination(req.query.page, req.query.limit, 50);
const filters = {
search: sanitizeString(req.query.search),
status: sanitizeString(req.query.status),
role: sanitizeString(req.query.role)
};

const result = await adminService.getUsers(filters, page, limit);

return res.status(200).json({
success: true,
users: result.users,
...buildPaginationMeta(result.total, page, limit)
});
} catch (error) {
console.error("ADMIN GET USERS ERROR:", error);
return res.status(500).json({ success: false, message: "Server error" });
}
};

const updateUserStatus = async (req, res) => {
try {
const targetId = safeNumber(req.params.id);
const status = sanitizeString(req.body.status); // 'active' or 'blocked'

if (!targetId || !['active', 'blocked'].includes(status)) {
return res.status(400).json({ success: false, message: "Invalid payload" });
}

if (targetId === req.user.id) {
return res.status(400).json({ success: false, message: "Cannot modify own status" });
}

await adminService.updateUserStatus(req.user.id, targetId, status, req.ip, req.headers['user-agent']);
return res.status(200).json({ success: true, message: `User ${status === 'active' ? 'unblocked' : 'blocked'} successfully` });
} catch (error) {
console.error("ADMIN UPDATE USER ERROR:", error);
return res.status(500).json({ success: false, message: "Server error" });
}
};

const bulkUpdateUserStatus = async (req, res) => {
try {
const targetIds = safeArray(req.body.userIds).map(id => safeNumber(id)).filter(id => id > 0 && id !== req.user.id);
const status = sanitizeString(req.body.status); // 'active' or 'blocked'

if (!targetIds.length || !['active', 'blocked'].includes(status)) {
return res.status(400).json({ success: false, message: "Invalid payload or users" });
}

await adminService.bulkUpdateUserStatus(req.user.id, targetIds, status, req.ip, req.headers['user-agent']);
return res.status(200).json({ success: true, message: `Users ${status === 'active' ? 'unblocked' : 'blocked'} successfully` });
} catch (error) {
console.error("ADMIN BULK UPDATE ERROR:", error);
return res.status(500).json({ success: false, message: "Server error" });
}
};

module.exports = {
getDashboardStats,
getUsers,
updateUserStatus,
bulkUpdateUserStatus
};
71 changes: 71 additions & 0 deletions backend/controllers/chat.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const chatService = require("../services/chat.service");
const { getPagination, sanitizeString, safeNumber } = require("../utils/helpers");

const getConversations = async (req, res) => {
try {
const { page, limit } = getPagination(req.query.page, req.query.limit, 20);
const filters = {
status: sanitizeString(req.query.status),
assigned_to: sanitizeString(req.query.assigned_to),
search: sanitizeString(req.query.search)
};

const data = await chatService.getConversationList(filters, page, limit);
res.status(200).json({ success: true, ...data });
} catch (error) {
console.error("GET CONVERSATIONS ERROR:", error);
res.status(500).json({ success: false, message: "Server error" });
}
};

const getConversationDetails = async (req, res) => {
try {
const id = safeNumber(req.params.id);
if (!id) return res.status(400).json({ success: false, message: "Invalid ID" });

const messages = await chatService.getConversationMessages(id);
res.status(200).json({ success: true, messages });
} catch (error) {
console.error("GET CONVERSATION DETAILS ERROR:", error);
res.status(500).json({ success: false, message: "Server error" });
}
};

const updateStatus = async (req, res) => {
try {
const id = safeNumber(req.params.id);
const { status } = req.body;
if (!id || !['open', 'pending', 'closed'].includes(status)) {
return res.status(400).json({ success: false, message: "Invalid payload" });
}

await chatService.updateConversationStatus(id, status);

// Emit socket event if needed, handled in socket logic usually
// but we return REST success
res.status(200).json({ success: true, message: `Conversation ${status}` });
} catch (error) {
console.error("UPDATE CONV STATUS ERROR:", error);
res.status(500).json({ success: false, message: "Server error" });
}
};

const assignAdmin = async (req, res) => {
try {
const id = safeNumber(req.params.id);
if (!id) return res.status(400).json({ success: false, message: "Invalid ID" });

await chatService.assignConversation(id, req.user.id);
res.status(200).json({ success: true, message: "Conversation assigned successfully" });
} catch (error) {
console.error("ASSIGN CONV ERROR:", error);
res.status(500).json({ success: false, message: "Server error" });
}
};

module.exports = {
getConversations,
getConversationDetails,
updateStatus,
assignAdmin
};
Loading