feat: Implement smart back navigation with fallback across all detail/edit pages
Implemented context-aware back button that respects user's navigation path:
Pattern:
```typescript
const handleBack = () => {
if (window.history.state?.idx > 0) {
navigate(-1); // Go back in history
} else {
navigate('/fallback'); // Safe fallback
}
};
```
Updated Pages:
✅ Orders/Detail.tsx → Fallback: /orders
✅ Orders/Edit.tsx → Fallback: /orders/:id
✅ Customers/Detail.tsx → Fallback: /customers
✅ Customers/Edit.tsx → Fallback: /customers
✅ Products/Edit.tsx → Fallback: /products
✅ Coupons/Edit.tsx → Fallback: /coupons
User Flow Examples:
1. Normal Navigation (History Available):
Customers Index → Customer Detail → Orders Tab → Order Detail
→ Click Back → Returns to Customer Detail ✅
2. Direct Access (No History):
User opens /orders/360 directly
→ Click Back → Goes to /orders (fallback) ✅
3. New Tab (No History):
User opens order in new tab
→ Click Back → Goes to /orders (fallback) ✅
4. Page Refresh (History Cleared):
User refreshes page
→ Click Back → Goes to fallback ✅
Benefits:
✅ Respects user's navigation path when possible
✅ Never breaks or leaves the app
✅ Predictable behavior in all scenarios
✅ Professional UX (like Gmail, Shopify, etc.)
✅ Works with deep links and bookmarks
Technical:
- Uses window.history.state.idx to detect history
- Falls back to safe default when no history
- Consistent pattern across all pages
- No URL parameters needed
Result: Back button now works intelligently based on context!
This commit is contained in:
@@ -37,6 +37,15 @@ export default function CustomerDetail() {
|
||||
const orders = ordersQuery.data?.rows || [];
|
||||
const { setPageHeader, clearPageHeader } = usePageHeader();
|
||||
|
||||
// Smart back handler: go back in history if available, otherwise fallback to /customers
|
||||
const handleBack = () => {
|
||||
if (window.history.state?.idx > 0) {
|
||||
navigate(-1); // Go back in history
|
||||
} else {
|
||||
navigate('/customers'); // Fallback to customers index
|
||||
}
|
||||
};
|
||||
|
||||
// Page header
|
||||
React.useEffect(() => {
|
||||
if (!customer) {
|
||||
@@ -46,7 +55,7 @@ export default function CustomerDetail() {
|
||||
|
||||
const actions = (
|
||||
<div className="flex gap-2">
|
||||
<Button size="sm" variant="ghost" onClick={() => navigate('/customers')}>
|
||||
<Button size="sm" variant="ghost" onClick={handleBack}>
|
||||
{__('Back')}
|
||||
</Button>
|
||||
<Button size="sm" onClick={() => navigate(`/customers/${customerId}/edit`)}>
|
||||
|
||||
@@ -46,11 +46,20 @@ export default function CustomerEdit() {
|
||||
await updateMutation.mutateAsync(data);
|
||||
};
|
||||
|
||||
// Smart back handler: go back in history if available, otherwise fallback to /customers
|
||||
const handleBack = () => {
|
||||
if (window.history.state?.idx > 0) {
|
||||
navigate(-1); // Go back in history
|
||||
} else {
|
||||
navigate('/customers'); // Fallback to customers index
|
||||
}
|
||||
};
|
||||
|
||||
// Set page header with back button and save button
|
||||
useEffect(() => {
|
||||
const actions = (
|
||||
<div className="flex gap-2">
|
||||
<Button size="sm" variant="ghost" onClick={() => navigate('/customers')}>
|
||||
<Button size="sm" variant="ghost" onClick={handleBack}>
|
||||
{__('Back')}
|
||||
</Button>
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user