Add version selector to /[locale]/search: new /api/bible/versions endpoint; fetch versions per locale; refetch books on version change; pass version to search API; localized label.
This commit is contained in:
@@ -69,6 +69,8 @@ export default function SearchPage() {
|
|||||||
const [searchHistory, setSearchHistory] = useState<string[]>([])
|
const [searchHistory, setSearchHistory] = useState<string[]>([])
|
||||||
const [filters, setFilters] = useState<SearchFilter>({ testament: 'all', bookKeys: [], exactMatch: false })
|
const [filters, setFilters] = useState<SearchFilter>({ testament: 'all', bookKeys: [], exactMatch: false })
|
||||||
const [booksData, setBooksData] = useState<BookOption[]>([])
|
const [booksData, setBooksData] = useState<BookOption[]>([])
|
||||||
|
const [versions, setVersions] = useState<Array<{ id: string; name: string; abbreviation: string; isDefault: boolean }>>([])
|
||||||
|
const [selectedVersion, setSelectedVersion] = useState<string>('')
|
||||||
|
|
||||||
const oldTestamentBooks = booksData.filter(b => b.orderNum <= 39)
|
const oldTestamentBooks = booksData.filter(b => b.orderNum <= 39)
|
||||||
const newTestamentBooks = booksData.filter(b => b.orderNum > 39)
|
const newTestamentBooks = booksData.filter(b => b.orderNum > 39)
|
||||||
@@ -84,8 +86,26 @@ export default function SearchPage() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
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
|
// Fetch available books for current locale/version
|
||||||
fetch(`/api/bible/books?locale=${locale}`)
|
const qs = new URLSearchParams({ locale, ...(selectedVersion ? { version: selectedVersion } : {}) })
|
||||||
|
fetch(`/api/bible/books?${qs}`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const mapped: BookOption[] = (data.books || []).map((b: any) => ({
|
const mapped: BookOption[] = (data.books || []).map((b: any) => ({
|
||||||
@@ -98,7 +118,7 @@ export default function SearchPage() {
|
|||||||
setBooksData(mapped)
|
setBooksData(mapped)
|
||||||
})
|
})
|
||||||
.catch(() => setBooksData([]))
|
.catch(() => setBooksData([]))
|
||||||
}, [locale])
|
}, [locale, selectedVersion, versions.length])
|
||||||
|
|
||||||
const handleSearch = async () => {
|
const handleSearch = async () => {
|
||||||
if (!searchQuery.trim()) return
|
if (!searchQuery.trim()) return
|
||||||
@@ -117,6 +137,7 @@ export default function SearchPage() {
|
|||||||
exactMatch: filters.exactMatch.toString(),
|
exactMatch: filters.exactMatch.toString(),
|
||||||
bookKeys: filters.bookKeys.join(','),
|
bookKeys: filters.bookKeys.join(','),
|
||||||
locale,
|
locale,
|
||||||
|
...(selectedVersion ? { version: selectedVersion } : {}),
|
||||||
})
|
})
|
||||||
|
|
||||||
const response = await fetch(`/api/search/verses?${params}`)
|
const response = await fetch(`/api/search/verses?${params}`)
|
||||||
@@ -231,6 +252,21 @@ export default function SearchPage() {
|
|||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl fullWidth sx={{ mb: 2 }}>
|
||||||
|
<InputLabel>{t('filters.version')}</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={selectedVersion}
|
||||||
|
label={t('filters.version')}
|
||||||
|
onChange={(e) => setSelectedVersion(e.target.value as string)}
|
||||||
|
>
|
||||||
|
{versions.map(v => (
|
||||||
|
<MenuItem key={v.abbreviation} value={v.abbreviation}>
|
||||||
|
{v.name} ({v.abbreviation})
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionSummary expandIcon={<ExpandMore />}>
|
<AccordionSummary expandIcon={<ExpandMore />}>
|
||||||
<Typography variant="body2">{t('filters.specificBooks')}</Typography>
|
<Typography variant="body2">{t('filters.specificBooks')}</Typography>
|
||||||
|
|||||||
33
app/api/bible/versions/route.ts
Normal file
33
app/api/bible/versions/route.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
|
import { prisma } from '@/lib/db'
|
||||||
|
|
||||||
|
export const runtime = 'nodejs'
|
||||||
|
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const { searchParams } = new URL(request.url)
|
||||||
|
const locale = (searchParams.get('locale') || 'ro').toLowerCase()
|
||||||
|
|
||||||
|
const langCandidates = Array.from(new Set([locale, locale.toLowerCase(), locale.toUpperCase()]))
|
||||||
|
|
||||||
|
const versions = await prisma.bibleVersion.findMany({
|
||||||
|
where: { language: { in: langCandidates } },
|
||||||
|
orderBy: [{ isDefault: 'desc' }, { name: 'asc' }]
|
||||||
|
})
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
versions: versions.map(v => ({
|
||||||
|
id: v.id,
|
||||||
|
name: v.name,
|
||||||
|
abbreviation: v.abbreviation,
|
||||||
|
language: v.language,
|
||||||
|
isDefault: v.isDefault,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching versions:', error)
|
||||||
|
return NextResponse.json({ success: false, versions: [] }, { status: 500 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -155,6 +155,7 @@
|
|||||||
"title": "Filters",
|
"title": "Filters",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"testament": "Testament",
|
"testament": "Testament",
|
||||||
|
"version": "Version",
|
||||||
"options": {
|
"options": {
|
||||||
"all": "Whole Bible",
|
"all": "Whole Bible",
|
||||||
"old": "Old Testament",
|
"old": "Old Testament",
|
||||||
|
|||||||
@@ -155,6 +155,7 @@
|
|||||||
"title": "Filtre",
|
"title": "Filtre",
|
||||||
"clear": "Șterge",
|
"clear": "Șterge",
|
||||||
"testament": "Testament",
|
"testament": "Testament",
|
||||||
|
"version": "Versiune",
|
||||||
"options": {
|
"options": {
|
||||||
"all": "Toată Biblia",
|
"all": "Toată Biblia",
|
||||||
"old": "Vechiul Testament",
|
"old": "Vechiul Testament",
|
||||||
|
|||||||
Reference in New Issue
Block a user