From b60f1ac73a041b97e501821f3f1f999236cc7f9a Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Tue, 8 Apr 2025 16:11:00 +0700 Subject: [PATCH 01/58] fix table and field agent on formField - show Host to Host - set field agent to optional with default value `''` --- src/pages/master/provider/blocks/EditDialog.tsx | 2 +- src/pages/master/provider/hooks/ManageProviderContext.tsx | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/master/provider/blocks/EditDialog.tsx b/src/pages/master/provider/blocks/EditDialog.tsx index ef00c19..ba8cb68 100644 --- a/src/pages/master/provider/blocks/EditDialog.tsx +++ b/src/pages/master/provider/blocks/EditDialog.tsx @@ -145,7 +145,7 @@ const EditDialog = () => { type: response?.data.type, status: response?.data.status, transaction_type: response?.data.transaction_type.id, - agent: response?.data.agent.id + agent: response?.data.agent?.id || '' })); } }, []); diff --git a/src/pages/master/provider/hooks/ManageProviderContext.tsx b/src/pages/master/provider/hooks/ManageProviderContext.tsx index 2cfe75f..85b25a9 100644 --- a/src/pages/master/provider/hooks/ManageProviderContext.tsx +++ b/src/pages/master/provider/hooks/ManageProviderContext.tsx @@ -94,7 +94,13 @@ const ManageProviderContextProvider = ({ children }: { children: React.ReactNode } }, { - accessorFn: (row) => row.provider_type, + accessorFn: (row) => { + const typeMapping: Record = { + h2h: 'Host To Host', + agent: 'Agent' + }; + return typeMapping[row.provider_type] || row.provider_type; + }, id: 'type', header: ({ column }) => , enableSorting: false, From 60bc51d7fdcd52223f51dc6b905cc7baf581db23 Mon Sep 17 00:00:00 2001 From: bagusajisaputroo Date: Tue, 8 Apr 2025 17:18:48 +0700 Subject: [PATCH 02/58] fix sucosid in aldeian form + clean up manage transfertype --- src/pages/master/aldeias/blocks/AddDialog.tsx | 7 +++- .../master/aldeias/blocks/EditDialog.tsx | 6 ++- .../hooks/ManageTransferTypeContext.tsx | 41 +++++++++++-------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/pages/master/aldeias/blocks/AddDialog.tsx b/src/pages/master/aldeias/blocks/AddDialog.tsx index 38e4c1b..6297958 100644 --- a/src/pages/master/aldeias/blocks/AddDialog.tsx +++ b/src/pages/master/aldeias/blocks/AddDialog.tsx @@ -175,7 +175,10 @@ const AddDialog = () => { - @@ -192,7 +195,7 @@ const AddDialog = () => { {sucos.map((suco) => ( { setFormField({ ...formField, diff --git a/src/pages/master/aldeias/blocks/EditDialog.tsx b/src/pages/master/aldeias/blocks/EditDialog.tsx index 79eb0ce..40033a7 100644 --- a/src/pages/master/aldeias/blocks/EditDialog.tsx +++ b/src/pages/master/aldeias/blocks/EditDialog.tsx @@ -198,7 +198,11 @@ const EditDialog = () => { - diff --git a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx index 4d2b233..7247c4a 100644 --- a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx +++ b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx @@ -82,7 +82,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React header: ({ column }) => ( ), - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -90,7 +90,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => row.description, id: 'description', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -98,7 +98,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => row.wallet_origin?.name || 'N/A', id: 'wallet_origin', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -106,7 +106,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => row.wallet_destination.name || 'N/A', id: 'wallet_destination', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -114,7 +114,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => row.maximum_amount, id: 'maximum_amount', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -122,7 +122,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => row.minimum_amount, id: 'minimum_amount', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -132,7 +132,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React header: ({ column }) => ( ), - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -142,7 +142,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React header: ({ column }) => ( ), - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -152,7 +152,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React header: ({ column }) => ( ), - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -162,7 +162,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React header: ({ column }) => ( ), - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[250px]' } }, @@ -170,7 +170,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => (row.status === 'Y' ? 'Active' : 'Inactive'), id: 'status', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[150px]' } }, @@ -178,7 +178,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React accessorFn: (row) => (row.status_approval === 'Y' ? 'Yes' : 'No'), id: 'status_approval', header: ({ column }) => , - enableSorting: true, + enableSorting: false, enableHiding: false, meta: { headerClassName: 'w-[150px]' } }, @@ -211,22 +211,29 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React ], [handleEditDialog, handleDeleteDialog] ); + const doGetTransferTypeListData = async ( page: number, limit: number, sorting: any, filter: any ) => { - sorting = sorting.length == 0 ? [{ id: 'id', desc: false }] : sorting; + + 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, with_deleted: false, - order_field: sorting[0].id, - order_direction: sorting[0].desc ? 'ASC' : 'DESC', + order_field: orderField, + order_direction: orderDirection, filter: JSON.stringify(filter) }); + return { data: response?.data.list, totalCount: response?.data.total_count }; }; @@ -253,7 +260,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React pagination={{ size: 10 }} layout={{ card: true }} toolbar={} - sorting={[{ id: 'id', desc: true }]} + sorting={[{ id: 'created_at', desc: true }]} // Default sorting serverSide={true} onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => doGetTransferTypeListData(pageIndex, pageSize, sorting, columnFilters) @@ -268,4 +275,4 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React }; export { ManageTransferTypeContext, ManageTransferTypeContextProvider }; -export type { TransferType }; +export type { TransferType }; \ No newline at end of file From 3043b39c8cf3221ab6d2b6d997bd0034e543545d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Apr 2025 21:58:32 +0700 Subject: [PATCH 03/58] fix member --- src/pages/members/kyc/Kyc.tsx | 23 ++-- .../manage-members/CustomerDetailModal.tsx | 104 ++++++++++++++++-- .../members/manage-members/ManageMembers.tsx | 23 +++- 3 files changed, 123 insertions(+), 27 deletions(-) diff --git a/src/pages/members/kyc/Kyc.tsx b/src/pages/members/kyc/Kyc.tsx index eb038ff..e7ea68e 100644 --- a/src/pages/members/kyc/Kyc.tsx +++ b/src/pages/members/kyc/Kyc.tsx @@ -67,7 +67,7 @@ const Kyc = () => { }); setMembers(resMembers); } catch (error: any) { - alert(error.message); + toast.error(error.message); console.log(error); } } @@ -117,6 +117,7 @@ const Kyc = () => { delete updateData.group_updated_at; delete updateData.group_deleted_by; delete updateData.group_deleted_at; + delete updateData.updated_at; try { if (dialogType === 'reject') { await axios.post(`${BASE_URL}/customer/reject`, { customerid: customerId }); @@ -134,7 +135,6 @@ const Kyc = () => { setIsDialogOpen(false); toast.success('Success Update Kyc Member'); } catch (error: any) { - alert(error.message); setDialogOpen(false); setIsDialogOpen(false); toast.error(error.message); @@ -156,15 +156,16 @@ const Kyc = () => { onYes={handleYes} onNo={() => setDialogOpen(false)} /> - + { member.id ? ( + + ): ""}

Manage Member KYC

diff --git a/src/pages/members/manage-members/CustomerDetailModal.tsx b/src/pages/members/manage-members/CustomerDetailModal.tsx index dc1711a..140b242 100644 --- a/src/pages/members/manage-members/CustomerDetailModal.tsx +++ b/src/pages/members/manage-members/CustomerDetailModal.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from "react"; import axios from 'axios'; import { Dialog,DialogActions,DialogContent,DialogTitle,TextField,Button,MenuItem,Select,InputLabel,FormControl,Typography, - InputAdornment,Grid,Box + InputAdornment,Grid,Box,List,ListItem, } from "@mui/material"; import UploadFileIcon from "@mui/icons-material/UploadFile"; import Divider from '@mui/material/Divider'; @@ -11,7 +11,7 @@ import ConfirmDialog from '@/components/confirm'; import { toast } from 'sonner'; const BASE_URL_MASTER_DATA = apiConfig.service_master_data; const BASE_URL_CUSTOMER = apiConfig.service_customer; - +// MAIN PAGE const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStats, handleReject, page, fetchCustomers }: any) => { const [formData, setFormData] = useState(initialData || initialMember); const [viewOnly, setViewOnly] = useState(viewStats || false); @@ -80,7 +80,8 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat const handleChange = async (e: any) => { const { name, value } = e.target; if (name === 'municipio' || name === 'posto_adms' || name === 'suco') await getMasterAfter(name, value); - if (name === "file_selfie" || name === "photouser") { // FOR FILE ONLY + if (name === "file_selfie" || name === "photouser" || name === 'file_document_id' || name === "file_document_id_selfie" || + name === "file_commercial_license") { // FOR FILE ONLY setFormData({ ...formData, [name]: e.target.files[0] }); } else { setFormData({ ...formData, [name]: value }); @@ -127,8 +128,9 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat } const onSubmit = () => { + if (page === 'kyc' && !formData.description) return toast.warning(`Description for approval needed!`) handleSubmit(formData); - handleClose(); + // handleClose(); }; const onReject = () => { @@ -274,9 +276,13 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat page === 'kyc' ? ( <> Approval - + - ) : (<>{getAdmAccess(page, formData, handleClose, fetchCustomers, viewOnly, setViewOnly)}) + ) : (<> + {getAdmAccess(page, formData, handleClose, fetchCustomers, viewOnly, setViewOnly)} + + {formData.id ? showCustomerWallet(formData.id) : ""} + ) } @@ -317,11 +323,11 @@ function fileTextFile(label: string, value: any, name: string, handleChange: any - */} ), }} /> ) } - +// ACCESS ADM function getAdmAccess(page: string, data: any, handleClose: any, fetchCustomers: any, viewOnly: any, setViewOnly: any) { const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState(''); @@ -517,7 +523,83 @@ function getPinStatus(status: string) { res: null } } +// CUSTOMER WALLET +function showCustomerWallet(customerid: any) { + const [dialogOpen, setDialogOpen] = useState(false); + const [customerWallet, setCustomerWallet] = useState([]); + if (!customerid) return '' + + useEffect(() => { + fetchCustomerWallet() + }, []); -function showCustomerWallet() { + async function fetchCustomerWallet() { + try { + let getCustWallet = await axios.get(`${BASE_URL_CUSTOMER}/customer/wallet`, { params: { customerid: customerid }}); + setCustomerWallet(getCustWallet.data.data.wallets) + } catch (error: any) { + toast.error(error.message) + } + } + const handleYes = async () => {} + + return ( + + Wallet Member + + + {customerWallet.map((item:any, index:any) => ( + + + + + Name + + + {item.wallet.name} + + + + + Description + + {item.wallet.description} + + + + Transaction Today + + {item.transaction_number_today} + + + {index < customerWallet.length - 1 && } + + ))} + + + setDialogOpen(false)} + title="Confirm Action" + content={`Are you sure you want to show?`} + onYes={handleYes} + onNo={() => setDialogOpen(false)} + /> + + ) } \ No newline at end of file diff --git a/src/pages/members/manage-members/ManageMembers.tsx b/src/pages/members/manage-members/ManageMembers.tsx index 67f7341..7adca08 100644 --- a/src/pages/members/manage-members/ManageMembers.tsx +++ b/src/pages/members/manage-members/ManageMembers.tsx @@ -20,7 +20,10 @@ const ManageMembers = () => { const [isDialogOpen, setIsDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState(''); - const closeDialog = () => setIsDialogOpen(false); + const closeDialog = () => { + setIsDialogOpen(false) + setMember(initialMember) + }; const { getUser } = useAuthContext(); useEffect(() => { @@ -48,7 +51,7 @@ const ManageMembers = () => { }); setMembers(resMembers); } catch (error: any) { - alert(error.message); + toast.error(error.message); console.log(error); } } @@ -99,8 +102,16 @@ const ManageMembers = () => { delete updateData.group_deleted_at; delete updateData.updated_at; try { - if (dialogType === 'update') - await axios.put(`${BASE_URL}/customer/update/${selectedMember}`, updateData); + const form = new FormData(); + for (const property in updateData) { + if (updateData[property]) form.append(property, updateData[property]); + } + + if (dialogType === 'update') await axios.put(`${BASE_URL}/customer/update/${selectedMember}`, form, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }); // if (dialogType === 'create') await axios.post(`${BASE_URL}/customers/create`, member) await fetchCustomers(); setDialogOpen(false); @@ -130,12 +141,14 @@ const ManageMembers = () => { onYes={handleYes} onNo={() => setDialogOpen(false)} /> - + ): ""}

Manage Members

From 0c5608273fe42456915e4309badbdd009a8ca617 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Apr 2025 00:13:45 +0700 Subject: [PATCH 04/58] fix member --- src/pages/members/manage-members/CustomerDetailModal.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/members/manage-members/CustomerDetailModal.tsx b/src/pages/members/manage-members/CustomerDetailModal.tsx index 140b242..0e302cf 100644 --- a/src/pages/members/manage-members/CustomerDetailModal.tsx +++ b/src/pages/members/manage-members/CustomerDetailModal.tsx @@ -192,6 +192,8 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat + + {fileTextFile("File Selfie", formData.file_selfie, "file_selfie", handleChange)} {"file_selfie"} {fileTextFile("File Document", formData.file_document_id, "file_document_id", handleChange)} From 0a1ff7de1864ef49c71d984dd2dbef05057f652b Mon Sep 17 00:00:00 2001 From: Raja Oktafrianto Date: Wed, 9 Apr 2025 09:56:26 +0700 Subject: [PATCH 05/58] fixing update delete reward --- .../master/products/blocks/AddDialog.tsx | 2 +- .../master/products/blocks/EditDialog.tsx | 2 +- src/pages/master/reward/blocks/AddDialog.tsx | 36 +++---- .../master/reward/blocks/DeleteDialog.tsx | 7 +- src/pages/master/reward/blocks/EditDialog.tsx | 98 ++++++++++--------- .../reward/hooks/ManageRewardContext.tsx | 12 +-- 6 files changed, 81 insertions(+), 76 deletions(-) diff --git a/src/pages/master/products/blocks/AddDialog.tsx b/src/pages/master/products/blocks/AddDialog.tsx index 0690b4b..0a5e192 100644 --- a/src/pages/master/products/blocks/AddDialog.tsx +++ b/src/pages/master/products/blocks/AddDialog.tsx @@ -130,7 +130,7 @@ const AddDialog = () => { } doCreateProduct(e); - console.log(formField); + // console.log(formField); setAlert({ show: false, message: '' }); }; diff --git a/src/pages/master/products/blocks/EditDialog.tsx b/src/pages/master/products/blocks/EditDialog.tsx index 66c809d..fa670fe 100644 --- a/src/pages/master/products/blocks/EditDialog.tsx +++ b/src/pages/master/products/blocks/EditDialog.tsx @@ -109,7 +109,7 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { const response = await GetData(`${API_URL}/product/getdata/${id}`, { id }); - console.log(response); + // console.log(response); if (response?.status) { setFormField((prev) => ({ diff --git a/src/pages/master/reward/blocks/AddDialog.tsx b/src/pages/master/reward/blocks/AddDialog.tsx index 40df444..9f44be0 100644 --- a/src/pages/master/reward/blocks/AddDialog.tsx +++ b/src/pages/master/reward/blocks/AddDialog.tsx @@ -14,6 +14,7 @@ import { apiConfig } from '@/config/api.config'; import { toast } from 'sonner'; import { getAuth } from '@/auth'; import { useCallApi } from '@/hooks'; +import { NumericFormat } from 'react-number-format'; import { useManageRewardContext } from '../hooks/useManageRewardContext'; import { Select, @@ -57,7 +58,7 @@ const AddDialog = () => { const doCreateReward = useCallback( async (e: React.FormEvent) => { e.preventDefault(); - console.log('Data yang akan dikirim:', formField); + // console.log('Data yang akan dikirim:', formField); const response = await PostData(`${API_URL}/reward/create`, formField); if (response?.status) { @@ -91,20 +92,15 @@ const AddDialog = () => { setAlert({ show: false, message: '' }); }; - const handleReset = () => { - resetForm(); - setAlert({ show: false, message: '' }); - }; - useEffect(() => { if (showAddDialog) { - setFormField({ - ...formField, + setFormField((prev) => ({ + ...prev, created_by: parsedUser?.username, created_at: formattedTime - }); + })); } - }, [formattedTime]); + }, [showAddDialog, parsedUser?.username, formattedTime]); useEffect(() => { if (showAddDialog === false) { @@ -159,19 +155,19 @@ const AddDialog = () => { Amount* - { - const value = parseFloat(e.target.value); - setFormField({ - ...formField, - amount: isNaN(value) ? 0 : value - }); + thousandSeparator="." + decimalSeparator="," + allowNegative={false} + onValueChange={(values) => { + setFormField((prev) => ({ + ...prev, + amount: values.floatValue || 0 + })); }} + placeholder="Enter Amount" />
diff --git a/src/pages/master/reward/blocks/DeleteDialog.tsx b/src/pages/master/reward/blocks/DeleteDialog.tsx index dd7639c..70aaf5e 100644 --- a/src/pages/master/reward/blocks/DeleteDialog.tsx +++ b/src/pages/master/reward/blocks/DeleteDialog.tsx @@ -25,13 +25,16 @@ const DeleteDialog = () => { message: '' }); + // console.log('ini data :', selectedReward); + const doDeleteReward = useCallback(async () => { if (!selectedReward) { toast.error('No Reward selected'); return; } - const response = await DeleteData(`${API_URL}/reward/delete/${selectedReward}`, { - id: selectedReward + // console.log('Ini datanya:', selectedReward); + const response = await DeleteData(`${API_URL}/reward/delete/${selectedReward?.id}/true`, { + id: selectedReward.id }); if (response?.status) { diff --git a/src/pages/master/reward/blocks/EditDialog.tsx b/src/pages/master/reward/blocks/EditDialog.tsx index cb3695a..2dc8c83 100644 --- a/src/pages/master/reward/blocks/EditDialog.tsx +++ b/src/pages/master/reward/blocks/EditDialog.tsx @@ -14,6 +14,7 @@ import { } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; +import { NumericFormat } from 'react-number-format'; import { Select, SelectContent, @@ -58,7 +59,8 @@ const EditDialog = () => { async (e: React.FormEvent) => { e.preventDefault(); - const response = await PutData(`${API_URL}/reward/update/${selectedReward}`, formField); + // console.log('Ini datanya:', selectedReward); + const response = await PutData(`${API_URL}/reward/update/${selectedReward?.id}`, formField); if (response?.status) { resetForm(); @@ -74,16 +76,17 @@ const EditDialog = () => { ); const doFetchData = useCallback(async (id: string) => { + // console.log('Ini datanya:', id); const response = await GetData(`${API_URL}/reward/getdata/${id}`, { id }); - console.log('API Response:', response); + // console.log('API Response:', response); if (response?.status) { setFormField((prev) => ({ ...prev, - name: response?.data.name, - type: response?.data.type, - amount: response?.data.amount, - status: response?.data.status + name: response.data.name, + type: response.data.type, + amount: response.data.amount, + status: response.data.status })); } }, []); @@ -107,21 +110,20 @@ const EditDialog = () => { // }; useEffect(() => { - // console.log('Selected Reward:', selectedReward); if (selectedReward) { - doFetchData(selectedReward); + doFetchData(selectedReward.id.toString()); } }, [selectedReward]); useEffect(() => { - if (showEditDialog) { - setFormField({ - ...formField, + if (showEditDialog && selectedReward) { + setFormField((prev) => ({ + ...prev, updated_by: parsedUser.username, updated_at: formattedTime - }); + })); } - }, [formattedTime]); + }, [showEditDialog, selectedReward]); useEffect(() => { if (showEditDialog === false) { @@ -142,67 +144,71 @@ const EditDialog = () => {
-
-