feat(04-01): wire BrowserRouter + BottomTabBar + empty Lists surface
- App.tsx: BrowserRouter with /calendar, /lists, /lists/:listId routes; / redirects to /calendar - BottomTabBar.tsx: fixed-bottom 56px tab bar with Calendar + Lists NavLinks, active accent - AppNav.tsx: add Calendar/Lists NavLinks to desktop sidebar (≥768px) - ListsIndex.tsx: full-height surface with isLoading/isError/empty state branches; "+ New List" FAB placeholder - ListDetail.tsx: placeholder stub for /lists/:listId (Plan 04-04 fills in) - listsStore.ts: Zustand UI-only store (activeTab, createListSheetOpen) - listsClient.ts: fetchLists + List/ListItem types (initial; Plans 04-02/03 expand) - Fix Wave-0 RED stubs: add vitest imports so stubs execute (todo) not error on import - Fix CalendarShell.test.tsx: wrap renderWithClient in MemoryRouter (AppNav uses NavLink)
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
* - Grid is primary focal point; AppNav is secondary chrome
|
||||
*/
|
||||
|
||||
import { NavLink } from 'react-router'
|
||||
import { CalendarDays, List } from 'lucide-react'
|
||||
import { ColorLegend, type LegendMember } from './ColorLegend.js'
|
||||
|
||||
interface AppNavProps {
|
||||
@@ -102,8 +104,23 @@ function PhoneNav({
|
||||
)
|
||||
}
|
||||
|
||||
/** Tablet/Desktop: 240px left sidebar — app name + color legend */
|
||||
/** Tablet/Desktop: 240px left sidebar — app name + nav links + color legend */
|
||||
function DesktopNav({ members }: { members: LegendMember[] }) {
|
||||
const navLinkStyle = ({ isActive }: { isActive: boolean }): React.CSSProperties => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '10px',
|
||||
padding: 'var(--space-2) var(--space-3, 12px)',
|
||||
borderRadius: 'var(--space-1, 4px)',
|
||||
textDecoration: 'none',
|
||||
fontSize: 'var(--text-body-size, 15px)',
|
||||
fontWeight: isActive ? 600 : 400,
|
||||
color: isActive ? 'var(--color-member-0)' : 'var(--color-text-primary)',
|
||||
background: isActive ? 'color-mix(in srgb, var(--color-member-0) 10%, transparent)' : 'transparent',
|
||||
minHeight: '44px',
|
||||
transition: 'color 0.1s ease, background 0.1s ease',
|
||||
})
|
||||
|
||||
return (
|
||||
<nav
|
||||
style={{
|
||||
@@ -133,6 +150,25 @@ function DesktopNav({ members }: { members: LegendMember[] }) {
|
||||
FamilySync
|
||||
</div>
|
||||
|
||||
{/* Section nav links */}
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 'var(--space-1, 4px)',
|
||||
marginBottom: 'var(--space-6)',
|
||||
}}
|
||||
>
|
||||
<NavLink to="/calendar" style={navLinkStyle} aria-label="Calendar">
|
||||
<CalendarDays size={18} aria-hidden="true" />
|
||||
Calendar
|
||||
</NavLink>
|
||||
<NavLink to="/lists" style={navLinkStyle} aria-label="Lists">
|
||||
<List size={18} aria-hidden="true" />
|
||||
Lists
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
{/* Color legend */}
|
||||
<div
|
||||
style={{
|
||||
|
||||
Reference in New Issue
Block a user