From 415aa45f4c44299cda70cfb5ff5a946a84ed5bc4 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 14:48:37 +0000 Subject: [PATCH] feat: Implement direct edit button for queue items --- src/components/moderation/ModerationQueue.tsx | 48 +++++++++++++++++++ src/components/moderation/QueueItem.tsx | 6 ++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/components/moderation/ModerationQueue.tsx b/src/components/moderation/ModerationQueue.tsx index 2802a8a9..9201ddd2 100644 --- a/src/components/moderation/ModerationQueue.tsx +++ b/src/components/moderation/ModerationQueue.tsx @@ -6,6 +6,7 @@ import { useUserRole } from '@/hooks/useUserRole'; import { useAuth } from '@/hooks/useAuth'; import { PhotoModal } from './PhotoModal'; import { SubmissionReviewManager } from './SubmissionReviewManager'; +import { ItemEditDialog } from './ItemEditDialog'; import { useIsMobile } from '@/hooks/use-mobile'; import { useAdminSettings } from '@/hooks/useAdminSettings'; import { useModerationQueueManager } from '@/hooks/moderation'; @@ -20,6 +21,7 @@ import { AutoRefreshIndicator } from './AutoRefreshIndicator'; import { NewItemsAlert } from './NewItemsAlert'; import { EmptyQueueState } from './EmptyQueueState'; import { QueuePagination } from './QueuePagination'; +import { fetchSubmissionItems, type SubmissionItemWithDeps } from '@/lib/submissionItemsService'; import type { ModerationQueueRef } from '@/types/moderation'; import type { PhotoItem } from '@/types/photos'; @@ -62,6 +64,8 @@ export const ModerationQueue = forwardRef((props, ref) => { const [selectedPhotoIndex, setSelectedPhotoIndex] = useState(0); const [reviewManagerOpen, setReviewManagerOpen] = useState(false); const [selectedSubmissionId, setSelectedSubmissionId] = useState(null); + const [showItemEditDialog, setShowItemEditDialog] = useState(false); + const [editingItem, setEditingItem] = useState(null); // UI-specific handlers const handleNoteChange = (id: string, value: string) => { @@ -79,6 +83,36 @@ export const ModerationQueue = forwardRef((props, ref) => { setReviewManagerOpen(true); }; + const handleOpenItemEditor = async (submissionId: string) => { + try { + const items = await fetchSubmissionItems(submissionId); + + // Find first pending item, fallback to first available + let itemToEdit = items.find(item => item.status === 'pending'); + if (!itemToEdit && items.length > 0) { + itemToEdit = items[0]; + } + + if (itemToEdit) { + setEditingItem(itemToEdit); + setShowItemEditDialog(true); + } else { + toast({ + title: 'No Items Found', + description: 'This submission has no items to edit', + variant: 'destructive', + }); + } + } catch (error) { + console.error('Error fetching items for edit:', error); + toast({ + title: 'Error', + description: 'Failed to load submission items', + variant: 'destructive', + }); + } + }; + // Expose imperative API useImperativeHandle(ref, () => ({ refresh: async () => { @@ -179,6 +213,7 @@ export const ModerationQueue = forwardRef((props, ref) => { onRetryFailed={queueManager.retryFailedItems} onOpenPhotos={handleOpenPhotos} onOpenReviewManager={handleOpenReviewManager} + onOpenItemEditor={handleOpenItemEditor} onClaimSubmission={queueManager.queue.claimSubmission} onDeleteSubmission={queueManager.deleteSubmission} onInteractionFocus={(id) => queueManager.markInteracting(id, true)} @@ -218,6 +253,19 @@ export const ModerationQueue = forwardRef((props, ref) => { onComplete={() => setReviewManagerOpen(false)} /> )} + + {editingItem && ( + { + setShowItemEditDialog(false); + setEditingItem(null); + await queueManager.refresh(); + }} + /> + )} ); }); diff --git a/src/components/moderation/QueueItem.tsx b/src/components/moderation/QueueItem.tsx index c4cc998a..ab9b9e64 100644 --- a/src/components/moderation/QueueItem.tsx +++ b/src/components/moderation/QueueItem.tsx @@ -39,6 +39,7 @@ interface QueueItemProps { onRetryFailed: (item: ModerationItem) => void; onOpenPhotos: (photos: any[], index: number) => void; onOpenReviewManager: (submissionId: string) => void; + onOpenItemEditor: (submissionId: string) => void; onClaimSubmission: (submissionId: string) => void; onDeleteSubmission: (item: ModerationItem) => void; onInteractionFocus: (id: string) => void; @@ -75,6 +76,7 @@ export const QueueItem = memo(({ onRetryFailed, onOpenPhotos, onOpenReviewManager, + onOpenItemEditor, onClaimSubmission, onDeleteSubmission, onInteractionFocus, @@ -430,7 +432,7 @@ export const QueueItem = memo(({ -

Edit submission items directly as a moderator

+

Quick edit first pending item

)}