diff --git a/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx b/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx index b7bde263..192449a8 100644 --- a/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx +++ b/src/components/pages/report/finance/tab/CustomerPaymentTab.tsx @@ -1,6 +1,7 @@ import { useState, useMemo, useCallback } from 'react'; import { ChangeEventHandler } from 'react'; import useSWR from 'swr'; +import { Icon } from '@iconify/react'; import Card from '@/components/Card'; import SelectInput, { useSelect, @@ -23,6 +24,8 @@ 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 toast from 'react-hot-toast'; import { generateCustomerPaymentExcel } from '@/components/pages/report/finance/export/CustomerPaymentExportXLSX'; import { generateCustomerPaymentPDF } from '@/components/pages/report/finance/export/CustomerPaymentExportPDF'; @@ -40,20 +43,16 @@ const CustomerPaymentTab = () => { // ===== SUBMISSION STATE ===== const [isSubmitted, setIsSubmitted] = useState(false); - // ===== TABLE FILTER STATE ===== - const { state: tableFilterState, updateFilter } = useTableFilter({ - initial: { - customer_id: [] as string[], - sales: [] as string[], - date_type: 'do_date' as 'do_date' | 'payment_date', - start_date: '', - end_date: '', - }, - paramMap: { - page: 'page', - pageSize: 'limit', - }, - }); + // ===== FILTER STATE ===== + const [filterCustomer, setFilterCustomer] = useState([]); + const [filterSales, setFilterSales] = useState([]); + const [filterDateType, setFilterDateType] = useState(null); + const [filterStartDate, setFilterStartDate] = useState(''); + const [filterEndDate, setFilterEndDate] = useState(''); + const [filterErrors, setFilterErrors] = useState>({}); + + // Filter Modal + const filterModal = useModal(); const { options: customerOptions, isLoadingOptions: isLoadingCustomers } = useSelect(CustomerApi.basePath, 'id', 'name', 'search'); @@ -76,93 +75,55 @@ const CustomerPaymentTab = () => { [] ); - const customerChangeHandler = useCallback( - (val: OptionType | OptionType[] | null) => { - const arr = Array.isArray(val) ? val : val ? [val] : []; - updateFilter( - 'customer_id', - arr.map((v) => String((v as OptionType).value)) - ); - setIsSubmitted(false); - }, - [updateFilter] - ); - - const salesChangeHandler = useCallback( - (val: OptionType | OptionType[] | null) => { - const arr = Array.isArray(val) ? val : val ? [val] : []; - updateFilter( - 'sales', - arr.map((v) => String((v as OptionType).value)) - ); - setIsSubmitted(false); - }, - [updateFilter] - ); - - const dataTypeChangeHandler = useCallback( - (val: OptionType | OptionType[] | null) => { - const newVal = val as OptionType; - const dateType = - (newVal?.value as 'do_date' | 'payment_date') || 'do_date'; - updateFilter('date_type', dateType); - setIsSubmitted(false); - }, - [updateFilter] - ); - - const startDateChangeHandler = useCallback< - ChangeEventHandler - >( - (e) => { - const val = e.target.value; - updateFilter('start_date', val || ''); - setIsSubmitted(false); - }, - [updateFilter] - ); - - const endDateChangeHandler = useCallback< - ChangeEventHandler - >( - (e) => { - const val = e.target.value; - updateFilter('end_date', val || ''); - setIsSubmitted(false); - }, - [updateFilter] - ); - - const resetFilters = useCallback(() => { - updateFilter('customer_id', []); - updateFilter('sales', []); - updateFilter('date_type', 'do_date'); - updateFilter('start_date', ''); - updateFilter('end_date', ''); + // ===== FILTER HANDLERS ===== + const handleResetFilters = useCallback(() => { setIsSubmitted(false); - }, [updateFilter]); - - const handleSubmit = useCallback(() => { - setIsSubmitted(true); - setCurrentPage(1); + setFilterCustomer([]); + setFilterSales([]); + setFilterDateType(null); + setFilterStartDate(''); + setFilterEndDate(''); + setFilterErrors({}); }, []); + const handleApplyFilters = useCallback(() => { + const errors: Record = {}; + + if (!filterStartDate) { + errors.start_date = 'Tanggal mulai wajib diisi'; + } + if (!filterEndDate) { + errors.end_date = 'Tanggal akhir wajib diisi'; + } + + setFilterErrors(errors); + + if (Object.keys(errors).length === 0) { + setIsSubmitted(true); + setCurrentPage(1); + filterModal.closeModal(); + } + }, [filterModal, filterStartDate, filterEndDate]); + // ===== DATA FETCHING ===== const { data: customerPayment, isLoading } = useSWR( isSubmitted ? () => { const params = { customer_id: - tableFilterState.customer_id.length > 0 - ? tableFilterState.customer_id.join(',') + filterCustomer.length > 0 + ? filterCustomer.map((v) => String(v.value)).join(',') : undefined, sales: - tableFilterState.sales.length > 0 - ? tableFilterState.sales.join(',') + filterSales.length > 0 + ? filterSales.map((v) => String(v.value)).join(',') : undefined, - date_type: tableFilterState.date_type || undefined, - start_date: tableFilterState.start_date || undefined, - end_date: tableFilterState.end_date || undefined, + date_type: filterDateType?.value as + | 'do_date' + | 'payment_date' + | undefined, + start_date: filterStartDate || undefined, + end_date: filterEndDate || undefined, page: currentPage, limit: pageSize, }; @@ -201,16 +162,19 @@ const CustomerPaymentTab = () => { > => { const params = { customer_id: - tableFilterState.customer_id.length > 0 - ? tableFilterState.customer_id.join(',') + filterCustomer.length > 0 + ? filterCustomer.map((v) => String(v.value)).join(',') : undefined, sales: - tableFilterState.sales.length > 0 - ? tableFilterState.sales.join(',') + filterSales.length > 0 + ? filterSales.map((v) => String(v.value)).join(',') : undefined, - date_type: tableFilterState.date_type || undefined, - start_date: tableFilterState.start_date || undefined, - end_date: tableFilterState.end_date || undefined, + date_type: filterDateType?.value as + | 'do_date' + | 'payment_date' + | undefined, + start_date: filterStartDate || undefined, + end_date: filterEndDate || undefined, limit: 100, page: 1, }; @@ -228,7 +192,13 @@ const CustomerPaymentTab = () => { return isResponseSuccess(response) ? (response.data as unknown as CustomerPaymentReport[]) : null; - }, [tableFilterState]); + }, [ + filterCustomer, + filterSales, + filterDateType, + filterStartDate, + filterEndDate, + ]); // ===== EXPORT HANDLERS ===== const handleExportExcel = useCallback(async () => { @@ -527,91 +497,164 @@ const CustomerPaymentTab = () => { className={{ wrapper: 'w-full', body: 'p-1!' }} >
- - + + } align='end' > - +
-
- - (tableFilterState.customer_id || []) - .map(String) - .includes(String(opt.value)) - )} - onChange={customerChangeHandler} - isLoading={isLoadingCustomers} - isClearable - /> - - (tableFilterState.sales || []) - .map(String) - .includes(String(opt.value)) - )} - onChange={salesChangeHandler} - isLoading={false} - isClearable - /> - option.value === tableFilterState.date_type - ) || null - } - onChange={dataTypeChangeHandler} - isLoading={false} - isClearable={false} - /> -
-
-
- - + + {/* Filter Modal */} + +
+ {/* Modal Header */} +
+
+ +

