Refactor: Separate escalated items queue

This commit is contained in:
gpt-engineer-app[bot]
2025-10-13 01:40:24 +00:00
parent ef913fcc8d
commit 9e25beedd5
3 changed files with 54 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
import { useState, useImperativeHandle, forwardRef, useMemo } from 'react'; import { useState, useImperativeHandle, forwardRef, useMemo } from 'react';
import { Card, CardContent } from '@/components/ui/card'; import { Card, CardContent } from '@/components/ui/card';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { useUserRole } from '@/hooks/useUserRole'; import { useUserRole } from '@/hooks/useUserRole';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
@@ -19,7 +20,8 @@ import { AutoRefreshIndicator } from './AutoRefreshIndicator';
import { NewItemsAlert } from './NewItemsAlert'; import { NewItemsAlert } from './NewItemsAlert';
import { EmptyQueueState } from './EmptyQueueState'; import { EmptyQueueState } from './EmptyQueueState';
import { QueuePagination } from './QueuePagination'; import { QueuePagination } from './QueuePagination';
import type { ModerationQueueRef } from '@/types/moderation'; import type { ModerationQueueRef, QueueTab } from '@/types/moderation';
import { AlertTriangle, Clock, Archive } from 'lucide-react';
export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => { export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@@ -87,6 +89,28 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
return ( return (
<div className="space-y-4"> <div className="space-y-4">
{/* Queue Tabs */}
<Tabs
value={queueManager.filters.activeTab}
onValueChange={(value) => queueManager.filters.setActiveTab(value as QueueTab)}
className="w-full"
>
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="mainQueue" className="flex items-center gap-2">
<Clock className="w-4 h-4" />
Main Queue
</TabsTrigger>
<TabsTrigger value="escalated" className="flex items-center gap-2">
<AlertTriangle className="w-4 h-4" />
Escalated
</TabsTrigger>
<TabsTrigger value="archive" className="flex items-center gap-2">
<Archive className="w-4 h-4" />
Archive
</TabsTrigger>
</TabsList>
</Tabs>
{/* Queue Statistics & Lock Status */} {/* Queue Statistics & Lock Status */}
{queueManager.queue.queueStats && ( {queueManager.queue.queueStats && (
<Card className="bg-gradient-to-r from-primary/5 to-primary/10 border-primary/20"> <Card className="bg-gradient-to-r from-primary/5 to-primary/10 border-primary/20">

View File

@@ -238,9 +238,8 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
ascending: sort.config.direction === 'asc' ascending: sort.config.direction === 'asc'
}); });
// Apply sorting: escalated first (desc), then user's chosen field // Apply sorting by user's chosen field only
submissionsQuery = submissionsQuery submissionsQuery = submissionsQuery
.order("escalated", { ascending: false })
.order(sortField, { ascending: sort.config.direction === 'asc' }); .order(sortField, { ascending: sort.config.direction === 'asc' });
// Apply tab-based status filtering // Apply tab-based status filtering
@@ -249,6 +248,20 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
const entityFilter = filters.debouncedEntityFilter; const entityFilter = filters.debouncedEntityFilter;
if (tab === "mainQueue") { if (tab === "mainQueue") {
// Main queue: non-escalated pending items
submissionsQuery = submissionsQuery.eq("escalated", false);
if (statusFilter === "all") {
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 if (tab === "escalated") {
// Escalated queue: only escalated items
submissionsQuery = submissionsQuery.eq("escalated", true);
if (statusFilter === "all") { if (statusFilter === "all") {
submissionsQuery = submissionsQuery.in("status", ["pending", "flagged", "partially_approved"]); submissionsQuery = submissionsQuery.in("status", ["pending", "flagged", "partially_approved"]);
} else if (statusFilter === "pending") { } else if (statusFilter === "pending") {
@@ -257,6 +270,7 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
submissionsQuery = submissionsQuery.eq("status", statusFilter); submissionsQuery = submissionsQuery.eq("status", statusFilter);
} }
} else { } else {
// Archive: completed items (non-escalated and escalated)
if (statusFilter === "all") { if (statusFilter === "all") {
submissionsQuery = submissionsQuery.in("status", ["approved", "rejected"]); submissionsQuery = submissionsQuery.in("status", ["approved", "rejected"]);
} else { } else {
@@ -286,6 +300,18 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
// Apply the exact same filters as the main query // Apply the exact same filters as the main query
if (tab === "mainQueue") { if (tab === "mainQueue") {
countQuery = countQuery.eq("escalated", false);
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 (tab === "escalated") {
countQuery = countQuery.eq("escalated", true);
if (statusFilter === "all") { if (statusFilter === "all") {
countQuery = countQuery.in("status", ["pending", "flagged", "partially_approved"]); countQuery = countQuery.in("status", ["pending", "flagged", "partially_approved"]);
} else if (statusFilter === "pending") { } else if (statusFilter === "pending") {

View File

@@ -97,7 +97,7 @@ export type StatusFilter = 'all' | 'pending' | 'partially_approved' | 'flagged'
/** /**
* Available tabs in the moderation interface * Available tabs in the moderation interface
*/ */
export type QueueTab = 'mainQueue' | 'archive'; export type QueueTab = 'mainQueue' | 'escalated' | 'archive';
/** /**
* Fields that can be used for sorting the moderation queue * Fields that can be used for sorting the moderation queue