feat: make navigation menu auth-aware
Navigation links now change based on authentication state: - Logged out: Home, Runs, Genlockes, Stats - Logged in: New Run, My Runs, Genlockes, Stats - Admin: adds Admin link Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
# nuzlocke-tracker-h205
|
# nuzlocke-tracker-h205
|
||||||
title: Auth-aware navigation menu
|
title: Auth-aware navigation menu
|
||||||
status: todo
|
status: completed
|
||||||
type: task
|
type: task
|
||||||
priority: normal
|
priority: normal
|
||||||
created_at: 2026-03-21T10:06:20Z
|
created_at: 2026-03-21T10:06:20Z
|
||||||
updated_at: 2026-03-21T10:06:24Z
|
updated_at: 2026-03-21T10:22:08Z
|
||||||
parent: nuzlocke-tracker-ce4o
|
parent: nuzlocke-tracker-ce4o
|
||||||
blocked_by:
|
blocked_by:
|
||||||
- nuzlocke-tracker-5svj
|
- nuzlocke-tracker-5svj
|
||||||
@@ -15,13 +15,24 @@ Update the Layout component to show different nav links based on auth state and
|
|||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
- [ ] Replace static \`navLinks\` array with dynamic links based on \`useAuth()\` state
|
- [x] Replace static \`navLinks\` array with dynamic links based on \`useAuth()\` state
|
||||||
- [ ] **Logged out**: Home, Runs, Genlockes, Stats (no New Run, no Admin)
|
- [x] **Logged out**: Home, Runs, Genlockes, Stats (no New Run, no Admin)
|
||||||
- [ ] **Logged in (non-admin)**: New Run, My Runs, Genlockes, Stats
|
- [x] **Logged in (non-admin)**: New Run, My Runs, Genlockes, Stats
|
||||||
- [ ] **Logged in (admin)**: New Run, My Runs, Genlockes, Stats, Admin
|
- [x] **Logged in (admin)**: New Run, My Runs, Genlockes, Stats, Admin
|
||||||
- [ ] Update both desktop and mobile nav (they share the same \`navLinks\` array, so this should be automatic)
|
- [x] Update both desktop and mobile nav (they share the same \`navLinks\` array, so this should be automatic)
|
||||||
- [ ] Verify menu updates reactively on login/logout
|
- [x] Verify menu updates reactively on login/logout
|
||||||
|
|
||||||
## Files to change
|
## Files to change
|
||||||
|
|
||||||
- \`frontend/src/components/Layout.tsx\` — make \`navLinks\` dynamic based on auth state
|
- \`frontend/src/components/Layout.tsx\` — make \`navLinks\` dynamic based on auth state
|
||||||
|
|
||||||
|
## Summary of Changes
|
||||||
|
|
||||||
|
- Removed static `navLinks` array from module scope
|
||||||
|
- Added dynamic `navLinks` computation inside `Layout` component using `useMemo`
|
||||||
|
- Navigation now depends on `user` and `isAdmin` from `useAuth()`:
|
||||||
|
- Logged out: Home, Runs, Genlockes, Stats
|
||||||
|
- Logged in (non-admin): New Run, My Runs, Genlockes, Stats
|
||||||
|
- Logged in (admin): New Run, My Runs, Genlockes, Stats, Admin
|
||||||
|
- Updated `isActive` function to handle Home route (`/`) correctly
|
||||||
|
- Both desktop and mobile nav automatically use the same dynamic `navLinks` array
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
import { useState } from 'react'
|
import { useState, useMemo } from 'react'
|
||||||
import { Link, Outlet, useLocation } from 'react-router-dom'
|
import { Link, Outlet, useLocation } from 'react-router-dom'
|
||||||
import { useTheme } from '../hooks/useTheme'
|
import { useTheme } from '../hooks/useTheme'
|
||||||
import { useAuth } from '../contexts/AuthContext'
|
import { useAuth } from '../contexts/AuthContext'
|
||||||
|
|
||||||
const navLinks = [
|
|
||||||
{ to: '/runs/new', label: 'New Run' },
|
|
||||||
{ to: '/runs', label: 'My Runs' },
|
|
||||||
{ to: '/genlockes', label: 'Genlockes' },
|
|
||||||
{ to: '/stats', label: 'Stats' },
|
|
||||||
{ to: '/admin', label: 'Admin' },
|
|
||||||
]
|
|
||||||
|
|
||||||
function NavLink({
|
function NavLink({
|
||||||
to,
|
to,
|
||||||
active,
|
active,
|
||||||
@@ -136,9 +128,34 @@ function UserMenu({ onAction }: { onAction?: () => void }) {
|
|||||||
export function Layout() {
|
export function Layout() {
|
||||||
const [menuOpen, setMenuOpen] = useState(false)
|
const [menuOpen, setMenuOpen] = useState(false)
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const { user, isAdmin } = useAuth()
|
||||||
|
|
||||||
|
const navLinks = useMemo(() => {
|
||||||
|
if (!user) {
|
||||||
|
// Logged out: Home, Runs, Genlockes, Stats
|
||||||
|
return [
|
||||||
|
{ to: '/', label: 'Home' },
|
||||||
|
{ to: '/runs', label: 'Runs' },
|
||||||
|
{ to: '/genlockes', label: 'Genlockes' },
|
||||||
|
{ to: '/stats', label: 'Stats' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
// Logged in: New Run, My Runs, Genlockes, Stats
|
||||||
|
const links = [
|
||||||
|
{ to: '/runs/new', label: 'New Run' },
|
||||||
|
{ to: '/runs', label: 'My Runs' },
|
||||||
|
{ to: '/genlockes', label: 'Genlockes' },
|
||||||
|
{ to: '/stats', label: 'Stats' },
|
||||||
|
]
|
||||||
|
// Admin gets Admin link
|
||||||
|
if (isAdmin) {
|
||||||
|
links.push({ to: '/admin', label: 'Admin' })
|
||||||
|
}
|
||||||
|
return links
|
||||||
|
}, [user, isAdmin])
|
||||||
|
|
||||||
function isActive(to: string) {
|
function isActive(to: string) {
|
||||||
if (to === '/runs/new') return location.pathname === '/runs/new'
|
if (to === '/' || to === '/runs/new') return location.pathname === to
|
||||||
return location.pathname.startsWith(to)
|
return location.pathname.startsWith(to)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user