Files
thrilltrack-explorer/src/components/moderation/ConflictResolutionDialog.tsx
2025-09-30 13:41:19 +00:00

97 lines
3.4 KiB
TypeScript

import { useState } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Label } from '@/components/ui/label';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { AlertCircle } from 'lucide-react';
import { type DependencyConflict, type SubmissionItemWithDeps } from '@/lib/submissionItemsService';
interface ConflictResolutionDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
conflicts: DependencyConflict[];
items: SubmissionItemWithDeps[];
onResolve: () => void;
}
export function ConflictResolutionDialog({
open,
onOpenChange,
conflicts,
items,
onResolve,
}: ConflictResolutionDialogProps) {
const [resolutions, setResolutions] = useState<Record<string, string>>({});
const handleResolutionChange = (itemId: string, action: string) => {
setResolutions(prev => ({ ...prev, [itemId]: action }));
};
const allConflictsResolved = conflicts.every(
conflict => resolutions[conflict.itemId]
);
const handleApply = () => {
// TODO: Apply resolutions
onResolve();
onOpenChange(false);
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Resolve Dependency Conflicts</DialogTitle>
<DialogDescription>
{conflicts.length} conflict(s) found. Choose how to resolve each one.
</DialogDescription>
</DialogHeader>
<div className="space-y-6 py-4">
{conflicts.map((conflict) => {
const item = items.find(i => i.id === conflict.itemId);
return (
<div key={conflict.itemId} className="space-y-3">
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertDescription>
<p className="font-medium">
{item?.item_type.replace('_', ' ').toUpperCase()}: {item?.item_data.name}
</p>
<p className="text-sm mt-1">{conflict.message}</p>
</AlertDescription>
</Alert>
<RadioGroup
value={resolutions[conflict.itemId] || ''}
onValueChange={(value) => handleResolutionChange(conflict.itemId, value)}
>
{conflict.suggestions.map((suggestion, idx) => (
<div key={idx} className="flex items-center space-x-2">
<RadioGroupItem value={suggestion.action} id={`${conflict.itemId}-${idx}`} />
<Label htmlFor={`${conflict.itemId}-${idx}`} className="cursor-pointer">
{suggestion.label}
</Label>
</div>
))}
</RadioGroup>
</div>
);
})}
</div>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button onClick={handleApply} disabled={!allConflictsResolved}>
Apply & Approve
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}