mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
refactor(FE): Refactor CustomerPaymentTab to use Formik for filter
management
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import * as yup from 'yup';
|
||||
|
||||
export type CustomerPaymentFilterType = {
|
||||
start_date: string | null;
|
||||
end_date: string | null;
|
||||
customer_ids: string | null;
|
||||
filter_by: string | null;
|
||||
};
|
||||
|
||||
export const CustomerPaymentFilterSchema = yup.object({
|
||||
start_date: yup.string().optional().nullable(),
|
||||
end_date: yup
|
||||
.string()
|
||||
.optional()
|
||||
.nullable()
|
||||
.test(
|
||||
'is-greater-than-start',
|
||||
'Tanggal akhir tidak boleh masa lampau',
|
||||
function (value) {
|
||||
const { start_date } = this.parent;
|
||||
if (!start_date || !value) return true;
|
||||
return new Date(value) >= new Date(start_date);
|
||||
}
|
||||
),
|
||||
customer_ids: yup.string().nullable(),
|
||||
filter_by: yup.string().nullable(),
|
||||
});
|
||||
|
||||
export type CustomerPaymentFilterValues = yup.InferType<
|
||||
typeof CustomerPaymentFilterSchema
|
||||
>;
|
||||
@@ -9,7 +9,6 @@ import SelectInputRadio from '@/components/input/SelectInputRadio';
|
||||
import DateInput from '@/components/input/DateInput';
|
||||
import { CustomerApi } from '@/services/api/master-data';
|
||||
import { FinanceApi } from '@/services/api/report/finance-report';
|
||||
// import { UserApi } from '@/services/api/user';
|
||||
import Table from '@/components/Table';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { formatCurrency, formatDate, formatNumber, cn } from '@/lib/helper';
|
||||
@@ -22,18 +21,30 @@ import Button from '@/components/Button';
|
||||
import Dropdown from '@/components/Dropdown';
|
||||
import MenuItem from '@/components/menu/MenuItem';
|
||||
import Menu from '@/components/menu/Menu';
|
||||
import Modal from '@/components/Modal';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import Modal, { useModal } from '@/components/Modal';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useFormik } from 'formik';
|
||||
import {
|
||||
CustomerPaymentFilterSchema,
|
||||
CustomerPaymentFilterType,
|
||||
} from '@/components/pages/report/finance/filter/CustomerPaymentFilter';
|
||||
import { generateCustomerPaymentExcel } from '@/components/pages/report/finance/export/CustomerPaymentExportXLSX';
|
||||
import { generateCustomerPaymentPDF } from '@/components/pages/report/finance/export/CustomerPaymentExportPDF';
|
||||
import { useFinanceTabStore } from '@/stores/finance-tab/finance-tab.store';
|
||||
import CustomerSupplierSkeleton from '@/components/pages/report/finance/skeleton/CustomerSupplierSkeleton';
|
||||
import { OptionType } from '@/components/table/TableRowSizeSelector';
|
||||
|
||||
interface CustomerPaymentTabProps {
|
||||
tabId: string;
|
||||
}
|
||||
|
||||
interface FilterParams {
|
||||
customer_ids?: string;
|
||||
start_date?: string;
|
||||
end_date?: string;
|
||||
filter_by?: string;
|
||||
}
|
||||
|
||||
const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
// ===== STATE MANAGEMENT =====
|
||||
const [isPdfExportLoading, setIsPdfExportLoading] = useState(false);
|
||||
@@ -46,31 +57,10 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
|
||||
// ===== SUBMISSION STATE =====
|
||||
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||
|
||||
// ===== FILTER STATE =====
|
||||
const [appliedFilterCustomer, setAppliedFilterCustomer] = useState<
|
||||
typeof customerOptions
|
||||
>([]);
|
||||
// TODO: Uncomment when BE is ready
|
||||
// const [appliedFilterSales, setAppliedFilterSales] = useState<
|
||||
// typeof salesOptions
|
||||
// >([]);
|
||||
const [appliedFilterByType, setAppliedFilterByType] = useState<
|
||||
(typeof dataTypeOptions)[0] | null
|
||||
>(null);
|
||||
const [appliedFilterStartDate, setAppliedFilterStartDate] = useState('');
|
||||
const [appliedFilterEndDate, setAppliedFilterEndDate] = useState('');
|
||||
const [filterParams, setFilterParams] = useState<FilterParams>({});
|
||||
const [dateErrorShown, setDateErrorShown] = useState(false);
|
||||
const [hasDateError, setHasDateError] = useState(false);
|
||||
|
||||
const [filterCustomer, setFilterCustomer] = useState<typeof customerOptions>(
|
||||
[]
|
||||
);
|
||||
// TODO: Uncomment when BE is ready
|
||||
// const [filterSales, setFilterSales] = useState<typeof salesOptions>([]);
|
||||
const [filterStartDate, setFilterStartDate] = useState('');
|
||||
const [filterEndDate, setFilterEndDate] = useState('');
|
||||
|
||||
const filterModal = useModal();
|
||||
|
||||
const dataTypeOptions = useMemo(
|
||||
@@ -81,10 +71,6 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
[]
|
||||
);
|
||||
|
||||
const [filterByType, setFilterByType] = useState<
|
||||
(typeof dataTypeOptions)[0] | null
|
||||
>(null);
|
||||
|
||||
const {
|
||||
options: customerOptions,
|
||||
setInputValue: setCustomerInputValue,
|
||||
@@ -92,14 +78,43 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
loadMore: loadMoreCustomers,
|
||||
} = useSelect(CustomerApi.basePath, 'id', 'name', 'search');
|
||||
|
||||
// TODO: Uncomment when BE is ready
|
||||
// const {
|
||||
// options: salesOptions,
|
||||
// setInputValue: setSalesInputValue,
|
||||
// isLoadingOptions: isLoadingSales,
|
||||
// loadMore: loadMoreSales,
|
||||
// hasMore: hasMoreSales,
|
||||
// } = useSelect(UserApi.basePath, 'id', 'name', 'search');
|
||||
const handleFilterModalOpen = () => {
|
||||
filterModal.openModal();
|
||||
formik.validateForm();
|
||||
};
|
||||
|
||||
// ===== FORMIK SETUP =====
|
||||
const formik = useFormik<CustomerPaymentFilterType>({
|
||||
initialValues: {
|
||||
start_date: null,
|
||||
end_date: null,
|
||||
customer_ids: null,
|
||||
filter_by: null,
|
||||
},
|
||||
validationSchema: CustomerPaymentFilterSchema,
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
setFilterParams({
|
||||
start_date: values.start_date || undefined,
|
||||
end_date: values.end_date || undefined,
|
||||
customer_ids: values.customer_ids || undefined,
|
||||
filter_by: values.filter_by || undefined,
|
||||
});
|
||||
filterModal.closeModal();
|
||||
setIsSubmitted(true);
|
||||
setCurrentPage(1);
|
||||
setSubmitting(false);
|
||||
},
|
||||
onReset: () => {
|
||||
setFilterParams({});
|
||||
setIsSubmitted(false);
|
||||
setCurrentPage(1);
|
||||
setHasDateError(false);
|
||||
if (dateErrorShown) {
|
||||
toast.dismiss();
|
||||
setDateErrorShown(false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const getPaymentStatusColor = (notes: string) => {
|
||||
const normalizedValue = notes.toLowerCase();
|
||||
@@ -137,63 +152,15 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
// ===== FILTER HANDLERS =====
|
||||
const handleFilterModalOpen = useCallback(() => {
|
||||
setFilterCustomer(appliedFilterCustomer);
|
||||
// setFilterSales(appliedFilterSales);
|
||||
setFilterByType(appliedFilterByType);
|
||||
setFilterStartDate(appliedFilterStartDate);
|
||||
setFilterEndDate(appliedFilterEndDate);
|
||||
filterModal.openModal();
|
||||
}, [
|
||||
filterModal,
|
||||
appliedFilterCustomer,
|
||||
appliedFilterByType,
|
||||
appliedFilterStartDate,
|
||||
appliedFilterEndDate,
|
||||
]);
|
||||
|
||||
const handleResetFilters = useCallback(() => {
|
||||
setIsSubmitted(false);
|
||||
setFilterCustomer([]);
|
||||
setFilterByType(null);
|
||||
setFilterStartDate('');
|
||||
setFilterEndDate('');
|
||||
setAppliedFilterCustomer([]);
|
||||
setAppliedFilterByType(null);
|
||||
setAppliedFilterStartDate('');
|
||||
setAppliedFilterEndDate('');
|
||||
setHasDateError(false);
|
||||
if (dateErrorShown) {
|
||||
toast.dismiss();
|
||||
setDateErrorShown(false);
|
||||
}
|
||||
}, [dateErrorShown]);
|
||||
|
||||
const handleApplyFilters = useCallback(() => {
|
||||
setAppliedFilterCustomer(filterCustomer);
|
||||
setAppliedFilterByType(filterByType);
|
||||
setAppliedFilterStartDate(filterStartDate);
|
||||
setAppliedFilterEndDate(filterEndDate);
|
||||
setIsSubmitted(true);
|
||||
setCurrentPage(1);
|
||||
filterModal.closeModal();
|
||||
}, [
|
||||
filterModal,
|
||||
filterCustomer,
|
||||
filterByType,
|
||||
filterStartDate,
|
||||
filterEndDate,
|
||||
]);
|
||||
|
||||
// ===== DATE CHANGE HANDLERS =====
|
||||
const handleStartDateChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setFilterStartDate(value);
|
||||
formik.setFieldValue('start_date', value || null);
|
||||
|
||||
if (value && filterEndDate) {
|
||||
if (value && formik.values.end_date) {
|
||||
const startDate = new Date(value);
|
||||
const endDateObj = new Date(filterEndDate);
|
||||
const endDateObj = new Date(formik.values.end_date);
|
||||
|
||||
if (endDateObj < startDate) {
|
||||
setHasDateError(true);
|
||||
@@ -214,16 +181,16 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
setHasDateError(false);
|
||||
}
|
||||
},
|
||||
[filterEndDate, dateErrorShown]
|
||||
[formik, dateErrorShown]
|
||||
);
|
||||
|
||||
const handleEndDateChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setFilterEndDate(value);
|
||||
formik.setFieldValue('end_date', value || null);
|
||||
|
||||
if (value && filterStartDate) {
|
||||
const startDateObj = new Date(filterStartDate);
|
||||
if (value && formik.values.start_date) {
|
||||
const startDateObj = new Date(formik.values.start_date);
|
||||
const endDate = new Date(value);
|
||||
|
||||
if (endDate < startDateObj) {
|
||||
@@ -244,41 +211,46 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
setDateErrorShown(false);
|
||||
}
|
||||
},
|
||||
[filterStartDate, dateErrorShown]
|
||||
[formik, dateErrorShown]
|
||||
);
|
||||
|
||||
// ===== FILTER HELPERS =====
|
||||
const customerIdsValue = useMemo(() => {
|
||||
if (!formik.values.customer_ids) return [];
|
||||
return customerOptions.filter((opt) =>
|
||||
formik.values.customer_ids?.split(',').includes(String(opt.value))
|
||||
);
|
||||
}, [formik.values.customer_ids, customerOptions]);
|
||||
|
||||
const filterByValue = useMemo(() => {
|
||||
if (!formik.values.filter_by) return null;
|
||||
return (
|
||||
dataTypeOptions.find((opt) => opt.value === formik.values.filter_by) ||
|
||||
null
|
||||
);
|
||||
}, [formik.values.filter_by]);
|
||||
|
||||
// ===== ACTIVE FILTERS COUNT =====
|
||||
const activeFiltersCount = useMemo(() => {
|
||||
let count = 0;
|
||||
|
||||
// Date filter (start_date + end_date = 1 filter)
|
||||
if (appliedFilterStartDate || appliedFilterEndDate) {
|
||||
if (filterParams.start_date || filterParams.end_date) {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// Customer filter
|
||||
if (appliedFilterCustomer.length > 0) {
|
||||
if (filterParams.customer_ids) {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// Filter by type filter (hanya dihitung jika ada nilai yang dipilih)
|
||||
if (appliedFilterByType) {
|
||||
if (filterParams.filter_by) {
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// TODO: Uncomment when BE is ready
|
||||
// // Sales filter
|
||||
// if (appliedFilterSales.length > 0) {
|
||||
// count += 1;
|
||||
// }
|
||||
|
||||
return count;
|
||||
}, [
|
||||
appliedFilterStartDate,
|
||||
appliedFilterEndDate,
|
||||
appliedFilterCustomer,
|
||||
appliedFilterByType,
|
||||
]);
|
||||
}, [filterParams]);
|
||||
|
||||
const hasFilters = activeFiltersCount > 0;
|
||||
|
||||
@@ -287,21 +259,13 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
isSubmitted
|
||||
? () => {
|
||||
const params = {
|
||||
customer_ids:
|
||||
appliedFilterCustomer.length > 0
|
||||
? appliedFilterCustomer.map((v) => String(v.value)).join(',')
|
||||
: undefined,
|
||||
// TODO: Uncomment when BE is ready
|
||||
// sales_id:
|
||||
// appliedFilterSales.length > 0
|
||||
// ? appliedFilterSales.map((v) => String(v.value)).join(',')
|
||||
// : undefined,
|
||||
filter_by: appliedFilterByType?.value as
|
||||
customer_ids: filterParams.customer_ids,
|
||||
filter_by: filterParams.filter_by as
|
||||
| 'trans_date'
|
||||
| 'realization_date'
|
||||
| undefined,
|
||||
start_date: appliedFilterStartDate || undefined,
|
||||
end_date: appliedFilterEndDate || undefined,
|
||||
start_date: filterParams.start_date,
|
||||
end_date: filterParams.end_date,
|
||||
page: currentPage,
|
||||
limit: pageSize,
|
||||
};
|
||||
@@ -333,21 +297,13 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
CustomerPaymentReport[] | null
|
||||
> => {
|
||||
const params = {
|
||||
customer_ids:
|
||||
appliedFilterCustomer.length > 0
|
||||
? appliedFilterCustomer.map((v) => String(v.value)).join(',')
|
||||
: undefined,
|
||||
// TODO: Uncomment when BE is ready
|
||||
// sales_id:
|
||||
// appliedFilterSales.length > 0
|
||||
// ? appliedFilterSales.map((v) => String(v.value)).join(',')
|
||||
// : undefined,
|
||||
filter_by: appliedFilterByType?.value as
|
||||
customer_ids: filterParams.customer_ids,
|
||||
filter_by: filterParams.filter_by as
|
||||
| 'trans_date'
|
||||
| 'realization_date'
|
||||
| undefined,
|
||||
start_date: appliedFilterStartDate || undefined,
|
||||
end_date: appliedFilterEndDate || undefined,
|
||||
start_date: filterParams.start_date,
|
||||
end_date: filterParams.end_date,
|
||||
limit: 100,
|
||||
page: 1,
|
||||
};
|
||||
@@ -364,13 +320,7 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
return isResponseSuccess(response)
|
||||
? (response.data as unknown as CustomerPaymentReport[])
|
||||
: null;
|
||||
}, [
|
||||
appliedFilterCustomer,
|
||||
// appliedFilterSales,
|
||||
appliedFilterStartDate,
|
||||
appliedFilterEndDate,
|
||||
appliedFilterByType,
|
||||
]);
|
||||
}, [filterParams]);
|
||||
|
||||
// ===== EXPORT HANDLERS =====
|
||||
const handleExportExcel = useCallback(async () => {
|
||||
@@ -410,21 +360,22 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const customerName = filterParams.customer_ids
|
||||
? customerOptions
|
||||
.filter((opt) =>
|
||||
filterParams.customer_ids?.split(',').includes(String(opt.value))
|
||||
)
|
||||
.map((opt) => opt.label)
|
||||
.join(', ') || 'Semua Customer'
|
||||
: 'Semua Customer';
|
||||
|
||||
await generateCustomerPaymentPDF({
|
||||
data: allDataForExport,
|
||||
params: {
|
||||
customer_name:
|
||||
appliedFilterCustomer.length > 0
|
||||
? appliedFilterCustomer.map((c) => c.label).join(', ')
|
||||
: undefined,
|
||||
// TODO: Uncomment when BE is ready
|
||||
// sales:
|
||||
// appliedFilterSales.length > 0
|
||||
// ? appliedFilterSales.map((s) => s.label).join(', ')
|
||||
// : undefined,
|
||||
start_date: appliedFilterStartDate || undefined,
|
||||
end_date: appliedFilterEndDate || undefined,
|
||||
filter_by: appliedFilterByType?.value as
|
||||
customer_name: customerName,
|
||||
start_date: filterParams.start_date,
|
||||
end_date: filterParams.end_date,
|
||||
filter_by: filterParams.filter_by as
|
||||
| 'trans_date'
|
||||
| 'realization_date'
|
||||
| undefined,
|
||||
@@ -436,7 +387,7 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
} finally {
|
||||
setIsPdfExportLoading(false);
|
||||
}
|
||||
}, [customerPaymentExport]);
|
||||
}, [customerPaymentExport, filterParams, customerOptions]);
|
||||
|
||||
// ===== REGISTER TAB ACTIONS TO STORE =====
|
||||
const setTabActions = useFinanceTabStore((state) => state.setTabActions);
|
||||
@@ -517,7 +468,6 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
setTabActions,
|
||||
]);
|
||||
|
||||
// Cleanup on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
clearTabActions(tabId);
|
||||
@@ -931,95 +881,86 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
|
||||
<Icon icon='heroicons:x-mark' width={20} height={20} />
|
||||
</Button>
|
||||
</div>
|
||||
<div className='p-4 flex flex-col gap-1.5'>
|
||||
<div>
|
||||
<label className='block text-xs font-semibold text-base-content py-2'>
|
||||
Tanggal
|
||||
</label>
|
||||
<div className='flex flex-row gap-1.5 items-center justify-between'>
|
||||
<DateInput
|
||||
name='start_date'
|
||||
value={filterStartDate}
|
||||
onChange={handleStartDateChange}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
isNestedModal
|
||||
/>
|
||||
<hr className='w-full max-w-3 h-px border-base-content/10' />
|
||||
<form onSubmit={formik.handleSubmit} onReset={formik.handleReset}>
|
||||
<div className='p-4 flex flex-col gap-1.5'>
|
||||
<div>
|
||||
<label className='block text-xs font-semibold text-base-content py-2'>
|
||||
Tanggal
|
||||
</label>
|
||||
<div className='flex flex-row gap-1.5 items-center justify-between'>
|
||||
<DateInput
|
||||
name='start_date'
|
||||
value={formik.values.start_date || ''}
|
||||
onChange={handleStartDateChange}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
isNestedModal
|
||||
/>
|
||||
<hr className='w-full max-w-3 h-px border-base-content/10' />
|
||||
|
||||
<DateInput
|
||||
name='end_date'
|
||||
value={filterEndDate}
|
||||
onChange={handleEndDateChange}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
isNestedModal
|
||||
/>
|
||||
<DateInput
|
||||
name='end_date'
|
||||
value={formik.values.end_date || ''}
|
||||
onChange={handleEndDateChange}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
isNestedModal
|
||||
isError={hasDateError}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SelectInputCheckbox
|
||||
label='Customer'
|
||||
placeholder='Pilih Customer'
|
||||
options={customerOptions}
|
||||
value={customerIdsValue}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue(
|
||||
'customer_ids',
|
||||
Array.isArray(val) && val.length > 0
|
||||
? val.map((v: OptionType) => String(v.value)).join(',')
|
||||
: null
|
||||
);
|
||||
}}
|
||||
onInputChange={setCustomerInputValue}
|
||||
isLoading={isLoadingCustomers}
|
||||
isClearable
|
||||
onMenuScrollToBottom={loadMoreCustomers}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
|
||||
<SelectInputRadio
|
||||
label='Filter Berdasarkan'
|
||||
placeholder='Pilih Filter Berdasarkan'
|
||||
options={dataTypeOptions}
|
||||
value={filterByValue}
|
||||
onChange={(val) => {
|
||||
if (!Array.isArray(val)) {
|
||||
formik.setFieldValue('filter_by', val?.value || null);
|
||||
}
|
||||
}}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
isClearable={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SelectInputCheckbox
|
||||
label='Customer'
|
||||
placeholder='Pilih Customer'
|
||||
options={customerOptions}
|
||||
value={filterCustomer}
|
||||
onChange={(val) => {
|
||||
setFilterCustomer(Array.isArray(val) ? val : val ? [val] : []);
|
||||
}}
|
||||
onInputChange={setCustomerInputValue}
|
||||
isLoading={isLoadingCustomers}
|
||||
isClearable
|
||||
onMenuScrollToBottom={loadMoreCustomers}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
|
||||
{/* TODO: Uncomment when BE is ready */}
|
||||
{/* <div>
|
||||
<SelectInputCheckbox
|
||||
label='Sales'
|
||||
placeholder='Pilih Sales'
|
||||
options={salesOptions}
|
||||
value={filterSales}
|
||||
onChange={(val) => {
|
||||
setFilterSales(Array.isArray(val) ? val : val ? [val] : []);
|
||||
}}
|
||||
onInputChange={setSalesInputValue}
|
||||
isLoading={isLoadingSales}
|
||||
isClearable
|
||||
onMenuScrollToBottom={loadMoreSales}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
</div> */}
|
||||
|
||||
<SelectInputRadio
|
||||
label='Filter Berdasarkan'
|
||||
placeholder='Pilih Filter Berdasarkan'
|
||||
options={dataTypeOptions}
|
||||
value={filterByType}
|
||||
onChange={(val) => {
|
||||
if (val && !Array.isArray(val)) {
|
||||
setFilterByType(val);
|
||||
}
|
||||
}}
|
||||
className={{ wrapper: 'w-full' }}
|
||||
/>
|
||||
|
||||
{/* Action Buttons */}
|
||||
</div>
|
||||
<div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'>
|
||||
<Button
|
||||
variant='soft'
|
||||
className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
|
||||
onClick={handleResetFilters}
|
||||
>
|
||||
Reset Filter
|
||||
</Button>
|
||||
<Button
|
||||
className='min-w-40 text-sm rounded-lg py-3 text-white font-semibold'
|
||||
onClick={handleApplyFilters}
|
||||
disabled={hasDateError}
|
||||
>
|
||||
Apply Filter
|
||||
</Button>
|
||||
</div>
|
||||
{/* Modal Footer */}
|
||||
<div className='flex justify-between items-center gap-4 p-4 border-t border-base-content/10 bg-gray-50'>
|
||||
<Button
|
||||
type='reset'
|
||||
variant='soft'
|
||||
className='rounded-lg text-base-content/65 bg-transparent border-none hover:bg-base-content/10 hover:text-base-content/65 transition-colors px-3 py-2'
|
||||
>
|
||||
Reset Filter
|
||||
</Button>
|
||||
<Button
|
||||
type='submit'
|
||||
className='min-w-40 text-sm rounded-lg py-3 text-white font-semibold'
|
||||
disabled={hasDateError || !formik.isValid || formik.isSubmitting}
|
||||
>
|
||||
Apply Filter
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user