Files
thrilltrack-explorer/src-old/components/moderation/ValidationBlockerDialog.tsx

98 lines
3.5 KiB
TypeScript

import { useState } from 'react';
import { AlertCircle, ChevronDown } from 'lucide-react';
import {
AlertDialog,
AlertDialogAction,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { ValidationError } from '@/lib/entityValidationSchemas';
interface ValidationBlockerDialogProps {
open: boolean;
onClose: () => void;
blockingErrors: ValidationError[];
itemNames: string[];
}
export function ValidationBlockerDialog({
open,
onClose,
blockingErrors,
itemNames,
}: ValidationBlockerDialogProps) {
const [showDetails, setShowDetails] = useState(false);
return (
<AlertDialog open={open} onOpenChange={onClose}>
<AlertDialogContent className="max-w-2xl">
<AlertDialogHeader>
<AlertDialogTitle className="flex items-center gap-2 text-destructive">
<AlertCircle className="w-5 h-5" />
Cannot Approve: Validation Errors
</AlertDialogTitle>
<AlertDialogDescription>
The following items have blocking validation errors that MUST be fixed before approval.
Edit the items to fix the errors, or reject them.
</AlertDialogDescription>
</AlertDialogHeader>
<div className="space-y-3 my-4">
{itemNames.map((name, index) => {
const itemErrors = blockingErrors.filter((_, i) =>
itemNames.length === 1 || i === index
);
return (
<div key={index} className="space-y-2">
<div className="font-medium text-sm flex items-center justify-between">
<span>{name}</span>
<Badge variant="destructive">
{itemErrors.length} error{itemErrors.length > 1 ? 's' : ''}
</Badge>
</div>
<Alert variant="destructive">
<AlertDescription className="space-y-1">
{itemErrors.map((error, errIndex) => (
<div key={errIndex} className="text-sm">
<span className="font-medium">{error.field}:</span> {error.message}
</div>
))}
</AlertDescription>
</Alert>
</div>
);
})}
</div>
<Collapsible open={showDetails} onOpenChange={setShowDetails}>
<CollapsibleTrigger asChild>
<Button variant="ghost" size="sm" className="w-full">
{showDetails ? 'Hide' : 'Show'} Technical Details
<ChevronDown className={`ml-2 h-4 w-4 transition-transform ${showDetails ? 'rotate-180' : ''}`} />
</Button>
</CollapsibleTrigger>
<CollapsibleContent className="mt-2">
<div className="bg-muted p-3 rounded text-xs font-mono max-h-60 overflow-auto">
<pre>{JSON.stringify(blockingErrors, null, 2)}</pre>
</div>
</CollapsibleContent>
</Collapsible>
<AlertDialogFooter>
<AlertDialogAction onClick={onClose}>
Close
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}