diff --git a/src/config/api.config.ts b/src/config/api.config.ts index c3c693c..d4948b1 100644 --- a/src/config/api.config.ts +++ b/src/config/api.config.ts @@ -10,8 +10,9 @@ interface apiConfigProps { service_disbursement: string; service_notification: string; service_feedback: string; - api_dashboard: string; service_card: string; + api_dashboard:string + } const API_URL = import.meta.env.VITE_APP_API_URL; diff --git a/src/pages/cards/history-card/HistoryCard.tsx b/src/pages/cards/history-card/HistoryCard.tsx new file mode 100644 index 0000000..c794a92 --- /dev/null +++ b/src/pages/cards/history-card/HistoryCard.tsx @@ -0,0 +1,50 @@ +import { Container, DataGridInner } from '@/components'; +// import { +// // ManageTransferTypeContext, +// // ManageTransferTypeContextProvider +// // } from './hooks/ManageTransferTypeContext'; +// // import AddDialog from './blocks/AddDialog'; +import { Breadcrumbs, Link } from '@mui/material'; +// import DeleteDialog from './blocks/DeleteDialog'; +// import { EditDialog } from './blocks/EditDialog'; +import { Helmet } from 'react-helmet'; +import { ManageHistoryCardsProvider } from './hooks/ManageHistoryCard'; +// import { ManageCardsContext, ManageCardsProvider } from './hooks/ManageCardContext'; +// import RevokeDialog from './blocks/RevokeDialog'; + +const HistoryCard = () => { + return ( + <> + + TPAY | Card History + + + +

History Cards

