mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 12:11:12 -05:00
Fix: Correct ban migration logic
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Search, Ban, Shield, UserCheck, UserX, AlertTriangle, Trash2 } from 'lucide-react';
|
||||
import { Search, Shield, Trash2, Ban, AlertTriangle } from 'lucide-react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useUserRole, UserRole } from '@/hooks/useUserRole';
|
||||
import { useSuperuserGuard } from '@/hooks/useSuperuserGuard';
|
||||
import { AdminUserDeletionDialog } from '@/components/admin/AdminUserDeletionDialog';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { BanUserDialog } from '@/components/admin/BanUserDialog';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
||||
import { handleError, handleSuccess, getErrorMessage } from '@/lib/errorHandler';
|
||||
import { logger } from '@/lib/logger';
|
||||
@@ -83,15 +83,32 @@ export function ProfileManager() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleBanUser = async (targetUserId: string, ban: boolean) => {
|
||||
const handleBanUser = async (
|
||||
targetUserId: string,
|
||||
ban: boolean,
|
||||
banReason?: string,
|
||||
banExpiresAt?: Date | null
|
||||
) => {
|
||||
if (!user || !permissions) return;
|
||||
|
||||
setActionLoading(targetUserId);
|
||||
try {
|
||||
// Prepare update data
|
||||
const updateData: any = { banned: ban };
|
||||
|
||||
if (ban && banReason) {
|
||||
updateData.ban_reason = banReason;
|
||||
updateData.ban_expires_at = banExpiresAt;
|
||||
} else if (!ban) {
|
||||
// Clear ban data when unbanning
|
||||
updateData.ban_reason = null;
|
||||
updateData.ban_expires_at = null;
|
||||
}
|
||||
|
||||
// Update banned status
|
||||
const { error: updateError } = await supabase
|
||||
.from('profiles')
|
||||
.update({ banned: ban })
|
||||
.update(updateData)
|
||||
.eq('user_id', targetUserId);
|
||||
|
||||
if (updateError) throw updateError;
|
||||
@@ -102,7 +119,11 @@ export function ProfileManager() {
|
||||
_admin_user_id: user.id,
|
||||
_target_user_id: targetUserId,
|
||||
_action: ban ? 'ban_user' : 'unban_user',
|
||||
_details: { banned: ban }
|
||||
_details: {
|
||||
banned: ban,
|
||||
ban_reason: banReason,
|
||||
ban_expires_at: banExpiresAt?.toISOString()
|
||||
}
|
||||
});
|
||||
|
||||
if (logError) logger.error('Failed to log admin action', { error: getErrorMessage(logError) });
|
||||
@@ -120,7 +141,7 @@ export function ProfileManager() {
|
||||
handleError(error, {
|
||||
action: `${ban ? 'Ban' : 'Unban'} User`,
|
||||
userId: user?.id,
|
||||
metadata: { targetUserId, ban }
|
||||
metadata: { targetUserId, ban, banReason, banExpiresAt }
|
||||
});
|
||||
} finally {
|
||||
setActionLoading(null);
|
||||
@@ -363,47 +384,12 @@ export function ProfileManager() {
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Ban/Unban Button */}
|
||||
{canManageUser(profile) && permissions.can_ban_any_user && (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button
|
||||
variant={profile.banned ? "outline" : "destructive"}
|
||||
size="sm"
|
||||
disabled={actionLoading === profile.user_id}
|
||||
>
|
||||
{profile.banned ? (
|
||||
<>
|
||||
<UserCheck className="w-4 h-4 mr-2" />
|
||||
Unban
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<UserX className="w-4 h-4 mr-2" />
|
||||
Ban
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
{profile.banned ? 'Unban' : 'Ban'} User
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Are you sure you want to {profile.banned ? 'unban' : 'ban'} {profile.username}?
|
||||
{!profile.banned && ' This will prevent them from accessing the application.'}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => handleBanUser(profile.user_id, !profile.banned)}
|
||||
className={profile.banned ? "" : "bg-destructive hover:bg-destructive/90"}
|
||||
>
|
||||
{profile.banned ? 'Unban' : 'Ban'} User
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
<BanUserDialog
|
||||
profile={profile}
|
||||
onBanComplete={fetchProfiles}
|
||||
onBanUser={handleBanUser}
|
||||
disabled={actionLoading === profile.user_id}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Delete User Button - Superusers Only */}
|
||||
|
||||
Reference in New Issue
Block a user