deletion reason and email for soft deleted forum posts and comments by admin
This commit is contained in:
@@ -23,6 +23,7 @@ const ForumPostDetail: React.FC = () => {
|
||||
type: 'deletePost' | 'deleteComment' | 'restorePost' | 'restoreComment' | 'closePost' | 'reopenPost';
|
||||
id?: string;
|
||||
} | null>(null);
|
||||
const [deletionReason, setDeletionReason] = useState('');
|
||||
|
||||
// Read filter from URL query param
|
||||
const filter = searchParams.get('filter') || 'active';
|
||||
@@ -174,13 +175,19 @@ const ForumPostDetail: React.FC = () => {
|
||||
const confirmAdminAction = async () => {
|
||||
if (!adminAction) return;
|
||||
|
||||
// Validate deletion reason for delete actions
|
||||
if ((adminAction.type === 'deletePost' || adminAction.type === 'deleteComment') && !deletionReason.trim()) {
|
||||
alert('Please provide a reason for deletion');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setActionLoading(true);
|
||||
setShowAdminModal(false);
|
||||
|
||||
switch (adminAction.type) {
|
||||
case 'deletePost':
|
||||
await forumAPI.adminDeletePost(id!);
|
||||
await forumAPI.adminDeletePost(id!, deletionReason.trim());
|
||||
break;
|
||||
case 'restorePost':
|
||||
await forumAPI.adminRestorePost(id!);
|
||||
@@ -192,7 +199,7 @@ const ForumPostDetail: React.FC = () => {
|
||||
await forumAPI.adminReopenPost(id!);
|
||||
break;
|
||||
case 'deleteComment':
|
||||
await forumAPI.adminDeleteComment(adminAction.id!);
|
||||
await forumAPI.adminDeleteComment(adminAction.id!, deletionReason.trim());
|
||||
break;
|
||||
case 'restoreComment':
|
||||
await forumAPI.adminRestoreComment(adminAction.id!);
|
||||
@@ -205,12 +212,14 @@ const ForumPostDetail: React.FC = () => {
|
||||
} finally {
|
||||
setActionLoading(false);
|
||||
setAdminAction(null);
|
||||
setDeletionReason('');
|
||||
}
|
||||
};
|
||||
|
||||
const cancelAdminAction = () => {
|
||||
setShowAdminModal(false);
|
||||
setAdminAction(null);
|
||||
setDeletionReason('');
|
||||
};
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
@@ -520,7 +529,26 @@ const ForumPostDetail: React.FC = () => {
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
{adminAction?.type === 'deletePost' && (
|
||||
<p>Are you sure you want to delete this post? It will be deleted and hidden from regular users but can be restored later.</p>
|
||||
<>
|
||||
<p>Are you sure you want to delete this post? It will be deleted and hidden from regular users but can be restored later.</p>
|
||||
<div className="mb-3">
|
||||
<label htmlFor="deletionReason" className="form-label">
|
||||
<strong>Reason for deletion <span className="text-danger">*</span></strong>
|
||||
</label>
|
||||
<textarea
|
||||
id="deletionReason"
|
||||
className="form-control"
|
||||
rows={4}
|
||||
placeholder="Please explain why this post is being deleted. The author will receive this reason via email."
|
||||
value={deletionReason}
|
||||
onChange={(e) => setDeletionReason(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<small className="text-muted">
|
||||
This reason will be sent to the post author via email.
|
||||
</small>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{adminAction?.type === 'restorePost' && (
|
||||
<p>Are you sure you want to restore this post? It will become visible to all users again.</p>
|
||||
@@ -532,7 +560,26 @@ const ForumPostDetail: React.FC = () => {
|
||||
<p>Are you sure you want to reopen this discussion? Users will be able to add comments again.</p>
|
||||
)}
|
||||
{adminAction?.type === 'deleteComment' && (
|
||||
<p>Are you sure you want to delete this comment? It will be deleted and hidden from regular users but can be restored later.</p>
|
||||
<>
|
||||
<p>Are you sure you want to delete this comment? It will be deleted and hidden from regular users but can be restored later.</p>
|
||||
<div className="mb-3">
|
||||
<label htmlFor="deletionReason" className="form-label">
|
||||
<strong>Reason for deletion <span className="text-danger">*</span></strong>
|
||||
</label>
|
||||
<textarea
|
||||
id="deletionReason"
|
||||
className="form-control"
|
||||
rows={4}
|
||||
placeholder="Please explain why this comment is being deleted. The author will receive this reason via email."
|
||||
value={deletionReason}
|
||||
onChange={(e) => setDeletionReason(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<small className="text-muted">
|
||||
This reason will be sent to the comment author via email.
|
||||
</small>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{adminAction?.type === 'restoreComment' && (
|
||||
<p>Are you sure you want to restore this comment? It will become visible to all users again.</p>
|
||||
|
||||
@@ -286,9 +286,9 @@ export const forumAPI = {
|
||||
deleteComment: (commentId: string) =>
|
||||
api.delete(`/forum/comments/${commentId}`),
|
||||
// Admin endpoints
|
||||
adminDeletePost: (id: string) => api.delete(`/forum/admin/posts/${id}`),
|
||||
adminDeletePost: (id: string, reason: string) => api.delete(`/forum/admin/posts/${id}`, { data: { reason } }),
|
||||
adminRestorePost: (id: string) => api.patch(`/forum/admin/posts/${id}/restore`),
|
||||
adminDeleteComment: (id: string) => api.delete(`/forum/admin/comments/${id}`),
|
||||
adminDeleteComment: (id: string, reason: string) => api.delete(`/forum/admin/comments/${id}`, { data: { reason } }),
|
||||
adminRestoreComment: (id: string) => api.patch(`/forum/admin/comments/${id}/restore`),
|
||||
adminClosePost: (id: string) => api.patch(`/forum/admin/posts/${id}/close`),
|
||||
adminReopenPost: (id: string) => api.patch(`/forum/admin/posts/${id}/reopen`),
|
||||
|
||||
Reference in New Issue
Block a user