Fix: Implement comprehensive sorting fix

This commit is contained in:
gpt-engineer-app[bot]
2025-10-13 12:58:29 +00:00
parent f6891296d6
commit 76cbf94ffc

View File

@@ -145,7 +145,7 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
const isMountingRef = useRef(true); const isMountingRef = useRef(true);
const fetchItemsRef = useRef<((silent?: boolean) => Promise<void>) | null>(null); const fetchItemsRef = useRef<((silent?: boolean) => Promise<void>) | null>(null);
const FETCH_COOLDOWN_MS = 1000; const FETCH_COOLDOWN_MS = 300; // Match filter debounce delay for responsive sort changes
// Store settings in refs to avoid re-creating fetchItems // Store settings in refs to avoid re-creating fetchItems
const settingsRef = useRef(settings); const settingsRef = useRef(settings);
@@ -162,10 +162,11 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
* Fetch queue items from database * Fetch queue items from database
*/ */
const fetchItems = useCallback( const fetchItems = useCallback(
async (silent = false) => { async (silent = false, bypassCooldown = false) => {
console.log('🔄 [fetchItems RECREATED]', { console.log('🔄 [fetchItems RECREATED]', {
sortField: sort.field, sortField: sort.field,
sortDirection: sort.direction, sortDirection: sort.direction,
bypassCooldown,
timestamp: new Date().toISOString() timestamp: new Date().toISOString()
}); });
@@ -195,10 +196,10 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
return; return;
} }
// Cooldown check // Cooldown check (can be bypassed for critical operations like sort changes)
const now = Date.now(); const now = Date.now();
const timeSinceLastFetch = now - lastFetchTimeRef.current; const timeSinceLastFetch = now - lastFetchTimeRef.current;
if (timeSinceLastFetch < FETCH_COOLDOWN_MS && lastFetchTimeRef.current > 0) { if (!bypassCooldown && timeSinceLastFetch < FETCH_COOLDOWN_MS && lastFetchTimeRef.current > 0) {
console.log(`⏸️ Fetch cooldown active (${timeSinceLastFetch}ms)`); console.log(`⏸️ Fetch cooldown active (${timeSinceLastFetch}ms)`);
return; return;
} }
@@ -321,12 +322,42 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
); );
} }
// Get total count // Get total count for pagination (rebuild query with same filters)
const { count } = await supabase let countQuery = supabase
.from("content_submissions") .from("content_submissions")
.select("*", { count: "exact", head: true }) .select("*", { count: "exact", head: true });
.match(submissionsQuery as any);
// Apply same filters as main query
if (tab === "mainQueue") {
if (statusFilter === "all") {
countQuery = countQuery.in("status", ["pending", "flagged", "partially_approved"]);
} else if (statusFilter === "pending") {
countQuery = countQuery.in("status", ["pending", "partially_approved"]);
} else {
countQuery = countQuery.eq("status", statusFilter);
}
} else {
if (statusFilter === "all") {
countQuery = countQuery.in("status", ["approved", "rejected"]);
} else {
countQuery = countQuery.eq("status", statusFilter);
}
}
if (entityFilter === "photos") {
countQuery = countQuery.eq("submission_type", "photo");
} else if (entityFilter === "submissions") {
countQuery = countQuery.neq("submission_type", "photo");
}
if (!isAdmin && !isSuperuser) {
const now = new Date().toISOString();
countQuery = countQuery.or(
`assigned_to.is.null,locked_until.lt.${now},assigned_to.eq.${user.id}`,
);
}
const { count } = await countQuery;
pagination.setTotalCount(count || 0); pagination.setTotalCount(count || 0);
// Apply pagination // Apply pagination
@@ -353,6 +384,22 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
if (submissionsError) throw submissionsError; if (submissionsError) throw submissionsError;
// VALIDATE: Log first few items to verify sort is working
if (submissions && submissions.length > 0) {
console.log('[Query] Results returned (first 3 items):', {
sortColumn,
sortDirection: sortAscending ? 'ASC' : 'DESC',
items: submissions.slice(0, 3).map(s => ({
id: s.id.substring(0, 8),
type: s.submission_type,
status: s.status,
created: s.created_at,
escalated: s.escalated,
sortValue: s[sortColumn as keyof typeof s]
}))
});
}
// Fetch related profiles and entities // Fetch related profiles and entities
const userIds = [ const userIds = [
...new Set([ ...new Set([
@@ -955,9 +1002,6 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
console.log('🔄 [Sort Changed]', { console.log('🔄 [Sort Changed]', {
field: sort.field, field: sort.field,
direction: sort.direction, direction: sort.direction,
configField: sort.config.field,
configDirection: sort.config.direction,
match: sort.field === sort.config.field && sort.direction === sort.config.direction,
timestamp: new Date().toISOString() timestamp: new Date().toISOString()
}); });
@@ -973,19 +1017,15 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
return; return;
} }
// CRITICAL: Ensure we're using the latest fetchItems console.log('✅ Triggering refetch due to sort change', {
if (fetchItemsRef.current) { willUseField: sort.field,
console.log('✅ Triggering refetch due to sort change', { willUseDirection: sort.direction
willUseField: sort.field, });
willUseDirection: sort.direction
});
// Force immediate refetch // Call fetchItems directly (guaranteed to have latest sort values in closure)
fetchItemsRef.current(false); // Use bypass to skip cooldown for immediate sort response
} else { fetchItems(false, true);
console.error('❌ fetchItemsRef.current is null - cannot refetch!'); }, [sort.field, sort.direction, fetchItems]);
}
}, [sort.field, sort.direction]);
// Initialize realtime subscriptions // Initialize realtime subscriptions
useRealtimeSubscriptions({ useRealtimeSubscriptions({