feat(ui): desktop page navigation + New Chat fix#315
Conversation
Desktop layout had no way to navigate to non-chat pages (Calendar, Inbox, Telos, Tasks, Files). Adds DesktopNav component in the left sidebar and wraps non-chat routes in DesktopShell via PageRoute. Also fixes the New Chat button which was broken because history.replaceState desynchronized React Router — handleNewChat now calls storeNewSession() directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dimakis
left a comment
There was a problem hiding this comment.
Centaur Review
Found 4 issue(s) (3 warning).
frontend/src/components/DesktopNav.tsx
Solid feature PR — the New Chat fix is correct (storeNewSession clears store state before navigation), and DesktopShell's optional props cleanly support the new PageRoute pattern. Main gap is missing tests for the new DesktopNav component and the center-only DesktopShell rendering path.
- 🟡 missing_tests: New component has no unit tests. It contains routing logic (match functions), badge rendering, and navigation — all worth covering. The project follows TDD, so tests should exist alongside the implementation.
[fixable] - 🔵 style (L16): The
itemsarray (with its closures) is re-allocated on every render. For 6 items this is negligible, but wrapping it inuseMemo(() => [...], [inboxCount, todoCount])would make dependencies explicit and avoid the allocation when onlylocationchanges.[fixable]
frontend/src/components/__tests__/DesktopShell.test.tsx
Solid feature PR — the New Chat fix is correct (storeNewSession clears store state before navigation), and DesktopShell's optional props cleanly support the new PageRoute pattern. Main gap is missing tests for the new DesktopNav component and the center-only DesktopShell rendering path.
- 🟡 missing_tests: No test covers the new center-only rendering path (right omitted). The PR made
rightoptional and wrapped it in a conditional ({right && ...}), but every existing test still passesright. A test rendering<DesktopShell center={...} />without left/right would verify the PageRoute usage path and confirm the right sidebar collapse button is correctly absent.[fixable]
frontend/src/components/DesktopShell.tsx
Solid feature PR — the New Chat fix is correct (storeNewSession clears store state before navigation), and DesktopShell's optional props cleanly support the new PageRoute pattern. Main gap is missing tests for the new DesktopNav component and the center-only DesktopShell rendering path.
- 🟡 bugs (L63): When
leftis undefined (the PageRoute case), the left sidebar still renders DesktopNav and the collapse toggle — which is the desired behavior. However, when the sidebar is collapsed and then expanded, the fragment renders<DesktopNav />followed by{undefined}. This is harmless in React (undefined children are ignored), but worth noting: there's no visual separator or empty-state handling between the nav and a missing session panel. If the left sidebar should be entirely hidden when noleftcontent exists, wrap the whole sidebar in a conditional too.
| const navigate = useNavigate(); | ||
| const { inboxCount, todoCount } = useTabBadges(); | ||
|
|
||
| const items: NavItem[] = [ |
There was a problem hiding this comment.
🔵 style: The items array (with its closures) is re-allocated on every render. For 6 items this is negligible, but wrapping it in useMemo(() => [...], [inboxCount, todoCount]) would make dependencies explicit and avoid the allocation when only location changes. [fixable]
| {leftCollapsed ? '\u25B6' : '\u25C0'} | ||
| </button> | ||
| {!leftCollapsed && left} | ||
| {!leftCollapsed && ( |
There was a problem hiding this comment.
🟡 bugs: When left is undefined (the PageRoute case), the left sidebar still renders DesktopNav and the collapse toggle — which is the desired behavior. However, when the sidebar is collapsed and then expanded, the fragment renders <DesktopNav /> followed by {undefined}. This is harmless in React (undefined children are ignored), but worth noting: there's no visual separator or empty-state handling between the nav and a missing session panel. If the left sidebar should be entirely hidden when no left content exists, wrap the whole sidebar in a conditional too.
Summary
DesktopNavcomponent to the left sidebar so desktop users can navigate to Calendar, Inbox, Telos, Tasks, and Files (previously only reachable by typing URLs)DesktopShellon desktop viaPageRoutewrapper — nav sidebar on the left, no right panelhistory.replaceStatedesynchronized React Router —handleNewChatnow callsstoreNewSession()directlyTest plan
🤖 Generated with Claude Code