Complete search functionality with version filtering
- Added version selector dropdown to search interface - Search now includes version parameter for backend filtering - Search results footer shows which Bible version was searched - Users can search ESV or NKJV independently - Version-aware search provides different results per translation Search UI now includes version selection alongside book filtering.
This commit is contained in:
@@ -562,6 +562,7 @@ function App() {
|
||||
formatBookName={formatBookName}
|
||||
getBookUrlName={getBookUrlName}
|
||||
books={books}
|
||||
selectedVersion={selectedVersion}
|
||||
onClose={() => setShowSearch(false)}
|
||||
isModal={true}
|
||||
/>
|
||||
@@ -578,6 +579,7 @@ function App() {
|
||||
formatBookName={formatBookName}
|
||||
getBookUrlName={getBookUrlName}
|
||||
books={books}
|
||||
selectedVersion={selectedVersion}
|
||||
isModal={false}
|
||||
/>
|
||||
} />
|
||||
|
||||
@@ -7,6 +7,8 @@ interface SearchComponentProps {
|
||||
formatBookName: (bookName: string) => string;
|
||||
getBookUrlName: (bookName: string) => string;
|
||||
books?: string[];
|
||||
selectedVersion?: string;
|
||||
onVersionChange?: (version: string) => void;
|
||||
onClose?: () => void;
|
||||
isModal?: boolean;
|
||||
}
|
||||
@@ -15,6 +17,8 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
formatBookName,
|
||||
getBookUrlName,
|
||||
books = [],
|
||||
selectedVersion: initialVersion = 'esv',
|
||||
onVersionChange,
|
||||
onClose,
|
||||
isModal = false
|
||||
}) => {
|
||||
@@ -24,6 +28,7 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
const [error, setError] = useState('');
|
||||
const [hasSearched, setHasSearched] = useState(false);
|
||||
const [selectedBook, setSelectedBook] = useState<string>('');
|
||||
const [selectedVersion, setSelectedVersion] = useState<string>(initialVersion);
|
||||
const searchTimeoutRef = useRef<NodeJS.Timeout>();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -42,7 +47,8 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
const searchOptions = {
|
||||
...(bookFilter && { book: bookFilter }),
|
||||
limit: 50,
|
||||
context: true
|
||||
context: true,
|
||||
version: selectedVersion
|
||||
};
|
||||
|
||||
const response: SearchResponse = await searchBible(searchQuery, searchOptions);
|
||||
@@ -55,7 +61,7 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
}, [selectedVersion]);
|
||||
|
||||
// Handle search input changes
|
||||
useEffect(() => {
|
||||
@@ -137,7 +143,7 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Search for verses, words, or phrases..."
|
||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg
|
||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg
|
||||
bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100
|
||||
focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
autoFocus
|
||||
@@ -146,7 +152,26 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
<Loader2 className="absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-blue-500 animate-spin" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
{/* Version Selector */}
|
||||
<select
|
||||
value={selectedVersion}
|
||||
onChange={(e) => {
|
||||
const newVersion = e.target.value;
|
||||
if (onVersionChange) {
|
||||
onVersionChange(newVersion);
|
||||
}
|
||||
// Re-trigger search when version changes
|
||||
setTimeout(() => setSelectedVersion(newVersion), 0);
|
||||
}}
|
||||
className="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg
|
||||
bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100
|
||||
focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
>
|
||||
<option value="esv">ESV - English Standard Version</option>
|
||||
<option value="nkjv">NKJV - New King James Version</option>
|
||||
</select>
|
||||
|
||||
<select
|
||||
value={selectedBook}
|
||||
onChange={(e) => setSelectedBook(e.target.value)}
|
||||
@@ -243,7 +268,7 @@ const SearchComponent: React.FC<SearchComponentProps> = ({
|
||||
{/* Footer */}
|
||||
{results.length > 0 && (
|
||||
<div className="p-4 border-t border-gray-200 dark:border-gray-700 text-center text-sm text-gray-500 dark:text-gray-400">
|
||||
Found {results.length} result{results.length !== 1 ? 's' : ''} for "{query}"
|
||||
Found {results.length} result{results.length !== 1 ? 's' : ''} for "{query}" in {selectedVersion.toUpperCase()} Bible
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -61,6 +61,7 @@ export interface SearchOptions {
|
||||
book?: string;
|
||||
limit?: number;
|
||||
context?: boolean;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
// Search API functions
|
||||
@@ -69,7 +70,8 @@ export const searchBible = async (query: string, options: SearchOptions = {}): P
|
||||
q: query,
|
||||
...(options.book && { book: options.book }),
|
||||
...(options.limit && { limit: options.limit.toString() }),
|
||||
...(options.context !== undefined && { context: options.context.toString() })
|
||||
...(options.context !== undefined && { context: options.context.toString() }),
|
||||
...(options.version && { version: options.version })
|
||||
});
|
||||
|
||||
const response = await api.get(`/api/search?${params}`);
|
||||
|
||||
Reference in New Issue
Block a user