chore: release [ci skip]

This commit is contained in:
gitea-actions
2026-03-25 03:07:52 +00:00
parent 372391381f
commit 6a6afc4436
21 changed files with 851 additions and 828 deletions
+52 -47
View File
@@ -1,40 +1,44 @@
# Components Documentation
> Whenever you create a new component in the components/ directory, automatically append a new section following the template below.
> Whenever you create a new component in the components/ directory,
> automatically append a new section following the template below.
---
## CartProduct
**File:** components/CartProduct.tsx
**Description:** Product card component. Displays product image, name, description, formatted price, and a Buy button. Width is controlled by the parent grid (w-full), not the card itself.
**File:** components/CartProduct.tsx **Description:** Product card component.
Displays product image, name, description, formatted price, and a Buy button.
Width is controlled by the parent grid (w-full), not the card itself.
### Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| image | string | yes | - | URL/path to product image (Next.js Image) |
| imageAlt | string | no | Anh san pham | Alt text for accessibility |
| productName | string | yes | - | Product display name |
| price | number or string | yes | - | If number: auto-formatted to VND. If string: rendered as-is |
| description | string | yes | - | Short description, clamped to 2 lines |
| onBuy | () => void | no | undefined | Callback when Buy button is clicked |
| Prop | Type | Required | Default | Description |
| ----------- | ---------------- | -------- | ------------ | ----------------------------------------------------------- |
| image | string | yes | - | URL/path to product image (Next.js Image) |
| imageAlt | string | no | Anh san pham | Alt text for accessibility |
| productName | string | yes | - | Product display name |
| price | number or string | yes | - | If number: auto-formatted to VND. If string: rendered as-is |
| description | string | yes | - | Short description, clamped to 2 lines |
| onBuy | () => void | no | undefined | Callback when Buy button is clicked |
### Internal Logic
- formattedPrice: number -> toLocaleString(vi-VN, { style: currency, currency: VND })
- Image fallback: fa-solid fa-mug-hot icon shown behind image; if image fails onError hides the img element
- formattedPrice: number -> toLocaleString(vi-VN, { style: currency, currency:
VND })
- Image fallback: fa-solid fa-mug-hot icon shown behind image; if image fails
onError hides the img element
### Styling (CSS variables)
| Element | Key classes |
|---------|-------------|
| Element | Key classes |
| ------------ | ------------------------------------------------------------------ |
| Card wrapper | flex flex-col w-full rounded-2xl, shadow uses --color-shadow-sm/md |
| Image area | relative w-full h-36, bg --color-border-light |
| Product name | font-bold text-sm, color --color-text-primary, line-clamp-1 |
| Description | text-xs, color --color-text-muted, line-clamp-2 |
| Price | text-sm font-bold, color --color-primary |
| Buy button | bg --color-primary, hover --color-primary-dark, active:scale-95 |
| Image area | relative w-full h-36, bg --color-border-light |
| Product name | font-bold text-sm, color --color-text-primary, line-clamp-1 |
| Description | text-xs, color --color-text-muted, line-clamp-2 |
| Price | text-sm font-bold, color --color-primary |
| Buy button | bg --color-primary, hover --color-primary-dark, active:scale-95 |
### Dependencies
@@ -52,17 +56,17 @@
## Navbar
**File:** components/Navbar.tsx
**Description:** Left sidebar with collapsible category filter. Sticky below header, full viewport height minus header.
**File:** components/Navbar.tsx **Description:** Left sidebar with collapsible
category filter. Sticky below header, full viewport height minus header.
### Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| isOpen | boolean | yes | - | true = expanded (240px), false = collapsed (64px) |
| onToggle | () => void | yes | - | Toggle expand/collapse |
| activeCategory | string | no | all | Currently selected category id |
| onCategoryChange | (id: string) => void | no | undefined | Fired when user clicks a category |
| Prop | Type | Required | Default | Description |
| ---------------- | -------------------- | -------- | --------- | ------------------------------------------------- |
| isOpen | boolean | yes | - | true = expanded (240px), false = collapsed (64px) |
| onToggle | () => void | yes | - | Toggle expand/collapse |
| activeCategory | string | no | all | Currently selected category id |
| onCategoryChange | (id: string) => void | no | undefined | Fired when user clicks a category |
### Behavior
@@ -74,11 +78,11 @@
### Styling
| Element | Key classes |
|---------|-------------|
| Aside | sticky, border-r --color-border, bg --color-bg-sidebar |
| Toggle button | w-8 h-8 rounded-lg, hover bg --color-border-light |
| Active item | bg --color-primary text-white shadow-sm |
| Element | Key classes |
| ------------- | ----------------------------------------------------------- |
| Aside | sticky, border-r --color-border, bg --color-bg-sidebar |
| Toggle button | w-8 h-8 rounded-lg, hover bg --color-border-light |
| Active item | bg --color-primary text-white shadow-sm |
| Inactive item | hover bg --color-border-light, color --color-text-secondary |
### Dependencies
@@ -92,8 +96,9 @@
## Header (layouts/header.tsx)
**File:** layouts/header.tsx
**Description:** Sticky top bar. 2-column layout: Brand (left) + Auth button (right). Auth cycles Guest -> Manager -> Staff -> Guest for UI demo.
**File:** layouts/header.tsx **Description:** Sticky top bar. 2-column layout:
Brand (left) + Auth button (right). Auth cycles Guest -> Manager -> Staff ->
Guest for UI demo.
### Props
@@ -101,17 +106,17 @@ None - reads SHOP_INFO and MOCK_USERS from lib/constants directly.
### Internal State
| State | Type | Description |
|-------|------|-------------|
| user | User or null | Current demo user. null = guest |
| State | Type | Description |
| ----- | ------------ | ------------------------------- |
| user | User or null | Current demo user. null = guest |
### Auth States
| State | Appearance |
|-------|------------|
| State | Appearance |
| ------------ | ------------------------------------- |
| Guest (null) | Brown primary button, Dang nhap label |
| Manager | Gold/caramel badge with user-tie icon |
| Staff | Avatar circle + name, bordered button |
| Manager | Gold/caramel badge with user-tie icon |
| Staff | Avatar circle + name, bordered button |
### Responsive
@@ -130,8 +135,8 @@ None - reads SHOP_INFO and MOCK_USERS from lib/constants directly.
## Footer (layouts/footer.tsx)
**File:** layouts/footer.tsx
**Description:** Site footer with 12-column grid. 3 sections: Brand info, Social links, WiFi card.
**File:** layouts/footer.tsx **Description:** Site footer with 12-column grid. 3
sections: Brand info, Social links, WiFi card.
### Props
@@ -139,9 +144,9 @@ None - reads SHOP_INFO and SOCIAL_LINKS from lib/constants directly.
### Layout
| Section | Mobile | md | lg/xl |
|---------|--------|----|-------|
| Brand info | col-span-12 | col-span-6 | col-span-8/6 |
| Section | Mobile | md | lg/xl |
| ------------- | ----------- | ---------- | ------------ |
| Brand info | col-span-12 | col-span-6 | col-span-8/6 |
| Social + WiFi | col-span-12 | col-span-6 | col-span-4/6 |
### Sections