+ + + Dashboard + + + + History Cards + + + + History Cards + + +
+ +
+ {/* */} + {/* + + */} +
+
+ + ); +}; + +export default HistoryCard; diff --git a/src/pages/cards/history-card/hooks/ManageHistoryCard.tsx b/src/pages/cards/history-card/hooks/ManageHistoryCard.tsx new file mode 100644 index 0000000..ead5f17 --- /dev/null +++ b/src/pages/cards/history-card/hooks/ManageHistoryCard.tsx @@ -0,0 +1,267 @@ +import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components'; +import { Toaster } from '@/components/ui/sonner'; +import { apiConfig } from '@/config/api.config'; +import { ColumnDef } from '@tanstack/react-table'; +import axios from 'axios'; +import React, { createContext, useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallApi } from '@/hooks'; +import { Button } from '@/components/ui/button'; +import { useNavigate } from 'react-router'; + +interface CardProps { + id: number; + serial_number: string; + provisioning_date: string; + customer: CustomerProps; +} +interface CustomerProps { + fullname: string; + msisdn: string; +} + +interface ContextProps { + cards: CardProps[]; + showSearchDialog: boolean; + handleSearchDialog: (show: boolean) => void; + showRevokeDialog: boolean; + handleRevokeDialog: (show: boolean, selected_card: string | null) => void; + showAddDialog: boolean; + handleAddDialog: (show: boolean) => void; + showDeleteDialog: boolean; + handleDeleteDialog: (show: boolean, selected_card: string | null) => void; + selectedCard: string | null; + getCardsLists: ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any + ) => Promise<{ data: CardProps[]; totalCount: number } | undefined>; +} + +const initialProps: ContextProps = { + cards: [], + showSearchDialog: false, + handleSearchDialog: (show: boolean) => {}, + showRevokeDialog: false, + handleRevokeDialog: (show: boolean, selected_card: string | null) => {}, + showAddDialog: false, + handleAddDialog: (show: boolean) => {}, + showDeleteDialog: false, + handleDeleteDialog: (show: boolean, selected_card: string | null) => {}, + selectedCard: null, + getCardsLists: async () => ({ data: [], totalCount: 0 }) +}; + +const ManageHistoryCardsContext = createContext(initialProps); +const API_URL = apiConfig.service_master_data; +const API_URL_CARD = apiConfig.service_card; + +const ManageHistoryCardsProvider = ({ children }: { children: React.ReactNode }) => { + const [showSearchDialog, setShowSearchDialog] = useState(false); + const [showRevokeDialog, setShowRevokeDialog] = useState(false); + const [showAddDialog, setShowAddDialog] = useState(false); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const [selectedCard, setSelectedCard] = useState(null); + const [cards, setCards] = useState([]); + const { GetData } = useCallApi(); + + const handleSearchDialog = useCallback((show: boolean) => { + setShowSearchDialog(show); + }, []); + + const handleAddDialog = useCallback((show: boolean) => { + setShowAddDialog(show); + }, []); + + const handleRevokeDialog = useCallback((show: boolean, selected_card: string | null) => { + setSelectedCard(show ? selected_card : null); + setShowRevokeDialog(show); + }, []); + + const handleDeleteDialog = useCallback((show: boolean, selected_card: string | null) => { + setSelectedCard(show ? selected_card : null); + setShowDeleteDialog(show); + }, []); + + const columns = useMemo[]>( + () => [ + { + accessorFn: (row) => row.id, + accessorKey: 'id', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.serial_number, + accessorKey: 'serial_number', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.serial_number, + accessorKey: 'serial_number', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.action, + accessorKey: 'action', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + +{ + accessorFn: (row) => { + const date = new Date(row.created_at); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + return `${year}-${month}-${day}, ${hours}.${minutes}`; + }, + accessorKey: 'created_at', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } +} + // { + // id: 'actionss', + // header: ({ column }) => , + // enableSorting: false, + // enableHiding: false, + // cell: (data) => { + // const row = data.row.original; + // return ( + // <> + // + // {/* */} + // + // ); + // }, + // meta: { + // headerClassName: 'w-[100px] text-center', + // cellClassName: 'text-center' + // } + // } + ], + [handleRevokeDialog, handleDeleteDialog] + ); + + // Fixed function signature to match the interface + const getCardsLists = useCallback(async ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any + ) => { + try { + const sorting = order_field ? [{ id: order_field, desc: order_direction === 'ASC' }] : [{ id: 'created_at', desc: false }]; + const response = await GetData(`${API_URL_CARD}/card/list-history`, { + limit, + page: page + 1, + with_deleted, + order_field, + order_direction, + filter: JSON.stringify({}) + }); + setCards(response?.data.list || []); + return { data: response?.data.list || [], totalCount: response?.data.total_count || 0 }; + } catch (error) { + console.error('Error fetching cards', error); + return { data: [], totalCount: 0 }; + } + }, [GetData]); + + // Internal function for DataGrid + const getCardsListsForDataGrid = useCallback(async (page: number, limit: number, sorting: any, filter: any) => { + try { + const sortingArray = sorting.length === 0 ? [{ id: 'created_at', desc: false }] : sorting; + const filterObj = filter.length === 0 ? {} : { any: filter[0].value?.toLowerCase() }; + + const response = await GetData(`${API_URL_CARD}/card/list-history`, { + limit, + page: page + 1, + with_deleted: false, + order_field: sortingArray[0].id, + order_direction: sortingArray[0].desc === false ? 'DESC' : 'ASC', + // filter: JSON.stringify(filterObj) + }); + + setCards(response?.data.list || []); + return { data: response?.data.list || [], totalCount: response?.data.total_count || 0 }; + } catch (error) { + console.error('Error fetching cards', error); + return { data: [], totalCount: 0 }; + } + }, [GetData]); + + return ( + + + + + getCardsListsForDataGrid(pageIndex, pageSize, sorting, columnFilters) + } + > + {children} + + + ); +}; + +export { ManageHistoryCardsProvider, ManageHistoryCardsContext }; +export type { CardProps }; \ No newline at end of file diff --git a/src/pages/cards/history-card/hooks/useManageHistoryCard.tsx b/src/pages/cards/history-card/hooks/useManageHistoryCard.tsx new file mode 100644 index 0000000..6d573ca --- /dev/null +++ b/src/pages/cards/history-card/hooks/useManageHistoryCard.tsx @@ -0,0 +1,14 @@ + +import { useContext } from 'react'; +import { ManageHistoryCardsContext } from './ManageHistoryCard'; +// import { ManageCardsContext } from './ManageCardContext'; + +const useManageHistoryCardsContext = () => { + const context = useContext(ManageHistoryCardsContext); + + if (!context) throw new Error('useManageHistoryCardsContext must be used within AuthProvider'); + + return context; +}; + +export { useManageHistoryCardsContext }; diff --git a/src/pages/cards/manage-card/ManageCard.tsx b/src/pages/cards/manage-card/ManageCard.tsx new file mode 100644 index 0000000..8cd4dd6 --- /dev/null +++ b/src/pages/cards/manage-card/ManageCard.tsx @@ -0,0 +1,51 @@ +import { Container, DataGridInner } from '@/components'; +// import { +// // ManageTransferTypeContext, +// // ManageTransferTypeContextProvider +// // } from './hooks/ManageTransferTypeContext'; +// // import AddDialog from './blocks/AddDialog'; +import { Breadcrumbs, Link } from '@mui/material'; +// import DeleteDialog from './blocks/DeleteDialog'; +// import { EditDialog } from './blocks/EditDialog'; +import { Helmet } from 'react-helmet'; +import { ManageCardsContext, ManageCardsProvider } from './hooks/ManageCardContext'; +import RevokeDialog from './blocks/RevokeDialog'; + +const ManageCards = () => { + + return ( + <> + + TPAY | Manage Cards + + + +

