diff --git a/src/components/moderation/ItemReviewCard.tsx b/src/components/moderation/ItemReviewCard.tsx index a1f5696c..eac7e76c 100644 --- a/src/components/moderation/ItemReviewCard.tsx +++ b/src/components/moderation/ItemReviewCard.tsx @@ -74,8 +74,10 @@ export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: I ); }; + const hasBlockingErrors = validationResult && validationResult.blockingErrors.length > 0; + return ( - +
@@ -89,6 +91,11 @@ export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: I Moderator Edited )} + {hasBlockingErrors && ( + + Blocked + + )}
diff --git a/src/components/moderation/SubmissionReviewManager.tsx b/src/components/moderation/SubmissionReviewManager.tsx index 43cc7800..87bb3b69 100644 --- a/src/components/moderation/SubmissionReviewManager.tsx +++ b/src/components/moderation/SubmissionReviewManager.tsx @@ -60,6 +60,7 @@ export function SubmissionReviewManager({ const [showWarningConfirmDialog, setShowWarningConfirmDialog] = useState(false); const [validationResults, setValidationResults] = useState>(new Map()); const [userConfirmedWarnings, setUserConfirmedWarnings] = useState(false); + const [hasBlockingErrors, setHasBlockingErrors] = useState(false); const { toast } = useToast(); const { isAdmin, isSuperuser } = useUserRole(); @@ -117,6 +118,9 @@ export function SubmissionReviewManager({ } else { next.add(itemId); } + // Clear blocking errors when selection changes + setHasBlockingErrors(false); + setValidationResults(new Map()); return next; }); }; @@ -176,6 +180,7 @@ export function SubmissionReviewManager({ }); if (itemsWithBlockingErrors.length > 0 && !userConfirmedWarnings) { + setHasBlockingErrors(true); setShowValidationBlockerDialog(true); setLoading(false); return; // Block approval @@ -475,6 +480,29 @@ export function SubmissionReviewManager({ onOpenChange={setShowEditDialog} onComplete={handleEditComplete} /> + + setShowValidationBlockerDialog(false)} + blockingErrors={Array.from(validationResults.values()).flatMap(r => r.blockingErrors)} + itemNames={items.filter(i => selectedItemIds.has(i.id)).map(i => + i.item_data?.name || i.item_type.replace('_', ' ') + )} + /> + + setShowWarningConfirmDialog(false)} + onProceed={() => { + setUserConfirmedWarnings(true); + setShowWarningConfirmDialog(false); + handleApprove(); + }} + warnings={Array.from(validationResults.values()).flatMap(r => r.warnings)} + itemNames={items.filter(i => selectedItemIds.has(i.id)).map(i => + i.item_data?.name || i.item_type.replace('_', ' ') + )} + /> ); @@ -532,11 +560,21 @@ export function SubmissionReviewManager({ + {/* Blocking error alert */} + {hasBlockingErrors && ( + + + + Cannot approve: Selected items have validation errors that must be fixed first. + + + )} + {/* Action buttons */}