From f032016f434adba2f0c533b9ee1371167abe47cb Mon Sep 17 00:00:00 2001 From: Ryderjj89 Date: Sun, 28 Sep 2025 15:15:31 -0400 Subject: [PATCH] Complete URL restructuring to use path-based version routing Major changes: - New URL structure: /version/esv/book/Genesis/chapter/1 instead of /book/Genesis/chapter/1?version=esv - Version extracted from URL path instead of query parameters - Component pages restructured: VersionPage, BookListPage, BookPage, ChapterPage - Navigation updated throughout to use new path structure - Routes updated to match new hierarchical structure - Breadcrumb navigation fixed for new paths - Version selector dropdown now navigates between versions This eliminates query parameter state management issues and provides clean, RESTful URLs --- frontend/src/App.tsx | 99 +++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 57 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f7c3902c..dcf2d531 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -34,17 +34,16 @@ function App() { // Debug logging console.log('App component rendered'); - // Read version from URL on mount and when location changes + // Extract version from URL path on mount and when location changes useEffect(() => { - const urlParams = new URLSearchParams(location.search); - const versionParam = urlParams.get('version'); - if (versionParam && (versionParam === 'esv' || versionParam === 'nkjv')) { - setSelectedVersion(versionParam); - } else if (location.pathname === '/' && !urlParams.get('version')) { - // If we're at home without version param, clear selection + const pathParts = location.pathname.split('/').filter(Boolean); + if (pathParts[0] === 'version' && (pathParts[1] === 'esv' || pathParts[1] === 'nkjv')) { + setSelectedVersion(pathParts[1]); + } else if (location.pathname === '/') { + // At root path, no version is selected setSelectedVersion(''); } - }, [location.search]); + }, [location.pathname]); useEffect(() => { console.log('App useEffect triggered'); @@ -56,14 +55,6 @@ function App() { // Load versions when version changes useEffect(() => { loadBooks(); - // Update URL with version when it changes - const url = new URL(window.location.href); - if (selectedVersion) { // Add version parameter when selected - url.searchParams.set('version', selectedVersion); - } else { - url.searchParams.delete('version'); - } - window.history.replaceState({}, '', url.toString()); // Update page title to reflect selected version const versionTitle = selectedVersion ? selectedVersion.toUpperCase() : ''; @@ -251,33 +242,40 @@ function App() { // Get current navigation info from URL const getCurrentNavInfo = () => { const pathParts = location.pathname.split('/').filter(Boolean); - - if (pathParts.length === 0) { + + if (pathParts.length < 3 || pathParts[0] !== 'version' || pathParts[2] !== 'book') { return { currentBook: null, currentChapter: null }; } - - if (pathParts[0] === 'book' && pathParts[1]) { - const currentBook = pathParts[1]; - const currentChapter = pathParts[2] === 'chapter' && pathParts[3] ? pathParts[3] : null; - return { currentBook, currentChapter }; - } - - return { currentBook: null, currentChapter: null }; + + const currentBook = pathParts[3]; // book name from /version/:versionId/book/:bookName + const currentChapter = pathParts[4] === 'chapter' && pathParts[5] ? pathParts[5] : null; + return { currentBook, currentChapter }; }; const { currentBook, currentChapter } = getCurrentNavInfo(); - // Component for the home page - const HomePage = () => { + // Component for the version selection page (root) + const VersionPage = () => { const handleVersionSelect = (version: 'esv' | 'nkjv') => { - setSelectedVersion(version); - setVersionSelected(true); + navigate(`/version/${version}`); }; + return ( + + ); + }; + + // Component for book list page (version-specific) + const BookListPage = () => { + const { versionId } = useParams<{ versionId: string }>(); + const handleBookSelect = (book: string) => { const urlName = getBookUrlName(book); - const url = selectedVersion ? `/book/${urlName}?version=${selectedVersion}` : `/book/${urlName}`; - navigate(url); + navigate(`/version/${versionId}/book/${urlName}`); + }; + + const handleBack = () => { + navigate('/'); }; const handleFavoriteChange = () => { @@ -285,14 +283,6 @@ function App() { setUser((prev: any) => ({ ...prev })); }; - // Show version selector if no version is selected - if (!selectedVersion) { - return ( - - ); - } - - // Show book selector once version is selected return ( { - const { bookName } = useParams<{ bookName: string }>(); + const { versionId, bookName } = useParams<{ versionId: string, bookName: string }>(); const actualBookName = bookName ? getBookFromUrl(bookName) : ''; const handleChapterSelect = (chapter: string) => { - navigate(`/book/${bookName}/chapter/${chapter}`); + navigate(`/version/${versionId}/book/${bookName}/chapter/${chapter}`); }; const handleBack = () => { - navigate('/'); + navigate(`/version/${versionId}`); }; const handleFavoriteChange = () => { @@ -340,11 +330,11 @@ function App() { // Component for chapter reading page const ChapterPage = () => { - const { bookName, chapterNumber } = useParams<{ bookName: string, chapterNumber: string }>(); + const { versionId, bookName, chapterNumber } = useParams<{ versionId: string, bookName: string, chapterNumber: string }>(); const actualBookName = bookName ? getBookFromUrl(bookName) : ''; const handleBack = () => { - navigate(`/book/${bookName}`); + navigate(`/version/${versionId}/book/${bookName}`); }; const handleFavoriteChange = () => { @@ -412,7 +402,7 @@ function App() { {selectedVersion ? (