SearchResults.tsx (1624B)
1 interface SearchResultMessage { 2 id: string; 3 content: string; 4 role: string; 5 } 6 7 interface SearchResultGroup { 8 session_id: string; 9 session_name: string | null; 10 messages: SearchResultMessage[]; 11 } 12 13 interface SearchResultsProps { 14 results: SearchResultGroup[]; 15 onSelectMessage: (sessionId: string, messageId: string) => void; 16 onClose: () => void; 17 } 18 19 export function SearchResults({ 20 results, 21 onSelectMessage, 22 onClose, 23 }: SearchResultsProps) { 24 if (results.length === 0) { 25 return ( 26 <div className="p-4 text-center text-sm text-gray-500"> 27 No results found 28 </div> 29 ); 30 } 31 32 return ( 33 <div className="max-h-96 overflow-y-auto"> 34 {results.map((group) => ( 35 <div key={group.session_id} className="border-b border-gray-800"> 36 <div className="px-4 py-2 text-xs font-medium text-gray-400"> 37 {group.session_name || "Unnamed session"} 38 </div> 39 {group.messages.map((msg) => ( 40 <button 41 key={msg.id} 42 type="button" 43 onClick={() => { 44 onSelectMessage(group.session_id, msg.id); 45 onClose(); 46 }} 47 className="block w-full px-4 py-2 text-left text-sm hover:bg-gray-800" 48 > 49 <span className="mr-2 text-xs text-gray-500">{msg.role}</span> 50 <span className="text-gray-300"> 51 {msg.content.length > 120 52 ? `${msg.content.slice(0, 120)}...` 53 : msg.content} 54 </span> 55 </button> 56 ))} 57 </div> 58 ))} 59 </div> 60 ); 61 }