fix: properly map book IDs from search to API UUIDs in Bible reader
Updates BibleReaderApp to handle the mismatch between numeric book IDs used by SearchNavigator (1-66) and UUID book IDs required by the API. Changes: - Add loadBooks() to fetch book metadata on mount - Map numeric orderNum to UUID book IDs for API calls - Implement proper hasNextChapter logic using actual chapter counts - Store books array and versionId in state - Update loadChapter to convert numeric bookId to UUID before API call This ensures the Bible reader works correctly with the existing database schema while maintaining a simple numeric interface for the SearchNavigator. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -8,31 +8,78 @@ import { ReadingView } from './reading-view'
|
|||||||
import { VersDetailsPanel } from './verse-details-panel'
|
import { VersDetailsPanel } from './verse-details-panel'
|
||||||
import { ReadingSettings } from './reading-settings'
|
import { ReadingSettings } from './reading-settings'
|
||||||
|
|
||||||
|
interface BookInfo {
|
||||||
|
id: string // UUID
|
||||||
|
orderNum: number
|
||||||
|
bookKey: string
|
||||||
|
name: string
|
||||||
|
chapterCount: number
|
||||||
|
}
|
||||||
|
|
||||||
export function BibleReaderApp() {
|
export function BibleReaderApp() {
|
||||||
const [bookId, setBookId] = useState(1) // Genesis
|
const [bookId, setBookId] = useState(1) // Genesis (numeric ID from search)
|
||||||
const [chapter, setChapter] = useState(1)
|
const [chapter, setChapter] = useState(1)
|
||||||
const [currentChapter, setCurrentChapter] = useState<BibleChapter | null>(null)
|
const [currentChapter, setCurrentChapter] = useState<BibleChapter | null>(null)
|
||||||
const [selectedVerse, setSelectedVerse] = useState<BibleVerse | null>(null)
|
const [selectedVerse, setSelectedVerse] = useState<BibleVerse | null>(null)
|
||||||
const [detailsPanelOpen, setDetailsPanelOpen] = useState(false)
|
const [detailsPanelOpen, setDetailsPanelOpen] = useState(false)
|
||||||
const [settingsOpen, setSettingsOpen] = useState(false)
|
const [settingsOpen, setSettingsOpen] = useState(false)
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(true)
|
||||||
const [bookmarks, setBookmarks] = useState<Set<string>>(new Set())
|
const [bookmarks, setBookmarks] = useState<Set<string>>(new Set())
|
||||||
|
const [books, setBooks] = useState<BookInfo[]>([])
|
||||||
|
const [versionId, setVersionId] = useState<string>('')
|
||||||
|
|
||||||
// Load chapter on navigation
|
// Load books on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadChapter(bookId, chapter)
|
loadBooks()
|
||||||
}, [bookId, chapter])
|
}, [])
|
||||||
|
|
||||||
async function loadChapter(bookId: number, chapterNum: number) {
|
// Load chapter when bookId or chapter changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (books.length > 0) {
|
||||||
|
loadChapter(bookId, chapter)
|
||||||
|
}
|
||||||
|
}, [bookId, chapter, books])
|
||||||
|
|
||||||
|
async function loadBooks() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/bible/books')
|
||||||
|
if (response.ok) {
|
||||||
|
const json = await response.json()
|
||||||
|
if (json.success && json.books) {
|
||||||
|
const bookMap: BookInfo[] = json.books.map((book: any) => ({
|
||||||
|
id: book.id,
|
||||||
|
orderNum: book.orderNum,
|
||||||
|
bookKey: book.bookKey,
|
||||||
|
name: book.name,
|
||||||
|
chapterCount: book.chapters.length
|
||||||
|
}))
|
||||||
|
setBooks(bookMap)
|
||||||
|
setVersionId(json.version.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading books:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadChapter(numericBookId: number, chapterNum: number) {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
|
// Find the book by orderNum
|
||||||
|
const book = books.find(b => b.orderNum === numericBookId)
|
||||||
|
if (!book) {
|
||||||
|
console.error('Book not found for orderNum:', numericBookId)
|
||||||
|
setCurrentChapter(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Try cache first
|
// Try cache first
|
||||||
const chapterId = `${bookId}-${chapterNum}`
|
const chapterId = `${book.id}-${chapterNum}`
|
||||||
let data = await getCachedChapter(chapterId)
|
let data = await getCachedChapter(chapterId)
|
||||||
|
|
||||||
// If not cached, fetch from API
|
// If not cached, fetch from API
|
||||||
if (!data) {
|
if (!data) {
|
||||||
const response = await fetch(`/api/bible/chapter?book=${bookId}&chapter=${chapterNum}`)
|
const response = await fetch(`/api/bible/chapter?book=${book.id}&chapter=${chapterNum}`)
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
data = json.chapter
|
data = json.chapter
|
||||||
@@ -40,6 +87,8 @@ export function BibleReaderApp() {
|
|||||||
// Cache it
|
// Cache it
|
||||||
if (data) {
|
if (data) {
|
||||||
data.id = chapterId
|
data.id = chapterId
|
||||||
|
data.bookId = numericBookId // Keep numeric ID for consistency
|
||||||
|
data.chapter = chapterNum
|
||||||
await cacheChapter(data)
|
await cacheChapter(data)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -112,11 +161,19 @@ export function BibleReaderApp() {
|
|||||||
chapter={currentChapter}
|
chapter={currentChapter}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onPrevChapter={() => chapter > 1 && setChapter(chapter - 1)}
|
onPrevChapter={() => chapter > 1 && setChapter(chapter - 1)}
|
||||||
onNextChapter={() => setChapter(chapter + 1)}
|
onNextChapter={() => {
|
||||||
|
const book = books.find(b => b.orderNum === bookId)
|
||||||
|
if (book && chapter < book.chapterCount) {
|
||||||
|
setChapter(chapter + 1)
|
||||||
|
}
|
||||||
|
}}
|
||||||
onVerseClick={handleVerseClick}
|
onVerseClick={handleVerseClick}
|
||||||
onSettingsOpen={() => setSettingsOpen(true)}
|
onSettingsOpen={() => setSettingsOpen(true)}
|
||||||
hasPrevChapter={chapter > 1}
|
hasPrevChapter={chapter > 1}
|
||||||
hasNextChapter={true} // TODO: Check actual chapter count based on book
|
hasNextChapter={(() => {
|
||||||
|
const book = books.find(b => b.orderNum === bookId)
|
||||||
|
return book ? chapter < book.chapterCount : false
|
||||||
|
})()}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Box sx={{ p: 4, textAlign: 'center' }}>
|
<Box sx={{ p: 4, textAlign: 'center' }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user