docs: update and create comprehensive markdown documentation

- Updated README.md with current features (Auth, Cart, Feed pages)
- Updated COMPONENTS.md with CartFab and all context providers (Auth, Cart, Menu)
- Created APP.md: detailed documentation of all routes and pages
- Created LIB.md: documentation of types, constants, and contexts
- Created LAYOUTS.md: header and footer component documentation
- Updated TODO.md: reflects completed implementations and future work

This provides agents with comprehensive documentation to understand the project structure and implementation details.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Thanh Quy - wolf
2026-03-29 20:17:55 +07:00
parent e2aeebd0e1
commit 284183098e
6 changed files with 1653 additions and 58 deletions
+92 -23
View File
@@ -8,17 +8,46 @@ Dự án Frontend cho hệ thống đặt món cà phê, xây dựng bằng Next
Giao diện người dùng (frontend) cho hệ thống đặt và bán đồ uống trực tuyến. Giao diện người dùng (frontend) cho hệ thống đặt và bán đồ uống trực tuyến.
### Trang Người Dùng (User Page - /) ### Tính Năng Hiện Tại
Dành cho khách hàng:
- Duyệt thực đơn theo danh mục (sidebar collapsible)
- Tìm kiếm món theo tên / mô tả
- Xem card sản phẩm với giá và nút Mua
- Lọc tự động theo trạng thái available
### Trang Quản Lý (Manager Page - chưa triển khai) #### 1. **Trang Đăng Nhập & Đăng Ký** (app/(main)/login, app/(main)/register)
Dành cho chủ quán / nhân viên: - Form đăng nhập với validation (username, password)
- Quản lý thực đơn (thêm, sửa, xóa món) - Form đăng ký với xác thực OTP
- Theo dõi và xử lý đơn hàng - Lưu trữ thông tin người dùng trong localStorage
- Hỗ trợ 3 loại tài khoản: Manager, Staff, Customer
- Hiển thị thông tin shop trong form
#### 2. **Trang Khám Phá Quán Nước** (app/(feed)/feed)
- Danh sách các quán cà phê
- Tìm kiếm theo tên quán và địa chỉ
- Thẻ quán với ảnh, địa chỉ, nút "Xem menu"
- Responsive layout (grid 1/2/3 cột)
- Empty state khi không tìm thấy quán
#### 3. **Trang Chính - Duyệt Thực Đơn** (app/(main))
Dành cho khách hàng:
- Sidebar collapsible (64px/240px) - danh mục sản phẩm
- Grid sản phẩm responsive (1-5 cột tuỳ thiết bị)
- Tìm kiếm món theo tên / mô tả
- Xem card sản phẩm với giá và nút "Mua"
- Lọc tự động theo trạng thái available
- Mobile menu: scrollable category tabs (< md)
#### 4. **Hệ Thống Giỏ Hàng** (lib/cart-context.tsx)
- Lưu trữ trạng thái giỏ trong localStorage
- Thêm/xóa/tăng/giảm số lượng sản phẩm
- Tính tổng giá và số mặt hàng
- Persist dữ liệu giữa các session
#### 5. **Hệ Thống Xác Thực** (lib/auth-context.tsx)
- Quản lý trạng thái người dùng (login/logout/register)
- Lưu thông tin user trong localStorage
- Mock auth database với 3 loại tài khoản
- Hỗ trợ hoàn tất đăng ký qua OTP
#### 6. **Hệ Thống Danh Mục** (lib/menu-context.tsx)
- Chia sẻ trạng thái category giữa Header mobile và Sidebar
- Tự động clear search khi thay đổi category
--- ---
@@ -56,23 +85,45 @@ pnpm lint
``` ```
frondend/ frondend/
+-- app/ # Next.js App Router +-- app/ # Next.js App Router
| +-- layout.tsx # Root layout | +-- layout.tsx # Root layout + Header + Footer
| +-- page.tsx # Trang chủ - sidebar + product grid
| +-- globals.css # CSS design tokens + Tailwind import | +-- globals.css # CSS design tokens + Tailwind import
| +-- providers.tsx # Context providers (Auth, Menu, Cart)
| +-- APP.md # Tài liệu chi tiết về routes
| +-- (main)/ # Main route group
| | +-- layout.tsx # Main layout
| | +-- page.tsx # Trang chính - duyệt thực đơn
| | +-- login/page.tsx # Trang đăng nhập
| | +-- register/page.tsx # Trang đăng ký
| | +-- payment/page.tsx # Trang thanh toán
| +-- (feed)/ # Feed route group
| +-- layout.tsx # Feed layout
| +-- feed/page.tsx # Trang khám phá quán nước
+-- components/ # Shared UI components +-- components/ # Shared UI components
| +-- Navbar.tsx # Sidebar danh mục (collapsible) | +-- Navbar.tsx # Sidebar danh mục (collapsible)
| +-- CartProduct.tsx # Card sản phẩm | +-- CartProduct.tsx # Card sản phẩm
| +-- COMPONENTS.md # Tài liệu component | +-- CartFab.tsx # FAB - nút giỏ hàng floating
| +-- COMPONENTS.md # Tài liệu chi tiết components & contexts
+-- layouts/ # Layout-level components +-- layouts/ # Layout-level components
| +-- header.tsx # Sticky top header | +-- header.tsx # Sticky top header + auth demo
| +-- footer.tsx # Footer | +-- footer.tsx # Footer + shop info
| +-- LAYOUTS.md # Tài liệu chi tiết layouts
+-- lib/ # Shared logic & data +-- lib/ # Shared logic & data
| +-- constants.ts # Mock data | +-- constants.ts # Mock data (products, shops, users, shop info)
| +-- types.ts # TypeScript interfaces | +-- types.ts # TypeScript interfaces
| +-- auth-context.tsx # Authentication context & provider
| +-- cart-context.tsx # Shopping cart context & provider
| +-- menu-context.tsx # Menu/Category context & provider
| +-- LIB.md # Tài liệu chi tiết về lib
+-- types/ # Global TypeScript declarations +-- types/ # Global TypeScript declarations
| +-- css.d.ts # CSS module type shim | +-- css.d.ts # CSS module type shim
+-- public/ # Static assets +-- public/ # Static assets
+-- WORKFLOW.md # Tài liệu kiến trúc & quy trình | +-- imgs/
| | +-- logo.png
| | +-- products/ # Ảnh sản phẩm
| +-- favicon/
+-- WORKFLOW.md # Tài liệu kiến trúc tổng thể & quy trình
+-- README.md # (file này) - Mô tả dự án
+-- TODO.md # Danh sách tính năng hoàn thành & chưa làm
+-- next.config.ts +-- next.config.ts
+-- tsconfig.json +-- tsconfig.json
+-- postcss.config.mjs +-- postcss.config.mjs
@@ -100,9 +151,27 @@ frondend/
## Ghi Chú Phát Triển ## Ghi Chú Phát Triển
- Trang chủ (app/page.tsx) là điểm vào chính của User Page ### Điểm Vào Chính
- Design tokens định nghĩa trong app/globals.css dưới dạng CSS custom properties - **Trang Chủ (User):** `app/(main)/page.tsx` - Duyệt thực đơn
- Mock data nằm trong lib/constants.ts - thay bằng API calls khi backend sẵn sàng - **Trang Khám Phá:** `app/(feed)/feed/page.tsx` - Khám phá quán
- Dark mode: biến CSS đã chuẩn bị sẵn trong globals.css nhưng chưa kích hoạt - **Đăng Nhập:** `app/(main)/login/page.tsx`
- Ảnh sản phẩm: thêm ảnh thực vào public/imgs/products/ - **Đăng Ký:** `app/(main)/register/page.tsx`
- Xem WORKFLOW.md để hiểu kiến trúc tổng thể và quy trình mở rộng dự án
### Design & Styling
- Design tokens (CSS variables) định nghĩa trong `app/globals.css`
- Tailwind CSS v4 + custom properties cho consistent color/spacing
- Dark mode: biến CSS đã chuẩn bị sẵn nhưng chưa kích hoạt
- FontAwesome icons từ CDN
### Data & Integration
- Mock data nằm trong `lib/constants.ts`
- Context providers trong `app/providers.tsx` - Sử dụng: AuthProvider, MenuProvider, CartProvider
- Thay bằng API calls khi backend sẵn sàng
- Ảnh sản phẩm: thêm vào `public/imgs/products/`
### Tài Liệu Chi Tiết
- **WORKFLOW.md** - Kiến trúc tổng thể, data flow, quy trình phát triển
- **APP.md** - Chi tiết các routes, layouts, pages
- **COMPONENTS.md** - Tài liệu từng component + contexts
- **LAYOUTS.md** - Header, Footer, responsive behavior
- **LIB.md** - Constants, Types, Contexts
+102 -35
View File
@@ -1,52 +1,119 @@
# Coffee Shop Frontend - TODO # Coffee Shop Frontend - TODO
## Completed Optimizations ## Completed Features & Implementations
### A. Dead Code Removed ### A. Documentation
- [x] lib/constants.ts - Removed unused NAV_LINKS export - [x] README.md - Updated with current features (Auth, Cart, Feed, etc.)
- [x] lib/types.ts - Removed unused NavLink interface - [x] COMPONENTS.md - Added CartFab, AuthContext, CartContext, MenuContext sections
- [x] components/Navbar.tsx - Removed trivial handleClick wrapper; inlined onCategoryChange call - [x] APP.md - New file: Detailed app routes, pages, layouts
- [x] components/Navbar.tsx - Removed unused Link import - [x] LIB.md - New file: Types, Constants, Contexts documentation
- [x] LAYOUTS.md - New file: Header & Footer detailed documentation
- [x] WORKFLOW.md - Architecture and workflow documentation
### B. Bugs / Inaccuracies Fixed ### B. Authentication System
- [x] layouts/header.tsx - Fixed JSDoc: 3-column -> 2-column layout (no center section exists) - [x] lib/auth-context.tsx - Created Auth context with login/logout/register
- [x] app/page.tsx - Added available !== false filter to product list - [x] lib/types.ts - User type with roles (manager, staff, customer)
- [x] app/page.tsx - Fixed setState-in-effect lint error: moved initial sidebar state to lazy useState initializer - [x] app/(main)/login/page.tsx - Login page with form validation
- [x] next.config.ts - Added explanatory JSDoc comment - [x] app/(main)/register/page.tsx - Register page with OTP verification
- [x] localStorage integration - Persist user across sessions
- [x] Mock auth database - Pre-configured accounts for testing
### C. Documentation Updated ### C. Shopping Cart System
- [x] README.md - Fixed file structure tree, removed SCSS, fixed dark mode note, updated tech table - [x] lib/cart-context.tsx - Cart context with add/remove/update operations
- [x] components/COMPONENTS.md - Fixed CartProduct styling (was outdated w-64/text-red-500/bg-blue-600); added Navbar, Header, Footer sections - [x] Cart persistence - localStorage integration
- [x] CartItem interface - With id, name, description, price, quantity
- [x] Cart operations - addToCart, increaseQty, decreaseQty, removeFromCart, setQuantity
- [x] Computed totals - totalItems and totalPrice memoized
### D. New Documentation Created ### D. Menu/Category System
- [x] WORKFLOW.md - Architecture, data flow, design token system, how-to guides, dev workflow - [x] lib/menu-context.tsx - MenuContext for shared category state
- [x] Shared state across components - Header mobile menu + Navbar sidebar sync
- [x] Category filtering - Products filtered by active category
### E. Mini-test Results ### E. Product Pages
- [x] npm run lint - PASSED (0 errors, 0 warnings) - [x] app/(main)/page.tsx - Main page with sidebar + product grid
- [x] npm run build - PASSED (Compiled successfully, TypeScript clean, static pages generated) - [x] Responsive product grid - 1-5 columns depending on sidebar & screen size
- [x] Product search - Search by name and description
- [x] Category filter - Sidebar collapsible navigation
- [x] Mobile category menu - Scrollable tabs on < md breakpoint
- [x] Empty states - Messaging when no products match filters
- [x] CartProduct component - Product card with image, price, buy button
### F. Feed/Discovery Page
- [x] app/(feed)/feed/page.tsx - Shop discovery page
- [x] Shop grid - Responsive 1/2/3 column layout
- [x] Search by name and address - Sticky bottom filter bar
- [x] Shop cards - Image, name, address, view menu button
- [x] Empty state - Message when no shops match filters
- [x] MOCK_SHOPS constant - 5 sample coffee shops
### G. Header & Footer
- [x] layouts/header.tsx - Sticky header with brand and auth demo
- [x] layouts/footer.tsx - Footer with shop info, social links, WiFi
- [x] Responsive layouts - Mobile/tablet/desktop optimized
- [x] Auth state display - Guest/Manager/Staff cycling demo
### H. Code Quality & Optimization
- [x] Dead code removed - Unused imports and exports cleaned
- [x] Lint passed - 0 errors, 0 warnings
- [x] Build passed - TypeScript clean, all pages compile
- [x] Type safety - Full TypeScript coverage
- [x] React best practices - Hooks, memoization, context patterns
--- ---
## Pending Features (Future Work) ## Pending Features (Future Work)
### Cart & Ordering ### Cart & Ordering
- [ ] Implement add-to-cart logic (onBuy callback in CartProduct) - [ ] Implement cart checkout flow (app/(main)/cart or modal)
- [ ] Cart sidebar or modal with item list and total - [ ] Cart sidebar/modal with item list and total
- [ ] Order submission flow - [ ] Order submission API integration
- [ ] Payment page - [ ] Payment page implementation (app/(main)/payment)
- [ ] Order history/tracking page
- [ ] Toast notifications for cart actions
### Authentication & User Management
- [ ] Real backend authentication (replace MOCK_AUTH_DB)
- [ ] Real OTP delivery service (SMS integration)
- [ ] User profile page with edit capability
- [ ] Password reset/recovery flow
- [ ] Session management and token refresh
### Manager Features
- [ ] Manager dashboard page (app/(manager)/page.tsx)
- [ ] Product management (add/edit/delete)
- [ ] Category management
- [ ] Order management & tracking
- [ ] Sales analytics/dashboard
- [ ] Inventory management
### Backend Integration ### Backend Integration
- [ ] Replace MOCK_PRODUCTS with real API calls (lib/api.ts) - [ ] Replace MOCK_PRODUCTS with API calls (GET /api/products)
- [ ] Replace MOCK_USERS with real authentication - [ ] Replace MOCK_SHOPS with API calls (GET /api/shops)
- [ ] Product images: replace placeholder with real images in public/imgs/products/ - [ ] Replace MOCK_USERS with real authentication (POST /api/auth/login)
- [ ] Real product images (replace placeholder.jpg)
### Manager Page - [ ] Image upload for products
- [ ] Create app/manager/page.tsx
- [ ] Menu management (add/edit/delete products)
- [ ] Order tracking dashboard
### UX Improvements ### UX Improvements
- [ ] Dark mode toggle (CSS variables already prepared in globals.css) - [ ] Dark mode toggle (CSS variables prepared, toggle UI needed)
- [ ] Loading skeleton for product grid - [ ] Loading skeletons for product grid
- [ ] Toast notifications for cart actions - [ ] Product detail modal/page with full description
- [ ] Product detail modal/page - [ ] Wishlist/favorites feature
- [ ] Sort products (price, rating, etc.)
- [ ] Filter by price range
- [ ] Quantity selector in product card
- [ ] Related products suggestions
### Performance & SEO
- [ ] Dynamic route generation for products (app/(main)/product/[id]/page.tsx)
- [ ] Dynamic route generation for shops (app/(feed)/shop/[id]/page.tsx)
- [ ] Meta tags and Open Graph for SEO
- [ ] Image optimization and lazy loading
- [ ] Code splitting and dynamic imports
### Accessibility & Testing
- [ ] Keyboard navigation testing
- [ ] ARIA labels audit
- [ ] Unit tests for contexts
- [ ] E2E tests for user flows
- [ ] Accessibility audit (WCAG 2.1 AA)
+361
View File
@@ -0,0 +1,361 @@
# App Routes & Pages Documentation
> Tài liệu chi tiết về Next.js App Router structure, routes, và layouts
---
## Route Structure Overview
```
app/
├── layout.tsx # Root layout - Header + Footer wrapper
├── globals.css # CSS tokens + Tailwind imports
├── providers.tsx # Context providers (Auth, Menu, Cart)
├── (main)/
│ ├── layout.tsx # Main layout for authenticated routes
│ ├── page.tsx # Main page - Duyệt thực đơn (/)
│ ├── login/
│ │ └── page.tsx # Trang đăng nhập (/login)
│ ├── register/
│ │ └── page.tsx # Trang đăng ký (/register)
│ └── payment/
│ └── page.tsx # Trang thanh toán (/payment)
└── (feed)/
├── layout.tsx # Feed layout
└── feed/
└── page.tsx # Trang khám phá quán (/feed)
```
---
## Root Layout (app/layout.tsx)
**Description:** Root layout wrapping entire application. Loads providers, fonts, and common layouts (header/footer).
### Structure
- Imports providers (AuthProvider, MenuProvider, CartProvider)
- Renders Header component (sticky top)
- Renders page content via {children}
- Renders Footer component
### Metadata
- Title: "Coffee Shop"
- Charset: UTF-8
- Viewport: responsive
### Key Features
- Global CSS variables loaded here
- Header remains sticky across all pages
- Footer always present
---
## Providers (app/providers.tsx)
**Description:** Client component that wraps all context providers for the application.
### Providers Included
1. **AuthProvider** (lib/auth-context.tsx)
- Manages user authentication state
- Persists user in localStorage
- Enables login/logout/register flows
2. **MenuProvider** (lib/menu-context.tsx)
- Shares active category state
- Syncs Header mobile menu and Navbar sidebar
3. **CartProvider** (lib/cart-context.tsx)
- Manages shopping cart state
- Persists cart items in localStorage
- Provides add/remove/update operations
### Usage in Root Layout
```tsx
<Providers>
<Header />
{children}
<Footer />
</Providers>
```
---
## (main) Route Group
### Layout (app/(main)/layout.tsx)
**Description:** Layout for authenticated/main routes. Can include route-specific UI (e.g., sidebar navigation).
### Usage
- Wraps all pages under `(main)/` route group
- Inherits root layout above it
- Can add additional styling or structure specific to main pages
---
## Pages
### 1. Main Page - Duyệt Thực Đơn (app/(main)/page.tsx)
**Route:** `/` (default) or `/(main)`
**Type:** Client component
**Description:** Main shopping interface. Shows product grid with sidebar category filter.
#### Key Features
- **Sidebar (Navbar):**
- Collapsible (64px collapsed / 240px expanded)
- Category list with icons
- Sticky, full viewport height minus header
- Responsive: desktop (expanded) vs mobile (collapsed)
- **Product Grid:**
- Responsive columns (1/2/3/4/5 depending on sidebar state and screen size)
- Filter by: availability, active category, search query
- Search bar with clear button
- Empty state when no products match
- **Mobile Category Menu:**
- Visible only on screens < md (768px)
- Sticky scrollable tabs below search
- Allows category selection on mobile
#### Context Usage
- **useMenu()** - Get/set active category
- **useCart()** - Add products to cart
- **MenuContext** - Shares category state with Header
#### State Management
```tsx
isSidebarOpen: boolean // Sidebar expanded/collapsed
searchQuery: string // Search input value
activeCategory: string // From MenuContext
```
#### Responsive Behavior
- **Mobile (<480px):** 1 col, sidebar collapsed
- **Small phone (480px):** 2 cols, sidebar collapsed
- **Tablet (768px):** Mobile menu tabs appear
- **Desktop (1024px):** Sidebar expands, 2-4 cols depending on sidebar
- **Large screen (1280px+):** 3-5 cols
---
### 2. Login Page (app/(main)/login/page.tsx)
**Route:** `/login`
**Type:** Client component
**Description:** User authentication form. Supports login for Manager, Staff, and Customer roles.
#### Key Features
- **Form Fields:**
- Username input (with icon)
- Password input (with show/hide toggle)
- "Dang nhap" button
- "Dang ky tai khoan" link to register
- **Validation:**
- Username: required, non-empty
- Password: required, min 4 characters
- Error messages displayed inline
- **Demo Credentials:**
- Shows example accounts for testing:
- Manager: `admin / admin`
- Staff: `Nguyễn Văn An / Nguyễn Văn An`
- Customer: `0987654321 / user1`
- **UI:**
- Centered card (max-width: 448px)
- Shop logo and name at top
- Error messages with icons
- Responsive design
#### Context Usage
- **useAuth()** - Login function
#### Navigation
- Success: redirect to `/` (main page)
- Register link: go to `/register`
---
### 3. Register Page (app/(main)/register/page.tsx)
**Route:** `/register`
**Type:** Client component
**Description:** User registration flow. Two-step process: phone verification → account creation.
#### Key Features
- **Step 1: Phone Verification**
- Input phone number
- "Request OTP" button
- Mock OTP validation (no real SMS)
- **Step 2: Account Creation** (after OTP)
- Confirm phone number
- "Create Account" button
- Auto-login after registration
- **Validation:**
- Phone format validation
- OTP code validation
- **UI:**
- Centered card layout
- Step indicator
- Progress feedback
#### Context Usage
- **useAuth()** - completeRegistration()
#### Navigation
- Success: redirect to `/` (main page)
- Login link: go to `/login`
---
### 4. Payment Page (app/(main)/payment/page.tsx)
**Route:** `/payment`
**Type:** Client component (TBD)
**Description:** Payment/checkout page. Currently a placeholder; implement when cart and order system are ready.
---
## (feed) Route Group
### Layout (app/(feed)/layout.tsx)
**Description:** Layout for feed routes. Can have specific styling for discovery/exploration pages.
---
### Feed Page - Khám Phá Quán (app/(feed)/feed/page.tsx)
**Route:** `/feed`
**Type:** Client component
**Description:** Discover coffee shops. Browse and search available shops with their location and details.
#### Key Features
- **Shop Cards:**
- Shop image (responsive height)
- Name and location
- "Xem menu" button (links to `/`)
- Hover effects with shadow/lift animation
- **Search & Filter:**
- Sticky bottom filter bar
- Search by shop name
- Search by address
- Clear buttons for each field
- **Grid Layout:**
- Responsive (1/2/3 columns)
- Adjusts to screen size
- **Empty State:**
- Icon and message when no shops match
- Clear filter button
#### Context Usage
- **useAuth()** - Optional: check user role
#### State Management
```tsx
searchName: string // Shop name search
searchAddress: string // Shop address search
filteredShops: Shop[] // Filtered results
```
#### Data Source
- MOCK_SHOPS from lib/constants.ts
---
## CSS & Styling
### Global Styles (app/globals.css)
**Description:** Root CSS file. Imports Tailwind CSS, defines design tokens (CSS variables), and global styles.
### Design Tokens (CSS Variables)
Defined at `:root` for light mode, with dark mode variants:
#### Colors
- `--color-primary` - Main brand color (brown)
- `--color-primary-dark` - Darker shade for hover
- `--color-accent` - Secondary accent color
- `--color-bg-*` - Background colors (main, card, sidebar)
- `--color-border-*` - Border colors
- `--color-text-*` - Text colors (primary, secondary, muted)
- `--color-shadow-*` - Shadow colors (sm, md)
#### Spacing
- `--spacing-header-height` - Header component height
- Standard Tailwind spacing (via Tailwind)
#### Typography
- Font stack defined via Google Fonts (Geist)
### Tailwind Config Integration
- v4 with custom properties support
- Extends with CSS variables
- Dark mode: CSS variable override
---
## Key Concepts
### Route Groups
- `(main)` and `(feed)` are route groups (don't appear in URL)
- Allow different layouts/providers per route group
- Used for organization and flexibility
### SSR vs Client Components
- Most pages are "use client" (need interactivity)
- Context providers must be client components
- Layout.tsx can be server component
### Responsive Design
- Breakpoints: sm (640px), md (768px), lg (1024px), xl (1280px), 2xl (1536px)
- Sidebar width affects grid columns
- Mobile: vertical layout, collapsed sidebar
- Desktop: horizontal layout, expanded sidebar
### Navigation
- Internal links use `next/link`
- useRouter() for programmatic navigation
- Auth redirects after login/register
---
## Development Workflow
### Adding a New Page
1. Create file under appropriate route group: `app/(main)/new-feature/page.tsx`
2. Make it a client component if it needs interactivity: `"use client"`
3. Use context hooks as needed (useAuth, useCart, useMenu)
4. Export default component
5. Add to documentation
### Adding a New Route Group
1. Create directory: `app/(group-name)/`
2. Create `layout.tsx` if custom layout needed
3. Add pages under this group
4. Update codebase understanding
### Styling Pages
- Use Tailwind classes + CSS variables
- Reference design tokens for consistency
- Follow responsive patterns from existing pages
---
## Future Enhancements
- [ ] Payment page implementation
- [ ] Order history/tracking page
- [ ] Manager dashboard (menu management, order tracking)
- [ ] User profile page
- [ ] Cart checkout flow
- [ ] Real backend API integration
+151
View File
@@ -156,3 +156,154 @@ None - reads SHOP_INFO and SOCIAL_LINKS from lib/constants directly.
- next/image, next/link - next/image, next/link
- lib/constants: SHOP_INFO, SOCIAL_LINKS - lib/constants: SHOP_INFO, SOCIAL_LINKS
- FontAwesome icons - FontAwesome icons
---
## CartFab
**File:** components/CartFab.tsx
**Description:** Floating Action Button displaying cart item count. Shows badge with number of items and total price on hover.
### Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| onClick | () => void | no | undefined | Callback when FAB is clicked |
### Features
- Displays cart icon with item count badge
- Shows total price on hover in tooltip
- Sticky position (bottom-right)
- Uses cart context to get items and total
### Styling
| Element | Key classes |
|---------|-------------|
| FAB button | fixed bottom-6 right-6, rounded-full, shadow-lg |
| Badge | absolute top-0 right-0, red bg, small font |
| Tooltip | appears on hover, shows total price |
### Dependencies
- lib/cart-context: useCart()
- FontAwesome icons
---
# Contexts Documentation
## AuthContext (lib/auth-context.tsx)
**File:** lib/auth-context.tsx
**Description:** Manages user authentication state including login, logout, and registration. Uses localStorage for persistence.
### Provider Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| children | React.ReactNode | yes | Child components |
### Hook: useAuth()
Returns `AuthContextType` with:
| Property | Type | Description |
|----------|------|-------------|
| user | User \| null | Current logged-in user or null |
| login | (username: string, password: string) => boolean | Login function; returns success status |
| logout | () => void | Logout function; clears user and localStorage |
| registerPhone | string \| null | Phone number during registration flow |
| setRegisterPhone | (phone: string \| null) => void | Update registerPhone state |
| completeRegistration | (phone: string) => void | Complete registration and create customer account |
### Mock Database
Pre-configured accounts:
- Manager: `admin / admin`
- Staff: `Nguyễn Văn An / Nguyễn Văn An`, `Trần Thị Bình / Trần Thị Bình`, etc.
- Customer: Phone number as username, `user1` as password
### Storage
- Key: `coffee-shop-user`
- Format: JSON serialized User object
---
## CartContext (lib/cart-context.tsx)
**File:** lib/cart-context.tsx
**Description:** Manages shopping cart state with localStorage persistence. Tracks items, quantities, and totals.
### Provider Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| children | React.ReactNode | yes | Child components |
### Hook: useCart()
Returns `CartContextValue` with:
| Property | Type | Description |
|----------|------|-------------|
| items | CartItem[] | Array of items in cart |
| totalItems | number | Total quantity of items |
| totalPrice | number | Total price in VND |
| addToCart | (product: Product) => void | Add or increase product quantity |
| increaseQty | (id: number) => void | Increase product quantity by 1 |
| decreaseQty | (id: number) => void | Decrease product quantity by 1 (removes if qty reaches 0) |
| removeFromCart | (id: number) => void | Remove product from cart |
| setQuantity | (id: number, quantity: number) => void | Set exact quantity (removes if 0) |
### CartItem Interface
```typescript
interface CartItem {
id: number;
name: string;
description: string;
price: number;
quantity: number;
}
```
### Storage
- Key: `coffee-shop-cart`
- Format: JSON serialized CartItem[]
- Auto-loads on mount and auto-saves on change
---
## MenuContext (lib/menu-context.tsx)
**File:** lib/menu-context.tsx
**Description:** Provides shared category/menu state across components. Synchronizes Header mobile menu and Navbar sidebar selection.
### Provider Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| children | React.ReactNode | yes | Child components |
### Hook: useMenu()
Returns `MenuContextType` with:
| Property | Type | Description |
|----------|------|-------------|
| activeCategory | string | Currently selected category id (default: "all") |
| setActiveCategory | (id: string) => void | Update active category |
### Use Cases
- Sync Navbar sidebar and Header mobile menu category selection
- Clear search query when category changes (implemented in main page)
- Pass selected category to product filter logic
### Default Value
- `activeCategory: "all"` - Show all products by default
+486
View File
@@ -0,0 +1,486 @@
# Layouts Documentation
> Tài liệu chi tiết về layout components (Header, Footer) và responsive behavior
---
## Overview
The `layouts/` directory contains layout-level components used across all pages. These are included in the root layout and provide consistent header/footer across the application.
```
layouts/
├── header.tsx # Sticky top header with shop branding and auth
├── footer.tsx # Footer with shop info, social links, WiFi details
└── LAYOUTS.md # (this file)
```
---
## Header (layouts/header.tsx)
**File:** layouts/header.tsx
**Type:** Client component
**Description:** Sticky top navigation bar with brand info and authentication status display.
### Layout
```
┌─────────────────────────────────────────────────────┐
│ [Logo] [Shop Name] [Tagline] │ [Auth Status] │
└─────────────────────────────────────────────────────┘
height: 72px (var(--spacing-header-height))
```
**2-Column Layout:**
- **Left:** Shop branding (logo + name + tagline)
- **Right:** Auth status indicator
### Features
#### Logo & Branding
- Shop logo (40x40px)
- Shop name (bold text)
- Tagline (hidden on mobile < md, visible md+)
**Responsive:**
| Breakpoint | Logo | Name | Tagline |
|-----------|------|------|---------|
| < sm (640px) | Yes | Yes | Hidden |
| sm-md | Yes | Yes | Hidden |
| md+ (768px) | Yes | Yes | Visible |
#### Authentication Status
The header cycles through 3 auth states (for UI demo):
**State 1: Guest (Not logged in)**
```
[brown button] "Dang nhap"
```
- Guest state (user = null)
- Brown primary button
- Click: toggles to next state
**State 2: Manager**
```
[caramel/gold badge] "👔 Quản lý"
```
- Shows manager role
- Gold/caramel colored badge
- User tie icon
- Name: Nguyễn Văn An
**State 3: Staff**
```
[border button] "👤 [Name]"
```
- Shows staff role with avatar placeholder
- Bordered button style
- Name: Trần Thị Bình
- Click: toggles back to Guest state
### Responsive Behavior
| Breakpoint | Layout |
|-----------|--------|
| < sm | Stacked vertically |
| sm-md (640px) | Side-by-side, reduced spacing |
| md+ (768px) | Full width, comfortable spacing |
**Mobile (<640px):**
- Logo smaller
- Name only (no tagline)
- Auth button text hidden, icon shown
- Touch-friendly padding
**Desktop (≥640px):**
- Normal logo size
- Full layout with tagline
- Button with text and icon
- Comfortable spacing
### Styling
| Element | Classes |
|---------|---------|
| Header wrapper | `sticky top-0 z-50 bg-white shadow-md` |
| Container | `max-w-7xl mx-auto px-4 md:px-6 h-72px flex items-center` |
| Left section (brand) | `flex items-center gap-3 flex-1` |
| Right section (auth) | `flex items-center gap-3 shrink-0` |
| Logo image | `w-10 h-10 md:w-12 md:h-12` |
| Brand text | `font-bold text-sm md:text-base` |
| Tagline | `hidden md:block text-xs text-muted-foreground` |
| Auth button | `px-4 py-2 rounded-lg text-sm font-medium` |
### CSS Variables Used
```css
--spacing-header-height: 72px;
--color-primary: brown;
--color-primary-dark: darker brown;
--color-text-primary: text color;
--color-text-muted: gray text;
--color-shadow-sm: subtle shadow;
```
### Dependencies
- **next/image** - Logo image rendering
- **next/link** - Navigation links
- **lib/constants:** SHOP_INFO, MOCK_USERS
- **lib/types:** User
- **FontAwesome icons:** fa-sign-in-alt, fa-sign-out-alt, fa-user-tie, fa-user-circle
### Key Code Snippets
**Auth Demo State Machine:**
```typescript
const [user, setUser] = useState<User | null>(null);
const handleAuthClick = () => {
if (!user) {
setUser(MOCK_USERS.manager);
} else if (user.role === "manager") {
setUser(MOCK_USERS.staff);
} else {
setUser(null);
}
};
```
**Responsive Brand Text:**
```typescript
<div className="flex flex-col">
<span className="font-bold text-sm md:text-base">{SHOP_INFO.name}</span>
<span className="hidden md:block text-xs text-muted-foreground">
{SHOP_INFO.tagline}
</span>
</div>
```
---
## Footer (layouts/footer.tsx)
**File:** layouts/footer.tsx
**Type:** Client component (uses constants)
**Description:** Site footer with shop information, social links, and WiFi details.
### Layout
```
┌────────────────────────────────────────────┐
│ [Brand Info] │ [Social + WiFi] │
├────────────────────────────────────────────┤
│ © 2024 Coffee Shop. Made with ❤️ in VN │
└────────────────────────────────────────────┘
```
**12-Column Grid Layout:**
| Breakpoint | Brand Info | Social + WiFi |
|-----------|-----------|---------------|
| Mobile | col-span-12 | col-span-12 |
| md (768px) | col-span-6 | col-span-6 |
| lg+ (1024px) | col-span-6 | col-span-6 |
### Sections
#### 1. Brand Info (Left Section)
**Content:**
- Shop logo (40x40px)
- Shop name (bold)
- Tagline (gray text)
- Address with location icon
- Phone with phone icon
- Email with envelope icon
- Open hours with clock icon
**Responsive:**
```
Mobile:
└─ Logo
└─ Name & Tagline (stacked)
└─ Address
└─ Phone
└─ Email
└─ Open Hours
Desktop:
└─ Logo + Name/Tagline (flexbox, side-by-side)
└─ Address, Phone, Email, Hours (stacked below)
```
#### 2. Social Links (Top Right)
**Links:**
- Facebook icon → SHOP_INFO.facebook
- TikTok icon → SHOP_INFO.tiktok
- Website icon → SHOP_INFO.website
**Styling:**
- Icons in circle backgrounds
- Hover effect (color change)
- Flex row layout
- Centered alignment
#### 3. WiFi Card (Bottom Right)
**Content:**
- "📶 WiFi miễn phí" label
- Network name (monospace)
- Password (monospace, can be hidden/shown)
**Styling:**
- Light gray background
- Rounded borders
- Monospace font for credentials
- Eye icon toggle for password visibility
**Example:**
```
📶 WiFi miễn phí
┌────────────────────────┐
│ Network: CoffeeShop │
│ Password: •••••••• │
│ (eye icon) │
└────────────────────────┘
```
#### 4. Copyright Bar (Bottom)
**Content:**
- Copyright text: "© 2024 Coffee Shop"
- "Made with ❤️ in Vietnam"
- Centered
**Styling:**
- Small text
- Gray color
- Subtle separator line above
### Responsive Behavior
**Mobile (<768px):**
- Single column layout
- Stacked sections
- Full width
- Padding around edges
**Tablet (768px):**
- 2-column layout
- Brand info left, Social + WiFi right
- Equal width columns
**Desktop (≥768px):**
- 2-column layout with more spacing
- Brand info slightly smaller
- Comfortable padding
### Styling
| Element | Classes |
|---------|---------|
| Footer wrapper | `bg-gray-100 border-t` |
| Container | `max-w-7xl mx-auto px-4 py-8` |
| Grid | `grid grid-cols-12 gap-8` |
| Brand section | `col-span-12 md:col-span-6` |
| Social section | `col-span-12 md:col-span-6` |
| Logo | `w-10 h-10` |
| Info text | `text-sm text-gray-600` |
| Social icons | `w-10 h-10 rounded-full flex items-center justify-center` |
| WiFi card | `bg-white p-4 rounded-lg border` |
| Copyright bar | `border-t mt-8 pt-6 text-center text-xs text-gray-500` |
### CSS Variables Used
```css
--color-primary: brand color;
--color-text-secondary: secondary text color;
--color-text-muted: muted/gray text color;
--color-accent: accent color;
--color-border: border color;
--color-bg-*: background colors;
--color-shadow-sm: subtle shadow;
```
### Dependencies
- **next/image** - Shop logo
- **next/link** - Social links
- **lib/constants:** SHOP_INFO, SOCIAL_LINKS
- **FontAwesome icons:** location-dot, phone, envelope, clock, facebook, tiktok, globe, wifi, eye, eye-slash
### Key Code Snippets
**Brand Info Section:**
```typescript
<div className="flex gap-4">
<Image src={SHOP_INFO.logo} alt={SHOP_INFO.name} width={40} height={40} />
<div>
<h3 className="font-bold">{SHOP_INFO.name}</h3>
<p className="text-sm text-muted-foreground">{SHOP_INFO.tagline}</p>
<p className="text-sm mt-2">{SHOP_INFO.address}</p>
{/* etc */}
</div>
</div>
```
**Social Links:**
```typescript
<div className="flex gap-3">
<Link href={SOCIAL_LINKS.facebook} target="_blank" rel="noopener">
<i className="fab fa-facebook" />
</Link>
{/* etc */}
</div>
```
**WiFi Display:**
```typescript
<div className="bg-white p-4 rounded-lg">
<p className="font-semibold text-sm">📶 WiFi miễn phí</p>
<p className="font-mono text-xs mt-2">{SHOP_INFO.wifi.name}</p>
<p className="font-mono text-xs">
{showPassword ? SHOP_INFO.wifi.password : "••••••••"}
</p>
</div>
```
---
## Integration in Root Layout
**File:** app/layout.tsx
```typescript
export default function RootLayout({ children }) {
return (
<html>
<body>
<Header />
{children}
<Footer />
</body>
</html>
);
}
```
**Result:**
- Header: Always at top (sticky)
- Content: Takes full width between header/footer
- Footer: Always at bottom
---
## Responsive Design Patterns
### Header Responsive Pattern
```css
/* Mobile first */
.header {
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
/* Tablet+ */
@media (min-width: 640px) {
.header {
flex-direction: row;
justify-content: space-between;
padding: 1.5rem;
}
}
/* Desktop+ */
@media (min-width: 768px) {
.header {
padding: 2rem;
}
.tagline {
display: block; /* Show tagline on desktop */
}
}
```
### Footer Responsive Pattern
```css
/* Mobile: stacked */
.footer-grid {
grid-template-columns: 1fr;
}
/* Tablet: 2 columns */
@media (min-width: 768px) {
.footer-grid {
grid-template-columns: 1fr 1fr;
}
}
```
---
## Dark Mode Support
CSS variables are set up for dark mode support. To enable:
1. Add dark mode CSS variable overrides:
```css
@media (prefers-color-scheme: dark) {
:root {
--color-bg-main: #1a1a1a;
--color-text-primary: #ffffff;
/* etc */
}
}
```
2. Or use Tailwind dark class:
```html
<div className="dark:bg-gray-900 dark:text-white">
Content
</div>
```
---
## Accessibility
### Header
- Logo has alt text
- Auth button has aria-label
- Icons have semantic meaning
- Good contrast ratios
### Footer
- Headings use semantic tags
- Links have descriptive text
- Icons are decorative (aria-hidden)
- Monospace font for technical info (WiFi credentials)
### General
- Touch targets ≥ 48px on mobile
- Sufficient color contrast
- Semantic HTML structure
- ARIA labels where needed
---
## Best Practices
1. **Keep layouts simple:** Avoid complex nested layouts
2. **Responsive first:** Use mobile-first CSS approach
3. **Reuse components:** Use Header/Footer across all pages
4. **Props over hardcoding:** Use lib/constants for data
5. **Type safety:** Use TypeScript for component props
6. **Performance:** Optimize images with next/image
7. **Accessibility:** Add ARIA labels and semantic HTML
+461
View File
@@ -0,0 +1,461 @@
# Lib Documentation
> Tài liệu chi tiết về utilities, contexts, types, và constants
---
## Overview
The `lib/` directory contains shared logic, data models, and context providers used throughout the application.
```
lib/
├── types.ts # TypeScript interfaces and types
├── constants.ts # Mock data (products, shops, users, info)
├── auth-context.tsx # Authentication context & provider
├── cart-context.tsx # Shopping cart context & provider
├── menu-context.tsx # Menu/category context & provider
└── LIB.md # (this file)
```
---
## Types (lib/types.ts)
**Description:** Central TypeScript definitions used throughout the application.
### User Type
```typescript
type UserRole = "manager" | "staff" | "customer";
interface User {
id: number;
name: string;
role: UserRole;
avatar: string | null;
phone?: string;
}
```
**Usage:** Authentication context, header component, role-based UI
**Roles:**
- **manager** - Shop owner, full access to menu management and orders
- **staff** - Staff member, can view/process orders
- **customer** - Regular customer, can browse and order
---
### Menu Types
```typescript
interface MenuCategory {
id: string;
name: string;
icon: string; // FontAwesome class e.g. "fa-solid fa-mug-hot"
}
```
**Usage:** Sidebar navigation, category filter, product display
**Example Categories:**
- `all` - All products
- `cafe` - Coffee
- `tra` - Tea
- `sua-chua` - Yogurt
- `nuoc-ep` - Juice
- `latte` - Latte drinks
- `giai-khat` - Snacks
- `topping` - Toppings
---
### Product Type
```typescript
interface Product {
id: number;
name: string;
category: string; // matches MenuCategory.id
price: number;
image: string;
description: string;
available?: boolean;
}
```
**Usage:** Product grid display, cart items, filtering
**Key Fields:**
- `id` - Unique product identifier
- `name` - Display name in Vietnamese
- `category` - Category ID for filtering
- `price` - Price in VND
- `image` - URL or path to product image
- `description` - Short 1-2 sentence description
- `available` - If `false`, product won't show (defaults to `true`)
---
### Shop Info Type
```typescript
interface WifiInfo {
name: string;
password: string;
}
interface ShopInfo {
name: string;
tagline: string;
logo: string;
address: string;
phone: string;
managerPhone: string;
email: string;
wifi: WifiInfo;
openHours: string;
}
```
**Usage:** Header, footer, login page display
**Example:**
```typescript
const SHOP_INFO: ShopInfo = {
name: "Coffee Shop",
tagline: "Hương vị đậm đà Khoảnh khắc thư giãn",
logo: "/imgs/logo.png",
address: "123 Đường Nguyễn Huệ, Quận 1, TP. Hồ Chí Minh",
phone: "0901 234 567",
managerPhone: "0912 345 678",
email: "contact@coffeeshop.vn",
wifi: { name: "CoffeeShop_Free", password: "coffee2024" },
openHours: "07:00 22:00 (Thứ 2 Chủ nhật)",
};
```
---
### Social Links Type
```typescript
interface SocialLinks {
facebook: string;
tiktok: string;
website: string;
}
```
**Usage:** Footer component
---
### Shop (Discovery) Type
```typescript
interface Shop {
id: number;
name: string;
address: string;
image: string;
}
```
**Usage:** Feed page - list of coffee shops to discover
---
## Constants (lib/constants.ts)
**Description:** Mock data used throughout the application. Replace with API calls when backend is ready.
### SHOP_INFO
Single instance of shop information displayed in header, footer, and login page.
**Key Info Used:**
- Header: name, logo, phone
- Footer: all fields
- Login: logo, name, email
---
### SOCIAL_LINKS
Social media links for footer component.
```typescript
export const SOCIAL_LINKS: SocialLinks = {
facebook: "https://facebook.com/coffeeshop",
tiktok: "https://tiktok.com/@coffeeshop",
website: "/",
};
```
---
### MENU_CATEGORIES
Array of 8 product categories. Used in sidebar, mobile menu, and product filtering.
```typescript
export const MENU_CATEGORIES: MenuCategory[] = [
{ id: "all", name: "Tất cả", icon: "fa-solid fa-border-all" },
{ id: "cafe", name: "Cà Phê", icon: "fa-solid fa-mug-hot" },
{ id: "tra", name: "Trà", icon: "fa-solid fa-leaf" },
{ id: "sua-chua", name: "Sữa Chua", icon: "fa-solid fa-jar" },
{ id: "nuoc-ep", name: "Nước Ép", icon: "fa-solid fa-blender" },
{ id: "latte", name: "Latte", icon: "fa-solid fa-mug-saucer" },
{ id: "giai-khat", name: "Giải Khát / Ăn Vặt", icon: "fa-solid fa-ice-cream" },
{ id: "topping", name: "Topping", icon: "fa-solid fa-layer-group" },
];
```
**Usage:**
- Navbar sidebar category buttons
- Header mobile scrollable menu
- Product grid category filter
---
### MOCK_PRODUCTS
Array of 18 mock product items across all categories.
**Example Product:**
```typescript
{
id: 1,
name: "Cà Phê Đen",
category: "cafe",
price: 25000,
image: "/imgs/products/placeholder.jpg",
description: "Cà phê đen truyền thống, đậm đà hương vị Việt Nam, pha phin thủ công.",
available: true,
}
```
**Product Distribution:**
- Café: 4 items (Đen, Sữa, Bạc Xỉu, Trứng)
- Tea: 3 items (Đào Cam Sả, Matcha, Vải Hoa Nhài)
- Yogurt: 2 items (Trân Châu, Dâu)
- Juice: 2 items (Cam, Dưa Hấu)
- Latte: 2 items (Caramel, Vanilla)
- Snacks: 2 items (Bánh Mì, Bánh Flan)
- Toppings: 3 items (Trân Châu Đen, Thạch, Trân Châu Trắng)
**Price Range:** 10,000 - 45,000 VND
---
### MOCK_SHOPS
Array of 5 coffee shops for the feed/discovery page.
```typescript
{
id: 1,
name: "The Coffee House",
address: "86 Cao Thắng, Quận 3, TP. Hồ Chí Minh",
image: "https://images.unsplash.com/...", // Unsplash URL
}
```
**Shops:**
1. The Coffee House - Quận 3
2. Highlands Coffee - Quận 1
3. Phúc Long Heritage - Quận 1
4. Katinat Saigon Kafe - Quận 1
5. Trung Nguyên E-Coffee - Quận 1
**Usage:** Feed page grid display
---
### MOCK_USERS
Pre-configured user accounts for authentication demo.
```typescript
export const MOCK_USERS: Record<string, User> = {
manager: {
id: 1,
name: "Nguyễn Văn An",
role: "manager",
avatar: null,
},
staff: {
id: 2,
name: "Trần Thị Bình",
role: "staff",
avatar: null,
},
};
```
**Usage:** AuthContext for login demo
**Note:** More accounts defined in `auth-context.tsx` MOCK_AUTH_DB
---
## Auth Context (lib/auth-context.tsx)
See [COMPONENTS.md - AuthContext](../components/COMPONENTS.md#authcontext) for detailed documentation.
**Quick Summary:**
- Manages user login/logout/register
- Persists user in localStorage
- Provides user info to components via useAuth() hook
---
## Cart Context (lib/cart-context.tsx)
See [COMPONENTS.md - CartContext](../components/COMPONENTS.md#cartcontext) for detailed documentation.
**Quick Summary:**
- Manages shopping cart items and quantities
- Persists cart in localStorage
- Provides cart operations via useCart() hook
---
## Menu Context (lib/menu-context.tsx)
See [COMPONENTS.md - MenuContext](../components/COMPONENTS.md#menucontext) for detailed documentation.
**Quick Summary:**
- Shares active category state
- Syncs sidebar and mobile menu selection
- Provides activeCategory and setActiveCategory via useMenu() hook
---
## Integration Guide
### Using Types
```typescript
import type { User, Product, MenuCategory } from "@/lib/types";
```
### Using Constants
```typescript
import { MENU_CATEGORIES, MOCK_PRODUCTS, SHOP_INFO } from "@/lib/constants";
// In a component:
const products = MOCK_PRODUCTS.filter(p => p.category === "cafe");
const shopName = SHOP_INFO.name;
```
### Using Auth Context
```typescript
import { useAuth } from "@/lib/auth-context";
export default function MyComponent() {
const { user, login, logout } = useAuth();
if (!user) return <p>Not logged in</p>;
return <p>Welcome, {user.name}!</p>;
}
```
### Using Cart Context
```typescript
import { useCart } from "@/lib/cart-context";
import type { Product } from "@/lib/types";
export default function ProductCard({ product }: { product: Product }) {
const { addToCart } = useCart();
return (
<button onClick={() => addToCart(product)}>
Add to Cart
</button>
);
}
```
### Using Menu Context
```typescript
import { useMenu } from "@/lib/menu-context";
import { MENU_CATEGORIES } from "@/lib/constants";
export default function CategoryFilter() {
const { activeCategory, setActiveCategory } = useMenu();
return (
<div>
{MENU_CATEGORIES.map(cat => (
<button
key={cat.id}
onClick={() => setActiveCategory(cat.id)}
className={activeCategory === cat.id ? "active" : ""}
>
{cat.name}
</button>
))}
</div>
);
}
```
---
## Data Flow & Updates
### When to Update Constants
1. **Product List:** When adding/removing products
- Update MOCK_PRODUCTS array
- Or replace with API call in the future
2. **Categories:** When adding new product categories
- Update MENU_CATEGORIES array
- Update product category references
3. **Shop Info:** When shop details change
- Update SHOP_INFO object
- Automatically reflects in header/footer
4. **Social Links:** When social handles change
- Update SOCIAL_LINKS object
### Future API Integration
When backend is ready:
```typescript
// Replace MOCK_PRODUCTS with:
const [products, setProducts] = useState<Product[]>([]);
useEffect(() => {
fetch("/api/products")
.then(r => r.json())
.then(setProducts);
}, []);
// Replace MOCK_USERS with:
const login = async (username: string, password: string) => {
const res = await fetch("/api/auth/login", {
method: "POST",
body: JSON.stringify({ username, password })
});
return res.ok;
};
```
---
## Best Practices
1. **Import Types:** Always use `import type` for types to avoid runtime bloat
2. **Immutability:** Contexts return functions to update state, not direct mutations
3. **localStorage:** Keys are centralized (`coffee-shop-user`, `coffee-shop-cart`)
4. **Validation:** Contexts validate/sanitize data (e.g., filter invalid cart items)
5. **Default Values:** Contexts have sensible defaults (activeCategory: "all")