Filter Data

+
+ +
+
+
+
+ { + setFilterStartDate(e.target.value); + setFilterErrors((prev) => ({ ...prev, start_date: '' })); + }} + className={{ wrapper: 'w-full' }} + /> + {filterErrors.start_date && ( +

+ {filterErrors.start_date} +

+ )} +
+ +
+ { + setFilterEndDate(e.target.value); + setFilterErrors((prev) => ({ ...prev, end_date: '' })); + }} + className={{ wrapper: 'w-full' }} + /> + {filterErrors.end_date && ( +

+ {filterErrors.end_date} +

+ )} +
+
+ +
+ { + setFilterCustomer( + Array.isArray(val) ? val : val ? [val] : [] + ); + }} + isLoading={isLoadingCustomers} + isClearable + className={{ wrapper: 'w-full' }} + /> +
+ +
+ { + setFilterSales(Array.isArray(val) ? val : val ? [val] : []); + }} + isClearable + className={{ wrapper: 'w-full' }} + /> +
+ +
+ { + setFilterDateType(val as OptionType | null); + }} + isClearable={false} + className={{ wrapper: 'w-full' }} + /> +
+
+ + {/* Action Buttons */} +
+ + +
-
+ {!isSubmitted ? (
- Silakan pilih filter dan klik tombol Submit untuk menampilkan data. + Silakan klik tombol Filter untuk mengatur filter dan menampilkan + data.
) : isLoading ? (