From 59a8f364d767da0549b670ea0268f58b78c94adb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Apr 2025 18:37:31 +0700 Subject: [PATCH 01/14] fix group --- src/pages/groups/ManageGroups.tsx | 6 +++++- src/pages/members/manage-members/blocks/DetailMember.tsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/groups/ManageGroups.tsx b/src/pages/groups/ManageGroups.tsx index 7704ad1..55ae1eb 100644 --- a/src/pages/groups/ManageGroups.tsx +++ b/src/pages/groups/ManageGroups.tsx @@ -89,6 +89,10 @@ const ManageGroups = () => { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); + if (!formData.groupName) return toast.warning(`Group name can not be empty!`) + if (!formData.status) return toast.warning(`Status can not be empty!`) + if (!formData.description) return toast.warning(`Description can not be empty!`) + setIsDialogOpen(false); setDialogOpen(true); }; @@ -198,7 +202,7 @@ const ManageGroups = () => {
- Create New Group + {dialogType==='create'?"Create New Group":"Update Group"} - - - ); - }, - meta: { - headerClassName: 'w-[100px]', - cellClassName: 'text-center' - } - } - ], - [handleEditFeeDialog, handleDeleteFeeDialog] - ); + try { + const response = await GetData( + `${API_URL}/transactionfees/getdatabytransactiontype/${selectedTransferType}`, + {} + ); - return ( -
-
-

Manage Transaction Fee

-
- - - } - sorting={[{ id: 'id', desc: true }]} - serverSide={true} - onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => - doGetTransferFeeListData(pageIndex, pageSize, sorting, columnFilters) - } - > - {children} + // console.log('API Response:', response?.data); - - -
- ); + return { + data: response?.data, + totalCount: 1 + }; + } catch (error) { + console.error('Error fetching transaction fees by transaction type:', error); + return { data: [], totalCount: 0 }; + } }; - export { ManageTransferFeeContext, ManageTransferFeeContextProvider }; + const columns = useMemo[]>( + () => [ + { + accessorFn: (row) => row.name, + id: 'name', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[200px]' } + }, + { + accessorFn: (row) => row.description, + id: 'description', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row) => row.minimum_amount, + id: 'minimum_amount', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[150px]' } + }, + { + accessorFn: (row) => row.maximum_amount, + id: 'maximum_amount', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[150px]' } + }, + { + accessorFn: (row) => row.fee_amount, + id: 'fee_amount', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[150px]' } + }, + { + accessorFn: (row) => row.deduct_amount, + id: 'deduct_amount', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[150px]' } + }, + { + accessorFn: (row) => row.deduct_percentage, + id: 'deduct_percentage', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[150px]' } + }, + + { + accessorFn: (row) => row.period_start?.split('T')[0], + id: 'period_start', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[200px]' } + }, + { + accessorFn: (row) => row.period_end?.split('T')[0], + id: 'period_end', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[200px]' } + }, + { + accessorFn: (row) => row.transaction_type?.name, + id: 'transactionTypeId', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row: { credit_to: string }) => { + const mapping: Record = { + D: 'Destination Member', + S: 'Source Member', + I: 'Input Customer' + }; + + return mapping[row.credit_to] || 'Unknown'; + }, + id: 'credit_to', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row) => { + if (row.credit_to === 'S' || row.credit_to === 'D' || !row.credit_destination) { + return 'N/A'; + } + return row.credit_destination?.fullname; + }, + id: 'credit_destination', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row) => row.credit_destination_account?.description, + id: 'credit_destination_account', + header: ({ column }) => ( + + ), + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row: { deduct_from: string }) => { + const mapping: Record = { + D: 'Destination Member', + S: 'Source Member' + }; + + return mapping[row.deduct_from]; + }, + id: 'deduct_from', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row) => row.deduct_from_account?.description, + id: 'deduct_from_account', + header: ({ column }) => ( + + ), + enableSorting: true, + enableHiding: false, + meta: { headerClassName: 'w-[250px]' } + }, + { + accessorFn: (row) => row.priority, + id: 'priority', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + cell: ({ row }) => { + const isActive = row.original.priority === 'Y'; + + return ( + + {isActive ? 'Yes' : 'No'} + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + }, + { + accessorFn: (row) => row.status, + id: 'status', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + cell: ({ row }) => { + const isActive = row.original.status === 'Y'; + + return ( + + {isActive ? 'Active' : 'Inactive'} + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + }, + { + accessorFn: (row) => row.status_include, + id: 'status_include', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + cell: ({ row }) => { + const isActive = row.original.status_include === 'Y'; + + return ( + + {isActive ? 'Yes' : 'No'} + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + }, + { + id: 'actions', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + cell: (data) => { + const row = data.row.original; + return ( + <> + + + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + } + ], + [handleEditFeeDialog, handleDeleteFeeDialog] + ); + + return ( +
+
+

Manage Transaction Fee

+
+ + + } + sorting={[{ id: 'id', desc: true }]} + serverSide={true} + onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => + doGetTransferFeeListData(pageIndex, pageSize, sorting, columnFilters) + } + > + {children} + + +
+ ); +}; + +export { ManageTransferFeeContext, ManageTransferFeeContextProvider }; diff --git a/src/pages/transfer/transfertype/blocks/AddDialog.tsx b/src/pages/transfer/transfertype/blocks/AddDialog.tsx index 6d35adc..6e5f51f 100644 --- a/src/pages/transfer/transfertype/blocks/AddDialog.tsx +++ b/src/pages/transfer/transfertype/blocks/AddDialog.tsx @@ -76,7 +76,6 @@ const AddDialog = () => { wallet_origin: '', wallet_destination: '', - minimum_amount: 0, maximum_amount: 0, max_transaction_per_day: 0, @@ -141,13 +140,13 @@ const AddDialog = () => { toast.success('Success Create Transfer Type'); reload(); resetForm(); - const createActivity = { - module: 'Manage Transfer Type', - description: `Create Transfer Type => ${formField.name}`, - action: 'C' - }; + const createActivity = { + module: 'Manage Transfer Type', + description: `Create Transfer Type => ${formField.name}`, + action: 'C' + }; - doSaveLogActivity(createActivity); + doSaveLogActivity(createActivity); } }) .finally(() => { @@ -222,7 +221,7 @@ const AddDialog = () => { page: 1, with_deleted: false, order_field: 'wallets.name', - order_direction: 'ASC', + order_direction: 'ASC' }; const response = await GetData(`${API_URL_MASTERDATA}/wallet/list`, params); // console.log(response) @@ -265,11 +264,11 @@ const AddDialog = () => {
{alert.show && ( -
- -

{alert.message}

-
-
+
+ +

{alert.message}

+
+
)}
@@ -439,11 +438,10 @@ const AddDialog = () => {
-
@@ -458,7 +456,7 @@ const AddDialog = () => { - Disbursement + Disbursement Other Change Group Emoney Customer to Agent Change Group Emoney Agent to Customer diff --git a/src/pages/transfer/transfertype/blocks/DeleteDialog.tsx b/src/pages/transfer/transfertype/blocks/DeleteDialog.tsx index e4c51ad..ec35bf1 100644 --- a/src/pages/transfer/transfertype/blocks/DeleteDialog.tsx +++ b/src/pages/transfer/transfertype/blocks/DeleteDialog.tsx @@ -1,4 +1,10 @@ -import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Alert, useDataGrid } from '@/components'; import { useCallback, useState } from 'react'; @@ -12,7 +18,8 @@ import { doSaveLogActivity } from '@/actions/GlobalActions'; const API_URL = apiConfig.service_transaction; const DeleteDialog = () => { - const { showDeleteDialog, handleDeleteDialog, selectedTransferType } = useManageTransferTypeContext(); + const { showDeleteDialog, handleDeleteDialog, selectedTransferType } = + useManageTransferTypeContext(); const { reload } = useDataGrid(); const { DeleteData } = useCallApi(); const [alert, setAlert] = useState({ @@ -26,9 +33,12 @@ const DeleteDialog = () => { return; } - const response = await DeleteData(`${API_URL}/transactiontype/delete/${selectedTransferType}/false`, { - id: selectedTransferType - }); + const response = await DeleteData( + `${API_URL}/transactiontype/delete/${selectedTransferType}/false`, + { + id: selectedTransferType + } + ); if (response?.status) { setAlert({ show: false, message: '' }); @@ -37,7 +47,7 @@ const DeleteDialog = () => { const createActivity = { module: 'Manage Transfer Type', description: `Delete Transfer Type => ${selectedTransferType}`, - action: 'D' + action: 'D' }; doSaveLogActivity(createActivity); // setTimeout(() => toast.success('Success Delete Transaction Type'), 0); @@ -51,7 +61,9 @@ const DeleteDialog = () => { Delete Transfer Type - Are you sure you want to delete this data? + + Are you sure you want to delete this data? +

Are you sure?

You will delete this data! diff --git a/src/pages/transfer/transfertype/blocks/EditDialog.tsx b/src/pages/transfer/transfertype/blocks/EditDialog.tsx index c4b9e8f..1e3ca41 100644 --- a/src/pages/transfer/transfertype/blocks/EditDialog.tsx +++ b/src/pages/transfer/transfertype/blocks/EditDialog.tsx @@ -589,7 +589,7 @@ const EditDialog = () => { - Disbursement + Disbursement Other Change Group Emoney Customer to Agent Change Group Emoney Agent to Customer diff --git a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx index efa6279..942ee8f 100644 --- a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx +++ b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx @@ -147,21 +147,21 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React meta: { headerClassName: 'w-[250px]' } }, { - accessorFn: (row: {type: string }) => { + accessorFn: (row: { type: string }) => { const mapping: Record = { D: 'Disbursement', O: 'Other', CA: 'Change Group Emoney Customer to Agent', - AC:'Change Group Emoney Agent to Customer', + AC: 'Change Group Emoney Agent to Customer', PC: 'Change Group Point Agent to Customer', PA: 'Change Group Point Customer to Agent', - CE:'Return Customer Emoney', - AD:'Return Agent Deposit', + CE: 'Return Customer Emoney', + AD: 'Return Agent Deposit', AM: 'Return Agent Merchant', AE: 'Return Agent Emoney', - R: 'Reward Point', + R: 'Reward Point' }; - + return mapping[row.type] || 'Unknown'; }, id: 'type', @@ -171,7 +171,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React enableSorting: true, enableHiding: false, meta: { headerClassName: 'w-[250px]' } - }, + }, { accessorFn: (row) => (row.status === 'Y' ? 'Active' : 'Inactive'), id: 'status', @@ -217,20 +217,19 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React ], [handleEditDialog, handleDeleteDialog] ); - + const doGetTransferTypeListData = async ( page: number, limit: number, sorting: any, filter: any ) => { - const orderField = 'created_at'; const orderDirection = sorting.length > 0 ? (sorting[0].desc ? 'DESC' : 'ASC') : 'DESC'; - + filter = filter.length == 0 ? {} : { any: filter[0].value?.toLowerCase() }; - + const response = await GetData(`${API_URL}/transactiontype/list`, { limit: limit, page: page + 1, @@ -281,4 +280,4 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React }; export { ManageTransferTypeContext, ManageTransferTypeContextProvider }; -export type { TransferType }; \ No newline at end of file +export type { TransferType }; From 9808b88eec49bdea6b9068adb25140deb968e550 Mon Sep 17 00:00:00 2001 From: Narul Hidayah Date: Mon, 14 Apr 2025 20:43:42 +0700 Subject: [PATCH 03/14] fixing manage account, kyc delete member --- .../account/manage-account/ManageAccount.tsx | 1 + .../blocks/DetailTransaction.tsx | 28 +- .../blocks/DetailTransactionLog.tsx | 4 +- .../hooks/TransactionContext.tsx | 13 +- .../kyc-delete-member/ManageKycDeletion.tsx | 37 +++ .../kyc-delete-member/blocks/ListToolbar.tsx | 61 +++++ .../hooks/ManageKycDeletionContext.tsx | 252 ++++++++++++++++++ .../members/kyc-delete-member/hooks/index.tsx | 2 + .../hooks/useManageKycDeletionContext.tsx | 12 + src/routing/AppRoutingSetup.tsx | 2 + 10 files changed, 385 insertions(+), 27 deletions(-) create mode 100644 src/pages/members/kyc-delete-member/ManageKycDeletion.tsx create mode 100644 src/pages/members/kyc-delete-member/blocks/ListToolbar.tsx create mode 100644 src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx create mode 100644 src/pages/members/kyc-delete-member/hooks/index.tsx create mode 100644 src/pages/members/kyc-delete-member/hooks/useManageKycDeletionContext.tsx diff --git a/src/pages/account/manage-account/ManageAccount.tsx b/src/pages/account/manage-account/ManageAccount.tsx index f116edd..2b6b33b 100644 --- a/src/pages/account/manage-account/ManageAccount.tsx +++ b/src/pages/account/manage-account/ManageAccount.tsx @@ -93,6 +93,7 @@ const ManageAccount = () => { {}} onUpdate={() => console.log('Callback update')} onDelete={() => console.log('Callback delete')} /> diff --git a/src/pages/disbursement/history-transaction/blocks/DetailTransaction.tsx b/src/pages/disbursement/history-transaction/blocks/DetailTransaction.tsx index dfa33ec..c3ded68 100644 --- a/src/pages/disbursement/history-transaction/blocks/DetailTransaction.tsx +++ b/src/pages/disbursement/history-transaction/blocks/DetailTransaction.tsx @@ -33,19 +33,19 @@ const statusMap: Record = { }; export const renderStatusBadge = (statusRaw: string | null | undefined) => { - const status = statusRaw as StatusCode; - const { label, bg, text } = statusMap[status] ?? { - label: 'Unknown', - bg: 'bg-gray-100', - text: 'text-gray-600', - }; - - return ( - - {label} - - ); - }; + const status = statusRaw as StatusCode; + const { label, bg, text } = statusMap[status] ?? { + label: 'Unknown', + bg: 'bg-gray-100', + text: 'text-gray-600', + }; + + return ( + + {label} + + ); +}; const DetailTransaction = () => { const { GetData } = useCallApi(); @@ -114,7 +114,7 @@ const DetailTransaction = () => { {log.customer.fullname ?? '-'} {log.amount ?? '-'} {renderStatusBadge(log.status) ?? '-'} - {log.request_date && moment(log.request_date).isValid() ? moment(log.request_date).format('YYYY-MM-DD HH:mm:ss') : '-'} + {log.request_date && moment(log.request_date).isValid() ? moment(log.request_date).format('DD/MM/YYYY HH:mm:ss') : '-'} {log.reference ?? '-'}
diff --git a/src/pages/disbursement/history-transaction/blocks/DetailTransactionLog.tsx b/src/pages/disbursement/history-transaction/blocks/DetailTransactionLog.tsx index 7b26b05..b2a668f 100644 --- a/src/pages/disbursement/history-transaction/blocks/DetailTransactionLog.tsx +++ b/src/pages/disbursement/history-transaction/blocks/DetailTransactionLog.tsx @@ -106,11 +106,11 @@ const TransactionLogViewer = () => { Prosess Date - {detailLogData.request_date && moment(detailLogData.request_date).isValid() ? moment(detailLogData.request_date).format('YYYY-MM-DD HH:mm:ss') : '-'} + {detailLogData.request_date && moment(detailLogData.request_date).isValid() ? moment(detailLogData.request_date).format('DD/MM/YYYY HH:mm:ss') : '-'} Response Date - {detailLogData.response_date && moment(detailLogData.response_date).isValid() ? moment(detailLogData.response_date).format('YYYY-MM-DD HH:mm:ss') : '-'} + {detailLogData.response_date && moment(detailLogData.response_date).isValid() ? moment(detailLogData.response_date).format('DD/MM/YYYY HH:mm:ss') : '-'} Reference Number diff --git a/src/pages/disbursement/history-transaction/hooks/TransactionContext.tsx b/src/pages/disbursement/history-transaction/hooks/TransactionContext.tsx index b1807a1..8c4862b 100644 --- a/src/pages/disbursement/history-transaction/hooks/TransactionContext.tsx +++ b/src/pages/disbursement/history-transaction/hooks/TransactionContext.tsx @@ -93,15 +93,6 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { const columns = useMemo[]>( () => [ - // { - // accessorKey: 'transaction_date', - // header: ({ column }) => , - // enableSorting: false, - // enableHiding: false, - // meta: { - // headerClassName: 'w-[250px]' - // } - // }, { accessorKey: 'file_name', header: ({ column }) => , @@ -192,7 +183,7 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { header: ({ column }) => , enableSorting: true, enableHiding: false, - cell: ({ row }) => moment(row.original.execution_date).format('YYYY-MM-DD HH:mm:ss') + cell: ({ row }) => moment(row.original.execution_date).format('DD/MM/YYYY HH:mm:ss') }, { accessorFn: (row) => row.done_date, @@ -200,7 +191,7 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { header: ({ column }) => , enableSorting: true, enableHiding: false, - cell: ({ row }) => row.original.done_date ? moment(row.original.done_date).format('YYYY-MM-DD HH:mm:ss') : '' + cell: ({ row }) => row.original.done_date ? moment(row.original.done_date).format('DD/MM/YYYY HH:mm:ss') : '' }, { id: 'actions', diff --git a/src/pages/members/kyc-delete-member/ManageKycDeletion.tsx b/src/pages/members/kyc-delete-member/ManageKycDeletion.tsx new file mode 100644 index 0000000..0d5962e --- /dev/null +++ b/src/pages/members/kyc-delete-member/ManageKycDeletion.tsx @@ -0,0 +1,37 @@ +import { Container, DataGridInner } from '@/components'; +import { ManageKycDeletionContextProvider } from './hooks/ManageKycDeletionContext'; +import { Breadcrumbs, Link } from '@mui/material'; +import { Helmet } from 'react-helmet'; + +const ManageKycDeletion = () => { + return ( + <> + + TPAY | List Deletion + + + +

MANAGE KYC DELETION

+ + + Dashboard + + + + Member + + + + History Disbursement + + +
+ +
+
+
+ + ); +}; + +export default ManageKycDeletion; diff --git a/src/pages/members/kyc-delete-member/blocks/ListToolbar.tsx b/src/pages/members/kyc-delete-member/blocks/ListToolbar.tsx new file mode 100644 index 0000000..013a15c --- /dev/null +++ b/src/pages/members/kyc-delete-member/blocks/ListToolbar.tsx @@ -0,0 +1,61 @@ +import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; +import { Button } from '@/components/ui/button'; +import { useCallback, useState, useEffect } from 'react'; +import { toast } from 'sonner'; + +const ListToolbar = () => { + const { table, reload } = useDataGrid(); + + // Set the initial state for trxDate + const [trxDate, settrxDate] = useState({ from: '', to: '' }); + + // Function to format date to YYYY-MM-DD + const formatDate = (date: Date): string => { + return date.toISOString().split('T')[0]; + }; + + // useEffect to set the default date values + useEffect(() => { + const today = new Date(); + const nextWeek = new Date(today); + nextWeek.setDate(today.getDate() + 7); + + settrxDate({ + from: formatDate(today), // Set 'from' to today + to: formatDate(nextWeek), // Set 'to' to 7 days later + }); + }, []); + + const handleFilterData = useCallback(() => { + try { + table.getColumn('transaction_date')?.setFilterValue(trxDate); + } catch (error) { + toast.error('Error applying filter'); + console.error('Error applying filter:', error); + } + }, [trxDate, table]); + + useEffect(() => { + if (trxDate.from && trxDate.to) { + handleFilterData(); + } + }, [trxDate]); + + return ( +
+
+
+
+ + + +
+
+
+
+ ); +}; + +export default ListToolbar; diff --git a/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx b/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx new file mode 100644 index 0000000..5fec6e7 --- /dev/null +++ b/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx @@ -0,0 +1,252 @@ +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 { createContext, useCallback, useMemo, useState } from 'react'; +import ListToolbar from '../blocks/ListToolbar'; +import { useCallApi } from '@/hooks'; +import moment from 'moment'; + +interface ManageKycDeletionProps { + id: string; + customers_id: string; + group_id: string; + username: string; + fullname: string; + email: string; + status: string; + created_at: Date; +} + +interface ContextProps { + getKycDeletionList: ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any, + filter: any + ) => Promise<{ data: ManageKycDeletionProps[]; totalCount: number } | undefined>; + showDetailDialog: boolean; + handleDetailDialog: (show: boolean, selected_user: ManageKycDeletionProps | null) => void; + showAddDialog: boolean; + handleAddDialog: (show: boolean) => void; + selectedUser: ManageKycDeletionProps | null; +} + +const initialProps: ContextProps = { + getKycDeletionList: async () => ({ data: [], totalCount: 0 }), + showDetailDialog: false, + handleDetailDialog: () => {}, + showAddDialog: false, + handleAddDialog: () => {}, + selectedUser: null +}; + +const ManageKycDeletionContext = createContext(initialProps); +const API_URL = apiConfig.service_customer; + +type StatusCode = 'W' | 'Y' | 'N' | 'T'; + +interface StatusInfo { + label: string; + bg: string; + text: string; +} + +const statusMap: Record = { + W: { label: 'Waiting Approval', bg: 'bg-yellow-100', text: 'text-yellow-600' }, + T: { label: 'No Need', bg: 'bg-blue-100', text: 'text-blue-600' }, + N: { label: 'Reject', bg: 'bg-red-100', text: 'text-red-600' }, + Y: { label: 'Approve', bg: 'bg-green-100', text: 'text-green-600' }, +}; + +export const renderStatusBadge = (statusRaw: string | null | undefined) => { + const status = statusRaw as StatusCode; + const { label, bg, text } = statusMap[status] ?? { + label: 'Unknown', + bg: 'bg-gray-100', + text: 'text-gray-600', + }; + + return ( + + {label} + + ); +}; + +const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactNode }) => { + const [showDetailDialog, setShowDetailDialog] = useState(false); + const [showAddDialog, setShowAddDialog] = useState(false); + const [selectedUser, setSelectedUser] = useState(null); + const [manageKyc, setManageKyc] = useState([]); + const { GetData } = useCallApi(); + + const getKycDeletionList = async (page: number, limit: number, sorting: any, filter: any) => { + try { + let startdate; + let enddate; + let formattedFilter; + + if (filter == undefined || filter.length == 0) { + const today = new Date(); + const nextWeek = new Date(); + nextWeek.setDate(today.getDate() + 7); + + startdate = today.toISOString().split('T')[0]; + enddate = nextWeek.toISOString().split('T')[0]; + } else if (filter != undefined || filter.length != 0) { + startdate = filter[0].value.from; + enddate = filter[0].value.to; + } + + formattedFilter = { + + }; + + const response = await GetData(`${API_URL}/customer_deletion/list`, { + limit, + page: page + 1, + with_deleted: false, + order_field: "id", + order_direction: 'DESC', + filter: JSON.stringify(formattedFilter) + }); + + setManageKyc(response?.data.list); + return { data: response?.data.list, totalCount: response?.data.total_count }; + } catch (error) { + console.error('Error fetching transaction', error); + } + }; + + const handleDetailDialog = useCallback((show: boolean, selected_user: ManageKycDeletionProps | null) => { + setSelectedUser(show ? selected_user : null); + setShowDetailDialog(show); + }, []); + + const handleAddDialog = useCallback((show: boolean) => { + setShowAddDialog(show); + }, []); + + const columns = useMemo[]>( + () => [ + { + accessorFn: (row) => row.id, + id: 'id', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[100px]' + }, + }, + { + accessorFn: (row) => row.created_at, + id: 'created_at', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + }, + cell: ({ row }) => moment(row.original.created_at).format('DD/MM/YYYY HH:mm:ss') + }, + { + accessorFn: (row) => row.username, + id: 'username', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[350px]' + } + }, + { + accessorFn: (row) => row.fullname, + id: 'fullname', + header: ({ column }) => , + enableSorting: true, + meta: { + headerClassName: 'w-[350px]' + } + }, + { + accessorFn: (row) => row.registered_email, + id: 'email', + header: ({ column }) => , + enableSorting: true, + meta: { + headerClassName: 'w-[350px]' + } + }, + { + accessorFn: (row) => row.status_approve, + id: 'status_approve', + header: ({ column }) => , + enableSorting: true, + meta: { + headerClassName: 'w-[350px]' + }, + cell: ({row}) => renderStatusBadge(row.original.status_approve) + }, + { + id: 'actions', + enableSorting: false, + header: ({ column }) => , + cell: (data: any) => { + const row = data.row.original; + + return ( + <> + + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + } + ], + [handleDetailDialog] + ); + + return ( + + + + } + layout={{ card: true }} + sorting={[{ id: 'name', desc: false }]} + serverSide={true} + onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => + getKycDeletionList(pageIndex, pageSize, sorting, columnFilters) + } + > + {children} + + + ); +}; + +export { ManageKycDeletionContextProvider, ManageKycDeletionContext }; +export type { ManageKycDeletionProps }; diff --git a/src/pages/members/kyc-delete-member/hooks/index.tsx b/src/pages/members/kyc-delete-member/hooks/index.tsx new file mode 100644 index 0000000..0d10e8a --- /dev/null +++ b/src/pages/members/kyc-delete-member/hooks/index.tsx @@ -0,0 +1,2 @@ +export * from './ManageKycDeletionContext'; +export * from './useManageKycDeletionContext'; diff --git a/src/pages/members/kyc-delete-member/hooks/useManageKycDeletionContext.tsx b/src/pages/members/kyc-delete-member/hooks/useManageKycDeletionContext.tsx new file mode 100644 index 0000000..f3a20c9 --- /dev/null +++ b/src/pages/members/kyc-delete-member/hooks/useManageKycDeletionContext.tsx @@ -0,0 +1,12 @@ +import { useContext } from 'react'; +import { ManageKycDeletionContext } from './ManageKycDeletionContext'; + +const useManageKycDeletionContext = () => { + const context = useContext(ManageKycDeletionContext); + + if (!context) throw new Error('useManageKycDeletionContext must be used within AuthProvider'); + + return context; +}; + +export { useManageKycDeletionContext }; diff --git a/src/routing/AppRoutingSetup.tsx b/src/routing/AppRoutingSetup.tsx index b7ce41f..865effb 100644 --- a/src/routing/AppRoutingSetup.tsx +++ b/src/routing/AppRoutingSetup.tsx @@ -15,6 +15,7 @@ import ManagePositionPage from '@/pages/settings/user/manage-position/ManagePosi import ManageAccount from '@/pages/account/manage-account/ManageAccount'; import ManageGroups from '@/pages/groups/ManageGroups'; import ManageMembers from '@/pages/members/manage-members/ManageMembers'; +import ManageKycDeletion from '@/pages/members/kyc-delete-member/ManageKycDeletion'; import Kyc from '@/pages/members/kyc/Kyc'; import AccessType from '@/pages/access/access-type/AccessType'; import MemberCredential from '@/pages/access/member-credentials/MemberCredentials'; @@ -79,6 +80,7 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> + } /> } /> } /> From 4aae4a3b412f94006807c97bafd27044fc0901e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Apr 2025 20:44:36 +0700 Subject: [PATCH 04/14] fix err --- src/pages/account/manage-account/ManageAccount.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/account/manage-account/ManageAccount.tsx b/src/pages/account/manage-account/ManageAccount.tsx index f116edd..402befa 100644 --- a/src/pages/account/manage-account/ManageAccount.tsx +++ b/src/pages/account/manage-account/ManageAccount.tsx @@ -93,6 +93,7 @@ const ManageAccount = () => { console.log('Callback update')} onDelete={() => console.log('Callback delete')} /> From 49b19629bdaaa8f2c8a99053be59bda8670de441 Mon Sep 17 00:00:00 2001 From: Narul Hidayah Date: Mon, 14 Apr 2025 22:27:20 +0700 Subject: [PATCH 05/14] detail deletion --- .../kyc-delete-member/blocks/DetailDialog.tsx | 98 +++++++++++++++++++ .../hooks/ManageKycDeletionContext.tsx | 31 ++++-- 2 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx diff --git a/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx b/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx new file mode 100644 index 0000000..7875949 --- /dev/null +++ b/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx @@ -0,0 +1,98 @@ +import { + Dialog, + DialogBody, + DialogContent, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Button } from '@/components/ui/button'; +import { useManageKycDeletionContext } from '../hooks'; +import { apiConfig } from '@/config/api.config'; +import axios from 'axios'; + +const API_URL = apiConfig.service_customer; +const DetailDialog = () => { + const { showDetailDialog, setShowDetailDialog, detailKyc } = useManageKycDeletionContext(); + + return ( + + + + Customer Deletion Details + + + {/* Tab Content */} + {detailKyc && detailKyc != null ? ( +
+ {generateInput(detailKyc, null, 'Group', 'group_name', 'text', false, true)} + {generateInput(detailKyc, null, 'Username', 'username', 'text', false, true)} + {generateInput(detailKyc, null, 'Full Name', 'fullname', 'text', false, true)} + {generateInput(detailKyc, null, 'Gender', 'customers_gender', 'text', false, true)} + {generateInput(detailKyc, null, 'Date of Birth', 'birthdate', 'date', false, true)} + {generateInput(detailKyc, null, 'Mother Name', 'registered_mother_fullname', 'text', false, true)} + {generateInput(detailKyc, null, 'MSISDN', 'registered_msisdn', 'text', false, true)} + {generateInput(detailKyc, null, 'Reason Deletion', 'reason_deletion', 'text', false, true)} + {generateInput(detailKyc, null, 'Reason Note', 'reason_note', 'text', false, true)} + {generateInput(detailKyc, null, 'Status Approval', 'status_approve', 'text', false, true)} + +
+ + + +
+
+ ) : (
)} +
+
+
+ ); +}; + +export default DetailDialog; + +function generateInput(formData:any, handleChange:any, label:string, name:string, type: string, required: boolean, disabled: boolean) { + function generateDate(isoString: string) { + return isoString.slice(0, 10); // "2000-01-18" + } + + type Code = 'W' | 'Y' | 'N' | 'T' | 'P' | 'D' | 'L'; + interface Reason { + label: string; + } + + const statusMap: Record = { + W: {label: 'Waiting Approval'}, + Y: {label: 'Approve'}, + N: {label: 'Reject'}, + T: {label: 'Tidak lagi menggunakan layanan'}, + P: {label: 'Privasi dan keamanan'}, + D: {label: 'Akun ganda'}, + L: {label: 'Lainnya'} + }; + if (name == 'reason_deletion' || name == 'status_approve') { + const status = formData[name] as Code + const fixStatus = statusMap[status] ?? {label: formData[name]} + formData[name] = fixStatus.label + } + return ( + <> +
+
+ + +
+
+ + ) +} \ No newline at end of file diff --git a/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx b/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx index 5fec6e7..bf5e46f 100644 --- a/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx +++ b/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx @@ -6,6 +6,7 @@ import { createContext, useCallback, useMemo, useState } from 'react'; import ListToolbar from '../blocks/ListToolbar'; import { useCallApi } from '@/hooks'; import moment from 'moment'; +import DetailDialog from '../blocks/DetailDialog'; interface ManageKycDeletionProps { id: string; @@ -28,10 +29,13 @@ interface ContextProps { filter: any ) => Promise<{ data: ManageKycDeletionProps[]; totalCount: number } | undefined>; showDetailDialog: boolean; - handleDetailDialog: (show: boolean, selected_user: ManageKycDeletionProps | null) => void; + setShowDetailDialog: React.Dispatch>; + handleDetailDialog: (show: boolean, selected_user: string | null) => void; showAddDialog: boolean; handleAddDialog: (show: boolean) => void; - selectedUser: ManageKycDeletionProps | null; + selectedIdCustomer: string | null; + detailKyc: any | null; + setDetailKyc: React.Dispatch>; } const initialProps: ContextProps = { @@ -40,7 +44,10 @@ const initialProps: ContextProps = { handleDetailDialog: () => {}, showAddDialog: false, handleAddDialog: () => {}, - selectedUser: null + selectedIdCustomer: null, + setShowDetailDialog: () => { }, + detailKyc: async () => {}, + setDetailKyc: () => { }, }; const ManageKycDeletionContext = createContext(initialProps); @@ -79,7 +86,8 @@ export const renderStatusBadge = (statusRaw: string | null | undefined) => { const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactNode }) => { const [showDetailDialog, setShowDetailDialog] = useState(false); const [showAddDialog, setShowAddDialog] = useState(false); - const [selectedUser, setSelectedUser] = useState(null); + const [selectedIdCustomer, setSelectedIdCustomer] = useState(null); + const [detailKyc, setDetailKyc] = useState(); const [manageKyc, setManageKyc] = useState([]); const { GetData } = useCallApi(); @@ -121,8 +129,13 @@ const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactN } }; - const handleDetailDialog = useCallback((show: boolean, selected_user: ManageKycDeletionProps | null) => { - setSelectedUser(show ? selected_user : null); + const handleDetailDialog = useCallback(async (show: boolean, selected_id_customer: string | null) => { + setSelectedIdCustomer(show ? selected_id_customer : null); + let detailCustomer = await GetData(`${API_URL}/customer_deletion/detail/${selected_id_customer}`, {}) + setDetailKyc(detailCustomer?.data) + console.log('detailCustomer: ',detailCustomer) + console.log('detailCustomer2: ',detailCustomer?.data) + console.log('detailKyc: ', detailKyc) setShowDetailDialog(show); }, []); @@ -226,10 +239,14 @@ const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactN handleDetailDialog, showAddDialog, handleAddDialog, - selectedUser + selectedIdCustomer, + setShowDetailDialog, + setDetailKyc, + detailKyc }} > + Date: Tue, 15 Apr 2025 00:31:55 +0700 Subject: [PATCH 06/14] fixing transaction_type field on update transactionfee --- .../transferfee/blocks/EditDialog.tsx | 808 ++++++++++-------- 1 file changed, 451 insertions(+), 357 deletions(-) diff --git a/src/pages/transfer/transferfee/blocks/EditDialog.tsx b/src/pages/transfer/transferfee/blocks/EditDialog.tsx index 9fd8e8f..c42823f 100644 --- a/src/pages/transfer/transferfee/blocks/EditDialog.tsx +++ b/src/pages/transfer/transferfee/blocks/EditDialog.tsx @@ -7,15 +7,6 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList -} from '@/components/ui/command'; import { Dialog, DialogBody, @@ -33,6 +24,8 @@ import { toast } from 'sonner'; import { useCallApi } from '@/hooks'; import { doSaveLogActivity } from '@/actions/GlobalActions'; import { getAuth } from '@/auth'; +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; +import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'; const API_URL = apiConfig.service_transaction; const API_URL_MASTER_DATA = apiConfig.service_master_data; @@ -41,14 +34,12 @@ const API_URL_CUSTOMER = apiConfig.service_customer; interface WalletProps { id: string; name: string; - description?: string; } interface CustomerProps { id: string; username: string; msisdn: string; - fullname?: string; } interface TransactionTypeProps { @@ -61,18 +52,32 @@ const EditFeeDialog = () => { const { showEditFeeDialog, handleEditFeeDialog, selectedTransferFee } = useManageTransferFeeContext(); const { reload } = useDataGrid(); - const [wallets, setWallets] = useState([]); const { GetData, PutData } = useCallApi(); - const [isSubmitting, setIsSubmitting] = useState(false); - const [transactionTypes, setTransactionTypes] = useState([]); const parsedUser = getAuth()?.user; + + const [wallets, setWallets] = useState([]); const [customers, setCustomers] = useState([]); + const [transactionTypes, setTransactionTypes] = useState([]); + const [transactionTypeName, setTransactionTypeName] = useState(''); + const customersWithNames = customers.map((customer) => ({ + id: customer.id, + name: customer.username + })); + const [customerSearchTerm, setCustomerSearchTerm] = useState(''); + const [showCustomerSearch, setShowCustomerSearch] = useState(false); const [open, setOpen] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); const [alert, setAlert] = useState({ show: false, message: '' }); + // Loading states + const [isLoadingTransferFee, setIsLoadingTransferFee] = useState(false); + const [isLoadingTransactionType, setIsLoadingTransactionType] = useState(false); + const [isLoadingWallets, setIsLoadingWallets] = useState(false); + const [isLoadingCustomers, setIsLoadingCustomers] = useState(false); + const initialState = { name: '', description: '', @@ -109,7 +114,7 @@ const EditFeeDialog = () => { updated_at: formattedTime })); } - }, [showEditFeeDialog]); + }, [showEditFeeDialog, parsedUser?.username]); const resetForm = () => { if (selectedTransferFee) { @@ -178,10 +183,11 @@ const EditFeeDialog = () => { reload(); handleEditFeeDialog(false, null); const createActivity = { - module: 'Manage Transfer Type', - description: `Edit Transfer Type => ${selectedTransferFee}`, + module: 'Manage Transfer Fee', + description: `Edit Transfer Fee => ${formField.name}`, action: 'U' }; + doSaveLogActivity(createActivity); } else { setAlert({ show: true, message: response?.message || 'Failed to update transfer fee' }); } @@ -196,6 +202,7 @@ const EditFeeDialog = () => { ); const fetchWallets = useCallback(async () => { + setIsLoadingWallets(true); const params = { limit: 100, page: 1, @@ -213,6 +220,8 @@ const EditFeeDialog = () => { } catch (error) { console.error('Error fetching wallets', error); setWallets([]); + } finally { + setIsLoadingWallets(false); } }, [GetData]); @@ -225,6 +234,7 @@ const EditFeeDialog = () => { if (!showEditFeeDialog) return; const getCustomerList = async (sorting: any) => { + setIsLoadingCustomers(true); try { sorting = sorting.length === 0 ? [{ id: 'name', desc: false }] : sorting; const response = await GetData(`${API_URL_CUSTOMER}/customer/list`, { @@ -237,16 +247,19 @@ const EditFeeDialog = () => { setCustomers(response?.data.list || []); } catch (error) { console.error('Error fetching customers', error); + } finally { + setIsLoadingCustomers(false); } }; - getCustomerList([{ id: 'msisdn', desc: false }]); + getCustomerList([{ id: 'id', desc: false }]); }, [showEditFeeDialog, GetData]); useEffect(() => { if (!showEditFeeDialog) return; const getTransactionTypeList = async (sorting: any) => { + setIsLoadingTransactionType(true); try { sorting = sorting.length === 0 ? [{ id: 'name', desc: false }] : sorting; const response = await GetData(`${API_URL}/transactiontype/list`, { @@ -259,6 +272,8 @@ const EditFeeDialog = () => { setTransactionTypes(response?.data.list || []); } catch (error) { console.error('Error fetching transaction types', error); + } finally { + setIsLoadingTransactionType(false); } }; @@ -272,6 +287,7 @@ const EditFeeDialog = () => { const fetchTransactionFee = useCallback( async (id: string) => { + setIsLoadingTransferFee(true); try { const response = await GetData(`${API_URL}/transactionfees/getdata/${id}`, {}); @@ -300,10 +316,16 @@ const EditFeeDialog = () => { updated_by: parsedUser?.username, updated_at: new Date().toISOString().slice(0, 19).replace('T', ' ') }); + + if (response.data.transaction_type?.name) { + setTransactionTypeName(response.data.transaction_type.name); + } } } catch (error) { console.error('Error fetching transaction fee details', error); setAlert({ show: true, message: 'Failed to fetch transaction fee details' }); + } finally { + setIsLoadingTransferFee(false); } }, [GetData, parsedUser?.username] @@ -328,6 +350,37 @@ const EditFeeDialog = () => { handleEditFeeDialog(false, null); }; + const renderSelectWithLoading = ( + value: string, + onChangeHandler: (value: string) => void, + options: { id: string; name: string }[] | null, + placeholder: string, + isLoading: boolean + ) => { + return ( + + ); + }; + return ( {
)} - - -
-
-
- - - setFormField((prev) => ({ ...prev, name: target.value })) - } - /> + + {isLoadingTransferFee ? ( +
+
+
+
+
+
+
+
- -
- - - setFormField((prev) => ({ ...prev, description: target.value })) - } - /> -
- -
- - { - setFormField((prev) => ({ - ...prev, - minimum_amount: values.floatValue || 0 - })); - }} - placeholder="Enter Minimum Amount" - /> -
- -
- - { - setFormField((prev) => ({ - ...prev, - maximum_amount: values.floatValue || 0 - })); - }} - placeholder="Enter Maximum Amount" - /> -
- -
- - - setFormField((prev) => ({ ...prev, period_start: target.value })) - } - /> -
- -
- - - setFormField((prev) => ({ ...prev, period_end: target.value })) - } - /> -
- -
- - { - setFormField((prev) => ({ - ...prev, - deduct_amount: values.floatValue || 0 - })); - }} - placeholder="Enter Deduct Amount" - /> -
- -
- - { - setFormField((prev) => ({ - ...prev, - deduct_percentage: values.floatValue || 0 - })); - }} - placeholder="Enter Deduct Percentage" - /> -
- -
- - { - setFormField((prev) => ({ - ...prev, - fee_amount: values.floatValue || 0 - })); - }} - placeholder="Enter Fee Amount" - /> -
- -
- - -
- -
- - -
- -
- - -
- - {formField.credit_to === 'I' && ( +
+

Loading transfer fee details...

+
+ ) : ( + +
+
+
+ + {isLoadingTransactionType && ( +
+
+
+ Loading transaction type... +
+
+ )} + +
+
+ +
+ + + setFormField((prev) => ({ ...prev, name: target.value })) + } + /> +
+ +
+ + + setFormField((prev) => ({ ...prev, description: target.value })) + } + /> +
+ +
+ + { + setFormField((prev) => ({ + ...prev, + minimum_amount: values.floatValue || 0 + })); + }} + placeholder="Enter Minimum Amount" + /> +
+ +
+ + { + setFormField((prev) => ({ + ...prev, + maximum_amount: values.floatValue || 0 + })); + }} + placeholder="Enter Maximum Amount" + /> +
+ +
+ + + setFormField((prev) => ({ ...prev, period_start: target.value })) + } + /> +
+ +
+ + + setFormField((prev) => ({ ...prev, period_end: target.value })) + } + /> +
+ +
+ + { + setFormField((prev) => ({ + ...prev, + deduct_amount: values.floatValue || 0 + })); + }} + placeholder="Enter Deduct Amount" + /> +
+ +
+ + { + setFormField((prev) => ({ + ...prev, + deduct_percentage: values.floatValue || 0 + })); + }} + placeholder="Enter Deduct Percentage" + /> +
+ +
+ + { + setFormField((prev) => ({ + ...prev, + fee_amount: values.floatValue || 0 + })); + }} + placeholder="Enter Fee Amount" + /> +
+ +
+
- )} + +
+ + {renderSelectWithLoading( + formField.deduct_from_account, + (value) => setFormField({ ...formField, deduct_from_account: value }), + wallets, + 'Select Wallet', + isLoadingWallets + )} +
+ +
+ + +
+ +{formField.credit_to === 'I' && ( +
+ + + + + + + + + + No Customer found. + + {customers.map((customer) => ( + { + setFormField({ + ...formField, + credit_destination: customer.id + }); + setOpen(false); + }} + > + {customer.username} + + ))} + + + + + +
+)} -
- - -
-
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- + +
+ + {renderSelectWithLoading( + formField.credit_destination_account, + (value) => setFormField({ ...formField, credit_destination_account: value }), + wallets, + 'Select Wallet', + isLoadingWallets + )} +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
-
- + + )}
); }; -export { EditFeeDialog }; +export {EditFeeDialog}; \ No newline at end of file From 83593db7ac76bce18c52e01f99842238b143bddf Mon Sep 17 00:00:00 2001 From: bagusajisaputroo Date: Tue, 15 Apr 2025 01:04:53 +0700 Subject: [PATCH 07/14] adding search in credit_destination on update transaction fee --- .../transferfee/blocks/EditDialog.tsx | 95 ++++++++++++------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/src/pages/transfer/transferfee/blocks/EditDialog.tsx b/src/pages/transfer/transferfee/blocks/EditDialog.tsx index c42823f..b8077b5 100644 --- a/src/pages/transfer/transferfee/blocks/EditDialog.tsx +++ b/src/pages/transfer/transferfee/blocks/EditDialog.tsx @@ -343,13 +343,19 @@ const EditFeeDialog = () => { hasFetchedRef.current = false; } }, [selectedTransferFee, showEditFeeDialog, fetchTransactionFee]); - const handleCloseDialog = () => { setFormField(initialState); setAlert({ show: false, message: '' }); + setCustomerSearchTerm(''); + setOpen(false); handleEditFeeDialog(false, null); }; - + useEffect(() => { + if (!showEditFeeDialog) { + setCustomerSearchTerm(''); + setOpen(false); + } + }, [showEditFeeDialog]); const renderSelectWithLoading = ( value: string, onChangeHandler: (value: string) => void, @@ -668,36 +674,51 @@ const EditFeeDialog = () => { -{formField.credit_to === 'I' && ( + {formField.credit_to === 'I' && (
- - - - - - - - - No Customer found. - - {customers.map((customer) => ( - { +
+
setOpen(!open)} + > + + {customers.find(customer => customer.id === formField.credit_destination)?.username || 'Search customer...'} + + + + +
+ + {open && ( +
+
+ setCustomerSearchTerm(e.target.value)} + autoComplete="off" + // Prevent clicks from closing the dropdown + onClick={(e) => e.stopPropagation()} + // Auto focus the input when opened + autoFocus + /> +
+
+ {customers + .filter(customer => + customer.username.toLowerCase().includes(customerSearchTerm.toLowerCase()) || + customer.msisdn.includes(customerSearchTerm) + ) + .map(customer => ( +
{ setFormField({ ...formField, credit_destination: customer.id @@ -706,17 +727,23 @@ const EditFeeDialog = () => { }} > {customer.username} - +
))} - - - - - + {customers.filter(customer => + customer.username.toLowerCase().includes(customerSearchTerm.toLowerCase()) || + customer.msisdn.includes(customerSearchTerm) + ).length === 0 && ( +
No customer found
+ )} +
+
+ )} +
)} +
) : (
)} diff --git a/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx b/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx index bf5e46f..c0742fd 100644 --- a/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx +++ b/src/pages/members/kyc-delete-member/hooks/ManageKycDeletionContext.tsx @@ -1,5 +1,6 @@ import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components'; import { Toaster } from '@/components/ui/sonner'; +import { toast } from 'sonner'; import { apiConfig } from '@/config/api.config'; import { ColumnDef } from '@tanstack/react-table'; import { createContext, useCallback, useMemo, useState } from 'react'; @@ -36,6 +37,7 @@ interface ContextProps { selectedIdCustomer: string | null; detailKyc: any | null; setDetailKyc: React.Dispatch>; + handleApproveReject: (customerDeletionId: string, status_approve: string) => {}; } const initialProps: ContextProps = { @@ -48,6 +50,7 @@ const initialProps: ContextProps = { setShowDetailDialog: () => { }, detailKyc: async () => {}, setDetailKyc: () => { }, + handleApproveReject: () => ({customerDeletionId: '0', status_approve: 'Y'}), }; const ManageKycDeletionContext = createContext(initialProps); @@ -83,13 +86,15 @@ export const renderStatusBadge = (statusRaw: string | null | undefined) => { ); }; +// const { reload } = useDataGrid(); + const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactNode }) => { const [showDetailDialog, setShowDetailDialog] = useState(false); const [showAddDialog, setShowAddDialog] = useState(false); const [selectedIdCustomer, setSelectedIdCustomer] = useState(null); const [detailKyc, setDetailKyc] = useState(); const [manageKyc, setManageKyc] = useState([]); - const { GetData } = useCallApi(); + const { GetData, PostData } = useCallApi(); const getKycDeletionList = async (page: number, limit: number, sorting: any, filter: any) => { try { @@ -130,12 +135,11 @@ const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactN }; const handleDetailDialog = useCallback(async (show: boolean, selected_id_customer: string | null) => { - setSelectedIdCustomer(show ? selected_id_customer : null); - let detailCustomer = await GetData(`${API_URL}/customer_deletion/detail/${selected_id_customer}`, {}) - setDetailKyc(detailCustomer?.data) - console.log('detailCustomer: ',detailCustomer) - console.log('detailCustomer2: ',detailCustomer?.data) - console.log('detailKyc: ', detailKyc) + if (show == true) { + setSelectedIdCustomer(show ? selected_id_customer : null); + let detailCustomer = await GetData(`${API_URL}/customer_deletion/detail/${selected_id_customer}`, {}) + setDetailKyc(detailCustomer?.data) + } setShowDetailDialog(show); }, []); @@ -143,6 +147,26 @@ const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactN setShowAddDialog(show); }, []); + const handleApproveReject = useCallback(async (customerDeletionId: string, status_approve: string) => { + console.log(customerDeletionId, status_approve) + try { + let approveReject = await PostData(`${API_URL}/customer_deletion/update_status/${customerDeletionId}`, { + status_approve + }) + + if (approveReject?.status == true) { + toast.success('Success update status approval') + handleDetailDialog(false, null) + } else { + toast.warning(`${approveReject?.message}`) + handleDetailDialog(false, null) + } + } catch (error) { + toast.warning('Failed to approve/reject') + handleDetailDialog(false, null) + } + }, []) + const columns = useMemo[]>( () => [ { @@ -242,7 +266,8 @@ const ManageKycDeletionContextProvider = ({ children }: { children: React.ReactN selectedIdCustomer, setShowDetailDialog, setDetailKyc, - detailKyc + detailKyc, + handleApproveReject, }} > From 172e8a0815f04b8b4d2abd37ba2df61aca8ed23e Mon Sep 17 00:00:00 2001 From: bagusajisaputroo Date: Tue, 15 Apr 2025 10:44:43 +0700 Subject: [PATCH 10/14] added search on credit_destination field in transaction fee add +edit --- .../transfer/transferfee/blocks/AddDialog.tsx | 83 +++++++++++++++++-- .../transferfee/blocks/EditDialog.tsx | 5 -- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/src/pages/transfer/transferfee/blocks/AddDialog.tsx b/src/pages/transfer/transferfee/blocks/AddDialog.tsx index 0860010..6b73eed 100644 --- a/src/pages/transfer/transferfee/blocks/AddDialog.tsx +++ b/src/pages/transfer/transferfee/blocks/AddDialog.tsx @@ -70,6 +70,8 @@ const AddFeeDialog = () => { selectedTransferFee, transactionTypeId } = useManageTransferFeeContext(); + const [customerSearchTerm, setCustomerSearchTerm] = useState(''); + const [open, setOpen] = useState(false); const [alert, setAlert] = useState({ show: false, @@ -111,6 +113,7 @@ const AddFeeDialog = () => { credit_destination_account: '' }; + const [formField, setFormField] = useState(initialState); const resetForm = () => { @@ -151,6 +154,13 @@ const AddFeeDialog = () => { } }, [showAddFeeDialog, transactionTypeId, GetData]); + useEffect(() => { + if (!showAddFeeDialog) { + setCustomerSearchTerm(''); + setOpen(false); + } + }, [showAddFeeDialog]); + useEffect(() => { const created_time = new Date(); const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' '); @@ -619,13 +629,72 @@ const AddFeeDialog = () => { - {renderSelectWithLoading( - formField.credit_destination, - (value) => setFormField({ ...formField, credit_destination: value }), - customersWithNames, - 'Select Customer', - isLoadingCustomers - )} +
+
setOpen(!open)} + > + + {customers.find( + (customer) => customer.id === formField.credit_destination + )?.username || 'Search customer...'} + + +
+ + {open && ( +
+
+ setCustomerSearchTerm(e.target.value)} + autoComplete="off" + onClick={(e) => e.stopPropagation()} + autoFocus + /> +
+
+ {customers + .filter( + (customer) => + customer.username + .toLowerCase() + .includes(customerSearchTerm.toLowerCase()) || + customer.msisdn.includes(customerSearchTerm) + ) + .map((customer) => ( +
{ + setFormField({ + ...formField, + credit_destination: customer.id + }); + setOpen(false); + }} + > + {customer.username} +
+ ))} + {customers.filter( + (customer) => + customer.username + .toLowerCase() + .includes(customerSearchTerm.toLowerCase()) || + customer.msisdn.includes(customerSearchTerm) + ).length === 0 && ( +
+ No customer found +
+ )} +
+
+ )} +
)}
diff --git a/src/pages/transfer/transferfee/blocks/EditDialog.tsx b/src/pages/transfer/transferfee/blocks/EditDialog.tsx index b8077b5..3d6b0ce 100644 --- a/src/pages/transfer/transferfee/blocks/EditDialog.tsx +++ b/src/pages/transfer/transferfee/blocks/EditDialog.tsx @@ -72,7 +72,6 @@ const EditFeeDialog = () => { message: '' }); - // Loading states const [isLoadingTransferFee, setIsLoadingTransferFee] = useState(false); const [isLoadingTransactionType, setIsLoadingTransactionType] = useState(false); const [isLoadingWallets, setIsLoadingWallets] = useState(false); @@ -687,9 +686,7 @@ const EditFeeDialog = () => { {customers.find(customer => customer.id === formField.credit_destination)?.username || 'Search customer...'} - -
{open && ( @@ -702,9 +699,7 @@ const EditFeeDialog = () => { value={customerSearchTerm} onChange={(e) => setCustomerSearchTerm(e.target.value)} autoComplete="off" - // Prevent clicks from closing the dropdown onClick={(e) => e.stopPropagation()} - // Auto focus the input when opened autoFocus /> From d84c62cee405f5a5a2fd5412cf88bdfb3bbc059a Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Tue, 15 Apr 2025 10:52:53 +0700 Subject: [PATCH 11/14] update bug type.name --- .../blocks/DetailApprovalTransaction.tsx | 8 +++++--- .../history-transaction/blocks/DetailTransaction.tsx | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx index e032a94..848eb7c 100644 --- a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx +++ b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx @@ -30,7 +30,7 @@ const DetailApprovalTransaction = () => { const response = await GetData(`${API_URL}/transaction/history/detail/${selectedTransactionId}`, { id: selectedTransactionId }); - // console.log(response?.data); + console.log(response?.data); setTransactionDetails(response?.data); } catch (error) { console.error('Error fetching transaction', error); @@ -190,7 +190,7 @@ const DetailApprovalTransaction = () => {

Name

-

{transactionDetails?.type.name}

+

{transactionDetails?.type?.name || '-'}

@@ -346,9 +346,11 @@ const DetailApprovalTransaction = () => {

Description

{transactionDetails?.description}

+

Name

-

{transactionDetails?.type.name}

+

{transactionDetails?.type?.name || '-'}

+

Reference

diff --git a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx index 55db0a0..6d774d7 100644 --- a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx +++ b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx @@ -189,7 +189,7 @@ const DetailTransaction = () => {

Name

-

{transactionDetails?.type.name}

+

{transactionDetails?.type?.name || '-'}

@@ -347,7 +347,7 @@ const DetailTransaction = () => {

Name

-

{transactionDetails?.type.name}

+

{transactionDetails?.type?.name || '-'}

Reference

From 249e09774d2a834cb8c882e4755906484f3f0669 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 Apr 2025 14:38:29 +0700 Subject: [PATCH 12/14] fix group --- src/pages/members/kyc/Kyc.tsx | 1 - src/pages/members/manage-members/Columns.tsx | 3 +- .../members/manage-members/ManageMembers.tsx | 1 - .../manage-members/blocks/AdmAccess.tsx | 39 +++--- .../manage-members/blocks/DetailMember.tsx | 123 ++++++++++-------- 5 files changed, 89 insertions(+), 78 deletions(-) diff --git a/src/pages/members/kyc/Kyc.tsx b/src/pages/members/kyc/Kyc.tsx index 49f1fdd..b3ecff9 100644 --- a/src/pages/members/kyc/Kyc.tsx +++ b/src/pages/members/kyc/Kyc.tsx @@ -135,7 +135,6 @@ const Kyc = () => { delete updateData.suco_name; delete updateData.aldeia_id; delete updateData.aldeia_name; - delete updateData.group_id; delete updateData.group_name; delete updateData.group_description; delete updateData.group_status; diff --git a/src/pages/members/manage-members/Columns.tsx b/src/pages/members/manage-members/Columns.tsx index 6c83c0b..983178e 100644 --- a/src/pages/members/manage-members/Columns.tsx +++ b/src/pages/members/manage-members/Columns.tsx @@ -180,5 +180,6 @@ export const initialMember = { aldeia: '', profession: '', approval_description_premium: '', - approval_description_agent: '' + approval_description_agent: '', + group_id: '' }; diff --git a/src/pages/members/manage-members/ManageMembers.tsx b/src/pages/members/manage-members/ManageMembers.tsx index 9710ce1..6d9cdd2 100644 --- a/src/pages/members/manage-members/ManageMembers.tsx +++ b/src/pages/members/manage-members/ManageMembers.tsx @@ -120,7 +120,6 @@ const ManageMembers = () => { delete updateData.suco_name; delete updateData.aldeia_id; delete updateData.aldeia_name; - delete updateData.group_id; delete updateData.group_name; delete updateData.group_description; delete updateData.group_status; diff --git a/src/pages/members/manage-members/blocks/AdmAccess.tsx b/src/pages/members/manage-members/blocks/AdmAccess.tsx index 0c4ceec..bf735c3 100644 --- a/src/pages/members/manage-members/blocks/AdmAccess.tsx +++ b/src/pages/members/manage-members/blocks/AdmAccess.tsx @@ -21,33 +21,33 @@ import ConfirmDialog from '@/components/confirm'; const BASE_URL_CUSTOMER = apiConfig.service_customer; // ACCESS ADM -export default function AdmAccess({page,formData,handleClose,fetchCustomers,viewOnly,setViewOnly}: any) { +export default function AdmAccess({page,groups,formData,handleClose,fetchCustomers,viewOnly,setViewOnly}: any) { const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState(''); const [changeGroup, setChangeGroup] = useState(''); const [changeGroupD, setChangeGroupD] = useState(false); - const [groups, setGroups] = useState([]); + // const [groups, setGroups] = useState([]); useEffect(() => { - fetchGroups(); + // fetchGroups(); }, []); - const fetchGroups = async () => { - try { - let getGroups = await axios.get(`${BASE_URL_CUSTOMER}/groups/list`, { - params: { - limit: 50, - page: 1, - with_deleted: false, - order_field: 'name', - order_direction: 'ASC' - } - }); - setGroups(getGroups.data.data.list); - } catch (error: any) { - toast.error(error.message); - } - }; + // const fetchGroups = async () => { + // try { + // let getGroups = await axios.get(`${BASE_URL_CUSTOMER}/groups/list`, { + // params: { + // limit: 50, + // page: 1, + // with_deleted: false, + // order_field: 'name', + // order_direction: 'ASC' + // } + // }); + // setGroups(getGroups.data.data.list); + // } catch (error: any) { + // toast.error(error.message); + // } + // }; const handleYes = async () => { try { @@ -119,6 +119,7 @@ export default function AdmAccess({page,formData,handleClose,fetchCustomers,view function btnConfirmDialog(status: boolean) { setDialogOpen(status); } + if (!formData.id) return ''; if (page !== 'kyc') { return ( diff --git a/src/pages/members/manage-members/blocks/DetailMember.tsx b/src/pages/members/manage-members/blocks/DetailMember.tsx index 85035ad..4eac2e1 100644 --- a/src/pages/members/manage-members/blocks/DetailMember.tsx +++ b/src/pages/members/manage-members/blocks/DetailMember.tsx @@ -24,6 +24,7 @@ import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; const BASE_URL_MASTER_DATA = apiConfig.service_master_data; const URL_NATIONALITY = apiConfig.nationality; +const BASE_URL_CUSTOMER = apiConfig.service_customer; import { initialMember } from "../Columns"; import AdmAccess from './AdmAccess'; import CustomerWallet from './CustomerWallet'; @@ -38,10 +39,8 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa const [aldeias, setAldeias] = useState([]); const [postoAdm, setPostoAdm] = useState([]); const [sucos, setSucos] = useState([]); + const [groups, setGroups] = useState([]); const [genders] = useState([ { name: 'Male',id: 'M' }, { name: 'Female',id: 'F' }]) - const [status] = useState([ - { name: 'Active',id: 'Y' }, { name: 'Inactive',id: 'N' }, { name: 'Suspend PIN',id: 'P' }, { name: 'Suspend OTP',id: 'O' } - ]) const [banks] = useState([ { name: 'BNCTL',id: 'BNCTL' }, { name: 'BRI',id: 'BRI' }, { name: 'BNU',id: 'BNU' }, { name: 'Mandiri',id: 'Mandiri' } ]) @@ -53,7 +52,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa useEffect(() => { setFormData(initialData || {}); - // fetchMasterData() + fetchMasterData() }, [initialData]); const handleChange = async (e: any) => { @@ -121,48 +120,59 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa async function fetchMasterData() { try { - let getMunicipios = await axios.get(`${BASE_URL_MASTER_DATA}/municipios/list`, { - params: { - limit: 50, - page: 1, - with_deleted: false, - order_field: 'name', - order_direction: 'ASC', - } + let getGroups = await axios.get(`${BASE_URL_CUSTOMER}/groups/list`, { + params: { + limit: 50, + page: 1, + with_deleted: false, + order_field: 'name', + order_direction: 'ASC' + } }); - setMunicipios(getMunicipios.data.data.list) - let getPostoAdms = await axios.get(`${BASE_URL_MASTER_DATA}/postoadms/list`, { - params: { - limit: 50, - page: 1, - with_deleted: false, - order_field: 'name', - order_direction: 'ASC', - } - }); - setPostoAdm(getPostoAdms.data.data.list) - let getSucos = await axios.get(`${BASE_URL_MASTER_DATA}/sucos/list`, { - params: { - limit: 50, - page: 1, - with_deleted: false, - order_field: 'name', - order_direction: 'ASC', - } - }); - setSucos(getSucos.data.data.list) - let getAldeias = await axios.get(`${BASE_URL_MASTER_DATA}/aldeias/list`, { - params: { - limit: 50, - page: 1, - with_deleted: false, - order_field: 'name', - order_direction: 'ASC', - } - }); - setAldeias(getAldeias.data.data.list) - } catch (error) { + setGroups(getGroups.data.data.list); + // let getMunicipios = await axios.get(`${BASE_URL_MASTER_DATA}/municipios/list`, { + // params: { + // limit: 50, + // page: 1, + // with_deleted: false, + // order_field: 'name', + // order_direction: 'ASC', + // } + // }); + // setMunicipios(getMunicipios.data.data.list) + // let getPostoAdms = await axios.get(`${BASE_URL_MASTER_DATA}/postoadms/list`, { + // params: { + // limit: 50, + // page: 1, + // with_deleted: false, + // order_field: 'name', + // order_direction: 'ASC', + // } + // }); + // setPostoAdm(getPostoAdms.data.data.list) + // let getSucos = await axios.get(`${BASE_URL_MASTER_DATA}/sucos/list`, { + // params: { + // limit: 50, + // page: 1, + // with_deleted: false, + // order_field: 'name', + // order_direction: 'ASC', + // } + // }); + // setSucos(getSucos.data.data.list) + // let getAldeias = await axios.get(`${BASE_URL_MASTER_DATA}/aldeias/list`, { + // params: { + // limit: 50, + // page: 1, + // with_deleted: false, + // order_field: 'name', + // order_direction: 'ASC', + // } + // }); + // setAldeias(getAldeias.data.data.list) + } catch (error:any) { console.log(error); + toast.error(error.message) } } @@ -213,20 +223,21 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa
- {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Group', 'group_name', 'text', true, true): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, groups, 'group_id', 'Group', true, dialogType === "update"||false): ''} + {/* {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Group', 'group_name', 'text', true, true): ''} */} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Username', 'username', 'text', true, dialogType==='create'?false:true): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Full Name', 'fullname', 'text', true, viewOnly): ''} {(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'Photo', 'photouser'): ''} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, genders, 'gender', 'Gender', null, true): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, genders, 'gender', 'Gender', true, false): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Date of Birth', 'date_birth', 'date', true, viewOnly): ''} - {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Phone Number', 'msisdn', 'text', true, viewOnly): ''} + {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Phone Number', 'msisdn', 'text', true, dialogType === "update"||false): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Email', 'email', 'text', true, viewOnly): ''} {/* {generateList(formData, handleChange, status, 'status', 'Status', null, true)} */} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, profession, 'profession', 'Profession', null, false): ''} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, municipios, 'municipio', 'Municipio', null, false): ''} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, postoAdm, 'posto_adms', 'Posto', 'posto_adms_id', false): ''} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, sucos, 'suco', 'Suco', 'sucos_id', false): ''} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, aldeias, 'aldeia', 'Aldeia', null, false): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, profession, 'profession', 'Profession', false, false): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, municipios, 'municipio', 'Municipio', false, false): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, postoAdm, 'posto_adms', 'Posto', false, false): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, sucos, 'suco', 'Suco', false, false): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, aldeias, 'aldeia', 'Aldeia', false, false): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Nationality', 'nationality', 'text', true, viewOnly): ''}
@@ -257,7 +268,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa {(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Document & Selfie', 'file_document_id_selfie'): ''} {(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Commercial License', 'file_commercial_license'): ''} - {(formData.id || dialogType === "create") ? generateList(formData, handleChange, banks, 'bank_name', 'Bank Name', null, false): ''} + {(formData.id || dialogType === "create") ? generateList(formData, handleChange, banks, 'bank_name', 'Bank Name', false, false): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Bank Account', 'bank_account', 'text', false, viewOnly): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'iBank Number', 'ibank_number', 'text', false, viewOnly): ''} @@ -265,7 +276,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa {(formData.id&&(!page||formData.destinationGroup === "Agent")) ? generateInput(formData, handleChange, 'Approval Agent Description', 'approval_description_agent', 'text', false, viewOnly): ''} {(formData.id && page!=='kyc') ? ( - + ): ""} {(formData.id && page!=='kyc') ? ( @@ -323,14 +334,14 @@ function generateInput(formData:any, handleChange:any, label:string, name:string } // ON DEV (DI SELECT MASI HILANG) -function generateList(formData:any, handleChange: any, list:any, name:string, label: string, difId: any, required: boolean) { +function generateList(formData:any, handleChange: any, list:any, name:string, label: string, required: boolean, disabled: boolean) { return ( <>
- (handleChange({ target : { name, value: e }}))}> From cab30d63cc817d552e95f81112e24ae5cf6ed9d2 Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Tue, 15 Apr 2025 15:05:47 +0700 Subject: [PATCH 13/14] add reload button in approval-transaction and history-transaction --- .../blocks/ListToolbar.tsx | 17 +++++++++++++++++ .../history-transaction/blocks/ListToolbar.tsx | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx index 3a82db3..366530e 100644 --- a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx @@ -70,6 +70,23 @@ const ListToolbar = () => { name="to" /> + + +
diff --git a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx index e0a15c3..7fcc065 100644 --- a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx @@ -70,6 +70,24 @@ const ListToolbar = () => { name="to" /> + + + +
From 99097a29507f8c61c38581ffc3eb60ef26d8e234 Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Tue, 15 Apr 2025 15:15:18 +0700 Subject: [PATCH 14/14] update dialog add kyc-delete-member --- .../kyc-delete-member/blocks/DetailDialog.tsx | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx b/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx index 4ba5dfc..016674c 100644 --- a/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx +++ b/src/pages/members/kyc-delete-member/blocks/DetailDialog.tsx @@ -1,9 +1,9 @@ import { - Dialog, - DialogBody, - DialogContent, - DialogHeader, - DialogTitle + Dialog, + DialogBody, + DialogContent, + DialogHeader, + DialogTitle } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; @@ -13,11 +13,11 @@ import axios from 'axios'; const API_URL = apiConfig.service_customer; const DetailDialog = () => { - const { showDetailDialog, setShowDetailDialog, detailKyc, handleApproveReject } = useManageKycDeletionContext(); - - return ( + const { showDetailDialog, setShowDetailDialog, detailKyc, handleApproveReject } = useManageKycDeletionContext(); + + return ( - + Customer Deletion Details @@ -38,9 +38,9 @@ const DetailDialog = () => {
- - -
+ + + ) : (
)} @@ -51,28 +51,28 @@ const DetailDialog = () => { export default DetailDialog; -function generateInput(formData:any, handleChange:any, label:string, name:string, type: string, required: boolean, disabled: boolean) { +function generateInput(formData: any, handleChange: any, label: string, name: string, type: string, required: boolean, disabled: boolean) { function generateDate(isoString: string) { - return isoString.slice(0, 10); // "2000-01-18" + return isoString.slice(0, 10); // "2000-01-18" } type Code = 'W' | 'Y' | 'N' | 'T' | 'P' | 'D' | 'L'; interface Reason { label: string; } - + const statusMap: Record = { - W: {label: 'Waiting Approval'}, - Y: {label: 'Approve'}, - N: {label: 'Reject'}, - T: {label: 'Tidak lagi menggunakan layanan'}, - P: {label: 'Privasi dan keamanan'}, - D: {label: 'Akun ganda'}, - L: {label: 'Lainnya'} + W: { label: 'Waiting Approval' }, + Y: { label: 'Approve' }, + N: { label: 'Reject' }, + T: { label: 'Tidak lagi menggunakan layanan' }, + P: { label: 'Privasi dan keamanan' }, + D: { label: 'Akun ganda' }, + L: { label: 'Lainnya' } }; if (name == 'reason_deletion' || name == 'status_approve') { const status = formData[name] as Code - const fixStatus = statusMap[status] ?? {label: formData[name]} + const fixStatus = statusMap[status] ?? { label: formData[name] } formData[name] = fixStatus.label } return ( @@ -80,15 +80,15 @@ function generateInput(formData:any, handleChange:any, label:string, name:string
- {required ? "*" : ""} + +