refactor(FE): Refactor tab actions to use memoized component

This commit is contained in:
rstubryan
2026-03-05 11:10:36 +07:00
parent 267ef9d812
commit ea88c3ce8e
@@ -17,7 +17,7 @@ import { generateDebtSupplierExcel } from '@/components/pages/report/finance/exp
import { generateDebtSupplierPDF } from '@/components/pages/report/finance/export/DebtSupllierExportPDF'; import { generateDebtSupplierPDF } from '@/components/pages/report/finance/export/DebtSupllierExportPDF';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
import { ColumnDef } from '@tanstack/react-table'; import { ColumnDef } from '@tanstack/react-table';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import useSWR from 'swr'; import useSWR from 'swr';
import { DebtSupplierApi } from '@/services/api/report/debt-supplier'; import { DebtSupplierApi } from '@/services/api/report/debt-supplier';
@@ -91,6 +91,8 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
const [dateErrorShown, setDateErrorShown] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false);
const [hasDateError, setHasDateError] = useState(false); const [hasDateError, setHasDateError] = useState(false);
const handleFilterModalOpenRef = useRef(() => {});
const filterModal = useModal(); const filterModal = useModal();
const { const {
@@ -108,11 +110,6 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
[] []
); );
const handleFilterModalOpen = () => {
filterModal.openModal();
formik.validateForm();
};
// ===== FORMIK SETUP ===== // ===== FORMIK SETUP =====
const formik = useFormik<DebtSupplierFilterType>({ const formik = useFormik<DebtSupplierFilterType>({
initialValues: { initialValues: {
@@ -146,6 +143,11 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
}, },
}); });
handleFilterModalOpenRef.current = () => {
filterModal.openModal();
formik.validateForm();
};
// ===== DATA FETCHING ===== // ===== DATA FETCHING =====
const { data: debtSupplier, isLoading } = useSWR( const { data: debtSupplier, isLoading } = useSWR(
isSubmitted isSubmitted
@@ -268,20 +270,30 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
} finally { } finally {
setIsPdfExportLoading(false); setIsPdfExportLoading(false);
} }
}, [debtSupplierExport]); }, [
debtSupplierExport,
formik.values.supplierIds,
formik.values.filterBy,
formik.values.startDate,
formik.values.endDate,
]);
// ===== REGISTER TAB ACTIONS TO STORE ===== // ===== TAB ACTIONS COMPONENT =====
const TabActions = useMemo(() => {
return function TabActionsComponent() {
const setTabActions = useTabActionsStore((state) => state.setTabActions); const setTabActions = useTabActionsStore((state) => state.setTabActions);
const clearTabActions = useTabActionsStore((state) => state.clearTabActions); const clearTabActions = useTabActionsStore(
(state) => state.clearTabActions
);
useEffect(() => { useEffect(() => {
setTabActions( setTabActions(
tabId, tabId,
<div className='flex flex-row gap-3'> <div className='flex flex-row gap-3'>
<ButtonFilter <ButtonFilter
values={formik.values} values={filterParams}
fieldGroups={[['startDate', 'endDate']]} fieldGroups={[['start_date', 'end_date']]}
onClick={handleFilterModalOpen} onClick={() => handleFilterModalOpenRef.current()}
variant='outline' variant='outline'
className='px-3 py-2.5' className='px-3 py-2.5'
/> />
@@ -311,7 +323,11 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
<div className='w-px self-stretch bg-base-content/10' /> <div className='w-px self-stretch bg-base-content/10' />
<Icon icon='heroicons:chevron-down' width={14} height={14} /> <Icon
icon='heroicons:chevron-down'
width={14}
height={14}
/>
</div> </div>
</Button> </Button>
} }
@@ -339,21 +355,27 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
</Dropdown> </Dropdown>
</div> </div>
); );
}, [ }, [setTabActions]);
tabId,
formik.values,
isAnyExportLoading,
handleExportExcel,
handleExportPdf,
setTabActions,
]);
// Cleanup on unmount
useEffect(() => { useEffect(() => {
return () => { return () => {
clearTabActions(tabId); clearTabActions(tabId);
}; };
}, [tabId, clearTabActions]); }, [clearTabActions]);
return null;
};
}, [
tabId,
filterParams,
isAnyExportLoading,
handleExportExcel,
handleExportPdf,
isExcelExportLoading,
isPdfExportLoading,
]);
const TabActionsElement = useMemo(() => <TabActions />, [TabActions]);
useEffect(() => { useEffect(() => {
return () => { return () => {
@@ -587,6 +609,7 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
]; ];
return ( return (
<> <>
{TabActionsElement}
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'> <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
{!isSubmitted ? ( {!isSubmitted ? (
<DebtSupplierSkeleton <DebtSupplierSkeleton