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

179 lines
5.1 KiB
TypeScript

import { useState, useEffect } from 'react';
import { UserCog } from 'lucide-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 {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { supabase } from '@/lib/supabaseClient';
import { handleError, getErrorMessage } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
interface Moderator {
user_id: string;
username: string;
display_name?: string | null;
role: string;
}
interface ReassignDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onReassign: (moderatorId: string) => Promise<void>;
submissionType: string;
}
export function ReassignDialog({
open,
onOpenChange,
onReassign,
submissionType,
}: ReassignDialogProps) {
const [selectedModerator, setSelectedModerator] = useState<string>('');
const [moderators, setModerators] = useState<Moderator[]>([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (open) {
fetchModerators();
}
}, [open]);
const fetchModerators = async () => {
setLoading(true);
try {
const { data: roles, error: rolesError } = await supabase
.from('user_roles')
.select('user_id, role')
.in('role', ['moderator', 'admin', 'superuser']);
if (rolesError) throw rolesError;
if (!roles || roles.length === 0) {
setModerators([]);
return;
}
const userIds = roles.map((r) => r.user_id);
let profiles: Array<{ user_id: string; username: string; display_name?: string | null }> | null = null;
const { data: allProfiles, error: rpcError } = await supabase
.rpc('get_users_with_emails');
if (rpcError) {
// Fall back to basic profiles
const { data: basicProfiles } = await supabase
.from('profiles')
.select('user_id, username, display_name')
.in('user_id', userIds);
profiles = basicProfiles as typeof profiles;
} else {
profiles = allProfiles?.filter(p => userIds.includes(p.user_id)) || null;
}
const moderatorsList = roles.map((role) => {
const profile = profiles?.find((p) => p.user_id === role.user_id);
return {
user_id: role.user_id,
username: profile?.username || 'Unknown',
display_name: profile?.display_name,
role: role.role,
};
});
setModerators(moderatorsList);
} catch (error: unknown) {
handleError(error, {
action: 'Load Moderators List',
metadata: { submissionType }
});
} finally {
setLoading(false);
}
};
const handleReassign = async () => {
if (!selectedModerator) return;
setIsSubmitting(true);
try {
await onReassign(selectedModerator);
setSelectedModerator('');
onOpenChange(false);
} finally {
setIsSubmitting(false);
}
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<UserCog className="h-5 w-5" />
Reassign Submission
</DialogTitle>
<DialogDescription>
Assign this {submissionType} to another moderator. They will receive a lock for 15 minutes.
</DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label htmlFor="moderator">Select Moderator</Label>
{loading ? (
<div className="text-sm text-muted-foreground">Loading moderators...</div>
) : moderators.length === 0 ? (
<div className="text-sm text-muted-foreground">No moderators available</div>
) : (
<Select value={selectedModerator} onValueChange={setSelectedModerator}>
<SelectTrigger id="moderator">
<SelectValue placeholder="Choose a moderator" />
</SelectTrigger>
<SelectContent>
{moderators.map((mod) => (
<SelectItem key={mod.user_id} value={mod.user_id}>
{mod.display_name || mod.username} ({mod.role})
</SelectItem>
))}
</SelectContent>
</Select>
)}
</div>
</div>
<DialogFooter>
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isSubmitting}
>
Cancel
</Button>
<Button
onClick={handleReassign}
disabled={!selectedModerator || isSubmitting}
>
{isSubmitting ? 'Reassigning...' : 'Reassign'}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}