From ff485a889a62fe625f34eb52107503dda432d852 Mon Sep 17 00:00:00 2001 From: dwindown Date: Sat, 8 Nov 2025 14:02:02 +0700 Subject: [PATCH] fix: OrderCard layout and filter UX improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed all issues from user feedback round 2. 1. OrderCard Layout - Icon Inline with 2 Lines Problem: Too much vertical space wasted, icon in separate column New Layout: ┌─────────────────────────────────┐ │ ☐ [Icon] Nov 04, 2025, 11:44 PM │ ← Line 1: Date (small) │ #337 →│ ← Line 2: Order# (big) │ Dwindi Ramadhana │ ← Line 3: Customer │ 1 item · Test Digital │ ← Line 4: Items │ Rp64.500 Completed │ ← Line 5: Total + Status └─────────────────────────────────┘ Changes: - Icon inline with first 2 lines (date + order#) - Date: text-xs, muted, top line - Order#: text-lg, bold, second line - Better space utilization - Reduced padding: p-4 → p-3 - Cleaner hierarchy Result: More compact, better use of horizontal space! 2. FilterBottomSheet Backdrop Margin Problem: Backdrop had top margin from parent space-y-4 Fix: - Added !m-0 to backdrop to override parent spacing - Backdrop now properly covers entire screen Result: Clean full-screen overlay! 3. DateRange Component Fixes Problem: - Horizontal overflow when custom dates selected - WP forms.css overriding input styles - Redundant "Apply" button Fixes: a) Layout: - Changed from horizontal to vertical (flex-col) - Full width inputs (w-full) - Prevents overflow in bottom sheet b) Styling: - Override WP forms.css with shadcn classes - border-input, bg-background, ring-offset-background - focus-visible:ring-2 focus-visible:ring-ring - WebkitAppearance: none to remove browser defaults - Custom calendar picker cursor c) Instant Filtering: - Removed "Apply" button - Added start/end to useEffect deps - Filters apply immediately on date change Result: Clean vertical layout, proper styling, instant filtering! 4. Filter Bottom Sheet UX Problem: Apply/Cancel buttons confusing (filters already applied) Industry Standard: Instant filtering on mobile - Gmail: Filters apply instantly - Amazon: Filters apply instantly - Airbnb: Filters apply instantly Solution: - Removed "Apply" button - Removed "Cancel" button - Keep "Clear all filters" button (only when filters active) - Filters apply instantly on change - User can close sheet anytime (tap backdrop or X) Result: Modern, intuitive mobile filter UX! Files Modified: - routes/Orders/components/OrderCard.tsx - routes/Orders/components/FilterBottomSheet.tsx - components/filters/DateRange.tsx Summary: ✅ OrderCard: Icon inline, better space usage ✅ Backdrop: No margin, full coverage ✅ DateRange: Vertical layout, no overflow, proper styling ✅ Filters: Instant application, industry standard UX ✅ Clean, modern, mobile-first! 🎯 --- .../src/components/filters/DateRange.tsx | 23 +++-- .../Orders/components/FilterBottomSheet.tsx | 31 +++---- .../routes/Orders/components/OrderCard.tsx | 89 ++++++++++--------- 3 files changed, 69 insertions(+), 74 deletions(-) diff --git a/admin-spa/src/components/filters/DateRange.tsx b/admin-spa/src/components/filters/DateRange.tsx index d6daf3e..50df1c5 100644 --- a/admin-spa/src/components/filters/DateRange.tsx +++ b/admin-spa/src/components/filters/DateRange.tsx @@ -47,12 +47,12 @@ export default function DateRange({ value, onChange }: Props) { setEnd(pr.date_end); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [preset]); + }, [preset, start, end]); return ( -
+
{preset === "custom" && ( -
+
setStart(e.target.value || undefined)} + placeholder={__("Start date")} /> - {__("to")} setEnd(e.target.value || undefined)} + placeholder={__("End date")} /> -
)}
diff --git a/admin-spa/src/routes/Orders/components/FilterBottomSheet.tsx b/admin-spa/src/routes/Orders/components/FilterBottomSheet.tsx index 7cdffe9..d3243f0 100644 --- a/admin-spa/src/routes/Orders/components/FilterBottomSheet.tsx +++ b/admin-spa/src/routes/Orders/components/FilterBottomSheet.tsx @@ -42,9 +42,9 @@ export function FilterBottomSheet({ return ( <> - {/* Backdrop */} + {/* Backdrop - use !m-0 to override parent spacing */}
@@ -67,7 +67,7 @@ export function FilterBottomSheet({
{/* Content */} -
+
{/* Status Filter */}
@@ -129,24 +129,21 @@ export function FilterBottomSheet({
- {/* Footer */} -
- {hasActiveFilters && ( + {/* Footer - Only show Reset if filters active */} + {hasActiveFilters && ( +
- )} - -
+
+ )}
); diff --git a/admin-spa/src/routes/Orders/components/OrderCard.tsx b/admin-spa/src/routes/Orders/components/OrderCard.tsx index 76d4e03..fae8f6e 100644 --- a/admin-spa/src/routes/Orders/components/OrderCard.tsx +++ b/admin-spa/src/routes/Orders/components/OrderCard.tsx @@ -29,9 +29,9 @@ export function OrderCard({ order, selected, onSelect, currencyConfig }: OrderCa return ( -
+
{/* Checkbox */} {onSelect && (
)} - {/* Icon */} -
- -
+
+ {/* Icon - inline with first 2 lines */} +
+
+ {/* Line 2: Order Number (big) */} + #{order.number} +
- {/* Content */} -
- {/* Order Number & Status */} -
-

#{order.number}

- - {order.status || 'unknown'} - -
- - {/* Customer */} -
- {order.customer || __('Guest')} -
- - {/* Items Brief */} - {order.items_brief && ( -
- {order.items_count} {order.items_count === 1 ? __('item') : __('items')} · {order.items_brief} +
+ {/* Line 1: Date (small) */} +
+ {formatRelativeOrDate(order.date_ts)} +
+
- )} - {/* Date & Total */} -
- - {formatRelativeOrDate(order.date_ts)} - - - {formatMoney(order.total, { - currency: order.currency || currencyConfig.currency, - symbol: order.currency_symbol || currencyConfig.symbol, - thousandSep: currencyConfig.thousand_sep, - decimalSep: currencyConfig.decimal_sep, - position: currencyConfig.position, - decimals: currencyConfig.decimals, - })} - -
+ {/* Content - 2 lines inline with icon */} +
+ {/* Line 3: Customer */} +
+ {order.customer || __('Guest')} +
+ + {/* Line 4: Items */} + {order.items_brief && ( +
+ {order.items_count} {order.items_count === 1 ? __('item') : __('items')} · {order.items_brief} +
+ )} + + {/* Line 5: Total & Status */} +
+ + {formatMoney(order.total, { + currency: order.currency || currencyConfig.currency, + symbol: order.currency_symbol || currencyConfig.symbol, + thousandSep: currencyConfig.thousand_sep, + decimalSep: currencyConfig.decimal_sep, + position: currencyConfig.position, + decimals: currencyConfig.decimals, + })} + +
+
+ {/* Chevron */} - +
);