diff --git a/src/components/CreateConversationModal.tsx b/src/components/CreateConversationModal.tsx index 4d91a607..708059ad 100644 --- a/src/components/CreateConversationModal.tsx +++ b/src/components/CreateConversationModal.tsx @@ -1,10 +1,10 @@ import { useState, useEffect } from 'react'; import { useCreateConversation } from '../hooks/useMessaging'; -import { supabase } from '../supabase-client'; +import { supabase, isBackendAvailable } from '../supabase-client'; import { useAuth } from '../hooks/useAuth'; import { X, Search, Users, MessageCircle, Check } from 'lucide-react'; import type { Conversation } from '../types/messaging'; -import { showSuccess,showError } from '../utils/toast'; +import { showSuccess, showError } from '../utils/toast'; interface CreateConversationModalProps { @@ -39,15 +39,34 @@ const CreateConversationModal = ({ onClose, onConversationCreated }: CreateConve // Fetch users for selection useEffect(() => { const fetchUsers = async () => { + if (!isBackendAvailable || !supabase) { + console.warn('Backend unavailable - cannot fetch users'); + setUsers([]); + return; + } + try { - const { data, error } = await supabase.auth.admin.listUsers(); + // ✅ SECURE: Query profiles table with RLS instead of admin API + const { data, error } = await supabase + .from('profiles') + .select('id, full_name, avatar_url'); + if (error) throw error; - - // Filter out current user - const filteredUsers = data.users.filter(u => u.id !== currentUser?.id); - setUsers(filteredUsers as User[]); + + // Map profiles to User format + const mappedUsers = (data || []).map(profile => ({ + id: profile.id, + email: '', // Email not exposed for privacy + user_metadata: { + full_name: profile.full_name, + avatar_url: profile.avatar_url, + }, + })); + + setUsers(mappedUsers as User[]); } catch (error) { console.error('Failed to fetch users:', error); + showError('Failed to load users'); } }; @@ -60,10 +79,10 @@ const CreateConversationModal = ({ onClose, onConversationCreated }: CreateConve const fullName = user.user_metadata?.full_name?.toLowerCase() || ''; const userName = user.user_metadata?.user_name?.toLowerCase() || ''; const email = user.email.toLowerCase(); - - return fullName.includes(searchLower) || - userName.includes(searchLower) || - email.includes(searchLower); + + return fullName.includes(searchLower) || + userName.includes(searchLower) || + email.includes(searchLower); }); const handleUserSelect = (user: User) => { @@ -83,14 +102,14 @@ const CreateConversationModal = ({ onClose, onConversationCreated }: CreateConve const handleCreate = async () => { if (selectedUsers.length === 0) return; - + if (conversationType === 'group' && !groupName.trim()) { showError('Please enter a group name'); return; } setIsLoading(true); - + try { const conversationData = { type: conversationType, @@ -101,12 +120,12 @@ const CreateConversationModal = ({ onClose, onConversationCreated }: CreateConve }; const conversation = await createConversation.mutateAsync(conversationData); - + showSuccess( - conversationType === 'group' + conversationType === 'group' ? "Group conversation created" - : "Conversation started" - ); + : "Conversation started" + ); onConversationCreated(conversation); @@ -119,9 +138,10 @@ const CreateConversationModal = ({ onClose, onConversationCreated }: CreateConve }; const getUserDisplayName = (user: User) => { - return user.user_metadata?.full_name || - user.user_metadata?.user_name || - user.email; + return user.user_metadata?.full_name || + user.user_metadata?.user_name || + user.email || + user.id; }; return ( @@ -196,7 +216,7 @@ const CreateConversationModal = ({ onClose, onConversationCreated }: CreateConve className="w-full px-3 py-2 bg-slate-800/50 border border-slate-700 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:border-cyan-400/50 focus:ring-1 focus:ring-cyan-400/50" /> - +
- +
{filteredUsers.map(user => { const isSelected = selectedUsers.some(u => u.id === user.id); - + return (
)} - +

{getUserDisplayName(user)}

{user.email}

- + {isSelected && ( )}
); })} - + {filteredUsers.length === 0 && (
No users found