import React, { useState, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Mic, MicOff, Search, Loader2 } from 'lucide-react'; import { useSearch } from '../../context/SearchContext'; interface SearchBarProps { onSearch: (query: string) => void; placeholder?: string; } export const SearchBar: React.FC = ({ onSearch, placeholder = 'Search...' }) => { const { searchQuery, setSearchQuery, isListening, setIsListening } = useSearch(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const recognitionRef = useRef(null); const startListening = () => { try { if (!('webkitSpeechRecognition' in window)) { setError('Voice search is not supported in your browser'); return; } // Reset any previous error setError(null); recognitionRef.current = new (window as any).webkitSpeechRecognition(); recognitionRef.current.continuous = false; recognitionRef.current.interimResults = false; recognitionRef.current.lang = 'en-US'; // Add language support recognitionRef.current.onstart = () => { setIsListening(true); console.log('Voice recognition started'); }; recognitionRef.current.onend = () => { setIsListening(false); console.log('Voice recognition ended'); }; recognitionRef.current.onerror = (event: any) => { setError(`Error: ${event.error}`); setIsListening(false); console.error('Voice recognition error:', event); }; recognitionRef.current.onresult = (event: any) => { try { const transcript = event.results[0][0].transcript; console.log('Transcript:', transcript); setSearchQuery(transcript); handleSearch(transcript); } catch (err) { setError('Failed to process voice input'); console.error('Result processing error:', err); } }; recognitionRef.current.start(); } catch (err) { setError('Failed to start voice recognition'); console.error('Start recognition error:', err); } }; const stopListening = () => { if (recognitionRef.current) { recognitionRef.current.stop(); setIsListening(false); } }; const handleSearch = async (searchQuery: string) => { setIsLoading(true); await onSearch(searchQuery); setIsLoading(false); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setIsLoading(true); await onSearch(searchQuery); setIsLoading(false); }; return (
{isLoading ? ( ) : ( )}
setSearchQuery(e.target.value)} placeholder={placeholder} className="w-full h-12 pl-12 pr-12 bg-white/95 rounded-full shadow-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-opacity-50 transition-all duration-200" /> {isListening ? ( ) : ( )}
{isListening && (
Listening... Speak now
)} {error && (
{error}
)}
); };