import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'; import { UserX, Trash2 } from 'lucide-react'; import { supabase } from '@/lib/supabaseClient'; import { useAuth } from '@/hooks/useAuth'; import { handleError, handleSuccess } from '@/lib/errorHandler'; import { logger } from '@/lib/logger'; import type { UserBlock } from '@/types/privacy'; export function BlockedUsers() { const { user } = useAuth(); const [blockedUsers, setBlockedUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { if (user) { fetchBlockedUsers(); } }, [user]); const fetchBlockedUsers = async () => { if (!user) return; try { // First get the blocked user IDs const { data: blocks, error: blocksError } = await supabase .from('user_blocks') .select('id, blocked_id, reason, created_at') .eq('blocker_id', user.id) .order('created_at', { ascending: false }); if (blocksError) { throw blocksError; } if (!blocks || blocks.length === 0) { setBlockedUsers([]); return; } // Then get the profile information for blocked users const blockedIds = blocks.map(b => b.blocked_id); const { data: profiles, error: profilesError } = await supabase .from('profiles') .select('user_id, username, display_name, avatar_url') .in('user_id', blockedIds); if (profilesError) { throw profilesError; } // Combine the data const blockedUsersWithProfiles = blocks.map(block => ({ ...block, blocker_id: user.id, blocked_profile: profiles?.find(p => p.user_id === block.blocked_id), reason: block.reason || undefined })); setBlockedUsers(blockedUsersWithProfiles as UserBlock[]); } catch (error: unknown) { handleError(error, { action: 'Load blocked users', userId: user.id }); } finally { setLoading(false); } }; const handleUnblock = async (blockId: string, blockedUserId: string, username: string) => { if (!user) return; try { const { error } = await supabase .from('user_blocks') .delete() .eq('id', blockId); if (error) { throw error; } // Log to audit trail await supabase.from('profile_audit_log').insert([{ user_id: user.id, changed_by: user.id, action: 'user_unblocked', changes: JSON.parse(JSON.stringify({ blocked_user_id: blockedUserId, username, timestamp: new Date().toISOString() })) }]); setBlockedUsers(prev => prev.filter(block => block.id !== blockId)); handleSuccess('User unblocked', `You have unblocked @${username}`); } catch (error: unknown) { handleError(error, { action: 'Unblock user', userId: user.id, metadata: { targetUsername: username } }); } }; if (loading) { return (
{Array.from({ length: 2 }, (_, i) => (
))}
); } if (blockedUsers.length === 0) { return (

No blocked users

Blocked users will appear here and can be unblocked at any time.

); } return (
{blockedUsers.map((block) => (
{(block.blocked_profile?.display_name || block.blocked_profile?.username || 'U').charAt(0).toUpperCase()}
{block.blocked_profile?.display_name || block.blocked_profile?.username || 'Unknown User'}
{block.blocked_profile?.display_name && (
@{block.blocked_profile.username}
)} {block.reason && (
Reason: {block.reason}
)}
Blocked {new Date(block.created_at).toLocaleDateString()}
Unblock User Are you sure you want to unblock @{block.blocked_profile?.username}? They will be able to interact with your content again. Cancel handleUnblock( block.id, block.blocked_id, block.blocked_profile?.username || 'user' )} > Unblock
))}
); }