diff --git a/app/APP.md b/app/APP.md index 41c8548..38a4431 100644 --- a/app/APP.md +++ b/app/APP.md @@ -233,9 +233,9 @@ registration flow. Two-step process: phone verification → account creation. ### 4. Payment Page (app/(main)/payment/page.tsx) -**Route:** `/payment` -**Type:** Client component -**Description:** Payment/checkout page. Shows cart items in a table with quantity controls and a summary aside with payment actions. +**Route:** `/payment` **Type:** Client component **Description:** +Payment/checkout page. Shows cart items in a table with quantity controls and a +summary aside with payment actions. #### Key Features @@ -248,32 +248,43 @@ registration flow. Two-step process: phone verification → account creation. - **Invoice Aside:** - Sticky on desktop (top offset = header height + 1rem) - Shows total price - - Payment buttons: Tiền mặt, QR Code (UI-only; trigger review modal for customers) - - **"Đánh giá" button** — only visible when `user.role === "customer"`; opens ReviewModal - - **"Quay về" button** — links back to `/`; spans full width when review button is absent + - Payment buttons: Tiền mặt, QR Code (UI-only; trigger review modal for + customers) + - **"Đánh giá" button** — only visible when `user.role === "customer"`; opens + ReviewModal + - **"Quay về" button** — links back to `/`; spans full width when review + button is absent - **Review Modal (ReviewModal):** - - Opened when a customer clicks "Đánh giá" OR clicks a payment button (Tiền mặt/QR) - - Closed via "Quay lại" button, backdrop click, or after submitting and closing + - Opened when a customer clicks "Đánh giá" OR clicks a payment button (Tiền + mặt/QR) + - Closed via "Quay lại" button, backdrop click, or after submitting and + closing - See `components/ReviewModal.tsx` for full documentation #### Context Usage -- **useCart()** — items, totalPrice, increaseQty, decreaseQty, removeFromCart, setQuantity -- **useAuth()** — user (to check `user.role === "customer"` for review button visibility) +- **useCart()** — items, totalPrice, increaseQty, decreaseQty, removeFromCart, + setQuantity +- **useAuth()** — user (to check `user.role === "customer"` for review button + visibility) #### State Management ```tsx -isReviewOpen: boolean // Controls ReviewModal visibility -isCustomer: boolean // Derived from user.role === "customer" +isReviewOpen: boolean; // Controls ReviewModal visibility +isCustomer: boolean; // Derived from user.role === "customer" ``` #### Responsive Behavior -- **Mobile:** Single column layout, table scrolls horizontally, button labels hidden (icon only) -- **Desktop (lg+):** Button labels visible, aside becomes sticky sidebar (xl: w-85) -- **Review button grid:** When customer is logged in, 3 buttons in 2-column grid; "Quay về" occupies remaining space. Otherwise 2-column grid with "Quay về" spanning full width. +- **Mobile:** Single column layout, table scrolls horizontally, button labels + hidden (icon only) +- **Desktop (lg+):** Button labels visible, aside becomes sticky sidebar (xl: + w-85) +- **Review button grid:** When customer is logged in, 3 buttons in 2-column + grid; "Quay về" occupies remaining space. Otherwise 2-column grid with "Quay + về" spanning full width. --- diff --git a/components/COMPONENTS.md b/components/COMPONENTS.md index 7fbba4d..5648581 100644 --- a/components/COMPONENTS.md +++ b/components/COMPONENTS.md @@ -200,52 +200,60 @@ hover. ## ReviewModal -**File:** components/ReviewModal.tsx -**Description:** Modal for customer reviews. Shows a 5-star rating selector and a textarea for written feedback. After submission, displays a thank-you message. Appears on the payment page for customers (via a dedicated "Đánh giá" button) and also opens automatically after a successful payment action. +**File:** components/ReviewModal.tsx **Description:** Modal for customer +reviews. Shows a 5-star rating selector and a textarea for written feedback. +After submission, displays a thank-you message. Appears on the payment page for +customers (via a dedicated "Đánh giá" button) and also opens automatically after +a successful payment action. ### Props -| Prop | Type | Required | Default | Description | -| ------- | ---------- | -------- | ------- | ------------------------------------------ | -| isOpen | boolean | yes | - | Controls modal visibility | -| onClose | () => void | yes | - | Callback to close the modal & reset state | +| Prop | Type | Required | Default | Description | +| ------- | ---------- | -------- | ------- | ----------------------------------------- | +| isOpen | boolean | yes | - | Controls modal visibility | +| onClose | () => void | yes | - | Callback to close the modal & reset state | ### Behavior -- **Star rating:** 5 interactive stars; hover highlights up to hovered star, click locks selection. Disabled submit button until at least 1 star selected. +- **Star rating:** 5 interactive stars; hover highlights up to hovered star, + click locks selection. Disabled submit button until at least 1 star selected. - **Star labels:** 1 = Rất tệ, 2 = Tệ, 3 = Bình thường, 4 = Tốt, 5 = Xuất sắc - **Textarea:** Optional free-text review (placeholder in Vietnamese). - **Footer buttons:** - "Quay lại" — closes modal without submitting; resets all state. - "Xác nhận" — submits (UI-only); transitions to thank-you state. -- **Thank-you state:** Replaces form with "Cảm ơn quý khách" message + close button. +- **Thank-you state:** Replaces form with "Cảm ơn quý khách" message + close + button. - **Backdrop click:** Also closes the modal (same as "Quay lại"). -- **State reset:** All state (rating, hover, review text, submitted) resets on close. +- **State reset:** All state (rating, hover, review text, submitted) resets on + close. ### Styling | Element | Key classes | | --------------- | ----------------------------------------------------------------------- | -| Backdrop | fixed inset-0, bg-black/50 backdrop-blur-sm, z-50 | +| Backdrop | fixed inset-0, bg-black/50 backdrop-blur-sm, z-50 | | Modal panel | max-w-md, rounded-2xl, border --color-border-light, white bg, shadow-xl | -| Stars | text-3xl sm:text-4xl, hover:scale-110, active:scale-95 | +| Stars | text-3xl sm:text-4xl, hover:scale-110, active:scale-95 | | Active star | fa-solid fa-star text-yellow-400 | -| Inactive star | fa-regular fa-star text-(--color-border) | -| Textarea | rounded-xl, focus:ring with --color-primary/20 | -| Quay lại button | border --color-border, hover --color-border-light | -| Xác nhận button | bg --color-primary, disabled:opacity-50 | -| Thank-you icon | fa-solid fa-heart text-(--color-accent), --color-accent-light bg | +| Inactive star | fa-regular fa-star text-(--color-border) | +| Textarea | rounded-xl, focus:ring with --color-primary/20 | +| Quay lại button | border --color-border, hover --color-border-light | +| Xác nhận button | bg --color-primary, disabled:opacity-50 | +| Thank-you icon | fa-solid fa-heart text-(--color-accent), --color-accent-light bg | ### Responsive - Padding: `p-6 sm:p-8` — larger on sm+ screens - Stars: `text-3xl sm:text-4xl` -- Modal width: `w-full max-w-md` with `p-4` page padding — works on all screen sizes +- Modal width: `w-full max-w-md` with `p-4` page padding — works on all screen + sizes ### Dependencies - React useState -- FontAwesome icons (fa-star, fa-regular fa-star, fa-heart, fa-arrow-left, fa-check) +- FontAwesome icons (fa-star, fa-regular fa-star, fa-heart, fa-arrow-left, + fa-check) - Tailwind CSS + CSS custom properties from globals.css ### Usage in Payment Page @@ -255,14 +263,14 @@ hover. const [isReviewOpen, setIsReviewOpen] = useState(false); // Button in payment aside (only visible to customers) - +; // Payment buttons (Tiền mặt / QR Code) also open the modal for customers const handlePayment = () => { if (isCustomer) setIsReviewOpen(true); }; - setIsReviewOpen(false)} /> + setIsReviewOpen(false)} />; ``` --- diff --git a/components/ReviewModal.tsx b/components/ReviewModal.tsx index 738fee7..0b3e41b 100644 --- a/components/ReviewModal.tsx +++ b/components/ReviewModal.tsx @@ -52,7 +52,7 @@ export default function ReviewModal({ isOpen, onClose }: ReviewModalProps) {

Cảm ơn quý khách

@@ -71,7 +71,7 @@ export default function ReviewModal({ isOpen, onClose }: ReviewModalProps) { <>

Đánh giá của bạn

@@ -138,7 +138,7 @@ export default function ReviewModal({ isOpen, onClose }: ReviewModalProps) { onChange={(e) => setReview(e.target.value)} placeholder="Chia sẻ cảm nhận của bạn về đồ uống, dịch vụ..." rows={4} - className="w-full resize-none rounded-xl border border-(--color-border) bg-transparent px-3 py-2.5 text-sm text-foreground placeholder:text-(--color-text-muted) focus:border-(--color-primary) focus:outline-none focus:ring-2 focus:ring-(--color-primary)/20 transition-colors" + className="text-foreground w-full resize-none rounded-xl border border-(--color-border) bg-transparent px-3 py-2.5 text-sm transition-colors placeholder:text-(--color-text-muted) focus:border-(--color-primary) focus:ring-2 focus:ring-(--color-primary)/20 focus:outline-none" /> @@ -147,7 +147,7 @@ export default function ReviewModal({ isOpen, onClose }: ReviewModalProps) {