Add tabs to organize moderation items and their statuses

Introduces a `QueueTab` type and state for 'mainQueue' and 'archive', updating `fetchItems` to accept the tab parameter. Modifies query logic to apply status filters based on the selected tab in `ModerationQueue.tsx`.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: e14c2292-b0e5-43fe-b301-a4ad668949e9
Replit-Commit-Checkpoint-Type: full_checkpoint
This commit is contained in:
pac7
2025-10-08 14:50:34 +00:00
parent 0050032681
commit 3e2ce53fa7

View File

@@ -55,6 +55,7 @@ interface ModerationItem {
type EntityFilter = 'all' | 'reviews' | 'submissions' | 'photos'; type EntityFilter = 'all' | 'reviews' | 'submissions' | 'photos';
type StatusFilter = 'all' | 'pending' | 'partially_approved' | 'flagged' | 'approved' | 'rejected'; type StatusFilter = 'all' | 'pending' | 'partially_approved' | 'flagged' | 'approved' | 'rejected';
type QueueTab = 'mainQueue' | 'archive';
export interface ModerationQueueRef { export interface ModerationQueueRef {
refresh: () => void; refresh: () => void;
@@ -67,6 +68,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
const [isInitialLoad, setIsInitialLoad] = useState(true); const [isInitialLoad, setIsInitialLoad] = useState(true);
const [actionLoading, setActionLoading] = useState<string | null>(null); const [actionLoading, setActionLoading] = useState<string | null>(null);
const [notes, setNotes] = useState<Record<string, string>>({}); const [notes, setNotes] = useState<Record<string, string>>({});
const [activeTab, setActiveTab] = useState<QueueTab>('mainQueue');
const [activeEntityFilter, setActiveEntityFilter] = useState<EntityFilter>('all'); const [activeEntityFilter, setActiveEntityFilter] = useState<EntityFilter>('all');
const [activeStatusFilter, setActiveStatusFilter] = useState<StatusFilter>('pending'); const [activeStatusFilter, setActiveStatusFilter] = useState<StatusFilter>('pending');
const [photoModalOpen, setPhotoModalOpen] = useState(false); const [photoModalOpen, setPhotoModalOpen] = useState(false);
@@ -119,7 +121,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
loadedIdsRef.current = new Set(items.map(item => item.id)); loadedIdsRef.current = new Set(items.map(item => item.id));
}, [items]); }, [items]);
const fetchItems = useCallback(async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending', silent = false) => { const fetchItems = useCallback(async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending', silent = false, tab: QueueTab = 'mainQueue') => {
if (!user) { if (!user) {
return; return;
} }
@@ -135,6 +137,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
console.log('🔍 fetchItems called:', { console.log('🔍 fetchItems called:', {
entityFilter, entityFilter,
statusFilter, statusFilter,
tab,
silent, silent,
timestamp: new Date().toISOString() timestamp: new Date().toISOString()
}); });
@@ -168,13 +171,23 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
.order('priority', { ascending: false }) .order('priority', { ascending: false })
.order('created_at', { ascending: true }); .order('created_at', { ascending: true });
// Apply status filter // Apply tab-based status filtering
if (statusFilter === 'all') { if (tab === 'mainQueue') {
submissionsQuery = submissionsQuery.in('status', ['pending', 'approved', 'rejected', 'partially_approved']); // Main queue: pending, flagged, partially_approved submissions
} else if (statusFilter === 'pending') { if (statusFilter === 'all') {
submissionsQuery = submissionsQuery.in('status', ['pending', 'partially_approved']); submissionsQuery = submissionsQuery.in('status', ['pending', 'flagged', 'partially_approved']);
} else if (statusFilter === 'pending') {
submissionsQuery = submissionsQuery.in('status', ['pending', 'partially_approved']);
} else {
submissionsQuery = submissionsQuery.eq('status', statusFilter);
}
} else { } else {
submissionsQuery = submissionsQuery.eq('status', statusFilter); // Archive: approved or rejected submissions
if (statusFilter === 'all') {
submissionsQuery = submissionsQuery.in('status', ['approved', 'rejected']);
} else {
submissionsQuery = submissionsQuery.eq('status', statusFilter);
}
} }
// Apply entity type filter // Apply entity type filter