docs: Update PROJECT_SOP and add customer data flow analysis
1. Updated PROJECT_SOP.md: ✅ Added mobile card linkable pattern with full example ✅ Added submenu mobile hiding rules and behavior matrix ✅ Documented stopPropagation pattern for checkboxes ✅ Added ChevronRight icon requirement ✅ Documented active:scale animation for tap feedback ✅ Added spacing rules (space-y-3 for cards) 2. Created CUSTOMER_DATA_FLOW_ANALYSIS.md: ✅ Comprehensive analysis of customer data flow ✅ Documented 2 customer types: Guest vs Site Member ✅ Identified validation issues in OrdersController ✅ Found weak ! empty() checks allowing bad data ✅ Documented inconsistent validation between controllers ✅ Created action items for fixes ✅ Added test cases for all scenarios Key Findings: ❌ OrdersController uses ! empty() - allows 'Indonesia' string ❌ No phone number sanitization in order creation ❌ No validation that phone is actually a phone number ✅ CustomersController has better validation (isset + sanitize) Next: Investigate source of 'Indonesia' value and implement fixes
This commit is contained in:
@@ -263,6 +263,39 @@ When updating an existing module to follow this pattern:
|
||||
</SubMenu>
|
||||
```
|
||||
|
||||
**Submenu Mobile Behavior:**
|
||||
|
||||
To reduce clutter on mobile detail/new/edit pages, submenu MUST be hidden on mobile for these pages:
|
||||
|
||||
```typescript
|
||||
// In SubmenuBar.tsx
|
||||
const isDetailPage = /\/(orders|products|coupons|customers)\/(?:new|\d+(?:\/edit)?)$/.test(pathname);
|
||||
const hiddenOnMobile = isDetailPage ? 'hidden md:block' : '';
|
||||
|
||||
return (
|
||||
<div className={`border-b border-border bg-background ${hiddenOnMobile}`}>
|
||||
{/* Submenu items */}
|
||||
</div>
|
||||
);
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
1. ✅ **Hide on mobile** for detail/new/edit pages (has own tabs + back button)
|
||||
2. ✅ **Show on desktop** for all pages (useful for quick navigation)
|
||||
3. ✅ **Show on mobile** for index pages only (list views)
|
||||
4. ✅ **Use regex pattern** to detect detail/new/edit pages
|
||||
5. ❌ **Never hide on desktop** - always useful for navigation
|
||||
6. ❌ **Never show on mobile detail pages** - causes clutter
|
||||
|
||||
**Behavior Matrix:**
|
||||
|
||||
| Page Type | Mobile | Desktop | Reason |
|
||||
|-----------|--------|---------|--------|
|
||||
| Index (`/orders`) | ✅ Show | ✅ Show | Main navigation |
|
||||
| New (`/orders/new`) | ❌ Hide | ✅ Show | Has form tabs + back button |
|
||||
| Edit (`/orders/123/edit`) | ❌ Hide | ✅ Show | Has form tabs + back button |
|
||||
| Detail (`/orders/123`) | ❌ Hide | ✅ Show | Has detail tabs + back button |
|
||||
|
||||
**Toolbar (React):**
|
||||
```typescript
|
||||
<Toolbar>
|
||||
@@ -394,18 +427,55 @@ All CRUD list pages MUST follow these consistent UI patterns:
|
||||
</tr>
|
||||
```
|
||||
|
||||
**Mobile Card Pattern:**
|
||||
**Mobile Card Pattern (Linkable):**
|
||||
|
||||
Mobile cards MUST be fully tappable (whole card is a link) for better UX:
|
||||
|
||||
```tsx
|
||||
<div className="md:hidden space-y-2">
|
||||
<div className="md:hidden space-y-3">
|
||||
{items.map(item => (
|
||||
<Card key={item.id} className="p-4">
|
||||
{/* Card content */}
|
||||
</Card>
|
||||
<Link
|
||||
key={item.id}
|
||||
to={`/entity/${item.id}/edit`}
|
||||
className="block bg-card border border-border rounded-xl p-3 hover:bg-accent/50 transition-colors active:scale-[0.98] active:transition-transform shadow-sm"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
{/* Checkbox with stopPropagation */}
|
||||
<div onClick={(e) => { e.preventDefault(); e.stopPropagation(); onSelect(item.id); }}>
|
||||
<Checkbox checked={selected} className="w-5 h-5" />
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="font-bold text-base leading-tight mb-1">{item.name}</h3>
|
||||
<div className="text-sm text-muted-foreground truncate mb-2">{item.description}</div>
|
||||
<div className="flex items-center gap-3 text-xs text-muted-foreground mb-1">
|
||||
<span>{item.stats}</span>
|
||||
</div>
|
||||
<div className="font-bold text-lg tabular-nums text-primary">{item.amount}</div>
|
||||
</div>
|
||||
|
||||
{/* Chevron */}
|
||||
<ChevronRight className="w-5 h-5 text-muted-foreground flex-shrink-0" />
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
**Card Rules:**
|
||||
1. ✅ **Whole card is Link** - Better mobile UX (single tap to view/edit)
|
||||
2. ✅ **Use `space-y-3`** - Consistent spacing between cards
|
||||
3. ✅ **Checkbox stopPropagation** - Prevent navigation when selecting
|
||||
4. ✅ **ChevronRight icon** - Visual indicator card is tappable
|
||||
5. ✅ **Active scale animation** - `active:scale-[0.98]` for tap feedback
|
||||
6. ✅ **Hover effect** - `hover:bg-accent/50` for desktop hover
|
||||
7. ✅ **Shadow** - `shadow-sm` for depth
|
||||
8. ✅ **Rounded corners** - `rounded-xl` for modern look
|
||||
9. ❌ **Never use separate edit button** - Whole card should be tappable
|
||||
10. ❌ **Never use `space-y-2`** - Use `space-y-3` for consistency
|
||||
|
||||
**Table Rules:**
|
||||
1. ✅ **Always use `p-3`** for table cells (NOT `px-3 py-2`)
|
||||
2. ✅ **Always add `hover:bg-muted/30`** to body rows
|
||||
3. ✅ **Always use `bg-muted/50`** for table headers
|
||||
@@ -419,6 +489,7 @@ All CRUD list pages MUST follow these consistent UI patterns:
|
||||
- Desktop: Show table with `hidden md:block`
|
||||
- Mobile: Show cards with `md:hidden`
|
||||
- Both views must support same actions (select, edit, delete)
|
||||
- Cards must be linkable (whole card tappable)
|
||||
|
||||
#### Variable Product Handling in Order Forms
|
||||
|
||||
|
||||
Reference in New Issue
Block a user