import { useState } from 'react'; import { Ban, UserCheck } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Textarea } from '@/components/ui/textarea'; import { Alert, AlertDescription } from '@/components/ui/alert'; const BAN_REASONS = [ { value: 'spam', label: 'Spam or advertising' }, { value: 'harassment', label: 'Harassment or bullying' }, { value: 'inappropriate_content', label: 'Inappropriate content' }, { value: 'violation_tos', label: 'Terms of Service violation' }, { value: 'abuse', label: 'Abuse of platform features' }, { value: 'fake_info', label: 'Posting false information' }, { value: 'copyright', label: 'Copyright infringement' }, { value: 'multiple_accounts', label: 'Multiple account abuse' }, { value: 'other', label: 'Other (specify below)' } ] as const; const BAN_DURATIONS = [ { value: '1', label: '1 Day', days: 1 }, { value: '7', label: '7 Days (1 Week)', days: 7 }, { value: '30', label: '30 Days (1 Month)', days: 30 }, { value: '90', label: '90 Days (3 Months)', days: 90 }, { value: 'permanent', label: 'Permanent', days: null } ] as const; const banFormSchema = z.object({ reason_type: z.enum([ 'spam', 'harassment', 'inappropriate_content', 'violation_tos', 'abuse', 'fake_info', 'copyright', 'multiple_accounts', 'other' ]), custom_reason: z.string().max(500).optional(), duration: z.enum(['1', '7', '30', '90', 'permanent']) }).refine( (data) => data.reason_type !== 'other' || (data.custom_reason && data.custom_reason.trim().length > 0), { message: "Please provide a custom reason", path: ["custom_reason"] } ); type BanFormValues = z.infer; interface BanUserDialogProps { profile: { user_id: string; username: string; banned: boolean; }; onBanComplete: () => void; onBanUser: (userId: string, ban: boolean, reason?: string, expiresAt?: Date | null) => Promise; disabled?: boolean; } export function BanUserDialog({ profile, onBanComplete, onBanUser, disabled }: BanUserDialogProps) { const [open, setOpen] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const form = useForm({ resolver: zodResolver(banFormSchema), defaultValues: { reason_type: 'violation_tos', custom_reason: '', duration: '7' } }); const watchReasonType = form.watch('reason_type'); const watchDuration = form.watch('duration'); const onSubmit = async (values: BanFormValues) => { setIsSubmitting(true); try { // Construct the ban reason let banReason: string; if (values.reason_type === 'other' && values.custom_reason) { banReason = values.custom_reason.trim(); } else { const selectedReason = BAN_REASONS.find(r => r.value === values.reason_type); banReason = selectedReason?.label || 'Policy violation'; } // Calculate expiration date let expiresAt: Date | null = null; if (values.duration !== 'permanent') { const durationConfig = BAN_DURATIONS.find(d => d.value === values.duration); if (durationConfig?.days) { expiresAt = new Date(); expiresAt.setDate(expiresAt.getDate() + durationConfig.days); } } await onBanUser(profile.user_id, true, banReason, expiresAt); setOpen(false); form.reset(); onBanComplete(); } catch (error) { // Error handling is done by the parent component } finally { setIsSubmitting(false); } }; const handleUnban = async () => { setIsSubmitting(true); try { await onBanUser(profile.user_id, false); setOpen(false); onBanComplete(); } catch (error) { // Error handling is done by the parent component } finally { setIsSubmitting(false); } }; // For unbanning, use simpler dialog if (profile.banned) { return ( Unban User Are you sure you want to unban @{profile.username}? They will be able to access the application again. ); } // For banning, use detailed form return ( Ban User Ban @{profile.username} from accessing the application. You must provide a reason and duration.
( Ban Reason Choose the primary reason for this ban )} /> {watchReasonType === 'other' && ( ( Custom Reason