feat: Add scroll-hide header and contextual FAB system

Implemented:

1. Scroll-Hide App Bar (Mobile)
   - Hides on scroll down (past 50px)
   - Shows on scroll up
   - Chrome URL bar behavior
   - Smooth slide animation (300ms)
   - Desktop always visible (md:translate-y-0)

2. Contextual FAB Hook
   - useFABConfig() hook for pages
   - Pre-configured for: orders, products, customers, coupons, dashboard
   - Automatic cleanup on unmount
   - Easy to use: useFABConfig('orders')

3. Removed Focus Styles
   - Bottom nav links: focus:outline-none
   - Cleaner mobile UX

Header Scroll Behavior:
- Scroll down > 50px: Header slides up (-translate-y-full)
- Scroll up: Header slides down (translate-y-0)
- Desktop: Always visible (md:translate-y-0)
- Smooth transition (duration-300)

FAB Configuration:
const configs = {
  orders: 'Create Order' → /orders/new
  products: 'Add Product' → /products/new
  customers: 'Add Customer' → /customers/new
  coupons: 'Create Coupon' → /coupons/new
  dashboard: 'Quick Actions' → (future speed dial)
  none: Hide FAB
}

Usage in Pages:
import { useFABConfig } from '@/hooks/useFABConfig';

function OrdersPage() {
  useFABConfig('orders'); // Sets up FAB automatically
  return <div>...</div>;
}

Next Steps:
- Add useFABConfig to actual pages
- Test scroll behavior on devices
- Implement speed dial for dashboard

Files Created:
- useFABConfig.tsx: Contextual FAB configuration hook

Files Modified:
- App.tsx: Scroll detection and header animation
- BottomNav.tsx: Removed focus outline styles
This commit is contained in:
dwindown
2025-11-06 20:27:19 +07:00
parent 76624bb473
commit 4d2469f826
3 changed files with 106 additions and 2 deletions

View File

@@ -0,0 +1,73 @@
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Plus } from 'lucide-react';
import { useFAB } from '@/contexts/FABContext';
/**
* Hook to configure FAB for different pages
* Usage: useFABConfig('orders') in Orders page component
*/
export function useFABConfig(page: 'orders' | 'products' | 'customers' | 'coupons' | 'dashboard' | 'none') {
const { setFAB, clearFAB } = useFAB();
const navigate = useNavigate();
useEffect(() => {
switch (page) {
case 'orders':
setFAB({
icon: <Plus className="w-6 h-6" />,
label: 'Create Order',
onClick: () => navigate('/orders/new'),
visible: true
});
break;
case 'products':
setFAB({
icon: <Plus className="w-6 h-6" />,
label: 'Add Product',
onClick: () => navigate('/products/new'),
visible: true
});
break;
case 'customers':
setFAB({
icon: <Plus className="w-6 h-6" />,
label: 'Add Customer',
onClick: () => navigate('/customers/new'),
visible: true
});
break;
case 'coupons':
setFAB({
icon: <Plus className="w-6 h-6" />,
label: 'Create Coupon',
onClick: () => navigate('/coupons/new'),
visible: true
});
break;
case 'dashboard':
// Dashboard could have a speed dial menu in the future
setFAB({
icon: <Plus className="w-6 h-6" />,
label: 'Quick Actions',
onClick: () => {
// TODO: Implement speed dial menu
console.log('Quick actions menu');
},
visible: true
});
break;
case 'none':
default:
clearFAB();
break;
}
return () => clearFAB();
}, [page, navigate, setFAB, clearFAB]);
}