diff --git a/src/pages/members/agent-balance/AgentBalance.tsx b/src/pages/members/agent-balance/AgentBalance.tsx index a66fc30..664e9db 100644 --- a/src/pages/members/agent-balance/AgentBalance.tsx +++ b/src/pages/members/agent-balance/AgentBalance.tsx @@ -15,7 +15,7 @@ import { DialogTitle, Typography, Button, - Box, + Box, Breadcrumbs, Link } from '@mui/material'; @@ -24,6 +24,7 @@ import { toast } from 'sonner'; import { Container, DataGridLoader, DataGridProvider, LoaderTransparant } from '@/components'; import { ListToolBar } from './ListToolbar'; import { toAbsoluteUrl } from '@/utils'; + const BASE_URL = apiConfig.service_customer; let initBalance = { @@ -52,10 +53,9 @@ const AgentBalance = () => { const [barcode, setBarcode] = useState(''); const [requested_date, setRequested_date] = useState(''); const [token_legacy, setToken_legacy] = useState(''); - // const [selectedMember, setSelectedMember] = useState(initBalance); useEffect(() => { - // fetchAgentBalance(); + // fetchAgentBalance(); }, []); const fetchAgentBalance = async (page: number, limit: number, sorting: any, filter: any) => { @@ -63,7 +63,7 @@ const AgentBalance = () => { let balances = await axios.get(`${BASE_URL}/customer/agent-balance`, { params: { limit: limit, - page: page + 1, // +1 because your API uses 1-based pages + page: page + 1, with_deleted: false, order_field: 'created_at', order_direction: 'DESC', @@ -80,6 +80,41 @@ const AgentBalance = () => { return { data: resBalance, totalCount: balances?.data.data.total_count }; }; + // ─── Export ─────────────────────────────────────────────────────────────────────────────── + const fetchExport = async (filter: any) => { + try { + toast.info('Preparing export…'); + + // API expects filter as array of { id, value } — same shape as columnFilters + const filterArray = Object.entries(filter) + .filter(([, value]) => value !== '' && value != null) + .map(([id, value]) => ({ id, value })); + + const res = await axios.get(`${BASE_URL}/customer/agent-balance/export-excel`, { + params: { + with_deleted: false, + order_field: 'created_at', + order_direction: 'DESC', + filter: JSON.stringify(filterArray), + specialFilter: true + }, + responseType: 'blob' + }); + + const url = URL.createObjectURL(new Blob([res.data])); + const link = document.createElement('a'); + link.href = url; + link.download = `agent_balance_export_${new Date().toISOString().slice(0, 10)}.xlsx`; + link.click(); + URL.revokeObjectURL(url); + toast.success('Export complete'); + } catch (error: any) { + const msg = error?.response?.data?.error || error.message; + toast.error(`Export failed: ${msg}`); + } + }; + // ───────────────────────────────────────────────────────────────────────────── + const openDialog = () => setIsDialogOpen(true); const closeDialog = () => { setIsDialogOpen(false); @@ -108,7 +143,6 @@ const AgentBalance = () => { await fetchAgentBalance(currentPage, pageSize, '', ''); closeDialog(); setIsReloading(false); - // fetchAgentBalance(); }; function formatDate(value: string) { @@ -139,24 +173,14 @@ const AgentBalance = () => { TPAY | Agent Balance - {/* setDialogOpen(false)} - title="Confirm Action" - content={''} - onYes={handleYes} - onNo={() => setDialogOpen(false)} - /> */}

Agent Balances

Dashboard - Members - Agent Balances @@ -166,7 +190,6 @@ const AgentBalance = () => { {isReloading && } {!isReloading && ( { createGroup={createGroup} onReload={handleReload} isReloading={isReloading} + onExport={fetchExport} /> } onRowSelectionChange={(selected, table: any) => { @@ -209,7 +233,7 @@ const AgentBalance = () => { ); }; -// ==================== +// ==================== const PaymentCard = ({ barcode, agent_name, @@ -335,4 +359,4 @@ const PaymentCard = ({ ); }; -export default AgentBalance; +export default AgentBalance; \ No newline at end of file diff --git a/src/pages/members/agent-balance/ListToolbar.tsx b/src/pages/members/agent-balance/ListToolbar.tsx index d066840..f4ed7a5 100644 --- a/src/pages/members/agent-balance/ListToolbar.tsx +++ b/src/pages/members/agent-balance/ListToolbar.tsx @@ -6,14 +6,13 @@ interface ListToolBarProps { createGroup: () => void; onReload: () => void; isReloading: boolean; + onExport: (filter: Record) => void; } -const ListToolBar = ({ createGroup, onReload, isReloading }: ListToolBarProps) => { +const ListToolBar = ({ createGroup, onReload, isReloading, onExport }: ListToolBarProps) => { const { table, reload } = useDataGrid(); const [usernameFilter, setUsernameFilter] = useState(''); const [msisdn, setMsisdn] = useState(''); - const [typeSearchValue, setSearchTypeValue] = useState(); - const [searchValue, setSearchValue] = useState(); const [fullname, setFullname] = useState(''); const [merchantName, setMerchantName] = useState(''); @@ -33,14 +32,27 @@ const ListToolBar = ({ createGroup, onReload, isReloading }: ListToolBarProps) = setMerchantName(e.target.value); }; - const handleSearch = (e: React.ChangeEvent) => { - e.preventDefault() - table.resetPageIndex() + /** Build the same filter object the table uses for server-side fetching */ + const buildFilter = (): Record => { + const filter: Record = {}; + if (msisdn) filter['msisdn'] = msisdn; + if (fullname) filter['fullname'] = fullname; + if (usernameFilter) filter['username'] = usernameFilter; + if (merchantName) filter['agent_name'] = merchantName; + return filter; + }; + + const handleSearch = (e: React.FormEvent) => { + e.preventDefault(); + table.resetPageIndex(); table.getColumn('username')?.setFilterValue(usernameFilter); table.getColumn('msisdn')?.setFilterValue(msisdn); table.getColumn('fullname')?.setFilterValue(fullname); table.getColumn('agent_name')?.setFilterValue(merchantName); - // if (!merchantName && !fullname && !msisdn && !usernameFilter) reload() + }; + + const handleExport = () => { + onExport(buildFilter()); }; return ( @@ -48,25 +60,30 @@ const ListToolBar = ({ createGroup, onReload, isReloading }: ListToolBarProps) =
-
handleSearch(e)}> +
- - - - - -
+ + + + + + +
-
+
+
); }; -export { ListToolBar }; +export { ListToolBar }; \ No newline at end of file