'use client' import { Container, Grid, Card, CardContent, Typography, Box, TextField, Button, Paper, List, ListItem, ListItemText, Chip, InputAdornment, FormControl, InputLabel, Select, MenuItem, Accordion, AccordionSummary, AccordionDetails, useTheme, CircularProgress, Skeleton, } from '@mui/material' import { Search, FilterList, ExpandMore, MenuBook, Close, History, } from '@mui/icons-material' import { useState, useEffect } from 'react' import { useTranslations, useLocale } from 'next-intl' interface SearchResult { id: string book: string chapter: number verse: number text: string relevance: number } interface SearchFilter { testament: 'all' | 'old' | 'new' bookKeys: string[] exactMatch: boolean } interface BookOption { id: string name: string bookKey: string orderNum: number testament: string } export default function SearchPage() { const theme = useTheme() const t = useTranslations('pages.search') const locale = useLocale() const [searchQuery, setSearchQuery] = useState('') const [results, setResults] = useState([]) const [loading, setLoading] = useState(false) const [searchHistory, setSearchHistory] = useState([]) const [filters, setFilters] = useState({ testament: 'all', bookKeys: [], exactMatch: false }) const [booksData, setBooksData] = useState([]) const [versions, setVersions] = useState>([]) const [selectedVersion, setSelectedVersion] = useState('') const oldTestamentBooks = booksData.filter(b => b.orderNum <= 39) const newTestamentBooks = booksData.filter(b => b.orderNum > 39) const popularSearches: string[] = t.raw('popular.items') useEffect(() => { // Load search history from localStorage const saved = localStorage.getItem('searchHistory') if (saved) { setSearchHistory(JSON.parse(saved)) } }, []) useEffect(() => { // Fetch available versions for locale fetch(`/api/bible/versions?locale=${locale}`) .then(res => res.json()) .then(data => { const list = (data.versions || []) as Array<{ id: string; name: string; abbreviation: string; isDefault: boolean }> setVersions(list) const def = list.find(v => v.isDefault) || list[0] setSelectedVersion(def?.abbreviation || '') }) .catch(() => { setVersions([]) setSelectedVersion('') }) }, [locale]) useEffect(() => { if (!selectedVersion && versions.length === 0) return // Fetch available books for current locale/version const qs = new URLSearchParams({ locale, ...(selectedVersion ? { version: selectedVersion } : {}) }) fetch(`/api/bible/books?${qs}`) .then(res => res.json()) .then(data => { const mapped: BookOption[] = (data.books || []).map((b: any) => ({ id: b.id, name: b.name, bookKey: b.bookKey, orderNum: b.orderNum, testament: b.testament, })) setBooksData(mapped) }) .catch(() => setBooksData([])) }, [locale, selectedVersion, versions.length]) const handleSearch = async () => { if (!searchQuery.trim()) return setLoading(true) // Add to search history const newHistory = [searchQuery, ...searchHistory.filter(s => s !== searchQuery)].slice(0, 10) setSearchHistory(newHistory) localStorage.setItem('searchHistory', JSON.stringify(newHistory)) try { const params = new URLSearchParams({ q: searchQuery, testament: filters.testament, exactMatch: filters.exactMatch.toString(), bookKeys: filters.bookKeys.join(','), locale, ...(selectedVersion ? { version: selectedVersion } : {}), }) const response = await fetch(`/api/search/verses?${params}`) if (!response.ok) { throw new Error('Search failed') } const data = await response.json() setResults(data.results || []) } catch (error) { console.error('Error searching:', error) // Mock results for demo setResults([ { id: '1', book: 'Ioan', chapter: 3, verse: 16, text: 'Fiindcă atât de mult a iubit Dumnezeu lumea, că a dat pe singurul Său Fiu, pentru ca oricine crede în El să nu piară, ci să aibă viața veșnică.', relevance: 0.95, }, { id: '2', book: '1 Corinteni', chapter: 13, verse: 4, text: 'Dragostea este îndelung răbdătoare, dragostea este binevoitoare; dragostea nu pizmuiește...', relevance: 0.89, }, ]) } finally { setLoading(false) } } const handleKeyPress = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { handleSearch() } } const clearFilters = () => { setFilters({ testament: 'all', books: [], exactMatch: false, }) } const highlightSearchTerm = (text: string, query: string) => { if (!query) return text const regex = new RegExp(`(${query})`, 'gi') const parts = text.split(regex) return parts.map((part, index) => regex.test(part) ? ( {part} ) : ( part ) ) } return ( {/* Header */} {t('title')} {t('subtitle')} {/* Search Sidebar */} {/* Search Filters */} {t('filters.title')} {t('filters.testament')} {t('filters.version')} }> {t('filters.specificBooks')} {(filters.testament === 'old' || filters.testament === 'all' ? oldTestamentBooks : []) .concat(filters.testament === 'new' || filters.testament === 'all' ? newTestamentBooks : []) .map((book) => ( { const exists = filters.bookKeys.includes(book.bookKey) const newBookKeys = exists ? filters.bookKeys.filter(b => b !== book.bookKey) : [...filters.bookKeys, book.bookKey] setFilters({ ...filters, bookKeys: newBookKeys }) }} sx={{ mb: 0.5, mr: 0.5 }} /> ))} {/* Search History */} {searchHistory.length > 0 && ( {t('history.title')} {searchHistory.slice(0, 5).map((query, index) => ( setSearchQuery(query)} sx={{ mb: 0.5, mr: 0.5 }} /> ))} )} {/* Popular Searches */} {t('popular.title')} {popularSearches.map((query, index) => ( setSearchQuery(query)} sx={{ mb: 0.5, mr: 0.5 }} /> ))} {/* Main Search Area */} {/* Search Input */} setSearchQuery(e.target.value)} onKeyPress={handleKeyPress} InputProps={{ startAdornment: ( ), endAdornment: searchQuery && ( ), }} /> {filters.bookKeys.length > 0 && ( {t('searchIn', { books: filters.bookKeys.map(k => booksData.find(b => b.bookKey === k)?.name || k).join(', ') })} )} {/* Search Results */} {loading && searchQuery && ( {t('searching')} {Array.from({ length: 3 }).map((_, index) => ( } secondary={ } /> ))} )} {results.length > 0 && !loading && ( {t('results', { count: results.length })} {results.map((result) => ( {result.book} {result.chapter}:{result.verse} } secondary={ {highlightSearchTerm(result.text, searchQuery)} } /> ))} )} {!loading && searchQuery && results.length === 0 && ( {t('noResults.title')} {t('noResults.description')} )} {!searchQuery && !loading && ( {t('empty.title')} {t('empty.description')} )} ) }