"use client"; import { useCallback, useEffect, useRef, useState } from "react"; import { NoPermissionState } from "@/components/auth/no-permission-state"; import { useSuperAdminSession } from "@/components/auth/session-context"; import { PageHeader } from "@/components/dashboard/page-header"; import { PaginationControls } from "@/components/dashboard/pagination-controls"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { EmptyState } from "@/components/ui/empty-state"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { useToast } from "@/components/ui/toast"; import { listModerationComments } from "@/lib/api/comments"; import { getItems, getPagination } from "@/lib/api/core"; import { listModerationPosts } from "@/lib/api/posts"; import { deleteSuperAdminComment, deleteSuperAdminPost, getSuperAdminReports, performSuperAdminBulkAction, updateSuperAdminCommentStatus, updateSuperAdminPostStatus, } from "@/lib/api/superadmin"; import { formatDateTime } from "@/lib/format"; import { getCommentAuthor, getPostAuthor, getUserLabel } from "@/lib/post-utils"; import { SUPERADMIN_PERMISSIONS, hasPermission } from "@/lib/permissions"; import type { ApiComment, ApiPost, CommentsResponse, ModerationStatus, PostsResponse, SuperAdminReportsResponse, } from "@/types/api"; type BulkTarget = "post" | "comment"; type BulkAction = "activate" | "flag" | "hide" | "delete"; const EMPTY_REPORTS: SuperAdminReportsResponse = { summary: { flaggedPostsCount: 0, flaggedCommentsCount: 0, disabledUsersCount: 0, inactiveListingsCount: 0, inactiveRepairShopsCount: 0, openCasesCount: 0, failedOutboxEventsCount: 0, pendingOutboxEventsCount: 0, }, flaggedPosts: [], flaggedComments: [], disabledUsers: [], inactiveListings: [], inactiveRepairShops: [], }; function promptReason(actionLabel: string) { if (typeof window === "undefined") { return ""; } const result = window.prompt(`Optional reason for ${actionLabel}`, ""); if (result === null) { return null; } return result.trim(); } export default function ContentPage() { const { permissions } = useSuperAdminSession(); const [query, setQuery] = useState(""); const [postType, setPostType] = useState("all"); const [visibility, setVisibility] = useState("all"); const [moderationStatus, setModerationStatus] = useState("all"); const [postsResponse, setPostsResponse] = useState(null); const [commentsResponse, setCommentsResponse] = useState(null); const [reports, setReports] = useState(EMPTY_REPORTS); const [loading, setLoading] = useState(true); const [postsPage, setPostsPage] = useState(1); const [commentsPage, setCommentsPage] = useState(1); const [selectedPostIds, setSelectedPostIds] = useState([]); const [selectedCommentIds, setSelectedCommentIds] = useState([]); const [bulkTarget, setBulkTarget] = useState("post"); const [bulkAction, setBulkAction] = useState("flag"); const [bulkReason, setBulkReason] = useState(""); const [bulkLoading, setBulkLoading] = useState(false); const { toast } = useToast(); const filtersRef = useRef({ query, postType, visibility, moderationStatus }); const canModerateContent = hasPermission( permissions, SUPERADMIN_PERMISSIONS.CONTENT_MODERATE, ); const canReadAnalytics = hasPermission(permissions, SUPERADMIN_PERMISSIONS.ANALYTICS_READ); const canUseBulkActions = canModerateContent && hasPermission(permissions, SUPERADMIN_PERMISSIONS.CASES_MANAGE); filtersRef.current = { query, postType, visibility, moderationStatus }; const loadContent = useCallback(async () => { if (!canModerateContent) { setLoading(false); return; } const { query: currentQuery, postType: currentPostType, visibility: currentVisibility, moderationStatus: currentModerationStatus, } = filtersRef.current; setLoading(true); try { const [posts, comments, nextReports] = await Promise.all([ listModerationPosts({ page: postsPage, limit: 10, q: currentQuery || undefined, postType: currentPostType === "all" ? undefined : currentPostType, visibility: currentVisibility === "all" ? undefined : currentVisibility, moderationStatus: currentModerationStatus === "all" ? undefined : currentModerationStatus, sortBy: "createdAt", sortOrder: "desc", }), listModerationComments({ page: commentsPage, limit: 10, q: currentQuery || undefined, moderationStatus: currentModerationStatus === "all" ? undefined : currentModerationStatus, sortOrder: "desc", }), canReadAnalytics ? getSuperAdminReports({ limit: 6 }) : Promise.resolve(EMPTY_REPORTS), ]); setPostsResponse(posts); setCommentsResponse(comments); setReports(nextReports); } catch (error) { toast({ title: "Failed to load content", description: String(error), variant: "danger" }); } finally { setLoading(false); } }, [canModerateContent, canReadAnalytics, commentsPage, postsPage, toast]); useEffect(() => { void loadContent(); }, [loadContent]); const applyFilters = () => { const shouldReloadDirectly = postsPage === 1 && commentsPage === 1; setPostsPage(1); setCommentsPage(1); if (shouldReloadDirectly) { void loadContent(); } }; const posts = getItems(postsResponse) as ApiPost[]; const comments = getItems(commentsResponse) as ApiComment[]; const bulkIds = bulkTarget === "post" ? selectedPostIds : selectedCommentIds; const updatePostStatus = async (postId: string, status: ModerationStatus) => { const reason = promptReason(`post ${status}`); if (reason === null) return; try { await updateSuperAdminPostStatus(postId, status, reason || undefined); await loadContent(); toast({ title: "Post updated", description: `${postId} -> ${status}`, variant: "success" }); } catch (error) { toast({ title: "Post update failed", description: String(error), variant: "danger" }); } }; const updateCommentStatus = async (commentId: string, status: ModerationStatus) => { const reason = promptReason(`comment ${status}`); if (reason === null) return; try { await updateSuperAdminCommentStatus(commentId, status, reason || undefined); await loadContent(); toast({ title: "Comment updated", description: `${commentId} -> ${status}`, variant: "success" }); } catch (error) { toast({ title: "Comment update failed", description: String(error), variant: "danger" }); } }; const toggleSelection = (kind: BulkTarget, id: string) => { const setter = kind === "post" ? setSelectedPostIds : setSelectedCommentIds; setter((prev) => (prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id])); }; if (!canModerateContent) { return (
); } return (
Apply filters } /> {canReadAnalytics ? (
Flagged posts {reports.summary.flaggedPostsCount} Flagged comments {reports.summary.flaggedCommentsCount} Disabled users {reports.summary.disabledUsersCount} Inactive listings {reports.summary.inactiveListingsCount} Inactive shops {reports.summary.inactiveRepairShopsCount} Open cases {reports.summary.openCasesCount} Failed outbox {reports.summary.failedOutboxEventsCount}
) : null} Filters setQuery(event.target.value)} placeholder="Search text or identity" /> {canUseBulkActions ? ( Bulk actions setBulkReason(event.target.value)} placeholder="Reason for audit/case log" /> ) : null}
Posts {!posts.length && !loading ? ( ) : ( {canUseBulkActions ? : null} Content Author Type State Engagement Actions {posts.map((post) => ( {canUseBulkActions ? ( toggleSelection("post", post._id)} /> ) : null} {post.content || "-"} {getUserLabel(getPostAuthor(post))} {post.postType ?? "-"} {post.moderationStatus ?? "active"} {post.likesCount ?? 0}/{post.commentsCount ?? 0}/{post.shareCount ?? 0} ))}
)}
Comments {!comments.length && !loading ? ( ) : (
{comments.map((comment) => (

{getUserLabel(getCommentAuthor(comment))}

{formatDateTime(comment.createdAt)}

{comment.moderationStatus ?? "comment"} {canUseBulkActions ? ( toggleSelection("comment", comment._id)} /> ) : null}

{comment.content}

))}
)}
); }