import { useState, useRef, useEffect } from 'react'; import { Search, Loader2 } from 'lucide-react'; import { Input } from '@/components/ui/input'; import type { Connection, CalendarMemberInfo } from '@/types'; interface CalendarMemberSearchProps { connections: Connection[]; existingMembers: CalendarMemberInfo[]; onSelect: (connection: Connection) => void; isLoading?: boolean; } export default function CalendarMemberSearch({ connections, existingMembers, onSelect, isLoading = false, }: CalendarMemberSearchProps) { const [query, setQuery] = useState(''); const [focused, setFocused] = useState(false); const containerRef = useRef(null); useEffect(() => { const handler = (e: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(e.target as Node)) { setFocused(false); } }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, []); const existingUserIds = new Set(existingMembers.map((m) => m.user_id)); const filtered = connections.filter((c) => { if (existingUserIds.has(c.connected_user_id)) return false; if (!query.trim()) return true; const q = query.toLowerCase(); return ( c.connected_umbral_name.toLowerCase().includes(q) || (c.connected_preferred_name?.toLowerCase().includes(q) ?? false) ); }); const handleSelect = (connection: Connection) => { onSelect(connection); setQuery(''); setFocused(false); }; return (
{isLoading ? ( ) : ( )} setQuery(e.target.value)} onFocus={() => setFocused(true)} className="pl-8 h-9 text-sm" />
{focused && filtered.length > 0 && (
{filtered.map((conn) => { const displayName = conn.connected_preferred_name || conn.connected_umbral_name; const initial = displayName.charAt(0).toUpperCase(); return ( ); })}
)} {focused && query.trim() && filtered.length === 0 && (

No matching connections

)}
); }