mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 21:31:12 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
136
src-old/components/moderation/ConflictResolutionDialog.tsx
Normal file
136
src-old/components/moderation/ConflictResolutionDialog.tsx
Normal file
@@ -0,0 +1,136 @@
|
||||
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';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { handleError, handleSuccess } from '@/lib/errorHandler';
|
||||
|
||||
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 [isApplying, setIsApplying] = useState(false);
|
||||
const { user } = useAuth();
|
||||
|
||||
const handleResolutionChange = (itemId: string, action: string) => {
|
||||
setResolutions(prev => ({ ...prev, [itemId]: action }));
|
||||
};
|
||||
|
||||
const allConflictsResolved = conflicts.every(
|
||||
conflict => resolutions[conflict.itemId]
|
||||
);
|
||||
|
||||
const handleApply = async () => {
|
||||
if (!user?.id) {
|
||||
handleError(new Error('Authentication required'), {
|
||||
action: 'Resolve Conflicts',
|
||||
metadata: { conflictCount: conflicts.length }
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setIsApplying(true);
|
||||
const { resolveConflicts } = await import('@/lib/conflictResolutionService');
|
||||
|
||||
try {
|
||||
const result = await resolveConflicts(conflicts, resolutions, items, user.id);
|
||||
|
||||
if (!result.success) {
|
||||
handleError(new Error(result.error || 'Failed to resolve conflicts'), {
|
||||
action: 'Resolve Conflicts',
|
||||
userId: user.id,
|
||||
metadata: { conflictCount: conflicts.length }
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
handleSuccess('Conflicts Resolved', 'All conflicts have been resolved successfully');
|
||||
onResolve();
|
||||
onOpenChange(false);
|
||||
} catch (error: unknown) {
|
||||
handleError(error, {
|
||||
action: 'Resolve Conflicts',
|
||||
userId: user.id,
|
||||
metadata: { conflictCount: conflicts.length }
|
||||
});
|
||||
} finally {
|
||||
setIsApplying(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 && typeof item.item_data === 'object' && item.item_data !== null && !Array.isArray(item.item_data) && 'name' in item.item_data
|
||||
? String((item.item_data as Record<string, unknown>).name)
|
||||
: 'Unnamed'
|
||||
}
|
||||
</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)} disabled={isApplying}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleApply} loading={isApplying} loadingText="Applying..." disabled={!allConflictsResolved}>
|
||||
Apply & Approve
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user