From 113a8a2c945bd99c09ecca6347f4ae374fbadd4c Mon Sep 17 00:00:00 2001 From: fcote Date: Sat, 5 Sep 2026 01:02:51 +0200 Subject: [PATCH] feat: introduce the control room dashboard The dashboard gave sync health, recent additions and configuration equal weight, making routine checks harder to scan. Navigation also disappeared on small screens. Introduce a responsive sidebar and a dashboard with prominent sync status, three summary counts, recent films and a preview of four watch lists. Keep the existing palette and live progress, distinguish missing data from empty results, and move configuration details into an expandable summary. Adjust shared controls and Settings fields to fit desktop and mobile screens. --- frontend/src/components/Layout.tsx | 99 +++-- frontend/src/components/SyncStatusBanner.tsx | 9 +- frontend/src/index.css | 22 +- frontend/src/pages/ConfigPage.tsx | 30 +- frontend/src/pages/DashboardPage.tsx | 438 ++++++++----------- frontend/src/pages/MoviesPage.tsx | 2 +- frontend/src/pages/UpcomingPage.tsx | 2 +- frontend/src/pages/WatchItemsPage.tsx | 6 +- 8 files changed, 269 insertions(+), 339 deletions(-) diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index e02d950..abe4795 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -5,7 +5,7 @@ import { CalendarIcon, CogIcon, FilmIcon, - PlayIcon, + Squares2X2Icon, ArrowRightOnRectangleIcon } from '@heroicons/react/24/outline'; @@ -14,7 +14,7 @@ interface LayoutProps { } const Layout: React.FC = ({ children }) => { - const { logout } = useAuth(); + const { user, logout } = useAuth(); const location = useLocation(); const navigate = useNavigate(); @@ -24,62 +24,65 @@ const Layout: React.FC = ({ children }) => { }; const navigation = [ - { name: 'Dashboard', href: '/', icon: PlayIcon }, - { name: 'Watch Items', href: '/watch-items', icon: FilmIcon }, + { name: 'Overview', href: '/', icon: Squares2X2Icon }, + { name: 'Watch lists', href: '/watch-items', icon: FilmIcon }, { name: 'Upcoming', href: '/upcoming', icon: CalendarIcon }, - { name: 'Configuration', href: '/config', icon: CogIcon }, + { name: 'Settings', href: '/config', icon: CogIcon }, ]; return ( -
- + +
+

Your personal film collection

+

{user?.username}

+
- + -
+
{children}
); }; -export default Layout; \ No newline at end of file +export default Layout; diff --git a/frontend/src/components/SyncStatusBanner.tsx b/frontend/src/components/SyncStatusBanner.tsx index 69dbdc6..87f33d4 100644 --- a/frontend/src/components/SyncStatusBanner.tsx +++ b/frontend/src/components/SyncStatusBanner.tsx @@ -5,6 +5,7 @@ import { ProgressTrack } from './CategoryProgress'; interface SyncStatusBannerProps { progress: SyncProgress; + embedded?: boolean; } // A round is four phases long and the slow ones are a page a second, so a sync @@ -15,7 +16,7 @@ interface SyncStatusBannerProps { // It is only rendered while a round runs, so there is no idle state to design: // it appears when one starts, whether or not this browser was what started it, // and goes when it ends. -const SyncStatusBanner: React.FC = ({ progress }) => { +const SyncStatusBanner: React.FC = ({ progress, embedded = false }) => { const { label, item, done, total, step, steps, added } = progress; // A phase with nothing due — release dates already current, say — is still a @@ -23,8 +24,8 @@ const SyncStatusBanner: React.FC = ({ progress }) => { const share = total > 0 ? done / total : 1; return ( -
-
+
+
{/* Self-evident from the moving bar below, so kept out of the reading */}