Manage Cards

+ + + Dashboard + + + + Manage Cards + + + + Manage Cards + + +
+ +
+ + {/* + + */} + +
+
+ + ); +}; + +export default ManageCards; diff --git a/src/pages/cards/manage-card/blocks/RevokeDialog.tsx b/src/pages/cards/manage-card/blocks/RevokeDialog.tsx new file mode 100644 index 0000000..226998f --- /dev/null +++ b/src/pages/cards/manage-card/blocks/RevokeDialog.tsx @@ -0,0 +1,273 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { Alert, useDataGrid } from '@/components'; +import axios from 'axios'; +import { apiConfig } from '@/config/api.config'; +import { toast } from 'sonner'; +import { + Dialog, + DialogBody, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Button } from '@/components/ui/button'; +import { getAuth, useAuthContext } from '@/auth'; +import { useCallApi } from '@/hooks'; +import { doSaveLogActivity } from '@/actions/GlobalActions'; +import { RefreshCw, AlertTriangle } from 'lucide-react'; +import { useManageCardsContext } from '../hooks/useManageCardContext'; + +const API_URL = apiConfig.service_card; + +const RevokeDialog = () => { + const { showRevokeDialog, handleRevokeDialog, selectedCard, cards } = useManageCardsContext(); + const { reload } = useDataGrid(); + const { PostData, PutData, GetData } = useCallApi(); + const parsedUser = getAuth()?.user; + const [isLoading, setIsLoading] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); + const [alert, setAlert] = useState({ + show: false, + message: '' + }); + + const [cardDetails, setCardDetails] = useState({ + id: '', + serial_number: '', + customer_fullname: '', + customer_msisdn: '', + provisioning_date: '' + }); + + const [errors, setErrors] = useState>({}); + console.log('selectedCard', selectedCard); + const resetForm = () => { + setCardDetails({ + id: '', + serial_number: '', + customer_fullname: '', + customer_msisdn: '', + provisioning_date: '' + }); + setErrors({}); + setAlert({ show: false, message: '' }); + }; + + const doRevokeCard = useCallback( + async (e: React.FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); + + try { + const response = await PostData(`${API_URL}/card/revoke`, { + id: selectedCard + }); + + if (response?.status) { + handleRevokeDialog(false, null); + resetForm(); + toast.success('Card has been revoked successfully'); + reload(); + + const createActivity = { + module: 'Manage Card', + description: `Revoke Card => ID: ${selectedCard}, Serial: ${cardDetails.serial_number}`, + action: 'C' + }; + + doSaveLogActivity(createActivity); + } else { + toast.error('Failed to revoke card'); + setAlert({ show: true, message: response?.message || 'Failed to revoke card' }); + } + } catch (error: any) { + console.error('Error revoking card:', error); + toast.error('Something went wrong, please try again.'); + setAlert({ + show: true, + message: error?.response?.data?.message || 'Something went wrong, please try again.' + }); + } finally { + setIsSubmitting(false); + } + }, + [selectedCard, cardDetails.serial_number, PostData, handleRevokeDialog, reload] + ); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + doRevokeCard(e); + }; + + const doFetchCardData = useCallback( + async (id: string) => { + setIsLoading(true); + try { + // Find card details from the cards context or fetch from API + const card = cards.find((c) => c.id.toString() === id); + + if (card) { + setCardDetails({ + id: card.id.toString(), + serial_number: card.serial_number, + customer_fullname: card.customer.fullname, + customer_msisdn: card.customer.msisdn, + provisioning_date: new Date(card.provisioning_date).toLocaleDateString() + }); + } else { + // If not found in context, fetch from API + const response = await GetData(`${API_URL}/card/getdata/${id}`, { id }); + + if (response?.status && response.data) { + const cardData = response.data; + setCardDetails({ + id: cardData.id.toString(), + serial_number: cardData.serial_number, + customer_fullname: cardData.customer?.fullname || '', + customer_msisdn: cardData.customer?.msisdn || '', + provisioning_date: new Date(cardData.provisioning_date).toLocaleDateString() + }); + } else { + setAlert({ show: true, message: 'Failed to load card details' }); + } + } + } catch (error) { + console.error('Error fetching card data:', error); + setAlert({ show: true, message: 'Failed to load card details' }); + } finally { + setIsLoading(false); + } + }, + [cards, GetData] + ); + + useEffect(() => { + if (selectedCard && showRevokeDialog) { + doFetchCardData(selectedCard); + } + }, [selectedCard, showRevokeDialog, doFetchCardData]); + + useEffect(() => { + if (showRevokeDialog === false) { + resetForm(); + } + }, [showRevokeDialog]); + + return ( + handleRevokeDialog(open, null)}> + + + + + Revoke Card + + + + +
+ {alert.show && ( + +

{alert.message}

+
+ )} + + {isLoading ? ( +
+
+
+
+
+
+
+
+
+
+

Loading Card Details...

+
+ ) : ( +
+
+ {/* Card Details Display +
+

Card Information

+
+
+ Card ID: +

{cardDetails.id}

+
+
+ Serial Number: +

{cardDetails.serial_number}

+
+
+ Customer Name: +

{cardDetails.customer_fullname}

+
+
+ Customer MSISDN: +

{cardDetails.customer_msisdn}

+
+
+ Provisioning Date: +

{cardDetails.provisioning_date}

+
+
+
*/} +

Are you sure you want to revoke this card? This action cannot be undone.

+

+ Revoking this card will deactivate it permanently. The customer will no longer + be able to use this card for any transactions or services. +

+ {/* Warning Message */} + {/*
+
+ +
+
Warning
+

+ Revoking this card will deactivate it permanently. The customer will no + longer be able to use this card for any transactions or services. +

+
+
+
*/} + + {/* Action Buttons */} +
+ + +
+
+
+ )} +
+
+
+
+ ); +}; + +export default RevokeDialog; diff --git a/src/pages/cards/manage-card/hooks/ManageCardContext.tsx b/src/pages/cards/manage-card/hooks/ManageCardContext.tsx new file mode 100644 index 0000000..f2c839e --- /dev/null +++ b/src/pages/cards/manage-card/hooks/ManageCardContext.tsx @@ -0,0 +1,264 @@ +import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components'; +import { Toaster } from '@/components/ui/sonner'; +import { apiConfig } from '@/config/api.config'; +import { ColumnDef } from '@tanstack/react-table'; +import axios from 'axios'; +import React, { createContext, useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallApi } from '@/hooks'; +import { Button } from '@/components/ui/button'; +import { useNavigate } from 'react-router'; + +interface CardProps { + id: number; + serial_number: string; + provisioning_date: string; + customer: CustomerProps; +} +interface CustomerProps { + fullname: string; + msisdn: string; +} + +interface ContextProps { + cards: CardProps[]; + showSearchDialog: boolean; + handleSearchDialog: (show: boolean) => void; + showRevokeDialog: boolean; + handleRevokeDialog: (show: boolean, selected_card: string | null) => void; + showAddDialog: boolean; + handleAddDialog: (show: boolean) => void; + showDeleteDialog: boolean; + handleDeleteDialog: (show: boolean, selected_card: string | null) => void; + selectedCard: string | null; + getCardsLists: ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any + ) => Promise<{ data: CardProps[]; totalCount: number } | undefined>; +} + +const initialProps: ContextProps = { + cards: [], + showSearchDialog: false, + handleSearchDialog: (show: boolean) => {}, + showRevokeDialog: false, + handleRevokeDialog: (show: boolean, selected_card: string | null) => {}, + showAddDialog: false, + handleAddDialog: (show: boolean) => {}, + showDeleteDialog: false, + handleDeleteDialog: (show: boolean, selected_card: string | null) => {}, + selectedCard: null, + getCardsLists: async () => ({ data: [], totalCount: 0 }) +}; + +const ManageCardsContext = createContext(initialProps); +const API_URL = apiConfig.service_master_data; +const API_URL_CARD = apiConfig.service_card; + +const ManageCardsProvider = ({ children }: { children: React.ReactNode }) => { + const [showSearchDialog, setShowSearchDialog] = useState(false); + const [showRevokeDialog, setShowRevokeDialog] = useState(false); + const [showAddDialog, setShowAddDialog] = useState(false); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const [selectedCard, setSelectedCard] = useState(null); + const [cards, setCards] = useState([]); + const { GetData } = useCallApi(); + + const handleSearchDialog = useCallback((show: boolean) => { + setShowSearchDialog(show); + }, []); + + const handleAddDialog = useCallback((show: boolean) => { + setShowAddDialog(show); + }, []); + + const handleRevokeDialog = useCallback((show: boolean, selected_card: string | null) => { + setSelectedCard(show ? selected_card : null); + setShowRevokeDialog(show); + }, []); + + const handleDeleteDialog = useCallback((show: boolean, selected_card: string | null) => { + setSelectedCard(show ? selected_card : null); + setShowDeleteDialog(show); + }, []); + + const columns = useMemo[]>( + () => [ + { + accessorFn: (row) => row.id, + accessorKey: 'id', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.serial_number, + accessorKey: 'serial_number', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.customer.fullname, + accessorKey: 'customer.fullname', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.customer.msisdn, + accessorKey: 'customer.msisdn', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => { + const date = new Date(row.provisioning_date); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }, + accessorKey: 'provisioning_date', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + id: 'actions', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + cell: (data) => { + const row = data.row.original; + return ( + <> + + {/* */} + + ); + }, + meta: { + headerClassName: 'w-[100px] text-center', + cellClassName: 'text-center' + } + } + ], + [handleRevokeDialog, handleDeleteDialog] + ); + + // Fixed function signature to match the interface + const getCardsLists = useCallback(async ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any + ) => { + try { + const sorting = order_field ? [{ id: order_field, desc: order_direction === 'ASC' }] : [{ id: 'provisioning_date', desc: false }]; + const response = await GetData(`${API_URL_CARD}/card/list`, { + limit, + page: page + 1, + with_deleted, + order_field, + order_direction, + filter: JSON.stringify({}) + }); + setCards(response?.data.list || []); + return { data: response?.data.list || [], totalCount: response?.data.total_count || 0 }; + } catch (error) { + console.error('Error fetching cards', error); + return { data: [], totalCount: 0 }; + } + }, [GetData]); + + // Internal function for DataGrid + const getCardsListsForDataGrid = useCallback(async (page: number, limit: number, sorting: any, filter: any) => { + try { + const sortingArray = sorting.length === 0 ? [{ id: 'provisioning_date', desc: false }] : sorting; + const filterObj = filter.length === 0 ? {} : { any: filter[0].value?.toLowerCase() }; + + const response = await GetData(`${API_URL_CARD}/card/list`, { + limit, + page: page + 1, + with_deleted: false, + order_field: sortingArray[0].id, + order_direction: sortingArray[0].desc === false ? 'DESC' : 'ASC', + filter: JSON.stringify(filterObj) + }); + + setCards(response?.data.list || []); + return { data: response?.data.list || [], totalCount: response?.data.total_count || 0 }; + } catch (error) { + console.error('Error fetching cards', error); + return { data: [], totalCount: 0 }; + } + }, [GetData]); + + return ( + + + + + getCardsListsForDataGrid(pageIndex, pageSize, sorting, columnFilters) + } + > + {children} + + + ); +}; + +export { ManageCardsProvider, ManageCardsContext }; +export type { CardProps }; \ No newline at end of file diff --git a/src/pages/cards/manage-card/hooks/useManageCardContext.tsx b/src/pages/cards/manage-card/hooks/useManageCardContext.tsx new file mode 100644 index 0000000..86c832a --- /dev/null +++ b/src/pages/cards/manage-card/hooks/useManageCardContext.tsx @@ -0,0 +1,12 @@ +import { useContext } from 'react'; +import { ManageCardsContext } from './ManageCardContext'; + +const useManageCardsContext = () => { + const context = useContext(ManageCardsContext); + + if (!context) throw new Error('useManageCardsContext must be used within AuthProvider'); + + return context; +}; + +export { useManageCardsContext }; diff --git a/src/routing/AppRoutingSetup.tsx b/src/routing/AppRoutingSetup.tsx index 3544d1e..6d162bd 100644 --- a/src/routing/AppRoutingSetup.tsx +++ b/src/routing/AppRoutingSetup.tsx @@ -51,6 +51,8 @@ import AgentBalance from '@/pages/members/agent-balance/AgentBalance'; import HistoryTransactionDisbursement from '@/pages/disbursement/history-transaction/HistoryTransaction'; import SearchMember from '@/pages/members/search-member/SearchMember'; import WithdrawalEmoney from '@/pages/transaction/withdrawl-emoney/WithdrawalEmoney'; +import ManageCards from '@/pages/cards/manage-card/ManageCard'; +import HistoryCard from '@/pages/cards/history-card/HistoryCard'; // DISBURSEMENT @@ -98,6 +100,11 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> + {/* cards */} + } /> + + } /> + } /> } />