diff --git a/src/components/pages/report/finance/tab/BalanceMonitoringTab.tsx b/src/components/pages/report/finance/tab/BalanceMonitoringTab.tsx index b2920008..e7ec6cb3 100644 --- a/src/components/pages/report/finance/tab/BalanceMonitoringTab.tsx +++ b/src/components/pages/report/finance/tab/BalanceMonitoringTab.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useMemo, useEffect } from 'react'; +import { useState, useMemo, useEffect, useCallback } from 'react'; import useSWR from 'swr'; import { Icon } from '@iconify/react'; import { useFormik } from 'formik'; @@ -24,6 +24,7 @@ import { BalanceMonitoringRow } from '@/types/api/report/balance-monitoring'; import { CustomerPaymentRow } from '@/types/api/report/customer-payment'; import Modal, { useModal } from '@/components/Modal'; import Button from '@/components/Button'; +import Dropdown from '@/components/Dropdown'; import DateInput from '@/components/input/DateInput'; import Table from '@/components/Table'; import CustomerSupplierSkeleton from '@/components/pages/report/finance/skeleton/CustomerSupplierSkeleton'; @@ -40,6 +41,7 @@ const filterByOptions: OptionType[] = [ const BalanceMonitoringTab = ({ tabId }: BalanceMonitoringTabProps) => { const [hasDateError, setHasDateError] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false); + const [isExcelExportLoading, setIsExcelExportLoading] = useState(false); const filterModal = useModal(); @@ -230,6 +232,33 @@ const BalanceMonitoringTab = ({ tabId }: BalanceMonitoringTabProps) => { ? balanceMonitoringsResponse.meta : null; + const handleExportExcel = useCallback(async () => { + setIsExcelExportLoading(true); + try { + const customer_ids = + tableFilterState.customers.length > 0 + ? tableFilterState.customers.map((o) => String(o.value)).join(',') + : undefined; + const sales_ids = + tableFilterState.salesPersons.length > 0 + ? tableFilterState.salesPersons.map((o) => String(o.value)).join(',') + : undefined; + + await FinanceApi.exportBalanceMonitoringToExcel( + customer_ids, + sales_ids, + tableFilterState.filterBy?.value, + tableFilterState.start_date || undefined, + tableFilterState.end_date || undefined + ); + toast.success('Excel berhasil dibuat dan diunduh.'); + } catch { + toast.error('Gagal membuat Excel. Silakan coba lagi.'); + } finally { + setIsExcelExportLoading(false); + } + }, [tableFilterState]); + // Inject tab actions directly — no nested component, no remount cycle useEffect(() => { setTabActions( @@ -248,9 +277,55 @@ const BalanceMonitoringTab = ({ tabId }: BalanceMonitoringTabProps) => { variant='outline' className='px-3 py-2.5' /> + + +
+ + Export +
+ +
+ + } + > + +
); - }, [tabId, setTabActions, tableFilterState, filterModal.openModal]); + }, [ + tabId, + setTabActions, + tableFilterState, + filterModal.openModal, + isExcelExportLoading, + handleExportExcel, + ]); useEffect(() => { return () => clearTabActions(tabId); diff --git a/src/components/pages/report/logistic-stock/tab/PurchasesPerSupplierTab.tsx b/src/components/pages/report/logistic-stock/tab/PurchasesPerSupplierTab.tsx index 9a9bb6c2..cd4f7d3b 100644 --- a/src/components/pages/report/logistic-stock/tab/PurchasesPerSupplierTab.tsx +++ b/src/components/pages/report/logistic-stock/tab/PurchasesPerSupplierTab.tsx @@ -16,7 +16,6 @@ import { LogisticPurchasePerSupplierReport, LogisticPurchasePerSupplierSummary, } from '@/types/api/report/logistic-stock'; -import { generatePurchasesPerSupplierExcel } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExportXLSX'; import { generatePurchasesPerSupplierPDF } from '@/components/pages/report/logistic-stock/export/PurchasesPerSupplierExportPDF'; import { Icon } from '@iconify/react'; import { ColumnDef } from '@tanstack/react-table'; @@ -53,7 +52,10 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => { // ===== STATE MANAGEMENT ===== const [isPdfExportLoading, setIsPdfExportLoading] = useState(false); const [isExcelExportLoading, setIsExcelExportLoading] = useState(false); - const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading; + const [isExcelGeneralExportLoading, setIsExcelGeneralExportLoading] = + useState(false); + const isAnyExportLoading = + isPdfExportLoading || isExcelExportLoading || isExcelGeneralExportLoading; // ===== PAGINATION STATE ===== const [currentPage, setCurrentPage] = useState(1); @@ -360,25 +362,44 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => { const handleExportExcel = useCallback(async () => { setIsExcelExportLoading(true); try { - const allDataForExport = await logisticPurchasePerSupplierExport(); - - if ( - !allDataForExport || - !Array.isArray(allDataForExport) || - allDataForExport.length === 0 - ) { - toast.error('Tidak ada data untuk diekspor.'); - return; - } - - await generatePurchasesPerSupplierExcel({ data: allDataForExport }); + await LogisticApi.exportToExcelSupplierPerSheet( + filterParams.area_id, + filterParams.supplier_id, + filterParams.product_id, + filterParams.product_category_id, + filterParams.start_date, + filterParams.end_date, + filterParams.sort_by, + filterParams.filter_by + ); toast.success('Excel berhasil dibuat dan diunduh.'); } catch { toast.error('Gagal membuat Excel. Silakan coba lagi.'); } finally { setIsExcelExportLoading(false); } - }, [logisticPurchasePerSupplierExport]); + }, [filterParams]); + + const handleExportExcelGeneral = useCallback(async () => { + setIsExcelGeneralExportLoading(true); + try { + await LogisticApi.exportToExcelGeneral( + filterParams.area_id, + filterParams.supplier_id, + filterParams.product_id, + filterParams.product_category_id, + filterParams.start_date, + filterParams.end_date, + filterParams.sort_by, + filterParams.filter_by + ); + toast.success('Excel General berhasil dibuat dan diunduh.'); + } catch { + toast.error('Gagal membuat Excel General. Silakan coba lagi.'); + } finally { + setIsExcelGeneralExportLoading(false); + } + }, [filterParams]); const handleExportPdf = useCallback(async () => { setIsPdfExportLoading(true); @@ -523,7 +544,17 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => { className='w-full p-3 justify-start text-sm text-base-content/50 font-semibold text-nowrap' > - Export to Excel + Export to Excel - Supplier Per Sheet + +