// UserSearch Component // Multi-field search for finding users by email, username, or share code function UserSearch({ token, onUserSelect, t }) { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [debounceTimer, setDebounceTimer] = useState(null); const searchUsers = async (searchQuery) => { if (!searchQuery || searchQuery.length < 2) { setResults([]); return; } setLoading(true); try { const response = await fetch(API_URL + `/users/search?q=${encodeURIComponent(searchQuery)}`, { headers: { 'Authorization': `Bearer ${token}` } }); const data = await response.json(); setResults(data.users || []); } catch (err) { console.error('Search failed:', err); setResults([]); } finally { setLoading(false); } }; const handleInputChange = (e) => { const value = e.target.value; setQuery(value); // Debounce search if (debounceTimer) { clearTimeout(debounceTimer); } const timer = setTimeout(() => { searchUsers(value); }, 300); // 300ms delay setDebounceTimer(timer); }; const handleUserClick = (user) => { if (onUserSelect) { onUserSelect(user); } }; const handleAddFriend = async (user) => { try { const response = await fetch(API_URL + `/connections/add?connected_user_id=${user.id}`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { // Update the user's is_friend status in results setResults(prev => prev.map(u => u.id === user.id ? { ...u, is_friend: true } : u )); window.showToast?.(`✓ Added ${user.name} to your friends!`, 'success'); } else { window.showToast?.('Failed to add friend', 'error'); } } catch (err) { console.error('Add friend failed:', err); window.showToast?.('Failed to add friend', 'error'); } }; return (
{/* Search Input */}
🔍 {loading && }

Search by username, email, share code, or profile URL

{/* Results */} {query.length >= 2 && (
{loading && results.length === 0 ? (
Searching...
) : results.length > 0 ? (
{results.map(user => (
{ e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.1)'; }} onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = 'none'; }} >
{/* Avatar */}
{user.name?.charAt(0).toUpperCase() || '?'}
{/* User Info */}
{user.name}
{user.username ? `@${user.username}` : user.email} {user.share_code && ( • NV-{user.share_code} )}
{user.bio && (
{user.bio}
)}
{/* Action Button */} {user.is_friend ? ( ✓ Friend ) : ( )}
))}
) : query.length >= 2 && !loading ? (
🔍

No users found

Try: @username, email, NV-ABC123, or /profile/username

) : null}
)} {/* Empty State */} {query.length === 0 && (
👥

Find People to Collaborate

Start typing to search for users

💡 @username 📧 email@example.com 🔢 NV-ABC123 🔗 /profile/user
)}
); } window.UserSearch = UserSearch;