Skip to content

feat(mobile): bottom navigation bar for mobile (aluno + dashboard) — PRD-3#179

Merged
EmiyaKiritsugu3 merged 4 commits into
mainfrom
feat/009-mobile-navigation
Jul 6, 2026
Merged

feat(mobile): bottom navigation bar for mobile (aluno + dashboard) — PRD-3#179
EmiyaKiritsugu3 merged 4 commits into
mainfrom
feat/009-mobile-navigation

Conversation

@EmiyaKiritsugu3

@EmiyaKiritsugu3 EmiyaKiritsugu3 commented Jul 6, 2026

Copy link
Copy Markdown
Owner

What

Mobile bottom navigation bar across both portals. Replaces dropdown-hidden primary nav (aluno) and drawer-buried destinations (dashboard) with a fixed mobile-only BottomNav.

Builds on PRD-1 mobile-first foundation (#176): uses .touch-target (44pt), pb-[env(safe-area-inset-bottom)], reduced-motion-safe transition-colors.

Changes

File Change
src/components/bottom-nav.tsx new shared client component. NavIconName string union avoids ReactNode serialization across server/client boundary. md:hidden — desktop unchanged.
src/app/dashboard/_components/dashboard-bottom-nav.tsx new client wrapper (usePathname + getNavItems). Dev item filtered out — stays sidebar Sheet-only.
src/components/dashboard-nav.tsx refactor: extract getNavItems(role) — single source of role-filtered nav truth shared by sidebar + bottom bar. DashboardNav/DashboardNavBottom signatures unchanged.
src/app/aluno/layout.tsx render BottomNav (2 items), pb-16 md:pb-0 on main.
src/app/dashboard/layout.tsx render DashboardBottomNav after main, pb-20 md:pb-8 on main.
src/app/aluno/aluno-header.tsx remove redundant md:hidden nav block from UserMenu dropdown (primary nav now bottom bar); drop unused navLinks prop.
src/components/bottom-nav.test.tsx new — 6 tests (label/href render, active state, root exact-match, md:hidden, empty).
src/app/aluno/aluno-header.test.tsx drop removed navLinks={[]} prop from UserMenu tests.

Behavior

  • Aluno (mobile): bottom bar 2 items — Dashboard (layout-dashboard), Meus Treinos (folder-kanban). Active highlighted text-primary border-t-2 border-primary + aria-current=page.
  • Dashboard (mobile): GERENTE 5 items (Dashboard/Alunos/Treinos/Financeiro/Planos), INSTRUTOR/RECEPCIONISTA 3 (FINANCIAL_ROUTES filter excludes Financeiro+Planos). Dev stays sidebar-only.
  • Desktop: zero change (md:hidden).
  • Safe-area: pb-[env(safe-area-inset-bottom)] clears iPhone home indicator (PRD-1 viewportFit: cover).

Gates

  • npm run typecheck ✅ clean
  • npm run lint ✅ changed files clean (pre-existing baseline errors in commitlint/coverage artifacts untouched)
  • prettier --check
  • npm test ✅ 1125/1125 passing (109 files; +6 bottom-nav tests)

Spec

docs/superpowers/specs/2026-07-07-mobile-navigation-design.md (PRD-3). Constitution v1.0.2 — Dual-Portal (shared src/components/), Type Safety (typed props + union), Test-Gated.

Out of scope (post-MVP per spec)

  • Haptic feedback
  • Spring-physics active indicator (CSS transition-colors sufficient, reduced-motion safe)

🤖 Generated with Claude Code


Summary by cubic

Add a mobile-only bottom navigation bar to both aluno and dashboard, replacing hidden/dropdown nav on small screens while keeping desktop unchanged. Implements PRD-3 by making primary actions clear and reachable on mobile and addressing review feedback on active state and landmarks.

  • New Features

    • Shared BottomNav with 44pt touch targets, safe-area padding, reduced-motion transitions, and md:hidden.
    • Wired into aluno (2 items: Dashboard, Meus Treinos) and dashboard via DashboardBottomNav; active state uses root exact-match and subpath prefix; aria-current=page.
    • Role-based items on dashboard: GERENTE (5), INSTRUTOR/RECEPCIONISTA (3); dev link excluded from bottom bar and stays in the sidebar.
    • Main content gets extra bottom padding (pb-16/pb-20) to clear the fixed bar.
  • Refactors

    • Extracted getNavItems(role) and isNavActive(); reuse in dashboard-nav to unify filtering and active logic.
    • Exported DEV_HREF and used it in DashboardBottomNav; moved DashboardBottomNav outside <main> to avoid landmark nesting.
    • Removed the mobile nav block from AlunoHeader dropdown and dropped the navLinks prop.
    • Tests: added bottom-nav (6) and dashboard-bottom-nav (4); updated aluno-header. Updated docs/CURRENT-STATE.md for PRD-3 and corrected the test count to 1129.

Written for commit 0c65bf4. Summary will update on new commits.

Review in cubic

…— PRD-3

- New src/components/bottom-nav.tsx: shared mobile-only BottomNav (md:hidden),
  44pt touch-target, safe-area pb, reduced-motion-safe transitions, lucide
  iconName string union avoids ReactNode serialization across server/client
- Wire BottomNav into aluno layout (2 items) + dashboard layout via
  DashboardBottomNav client wrapper (usePathname + getNavItems, role-filtered;
  dev item stays sidebar-only)
- Extract getNavItems(role) from DashboardNav into reusable selector;
  sidebar + bottom bar share one source of role-filtered nav truth
- Remove redundant md:hidden nav block from aluno UserMenu dropdown
  (primary nav now bottom bar); drop unused navLinks prop from UserMenu
- pb-16/pb-20 on main content reserves space above fixed bottom bar
- Tests: bottom-nav.test.tsx (6), updated aluno-header.test.tsx (drop
  removed prop); dashboard-nav.test.tsx unchanged (14 green)

Refs: PRD-3 mobile-navigation-design, builds on PRD-1 foundation (#176)

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
smartmanagementsystem Ready Ready Preview, Comment Jul 6, 2026 11:19am

@ecc-tools

ecc-tools Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@EmiyaKiritsugu3, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1631e108-46c7-4348-942d-ab8286c4b5df

📥 Commits

Reviewing files that changed from the base of the PR and between 222e1b3 and 0c65bf4.

📒 Files selected for processing (11)
  • docs/CURRENT-STATE.md
  • src/app/aluno/aluno-header.test.tsx
  • src/app/aluno/aluno-header.tsx
  • src/app/aluno/layout.tsx
  • src/app/dashboard/_components/dashboard-bottom-nav.test.tsx
  • src/app/dashboard/_components/dashboard-bottom-nav.tsx
  • src/app/dashboard/layout.tsx
  • src/components/bottom-nav.test.tsx
  • src/components/bottom-nav.tsx
  • src/components/dashboard-nav.test.tsx
  • src/components/dashboard-nav.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/009-mobile-navigation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Co-Authored-By: Claude <noreply@anthropic.com>
@ecc-tools

ecc-tools Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/app/dashboard/_components/dashboard-bottom-nav.tsx">

<violation number="1" location="src/app/dashboard/_components/dashboard-bottom-nav.tsx:7">
P3: The dev route string `/dashboard/dev` is duplicated here and in the `DEV_ITEM` definition inside `dashboard-nav.tsx`. If someone changes one without the other, the filter silently stops excluding the dev item from the bottom bar. Consider exporting a shared constant (e.g. `DEV_HREF`) from `dashboard-nav.tsx` and reusing it here.</violation>

<violation number="2" location="src/app/dashboard/_components/dashboard-bottom-nav.tsx:12">
P2: Custom agent: **Enforce Pragmatic Test Coverage**

The new `DashboardBottomNav` wrapper implements a specific user-visible business rule (excluding the `/dashboard/dev` route from the mobile bottom nav), yet it has no test coverage. While the shared `BottomNav` component is tested, this dashboard-specific behavior — including role-based filtering via `getNavItems` and the `DEV_HREF` exclusion — could break silently if the nav item structure changes or the filter is accidentally removed. Consider adding tests that mount `DashboardBottomNav` and assert the returned items contain the expected routes for each role while omitting the dev route.</violation>
</file>

<file name="src/app/dashboard/layout.tsx">

<violation number="1" location="src/app/dashboard/layout.tsx:123">
P3: Minor: `DashboardBottomNav` is rendered inside `<SidebarInset>`, which is a `<main>` element. This places the primary page navigation landmark inside the main content region. The aluno layout keeps its `BottomNav` outside `<main>` — moving this one out of `SidebarInset` aligns both portals and avoids nesting a nav landmark inside main. Since the nav is `fixed`, the DOM move won't affect visuals.</violation>
</file>

<file name="src/components/dashboard-nav.tsx">

<violation number="1" location="src/components/dashboard-nav.tsx:68">
P3: The `DashboardNavItem` type alias is exported but never consumed anywhere in the codebase. Since `NavItemDef` is already exported directly and used by all callers, this re-export adds no value and creates a stale symbol that future maintainers might think is used. Consider removing the `export type DashboardNavItem = NavItemDef;` line to keep the public API surface minimal and avoid confusion.</violation>
</file>

<file name="src/components/bottom-nav.tsx">

<violation number="1" location="src/components/bottom-nav.tsx:32">
P2: Custom agent: **Enforce Strict Maintainability Standards**

The `isActive` matching logic is duplicated from `dashboard-nav.tsx` (the PR comment even notes it "mirrors dashboard-nav isActive"). While `getNavItems` was extracted as a shared helper, `isActive` was not. Extracting this as a single parameterized pure function would remove the duplication and ensure navigation matching behavior stays consistent across components.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/app/dashboard/_components/dashboard-bottom-nav.tsx
Comment thread src/components/bottom-nav.tsx Outdated
Comment thread src/app/dashboard/_components/dashboard-bottom-nav.tsx Outdated
Comment thread src/app/dashboard/layout.tsx Outdated
Comment thread src/components/dashboard-nav.tsx Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/CURRENT-STATE.md
- Extract isNavActive() pure fn to bottom-nav.tsx, reuse in DashboardNav
  (P2: was duplicated isActive logic)
- Export DEV_HREF from dashboard-nav, import in DashboardBottomNav wrapper
  (P3: dev route string duplicated)
- Move DashboardBottomNav out of SidebarInset (<main>) into parent div
  (P3: nav landmark nested inside main — aluno layout already kept nav outside main)
- Remove dead DashboardNavItem type alias (P3: exported never consumed)
- Add dashboard-bottom-nav.test.tsx: 4 tests asserting role filtering
  (GERENTE 5 items, FINANCIAL_ROUTES excludes Financeiro+Planos for
  INSTRUTOR), DEV_HREF exclusion, bottom-nav-limit ≤5 (P2: no test coverage)
- Add FolderKanban to dashboard-nav.test.tsx lucide mock (now imported via
  bottom-nav real module chain)

Gates: typecheck ✅, lint ✅, 1129/1129 tests ✅.

Co-Authored-By: Claude <noreply@anthropic.com>
@ecc-tools

ecc-tools Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

Co-Authored-By: Claude <noreply@anthropic.com>
@ecc-tools

ecc-tools Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

@EmiyaKiritsugu3 EmiyaKiritsugu3 merged commit 7b0d7e1 into main Jul 6, 2026
14 checks passed
@EmiyaKiritsugu3 EmiyaKiritsugu3 deleted the feat/009-mobile-navigation branch July 6, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant