diff --git a/src/components/pages/finance/FinanceTable.tsx b/src/components/pages/finance/FinanceTable.tsx index 211af1f7..a4cb9cbd 100644 --- a/src/components/pages/finance/FinanceTable.tsx +++ b/src/components/pages/finance/FinanceTable.tsx @@ -29,7 +29,7 @@ import { FINANCE_TRANSACTION_TYPE_OPTIONS, } from '@/config/constant'; import { FinanceApi } from '@/services/api/finance'; -import { isResponseSuccess } from '@/lib/api-helper'; +import { getErrorMessage, isResponseSuccess } from '@/lib/api-helper'; import { BankApi, CustomerApi, SupplierApi } from '@/services/api/master-data'; import { Bank } from '@/types/api/master-data/bank'; import Modal, { useModal } from '@/components/Modal'; @@ -39,6 +39,7 @@ import ConfirmationModal from '@/components/modal/ConfirmationModal'; import toast from 'react-hot-toast'; import RequirePermission from '@/components/helper/RequirePermission'; import ButtonFilter from '@/components/helper/ButtonFilter'; +import Dropdown from '@/components/dropdown/Dropdown'; import { FinanceTableFilterSchema, FinanceTableFilterValues, @@ -233,6 +234,7 @@ const FinanceTable = () => { const [selectedSortBy, setSelectedSortBy] = useState(null); const [selectedFinance, setSelectedFinance] = useState(null); const [isDeleteLoading, setIsDeleteLoading] = useState(false); + const [isExportLoading, setIsExportLoading] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false); const [hasDateError, setHasDateError] = useState(false); @@ -552,6 +554,20 @@ const FinanceTable = () => { filterModal.openModal(); }; + const exportToExcel = async () => { + setIsExportLoading(true); + try { + await FinanceApi.exportToExcel(getTableFilterQueryString()); + toast.success('Excel berhasil dibuat dan diunduh.'); + } catch (error) { + toast.error( + await getErrorMessage(error, 'Gagal mengekspor data finance.') + ); + } finally { + setIsExportLoading(false); + } + }; + const confirmationModalDeleteClickHandler = async () => { setIsDeleteLoading(true); @@ -759,6 +775,51 @@ const FinanceTable = () => { onClick={handleFilterModalOpen} className='px-3 py-2.5' /> + + +
+ + + Ekspor + +
+ + +
+ + } + > + +
diff --git a/src/services/api/finance.ts b/src/services/api/finance.ts index f9ba367f..291551f3 100644 --- a/src/services/api/finance.ts +++ b/src/services/api/finance.ts @@ -2,6 +2,7 @@ import axios from 'axios'; import { BaseApiService } from '@/services/api/base'; import { BaseApiResponse } from '@/types/api/api-general'; import { httpClient, httpClientFetcher } from '@/services/http/client'; +import { formatDate } from '@/lib/helper'; import { CreateFinancePayment, CreateInitialBalance, @@ -174,6 +175,30 @@ export class FinanceApiService extends BaseApiService< } } + async exportToExcel(initialQueryString: string) { + const params = new URLSearchParams(initialQueryString); + + params.set('export', 'excel'); + params.set('page', '1'); + params.set('limit', '99999999999'); + + const res = await httpClient( + `${this.basePath}/transactions?${params.toString()}`, + { method: 'GET', responseType: 'blob' } + ); + + const url = window.URL.createObjectURL(new Blob([res])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute( + 'download', + `finance-${formatDate(Date.now(), 'DD-MM-YYYY')}.xlsx` + ); + document.body.appendChild(link); + link.click(); + link.remove(); + } + async delete(id: number) { try { const deletePath = `${this.basePath}/transactions/${id}`;