# Plan: Bottom Navigation Bar & Global Header Restructure
## Overview
Restructure the GreenHomeUI app to have an Android-style layout with:
- A **persistent Bottom Navigation Bar** (4 tabs: Profile, Alerts, Report, Weather)
- A **global Top Header** showing device title, page title with icon, and page info
- Applied to all authenticated pages (after device selection)
---
## Current Architecture
```
App Flow:
/ (login) → /verify-code → /devices → /daily-report?deviceId=X&date=Y
├── /alert-settings?deviceId=X
├── /calendar?deviceId=X
├── /day-details?deviceId=X&year=Y&month=Z
└── /device-settings?deviceId=X
```
Each page currently has its own `PageHeader` and manages its own layout independently. There is no shared shell/layout for authenticated pages.
---
## Target Architecture
```
Authenticated Shell (Layout)
┌──────────────────────────────────┐
│ Top Header │
│ [Device Name] [Page Icon+Title]│
│ [Page-specific info] │
├──────────────────────────────────┤
│ │
│ Page Content │
│ (children) │
│ │
├──────────────────────────────────┤
│ [Profile] [Alerts] [Report] [W] │
│ Bottom Navigation Bar │
└──────────────────────────────────┘
```
### Route Mapping
| Bottom Nav Tab | Route | Page Component | Icon |
|---|---|---|---|
| Profile | `/profile?deviceId=X` | New `src/app/profile/page.tsx` | `User` |
| Alerts | `/alert-settings?deviceId=X` | Existing (refactored) | `Bell` |
| Report | `/daily-report?deviceId=X&date=Y` | Existing (refactored) | `BarChart3` |
| Weather | `/weather?deviceId=X` | New `src/app/weather/page.tsx` | `CloudSun` |
### Pages OUTSIDE the shell (no bottom nav/header):
- `/` (login page)
- `/login`
- `/verify-code`
- `/devices` (device selection - this is the gateway before entering the shell)
### Pages INSIDE the shell (with bottom nav + header):
- `/daily-report` (Report tab)
- `/alert-settings` (Alerts tab)
- `/profile` (Profile tab - NEW)
- `/weather` (Weather tab - NEW)
- `/calendar` (calendar navigation)
- `/day-details` (day detail view)
- `/device-settings` (device configuration)
---
## Component Architecture
### 1. [`src/components/layout/AppShell.tsx`](src/components/layout/AppShell.tsx) — NEW
The main layout wrapper for authenticated pages. Provides:
- Top header bar
- Bottom navigation bar
- Main content area (children)
### 2. [`src/components/layout/TopHeader.tsx`](src/components/layout/TopHeader.tsx) — NEW
Global top header component showing:
- **Left side**: Device name (from context/query param)
- **Center/Right**: Page title with icon
- **Optional**: Page-specific info (e.g., selected date for daily-report)
Props:
```typescript
type TopHeaderProps = {
deviceName: string
pageTitle: string
pageIcon: LucideIcon
pageInfo?: string // e.g., "۱۴۰۴/۰۲/۲۱" for date
iconGradient?: string
}
```
### 3. [`src/components/layout/BottomNav.tsx`](src/components/layout/BottomNav.tsx) — NEW
Bottom navigation bar with 4 tabs:
- Uses `lucide-react` icons
- Highlights active tab based on current route
- Fixed at bottom, safe-area aware for notched devices
- Each tab navigates via `next/navigation` `useRouter`
### 4. [`src/components/layout/DeviceProvider.tsx`](src/components/layout/DeviceProvider.tsx) — NEW
React Context provider that stores the currently selected `deviceId` and `deviceName` so all pages within the shell can access them without passing through query params everywhere.
### 5. [`src/app/profile/page.tsx`](src/app/profile/page.tsx) — NEW
User profile page showing:
- User name, family, mobile
- Logout button
- Link to device settings
### 6. [`src/app/weather/page.tsx`](src/app/weather/page.tsx) — NEW
Dedicated weather page (extracted from the weather tab inside daily-report):
- Shows forecast weather data
- Reuses existing [`WeatherTab`](src/components/daily-report/WeatherTab.tsx) or creates a standalone version
---
## Data Flow
```
User logs in → /devices (selects device)
→ Stores deviceId + deviceName in DeviceProvider context
→ Redirects to /daily-report?deviceId=X&date=today
→ AppShell renders with TopHeader + BottomNav + page content
→ BottomNav tab changes update the route
→ DeviceProvider persists across tab switches
```
### DeviceProvider Context
```typescript
type DeviceContextType = {
deviceId: number
deviceName: string
setDevice: (id: number, name: string) => void
}
```
The provider wraps all authenticated pages. When a user selects a device on `/devices`, it sets the context. The `AppShell` reads from this context to display the device name in the header.
---
## File Changes Summary
### New Files to Create
| File | Purpose |
|---|---|
| [`src/components/layout/AppShell.tsx`](src/components/layout/AppShell.tsx) | Main layout shell with header + bottom nav |
| [`src/components/layout/TopHeader.tsx`](src/components/layout/TopHeader.tsx) | Global top header component |
| [`src/components/layout/BottomNav.tsx`](src/components/layout/BottomNav.tsx) | Bottom navigation bar |
| [`src/components/layout/DeviceProvider.tsx`](src/components/layout/DeviceProvider.tsx) | Device context provider |
| [`src/components/layout/index.ts`](src/components/layout/index.ts) | Barrel exports |
| [`src/app/profile/page.tsx`](src/app/profile/page.tsx) | Profile page |
| [`src/app/weather/page.tsx`](src/app/weather/page.tsx) | Weather page |
### Files to Modify
| File | Changes |
|---|---|
| [`src/app/layout.tsx`](src/app/layout.tsx) | Wrap children with `DeviceProvider` for authenticated routes |
| [`src/app/daily-report/page.tsx`](src/app/daily-report/page.tsx) | Remove standalone `PageHeader`, use `AppShell` instead. Remove `BackLink`. |
| [`src/app/alert-settings/page.tsx`](src/app/alert-settings/page.tsx) | Remove standalone `PageHeader`, use `AppShell`. Remove `BackLink`. |
| [`src/app/calendar/page.tsx`](src/app/calendar/page.tsx) | Remove standalone `PageHeader`, use `AppShell`. Remove `BackLink`. |
| [`src/app/day-details/page.tsx`](src/app/day-details/page.tsx) | Remove standalone `PageHeader`, use `AppShell`. Remove `BackLink`. |
| [`src/app/device-settings/page.tsx`](src/app/device-settings/page.tsx) | Remove standalone `PageHeader`, use `AppShell`. Remove `BackLink`. |
| [`src/app/devices/page.tsx`](src/app/devices/page.tsx) | After device selection, set `DeviceProvider` context before redirecting |
| [`src/app/globals.css`](src/app/globals.css) | Add styles for bottom nav (safe-area padding, fixed positioning) |
---
## Implementation Steps (Ordered)
### Step 1: Create Layout Components
- Create [`DeviceProvider`](src/components/layout/DeviceProvider.tsx) context
- Create [`TopHeader`](src/components/layout/TopHeader.tsx) component
- Create [`BottomNav`](src/components/layout/BottomNav.tsx) component
- Create [`AppShell`](src/components/layout/AppShell.tsx) that composes them
- Create barrel export [`index.ts`](src/components/layout/index.ts)
### Step 2: Update Root Layout
- Modify [`src/app/layout.tsx`](src/app/layout.tsx) to wrap with `DeviceProvider`
- Add bottom nav CSS to [`src/app/globals.css`](src/app/globals.css)
### Step 3: Create New Pages
- Create [`src/app/profile/page.tsx`](src/app/profile/page.tsx) — user info + logout
- Create [`src/app/weather/page.tsx`](src/app/weather/page.tsx) — dedicated weather page
### Step 4: Refactor Existing Pages to Use AppShell
- [`src/app/daily-report/page.tsx`](src/app/daily-report/page.tsx) — remove standalone PageHeader, wrap content in AppShell
- [`src/app/alert-settings/page.tsx`](src/app/alert-settings/page.tsx) — same
- [`src/app/calendar/page.tsx`](src/app/calendar/page.tsx) — same
- [`src/app/day-details/page.tsx`](src/app/day-details/page.tsx) — same
- [`src/app/device-settings/page.tsx`](src/app/device-settings/page.tsx) — same
### Step 5: Update Device Selection Flow
- Modify [`src/app/devices/page.tsx`](src/app/devices/page.tsx) to set device context on selection
- Ensure single-device auto-redirect also sets context
### Step 6: Polish & Testing
- Ensure bottom nav highlights correct tab based on route
- Ensure safe-area padding for notched phones
- Test navigation between all tabs
- Verify header shows correct device name and page info
---
## Mermaid Diagram: Component Tree
```mermaid
flowchart TD
RootLayout[RootLayout] --> DeviceProvider[DeviceProvider]
DeviceProvider --> AuthPages[Auth Pages Group]
subgraph AuthPages[Authenticated Pages]
AppShell[AppShell] --> TopHeader[TopHeader]
AppShell --> PageContent[Page Content]
AppShell --> BottomNav[BottomNav]
PageContent --> DailyReport[/daily-report]
PageContent --> AlertSettings[/alert-settings]
PageContent --> Profile[/profile]
PageContent --> Weather[/weather]
PageContent --> Calendar[/calendar]
PageContent --> DayDetails[/day-details]
PageContent --> DeviceSettings[/device-settings]
end
NonAuth[Non-Auth Pages] -.-> Login[/login]
NonAuth -.-> VerifyCode[/verify-code]
NonAuth -.-> Devices[/devices]
Devices -.->|select device| AppShell
```
## Mermaid Diagram: Navigation Flow
```mermaid
flowchart LR
Login[/login] --> Verify[/verify-code]
Verify --> Devices[/devices]
Devices -->|select device + set context| DailyReport[/daily-report
Tab: Report]
DailyReport -->|BottomNav: Alerts| AlertSettings[/alert-settings
Tab: Alerts]
DailyReport -->|BottomNav: Profile| Profile[/profile
Tab: Profile]
DailyReport -->|BottomNav: Weather| Weather[/weather
Tab: Weather]
AlertSettings -->|BottomNav: Report| DailyReport
AlertSettings -->|BottomNav: Profile| Profile
AlertSettings -->|BottomNav: Weather| Weather
Profile -->|BottomNav: Report| DailyReport
Profile -->|BottomNav: Alerts| AlertSettings
Profile -->|BottomNav: Weather| Weather
Weather -->|BottomNav: Report| DailyReport
Weather -->|BottomNav: Alerts| AlertSettings
Weather -->|BottomNav: Profile| Profile
DailyReport -->|internal link| Calendar[/calendar]
Calendar -->|select day| DayDetails[/day-details]
DayDetails -->|select date| DailyReport
DailyReport -->|settings icon| DeviceSettings[/device-settings]
Profile -->|settings link| DeviceSettings
```
---
## Key Design Decisions
1. **DeviceProvider Context**: Rather than passing `deviceId` as a query param on every navigation, we use React Context. This simplifies all page components and makes the header always aware of the current device.
2. **AppShell as a wrapper**: Each page inside the shell imports `AppShell` and wraps its content. The shell provides the header and bottom nav. This keeps pages clean and focused on their content.
3. **BottomNav uses route matching**: The active tab is determined by matching `usePathname()` against known routes. This is simpler than managing state across pages.
4. **Safe-area handling**: The bottom nav uses `env(safe-area-inset-bottom)` CSS to avoid overlapping with system navigation bars on notched devices.
5. **Existing PageHeader component**: The existing `PageHeader` component can still be used inside page content if needed (e.g., for sub-headers within a page), but the main header is now provided by `AppShell`.