diff --git a/src/components/moderation/ItemReviewCard.tsx b/src/components/moderation/ItemReviewCard.tsx index eac7e76c..30e7620c 100644 --- a/src/components/moderation/ItemReviewCard.tsx +++ b/src/components/moderation/ItemReviewCard.tsx @@ -20,6 +20,7 @@ interface ItemReviewCardProps { export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: ItemReviewCardProps) { const isMobile = useIsMobile(); const [validationResult, setValidationResult] = useState(null); + const [validationKey, setValidationKey] = useState(0); const handleValidationChange = useCallback((result: ValidationResult) => { setValidationResult(result); @@ -131,6 +132,7 @@ export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: I }} onValidationChange={handleValidationChange} compact={false} + validationKey={validationKey} /> diff --git a/src/components/moderation/SubmissionReviewManager.tsx b/src/components/moderation/SubmissionReviewManager.tsx index 5c1ec05c..a1d83ed9 100644 --- a/src/components/moderation/SubmissionReviewManager.tsx +++ b/src/components/moderation/SubmissionReviewManager.tsx @@ -62,6 +62,7 @@ export function SubmissionReviewManager({ const [validationResults, setValidationResults] = useState>(new Map()); const [userConfirmedWarnings, setUserConfirmedWarnings] = useState(false); const [hasBlockingErrors, setHasBlockingErrors] = useState(false); + const [globalValidationKey, setGlobalValidationKey] = useState(0); const { toast } = useToast(); const { isAdmin, isSuperuser } = useUserRole(); @@ -374,6 +375,7 @@ export function SubmissionReviewManager({ setShowEditDialog(false); setEditingItem(null); await loadSubmissionItems(); + setGlobalValidationKey(prev => prev + 1); }; const handleItemStatusChange = async (itemId: string, status: 'approved' | 'rejected') => { diff --git a/src/components/moderation/ValidationSummary.tsx b/src/components/moderation/ValidationSummary.tsx index b4e1c476..ac3ab0c0 100644 --- a/src/components/moderation/ValidationSummary.tsx +++ b/src/components/moderation/ValidationSummary.tsx @@ -1,6 +1,7 @@ import { useEffect, useState, useMemo } from 'react'; -import { AlertCircle, CheckCircle, Info, AlertTriangle } from 'lucide-react'; +import { AlertCircle, CheckCircle, Info, AlertTriangle, RefreshCw } from 'lucide-react'; import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; import { validateEntityData, ValidationResult } from '@/lib/entityValidationSchemas'; @@ -13,12 +14,14 @@ interface ValidationSummaryProps { }; onValidationChange?: (result: ValidationResult) => void; compact?: boolean; + validationKey?: number; } -export function ValidationSummary({ item, onValidationChange, compact = false }: ValidationSummaryProps) { +export function ValidationSummary({ item, onValidationChange, compact = false, validationKey }: ValidationSummaryProps) { const [validationResult, setValidationResult] = useState(null); const [isLoading, setIsLoading] = useState(true); const [isExpanded, setIsExpanded] = useState(false); + const [manualTriggerCount, setManualTriggerCount] = useState(0); // Create stable reference for item_data to prevent unnecessary re-validations const itemDataString = useMemo( @@ -68,7 +71,7 @@ export function ValidationSummary({ item, onValidationChange, compact = false }: } validate(); - }, [item.item_type, itemDataString, item.id]); + }, [item.item_type, itemDataString, item.id, validationKey, manualTriggerCount]); // Auto-expand when there are blocking errors or warnings useEffect(() => { @@ -158,7 +161,7 @@ export function ValidationSummary({ item, onValidationChange, compact = false }: return (
{/* Summary Badge */} -
+
{validationResult.isValid && !hasWarnings && !hasSuggestions && ( @@ -183,6 +186,16 @@ export function ValidationSummary({ item, onValidationChange, compact = false }: {validationResult.suggestions.length} Suggestion{validationResult.suggestions.length !== 1 ? 's' : ''} )} + +
{/* Detailed Issues */}