forked from UKSOURCE/cms.hailearning.edu.vn
feat: Enhance comment management functionality in blog module
This commit is contained in:
@@ -198,6 +198,21 @@ exports.edit = async (req, res) => {
|
||||
const categories = await BlogCategory.getActive();
|
||||
const tags = await BlogTag.getActive();
|
||||
|
||||
// Get all comments for this blog post (including pending, approved, rejected)
|
||||
const allComments = await BlogComment.find({ postId: blog._id })
|
||||
.sort({ createdAt: -1 })
|
||||
.lean();
|
||||
|
||||
// Organize comments with replies
|
||||
const parentComments = allComments.filter(c => !c.parentId);
|
||||
const commentsWithReplies = parentComments.map(parent => {
|
||||
const replies = allComments.filter(c => c.parentId && c.parentId.toString() === parent._id.toString());
|
||||
return {
|
||||
...parent,
|
||||
replies: replies
|
||||
};
|
||||
});
|
||||
|
||||
const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3000';
|
||||
|
||||
res.render('admin/blog/edit', {
|
||||
@@ -206,6 +221,8 @@ exports.edit = async (req, res) => {
|
||||
blog,
|
||||
categories,
|
||||
tags,
|
||||
comments: commentsWithReplies,
|
||||
commentsCount: allComments.length,
|
||||
currentPath: req.path,
|
||||
user: req.session.user,
|
||||
frontendUrl
|
||||
@@ -437,7 +454,7 @@ exports.apiShow = async (req, res) => {
|
||||
// Create a comment (no moderation for now: default approved)
|
||||
exports.apiCreateComment = async (req, res) => {
|
||||
try {
|
||||
const { authorName, content, parentId } = req.body || {};
|
||||
const { authorName, authorEmail, authorPhone, authorAddress, authorDate, content, parentId } = req.body || {};
|
||||
|
||||
if (!authorName || !String(authorName).trim()) {
|
||||
return res.status(400).json({
|
||||
@@ -477,6 +494,10 @@ exports.apiCreateComment = async (req, res) => {
|
||||
const newComment = await BlogComment.create({
|
||||
postId: blog._id,
|
||||
authorName: String(authorName).trim(),
|
||||
...(authorEmail ? { authorEmail: String(authorEmail).trim() } : {}),
|
||||
...(authorPhone ? { authorPhone: String(authorPhone).trim() } : {}),
|
||||
...(authorAddress ? { authorAddress: String(authorAddress).trim() } : {}),
|
||||
...(authorDate ? { authorDate: String(authorDate).trim() } : {}),
|
||||
content: String(content).trim(),
|
||||
parentId: parentObjectId,
|
||||
status: "approved",
|
||||
@@ -653,4 +674,129 @@ exports.apiTags = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------- Comment Management Controllers --------------------
|
||||
|
||||
// Approve a comment
|
||||
exports.approveComment = async (req, res) => {
|
||||
try {
|
||||
const { blogId, commentId } = req.params;
|
||||
|
||||
const blog = await Blog.findById(blogId);
|
||||
if (!blog) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Blog post not found'
|
||||
});
|
||||
}
|
||||
|
||||
const comment = await BlogComment.findById(commentId);
|
||||
if (!comment || comment.postId.toString() !== blogId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Comment not found'
|
||||
});
|
||||
}
|
||||
|
||||
comment.status = 'approved';
|
||||
await comment.save();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Comment approved successfully'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Approve comment error:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Error approving comment',
|
||||
error: err.message || 'Error approving comment'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Reject a comment
|
||||
exports.rejectComment = async (req, res) => {
|
||||
try {
|
||||
const { blogId, commentId } = req.params;
|
||||
|
||||
const blog = await Blog.findById(blogId);
|
||||
if (!blog) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Blog post not found'
|
||||
});
|
||||
}
|
||||
|
||||
const comment = await BlogComment.findById(commentId);
|
||||
if (!comment || comment.postId.toString() !== blogId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Comment not found'
|
||||
});
|
||||
}
|
||||
|
||||
comment.status = 'rejected';
|
||||
await comment.save();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Comment rejected successfully'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Reject comment error:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Error rejecting comment',
|
||||
error: err.message || 'Error rejecting comment'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Delete a comment
|
||||
exports.deleteComment = async (req, res) => {
|
||||
try {
|
||||
const { blogId, commentId } = req.params;
|
||||
|
||||
const blog = await Blog.findById(blogId);
|
||||
if (!blog) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Blog post not found'
|
||||
});
|
||||
}
|
||||
|
||||
const comment = await BlogComment.findById(commentId);
|
||||
if (!comment || comment.postId.toString() !== blogId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Comment not found'
|
||||
});
|
||||
}
|
||||
|
||||
// Delete the comment and all its replies
|
||||
await BlogComment.deleteMany({
|
||||
$or: [
|
||||
{ _id: commentId },
|
||||
{ parentId: commentId }
|
||||
]
|
||||
});
|
||||
|
||||
// Update blog comment count
|
||||
const remainingComments = await BlogComment.countDocuments({ postId: blogId });
|
||||
await Blog.updateOne({ _id: blogId }, { commentsCount: remainingComments });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Comment deleted successfully'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Delete comment error:', err);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Error deleting comment',
|
||||
error: err.message || 'Error deleting comment'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = exports;
|
||||
Reference in New Issue
Block a user