feat(ui): Make cards linkable and hide submenu on detail pages
Improved mobile UX matching Orders/Products pattern Issue 1: Coupons and Customers cards not linkable ❌ Cards had separate checkbox and edit button ❌ Inconsistent with Orders/Products beautiful card design ❌ Less intuitive UX (extra tap required) Issue 2: Submenu showing on detail/new/edit pages ❌ Submenu tabs visible on mobile detail/new/edit pages ❌ Distracting and annoying (user feedback) ❌ Redundant (page has own tabs + back button) Changes Made: 1. Created CouponCard Component: ✅ Linkable card matching OrderCard/ProductCard pattern ✅ Whole card is tappable (better mobile UX) ✅ Checkbox with stopPropagation for selection ✅ Chevron icon indicating it's tappable ✅ Beautiful layout: Badge + Description + Usage + Amount ✅ Active scale animation on tap ✅ Hover effects 2. Updated Coupons/index.tsx: ✅ Replaced old card structure with CouponCard ✅ Fixed desktop edit link: /coupons/${id} → /coupons/${id}/edit ✅ Changed spacing: space-y-2 → space-y-3 (consistent with Orders) ✅ Cleaner, more maintainable code 3. Updated Customers/index.tsx: ✅ Made cards linkable (whole card is Link) ✅ Added ChevronRight icon ✅ Checkbox with stopPropagation ✅ Better layout: Name + Email + Stats + Total Spent ✅ Changed spacing: space-y-2 → space-y-3 ✅ Matches Orders/Products card design 4. Updated SubmenuBar.tsx: ✅ Hide on mobile for detail/new/edit pages ✅ Show on desktop (still useful for navigation) ✅ Regex pattern: /\/(orders|products|coupons|customers)\/(?:new|\d+(?:\/edit)?)$/ ✅ Applied via: hidden md:block class Card Pattern Comparison: Before (Coupons/Customers): After (All modules): Submenu Behavior: Mobile: - Index pages: ✅ Show submenu [All | New] - Detail/New/Edit: ❌ Hide submenu (has own tabs + back button) Desktop: - All pages: ✅ Show submenu (useful for quick navigation) Benefits: ✅ Consistent UX across all modules ✅ Better mobile experience (fewer taps) ✅ Less visual clutter on detail pages ✅ Cleaner, more intuitive navigation ✅ Matches industry standards (Shopify, WooCommerce) Result: Mobile UX now matches the beautiful Orders/Products design!
This commit is contained in:
@@ -11,7 +11,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Card } from '@/components/ui/card';
|
||||
import { ErrorCard } from '@/components/ErrorCard';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { RefreshCw, Trash2, Search, User } from 'lucide-react';
|
||||
import { RefreshCw, Trash2, Search, User, ChevronRight } from 'lucide-react';
|
||||
import { formatMoney } from '@/lib/currency';
|
||||
|
||||
export default function CustomersIndex() {
|
||||
@@ -226,7 +226,7 @@ export default function CustomersIndex() {
|
||||
</div>
|
||||
|
||||
{/* Mobile: Cards */}
|
||||
<div className="md:hidden space-y-2">
|
||||
<div className="md:hidden space-y-3">
|
||||
{customers.length === 0 ? (
|
||||
<Card className="p-8 text-center text-muted-foreground">
|
||||
<User className="w-12 h-12 mx-auto mb-2 opacity-50" />
|
||||
@@ -234,26 +234,55 @@ export default function CustomersIndex() {
|
||||
</Card>
|
||||
) : (
|
||||
customers.map((customer) => (
|
||||
<Card key={customer.id} className="p-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(customer.id)}
|
||||
onCheckedChange={() => toggleSelection(customer.id)}
|
||||
/>
|
||||
<Link
|
||||
key={customer.id}
|
||||
to={`/customers/${customer.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 */}
|
||||
<div
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
toggleSelection(customer.id);
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedIds.includes(customer.id)}
|
||||
aria-label={__('Select customer')}
|
||||
className="w-5 h-5"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<Link to={`/customers/${customer.id}/edit`} className="font-medium hover:underline block">
|
||||
{/* Line 1: Name */}
|
||||
<h3 className="font-bold text-base leading-tight mb-1">
|
||||
{customer.display_name || `${customer.first_name} ${customer.last_name}`}
|
||||
</Link>
|
||||
<p className="text-sm text-muted-foreground truncate">{customer.email}</p>
|
||||
<div className="flex gap-4 mt-2 text-sm">
|
||||
</h3>
|
||||
|
||||
{/* Line 2: Email */}
|
||||
<div className="text-sm text-muted-foreground truncate mb-2">
|
||||
{customer.email}
|
||||
</div>
|
||||
|
||||
{/* Line 3: Stats */}
|
||||
<div className="flex items-center gap-3 text-xs text-muted-foreground mb-1">
|
||||
<span>{customer.stats?.total_orders || 0} {__('orders')}</span>
|
||||
<span className="font-medium">
|
||||
{customer.stats?.total_spent ? formatMoney(customer.stats.total_spent) : '—'}
|
||||
</span>
|
||||
<span>{new Date(customer.registered).toLocaleDateString()}</span>
|
||||
</div>
|
||||
|
||||
{/* Line 4: Total Spent */}
|
||||
<div className="font-bold text-lg tabular-nums text-primary">
|
||||
{customer.stats?.total_spent ? formatMoney(customer.stats.total_spent) : '—'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Chevron */}
|
||||
<ChevronRight className="w-5 h-5 text-muted-foreground flex-shrink-0" />
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user