import React, { useCallback, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { IReduxState } from '../../../app/types'; import { searchTranscripts, selectMeeting } from '../../actions'; import { formatDate, formatTime, getMeetingIntelligenceState } from '../../functions'; /** * Search panel for searching across all meeting transcripts. * * @returns {React.ReactElement} The search panel component. */ const SearchPanel: React.FC = () => { const dispatch = useDispatch(); const { searchQuery, searchResults, searchLoading, searchError } = useSelector( (state: IReduxState) => getMeetingIntelligenceState(state) ); const [ inputValue, setInputValue ] = useState(searchQuery); const handleInputChange = useCallback((e: React.ChangeEvent) => { setInputValue(e.target.value); }, []); const handleSubmit = useCallback((e: React.FormEvent) => { e.preventDefault(); dispatch(searchTranscripts(inputValue) as any); }, [ dispatch, inputValue ]); const handleResultClick = useCallback((e: React.MouseEvent | React.KeyboardEvent) => { const meetingId = e.currentTarget.dataset.meetingId; if (meetingId) { dispatch(selectMeeting(meetingId) as any); } }, [ dispatch ]); return (
{searchError && (

Search failed: {searchError}

)} {searchResults.length > 0 && (
{searchResults.length} result{searchResults.length !== 1 ? 's' : ''} found
{searchResults.map((result, index) => (
{result.title || result.conference_id} {result.started_at && ( {formatDate(result.started_at)} )}
{result.speaker_label && ( {result.speaker_label}: )} {result.segment_text}
at {formatTime(result.start_time)} Relevance: {Math.round(result.score * 100)}%
))}
)} {searchQuery && searchResults.length === 0 && !searchLoading && !searchError && (

No results found

Try different keywords or check the spelling.

)} {!searchQuery && (

Search across all meetings

Find specific topics, decisions, or action items mentioned in any meeting.

)}
); }; export default SearchPanel;