mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:51:14 -05:00
feat: Add manual re-validation button
This commit is contained in:
@@ -20,6 +20,7 @@ interface ItemReviewCardProps {
|
||||
export function ItemReviewCard({ item, onEdit, onStatusChange, submissionId }: ItemReviewCardProps) {
|
||||
const isMobile = useIsMobile();
|
||||
const [validationResult, setValidationResult] = useState<ValidationResult | null>(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}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ export function SubmissionReviewManager({
|
||||
const [validationResults, setValidationResults] = useState<Map<string, ValidationResult>>(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') => {
|
||||
|
||||
@@ -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<ValidationResult | null>(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 (
|
||||
<div className="space-y-3">
|
||||
{/* Summary Badge */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
{validationResult.isValid && !hasWarnings && !hasSuggestions && (
|
||||
<Badge variant="secondary" className="bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300 border-green-300 dark:border-green-700">
|
||||
<CheckCircle className="w-4 h-4 mr-1" />
|
||||
@@ -183,6 +186,16 @@ export function ValidationSummary({ item, onValidationChange, compact = false }:
|
||||
{validationResult.suggestions.length} Suggestion{validationResult.suggestions.length !== 1 ? 's' : ''}
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setManualTriggerCount(prev => prev + 1)}
|
||||
className="text-xs h-7"
|
||||
>
|
||||
<RefreshCw className="w-3 h-3 mr-1" />
|
||||
Re-validate
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Detailed Issues */}
|
||||
|
||||
Reference in New Issue
Block a user