Files
WooNooW/admin-spa/src/routes/Coupons/New.tsx
dwindown e8ca3ceeb2 fix: Vertical tabs visibility and add mobile search/filter
Fixed 3 critical issues:

1. Fixed Vertical Tabs - Cards All Showing
   - Updated VerticalTabForm to hide inactive sections
   - Only active section visible (className: hidden for others)
   - Proper tab switching now works

2. Added Mobile Search/Filter to Coupons
   - Created CouponFilterSheet component
   - Added mobile search bar with icon
   - Filter button with active count badge
   - Matches Products pattern exactly
   - Sheet with Apply/Reset buttons

3. Removed max-height from VerticalTabForm
   - User removed max-h-[calc(100vh-200px)]
   - Content now flows naturally
   - Better for forms with varying heights

Components Created:
- CouponFilterSheet.tsx - Mobile filter bottom sheet
  - Discount type filter
  - Apply/Reset actions
  - Active filter count

Changes to Coupons/index.tsx:
- Added mobile search bar (md:hidden)
- Added filter sheet state
- Added activeFiltersCount
- Search icon + SlidersHorizontal icon
- Filter badge indicator

Changes to VerticalTabForm:
- Hide inactive sections (className: hidden)
- Only show section matching activeTab
- Proper visibility control

Result:
 Vertical tabs work correctly (only one section visible)
 Mobile search/filter on Coupons (like Products)
 Filter count badge
 Professional mobile UX

Next: Move customer site member checkbox to settings
2025-11-20 20:32:46 +07:00

68 lines
2.1 KiB
TypeScript

import React, { useRef, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { __ } from '@/lib/i18n';
import { CouponsApi, type CouponFormData } from '@/lib/api/coupons';
import { showErrorToast, showSuccessToast } from '@/lib/errorHandling';
import { usePageHeader } from '@/contexts/PageHeaderContext';
import { Button } from '@/components/ui/button';
import { useFABConfig } from '@/hooks/useFABConfig';
import CouponForm from './CouponForm';
export default function CouponNew() {
const navigate = useNavigate();
const queryClient = useQueryClient();
const formRef = useRef<HTMLFormElement>(null);
const { setPageHeader, clearPageHeader } = usePageHeader();
// Hide FAB on create page
useFABConfig('none');
// Create mutation
const createMutation = useMutation({
mutationFn: (data: CouponFormData) => CouponsApi.create(data),
onSuccess: (coupon) => {
queryClient.invalidateQueries({ queryKey: ['coupons'] });
showSuccessToast(__('Coupon created successfully'), `${__('Coupon')} ${coupon.code} ${__('created')}`);
navigate('/coupons');
},
onError: (error) => {
showErrorToast(error);
},
});
// Set contextual header
useEffect(() => {
const actions = (
<div className="flex gap-2">
<Button size="sm" variant="ghost" onClick={() => navigate('/coupons')}>
{__('Cancel')}
</Button>
<Button
size="sm"
onClick={() => formRef.current?.requestSubmit()}
disabled={createMutation.isPending}
>
{createMutation.isPending ? __('Creating...') : __('Create')}
</Button>
</div>
);
setPageHeader(__('New Coupon'), actions);
return () => clearPageHeader();
}, [createMutation.isPending, setPageHeader, clearPageHeader, navigate]);
return (
<div>
<CouponForm
mode="create"
onSubmit={async (data) => {
await createMutation.mutateAsync(data);
}}
formRef={formRef}
hideSubmitButton={true}
/>
</div>
);
}