From 1dc4d761b57989ef631e4b9ec0d8a23b82ca37b8 Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 11 Nov 2025 20:17:13 +0000 Subject: [PATCH] fix: properly map book IDs from search to API UUIDs in Bible reader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- components/bible/bible-reader-app.tsx | 77 +++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/components/bible/bible-reader-app.tsx b/components/bible/bible-reader-app.tsx index 59b6430..875e8c5 100644 --- a/components/bible/bible-reader-app.tsx +++ b/components/bible/bible-reader-app.tsx @@ -8,31 +8,78 @@ import { ReadingView } from './reading-view' import { VersDetailsPanel } from './verse-details-panel' import { ReadingSettings } from './reading-settings' +interface BookInfo { + id: string // UUID + orderNum: number + bookKey: string + name: string + chapterCount: number +} + 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 [currentChapter, setCurrentChapter] = useState(null) const [selectedVerse, setSelectedVerse] = useState(null) const [detailsPanelOpen, setDetailsPanelOpen] = useState(false) const [settingsOpen, setSettingsOpen] = useState(false) - const [loading, setLoading] = useState(false) + const [loading, setLoading] = useState(true) const [bookmarks, setBookmarks] = useState>(new Set()) + const [books, setBooks] = useState([]) + const [versionId, setVersionId] = useState('') - // Load chapter on navigation + // Load books on mount useEffect(() => { - loadChapter(bookId, chapter) - }, [bookId, chapter]) + loadBooks() + }, []) - 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) 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 - const chapterId = `${bookId}-${chapterNum}` + const chapterId = `${book.id}-${chapterNum}` let data = await getCachedChapter(chapterId) // If not cached, fetch from API 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) { const json = await response.json() data = json.chapter @@ -40,6 +87,8 @@ export function BibleReaderApp() { // Cache it if (data) { data.id = chapterId + data.bookId = numericBookId // Keep numeric ID for consistency + data.chapter = chapterNum await cacheChapter(data) } } else { @@ -112,11 +161,19 @@ export function BibleReaderApp() { chapter={currentChapter} loading={loading} 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} onSettingsOpen={() => setSettingsOpen(true)} 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 + })()} /> ) : (