From b4009132d158ea389f07a5d9876164e3da15c878 Mon Sep 17 00:00:00 2001 From: Cody Kickertz Date: Sun, 21 Dec 2025 19:51:31 -0600 Subject: [PATCH] feat(ui): add Books and Audiobooks navigation sections (#121) Add navigation sidebar entries for Books and Audiobooks with: - New BOOK and AUDIOBOOK icons in props - Books/Audiobooks sections in PageSidebar with Add New/Import children - Routes for /books and /audiobooks paths - Placeholder index pages for both media types - Translation strings for Books/Audiobooks Part of Phase 3 UI work for Issue #7. Co-authored-by: admin --- frontend/src/App/AppRoutes.tsx | 14 ++++++++ .../src/Audiobook/Index/AudiobookIndex.tsx | 20 ++++++++++++ frontend/src/Book/Index/BookIndex.tsx | 20 ++++++++++++ .../Components/Page/Sidebar/PageSidebar.tsx | 32 +++++++++++++++++++ frontend/src/Helpers/Props/icons.ts | 4 +++ src/NzbDrone.Core/Localization/Core/en.json | 2 ++ 6 files changed, 92 insertions(+) create mode 100644 frontend/src/Audiobook/Index/AudiobookIndex.tsx create mode 100644 frontend/src/Book/Index/BookIndex.tsx diff --git a/frontend/src/App/AppRoutes.tsx b/frontend/src/App/AppRoutes.tsx index 2b8e105d69..4b42bacf37 100644 --- a/frontend/src/App/AppRoutes.tsx +++ b/frontend/src/App/AppRoutes.tsx @@ -5,6 +5,8 @@ import History from 'Activity/History/History'; import Queue from 'Activity/Queue/Queue'; import AddNewMovieConnector from 'AddMovie/AddNewMovie/AddNewMovieConnector'; import ImportMovies from 'AddMovie/ImportMovie/ImportMovies'; +import AudiobookIndex from 'Audiobook/Index/AudiobookIndex'; +import BookIndex from 'Book/Index/BookIndex'; import CalendarPage from 'Calendar/CalendarPage'; import CollectionConnector from 'Collection/CollectionConnector'; import NotFound from 'Components/NotFound'; @@ -69,6 +71,18 @@ function AppRoutes() { + {/* + Books + */} + + + + {/* + Audiobooks + */} + + + {/* Calendar */} diff --git a/frontend/src/Audiobook/Index/AudiobookIndex.tsx b/frontend/src/Audiobook/Index/AudiobookIndex.tsx new file mode 100644 index 0000000000..178fbbb9b4 --- /dev/null +++ b/frontend/src/Audiobook/Index/AudiobookIndex.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import PageContent from 'Components/Page/PageContent'; +import PageContentBody from 'Components/Page/PageContentBody'; +import translate from 'Utilities/String/translate'; + +function AudiobookIndex() { + return ( + + +
+

{translate('Audiobooks')}

+

Audiobook management coming soon.

+

This feature is part of Phase 3 development.

+
+
+
+ ); +} + +export default AudiobookIndex; diff --git a/frontend/src/Book/Index/BookIndex.tsx b/frontend/src/Book/Index/BookIndex.tsx new file mode 100644 index 0000000000..3ca742dc1d --- /dev/null +++ b/frontend/src/Book/Index/BookIndex.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import PageContent from 'Components/Page/PageContent'; +import PageContentBody from 'Components/Page/PageContentBody'; +import translate from 'Utilities/String/translate'; + +function BookIndex() { + return ( + + +
+

{translate('Books')}

+

Book management coming soon.

+

This feature is part of Phase 3 development.

+
+
+
+ ); +} + +export default BookIndex; diff --git a/frontend/src/Components/Page/Sidebar/PageSidebar.tsx b/frontend/src/Components/Page/Sidebar/PageSidebar.tsx index df62adad0e..bf31710513 100644 --- a/frontend/src/Components/Page/Sidebar/PageSidebar.tsx +++ b/frontend/src/Components/Page/Sidebar/PageSidebar.tsx @@ -69,6 +69,38 @@ const LINKS: SidebarItem[] = [ ], }, + { + iconName: icons.BOOK, + title: () => translate('Books'), + to: '/books', + children: [ + { + title: () => translate('AddNew'), + to: '/books/add/new', + }, + { + title: () => translate('ImportLibrary'), + to: '/books/add/import', + }, + ], + }, + + { + iconName: icons.AUDIOBOOK, + title: () => translate('Audiobooks'), + to: '/audiobooks', + children: [ + { + title: () => translate('AddNew'), + to: '/audiobooks/add/new', + }, + { + title: () => translate('ImportLibrary'), + to: '/audiobooks/add/import', + }, + ], + }, + { iconName: icons.CALENDAR, title: () => translate('Calendar'), diff --git a/frontend/src/Helpers/Props/icons.ts b/frontend/src/Helpers/Props/icons.ts index 35c6217ebc..166baa71de 100644 --- a/frontend/src/Helpers/Props/icons.ts +++ b/frontend/src/Helpers/Props/icons.ts @@ -32,6 +32,7 @@ import { faBan as fasBan, faBars as fasBars, faBolt as fasBolt, + faBook as fasBook, faBookmark as fasBookmark, faBookReader as fasBookReader, faBroadcastTower as fasBroadcastTower, @@ -73,6 +74,7 @@ import { faFolderOpen as fasFolderOpen, faFolderTree as farFolderTree, faForward as fasForward, + faHeadphones as fasHeadphones, faHeart as fasHeart, faHistory as fasHistory, faHome as fasHome, @@ -129,6 +131,7 @@ export const ACTIVITY = farClock; export const ADD = fasPlus; export const ALTERNATE_TITLES = farClone; export const ADVANCED_SETTINGS = fasCog; +export const AUDIOBOOK = fasHeadphones; export const ANNOUNCED = fasBullhorn; export const ARROW_LEFT = fasArrowCircleLeft; export const ARROW_RIGHT = fasArrowCircleRight; @@ -252,3 +255,4 @@ export const VIEW = fasEye; export const WARNING = fasExclamationTriangle; export const WIKI = fasBookReader; export const BLOCKLIST = fasBan; +export const BOOK = fasBook; diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 512948d073..8d32c3a33f 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -98,6 +98,7 @@ "AudioInfo": "Audio Info", "AudioLanguages": "Audio Languages", "Audiobook": "Audiobook", + "Audiobooks": "Audiobooks", "AuthBasic": "Basic (Browser Popup)", "AuthForm": "Forms (Login Page)", "Authentication": "Authentication", @@ -165,6 +166,7 @@ "Blocklisted": "Blocklisted", "BlocklistedAt": "Blocklisted at {date}", "Book": "Book", + "Books": "Books", "Branch": "Branch", "BranchUpdate": "Branch to use to update {appName}", "BranchUpdateMechanism": "Branch used by external update mechanism",