diff --git a/src/components/moderation/RejectionDialog.tsx b/src/components/moderation/RejectionDialog.tsx new file mode 100644 index 00000000..953f1dfb --- /dev/null +++ b/src/components/moderation/RejectionDialog.tsx @@ -0,0 +1,160 @@ +import { useState } from 'react'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; +import { AlertCircle } from 'lucide-react'; + +export const REJECTION_REASONS = [ + { value: 'incomplete', label: 'Incomplete Information', template: 'The submission is missing required information or details.' }, + { value: 'inaccurate', label: 'Inaccurate Data', template: 'The information provided appears to be inaccurate or incorrect.' }, + { value: 'duplicate', label: 'Duplicate Entry', template: 'This entry already exists in the database.' }, + { value: 'inappropriate', label: 'Inappropriate Content', template: 'The submission contains inappropriate or irrelevant content.' }, + { value: 'poor_quality', label: 'Poor Quality', template: 'The submission does not meet quality standards (e.g., blurry photos, unclear descriptions).' }, + { value: 'spam', label: 'Spam', template: 'This appears to be spam or a test submission.' }, + { value: 'custom', label: 'Other (Custom Reason)', template: '' }, +]; + +interface RejectionDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + itemCount: number; + hasDependents: boolean; + onReject: (reason: string, cascade: boolean) => void; +} + +export function RejectionDialog({ + open, + onOpenChange, + itemCount, + hasDependents, + onReject, +}: RejectionDialogProps) { + const [selectedReason, setSelectedReason] = useState('incomplete'); + const [customReason, setCustomReason] = useState(''); + const [cascade, setCascade] = useState(true); + + const handleSubmit = () => { + const reasonTemplate = REJECTION_REASONS.find(r => r.value === selectedReason); + const finalReason = selectedReason === 'custom' + ? customReason + : reasonTemplate?.template || ''; + + if (!finalReason.trim()) { + return; + } + + onReject(finalReason, cascade); + onOpenChange(false); + + // Reset state + setSelectedReason('incomplete'); + setCustomReason(''); + setCascade(true); + }; + + const currentReason = selectedReason === 'custom' ? customReason : + REJECTION_REASONS.find(r => r.value === selectedReason)?.template || ''; + + return ( + + + + Reject Submission Items + + You are about to reject {itemCount} item{itemCount !== 1 ? 's' : ''}. + Please provide a reason for rejection. + + + +
+ {hasDependents && ( +
+ +
+

Dependency Warning

+

+ Some selected items have dependent items. You can choose to cascade the rejection to all dependents. +

+
+
+ )} + +
+ + + {REJECTION_REASONS.map((reason) => ( +
+ + +
+ ))} +
+
+ + {selectedReason === 'custom' && ( +
+ +