fix: OrderForm variable product issues - empty colors, desktop dialog, duplicate handling

**Issues Fixed:**

1. **Empty Color Values**
   - Problem: Variation attributes showed 'Color:' with no value
   - Cause: Backend returned empty strings for some attributes
   - Fix: Filter empty values with .filter(([_, value]) => value)
   - Result: Only non-empty attributes displayed

2. **Desktop Should Use Dialog**
   - Problem: Both desktop and mobile used Drawer (bottom sheet)
   - Expected: Desktop = Dialog (modal), Mobile = Drawer
   - Fix: Added useMediaQuery hook, conditional rendering
   - Pattern: Same as Settings pages (Payments, Shipping, etc.)

3. **Duplicate Product+Variation Handling**
   - Problem: Same product+variation created new row each time
   - Expected: Should increment quantity of existing row
   - Fix: Check for existing item before adding
   - Logic: findIndex by product_id + variation_id, then increment qty

**Changes to OrderForm.tsx:**
- Added Dialog and useMediaQuery imports
- Added isDesktop detection
- Split variation selector into Desktop (Dialog) and Mobile (Drawer)
- Fixed variationLabel to filter empty values
- Added duplicate check logic before adding to cart
- If exists: increment qty, else: add new item

**Changes to PROJECT_SOP.md:**
- Added Responsive Modal Pattern section
- Documented Dialog/Drawer pattern with code example
- Added rule 3: Same product+variation = increment qty
- Added rule 6: Filter empty attribute values
- Added rule 7: Responsive modals (Dialog/Drawer)

**Result:**
 Color values display correctly (empty values filtered)
 Desktop uses Dialog (centered modal)
 Mobile uses Drawer (bottom sheet)
 Duplicate product+variation increments quantity
 UX matches Tokopedia/Shopee pattern
 Follows Settings page modal pattern
This commit is contained in:
dwindown
2025-11-20 10:44:48 +07:00
parent dfbd992a22
commit be69b40237
4 changed files with 176 additions and 24 deletions

View File

@@ -412,6 +412,40 @@ All CRUD list pages MUST follow these consistent UI patterns:
When adding products to orders, variable products MUST follow the Tokopedia/Shopee pattern:
**Responsive Modal Pattern:**
- **Desktop:** Use `Dialog` component (centered modal)
- **Mobile:** Use `Drawer` component (bottom sheet)
- **Detection:** Use `useMediaQuery("(min-width: 768px)")`
**Implementation:**
```tsx
const isDesktop = useMediaQuery("(min-width: 768px)");
{/* Desktop: Dialog */}
{selectedProduct && isDesktop && (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>{product.name}</DialogTitle>
</DialogHeader>
{/* Variation list */}
</DialogContent>
</Dialog>
)}
{/* Mobile: Drawer */}
{selectedProduct && !isDesktop && (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>{product.name}</DrawerTitle>
</DrawerHeader>
{/* Variation list */}
</DrawerContent>
</Drawer>
)}
```
**Desktop Pattern:**
```
[Search Product...]
@@ -438,7 +472,6 @@ When adding products to orders, variable products MUST follow the Tokopedia/Shop
✓ Anker Earbuds
Black Rp296,000 [-] 1 [+] [🗑️]
```
**Rules:**
1. ✅ Each variation is a **separate line item**
@@ -447,6 +480,8 @@ When adding products to orders, variable products MUST follow the Tokopedia/Shop
4. ✅ Mobile: Click variation to open drawer for selection
5. ❌ Don't auto-select first variation
6. ❌ Don't hide variation selector
7. ✅ **Duplicate Handling**: Same product + same variation = increment quantity (NOT new row)
8. ✅ **Empty Attribute Values**: Filter empty attribute values - Use `.filter()` to remove empty strings
**Implementation:**
- Product search shows variable products