import React, { createContext, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; // FIXED HERE import { ColumnDef } from '@tanstack/react-table'; import axios from 'axios'; import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components'; import { Toaster } from '@/components/ui/sonner'; import { apiConfig } from '@/config/api.config'; import { useCallApi } from '@/hooks'; import ListToolbar from '../blocks/ListToolbar'; import DetailApprovalTransaction from '../blocks/DetailApprovalTransaction'; import ApprovalDialog from '../blocks/ApprovalDialog'; import { Button } from '@/components/ui/button'; interface ApprovalTransactionProps { id: number; name: string; } interface ContextProps { getTransactionLists: ( page: number, limit: number, sorting: any, filter: any ) => Promise<{ data: ApprovalTransactionProps[]; totalCount: number } | undefined>; showDetailDialog: boolean; setShowDetailDialog: React.Dispatch>; showApprovalDialog: boolean; setShowApprovalDialog: React.Dispatch>; selectedTransactionId: number | null; setSelectedTransactionId: React.Dispatch>; selectedTransactionIdForApproval: number | null; setSelectedTransactionIdForApproval: React.Dispatch>; } const initialProps: ContextProps = { getTransactionLists: async () => ({ data: [], totalCount: 0 }), showDetailDialog: false, setShowDetailDialog: () => { }, showApprovalDialog: false, setShowApprovalDialog: () => { }, selectedTransactionId: null, setSelectedTransactionId: () => { }, selectedTransactionIdForApproval: null, setSelectedTransactionIdForApproval: () => { }, }; const ManageApprovalTransactionContext = createContext(initialProps); const API_URL = apiConfig.transaction; const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode }) => { const [showDetailDialog, setShowDetailDialog] = useState(false); const [showApprovalDialog, setShowApprovalDialog] = useState(false); const [selectedTransactionId, setSelectedTransactionId] = useState(null); const [selectedTransactionIdForApproval, setSelectedTransactionIdForApproval] = useState(null); const [transaction, setTransaction] = useState([]); const { GetData } = useCallApi(); const navigate = useNavigate(); const columns = useMemo[]>( () => [ { accessorKey: 'code', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, { accessorKey: 'transaction_date', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, cell: ({ row }) => { const transactionDate = new Date(row.original.transaction_date); return transactionDate.toLocaleString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }); }, }, { accessorKey: 'origin_name', header: ({ column }) => ( ), enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' }, cell: ({ row }) => row.original.origin_customer?.fullname ?? '' }, { accessorFn: (row) => { const purchase = row?.purchase?.destination_customer?.fullname; const transfer = row?.transfer?.destination_customer?.fullname; return purchase ?? transfer ?? ""; }, id: 'destination_customer.fullname', header: ({ column }) => ( ), enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, }, { accessorFn: (row) => { const purchaseAmount = row?.purchase?.amount; const transferAmount = row?.transfer?.amount; return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }).format(purchaseAmount ?? transferAmount ?? 0); }, id: 'amount', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, }, { accessorFn: (row) => { const purchaseFee = row?.purchase?.fee_amount; const transferFee = row?.transfer?.fee_amount; return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }).format(purchaseFee ?? transferFee ?? 0); }, id: 'feeamount', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, }, { accessorFn: (row) => { switch (row.status) { case 'C': return 'COMPLETE'; case 'F': return 'FAILED'; case 'O': return 'ON PROCESS'; case "P" : return 'PENDING'; case 'R': return 'ROLLBACK'; case 'S': return 'REVERSAL'; default: return 'UNKNOWN'; } }, id: 'status', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, }, { accessorKey: 'description', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, }, { accessorKey: 'type.name', header: ({ column }) => , enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]', }, }, { accessorKey: 'status_approve', header: 'Status Approval', cell: ({ row }) => { const statusCode = row.original.status_approve; let label = ''; let badgeClass = ''; switch (statusCode) { case 'Y': label = 'APPROVED'; badgeClass = 'bg-green-100 text-green-800'; break; case 'N': label = 'REJECTED'; badgeClass = 'bg-red-100 text-red-800'; break; case 'W': label = 'WAITING APPROVAL'; badgeClass = 'bg-gray-100 text-gray-800'; break; } return ( {label} ); }, }, { id: 'actions', header: ({ column }) => , enableSorting: false, enableHiding: false, cell: (data) => { const row = data.row.original; return (
); }, meta: { headerClassName: 'w-[100px]', cellClassName: 'text-center', }, }, ], [] ); const getTransactionLists = async (page: number, limit: number, sorting: any, filter: any) => { try { const today = new Date(); const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); // Default values let startdate = firstDayOfMonth.toISOString().split('T')[0]; let enddate = today.toISOString().split('T')[0]; let transactioncode = ''; let approvalstatus = ''; if (Array.isArray(filter)) { filter.forEach((f: any) => { // console.log(f.id); if (f.id === 'transaction_date' && f.value?.from && f.value?.to) { startdate = f.value.from; enddate = f.value.to; } if (f.id === 'code' && f.value) { transactioncode = f.value; } if (f.id === 'status_approve' && f.value) { approvalstatus = f.value; } }); } // ✅ Declare formattedFilter early const formattedFilter: any = { "Transactions.transaction_date": { from: `${startdate} 00:00:00`, to: `${enddate} 23:59:59` } }; if (Array.isArray(filter)) { let searchType = ''; let codeValue = ''; // Ambil code dan searchtype dulu filter.forEach((f: any) => { if (f.id === 'code' && f.value) { codeValue = f.value; } if (f.id === 'searchtype' && f.value) { searchType = f.value; } if (f.id === 'transaction_date' && f.value?.from && f.value?.to) { startdate = f.value.from; enddate = f.value.to; formattedFilter["Transactions.transaction_date"] = { from: `${startdate} 00:00:00`, to: `${enddate} 23:59:59` }; } }); // Terapkan berdasarkan searchtype + code if (searchType && codeValue) { if (searchType === "msisdn") { formattedFilter["Transactions.origin_msisdn"] = { like: `%${codeValue}%` }; } else if (searchType === "fullname") { formattedFilter["Transactions.origin_name"] = { like: `%${codeValue}%` }; } else if (searchType === "trxid") { formattedFilter["Transactions.code"] = { like: `%${codeValue}%` }; } } } // Handle approval status filter formattedFilter["Transactions.status_approve"] = approvalstatus ? approvalstatus : { in: ["W", "Y", "N"] }; // Fetch data from API const response = await GetData(`${API_URL}/transaction/history`, { limit, page: page + 1, with_deleted: false, order_field: "Transactions.created_at", order_direction: 'DESC', filter: JSON.stringify(formattedFilter), }); if (!response || !response.data) { console.warn('No data received:', response); return { data: [], totalCount: 0 }; } setTransaction(response.data.list); // Assuming this is a state setter return { data: response.data.list, totalCount: response.data.total_count }; } catch (error) { console.error('Error fetching transaction', error); return { data: [], totalCount: 0 }; // Fail-safe fallback } }; return ( } layout={{ card: true }} sorting={[{ id: 'id', desc: false }]} serverSide={true} onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => getTransactionLists(pageIndex, pageSize, sorting, columnFilters) } > {children} ); }; export { ApprovalTransactionProvider, ManageApprovalTransactionContext }; export type { ApprovalTransactionProps };