diff --git a/.env b/.env deleted file mode 100644 index 04d3402..0000000 --- a/.env +++ /dev/null @@ -1,7 +0,0 @@ -VITE_APP_NAME=tpay-dashboard-tl -VITE_APP_VERSION=1=9.1.1 -GENERATE_SOURCEMAP=false - -VITE_APP_API_URL=https://tpay.shiblysolution.id/api -# VITE_APP_API_URL=http://0.0.0.0:4001/api -VITE_ENV=default \ No newline at end of file diff --git a/.gitignore b/.gitignore index baee0cd..d2a16d3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ yarn-error.log* pnpm-debug.log* lerna-debug.log* +.env node_modules dist dist-ssr diff --git a/src/config/api.config.ts b/src/config/api.config.ts index 4780676..9f8af61 100644 --- a/src/config/api.config.ts +++ b/src/config/api.config.ts @@ -3,6 +3,7 @@ interface apiConfigProps { service_customer: string; service_master_data: string; service_transaction: string; + service_wallet: string; } const API_URL = import.meta.env.VITE_APP_API_URL; @@ -12,7 +13,8 @@ const apiConfig: apiConfigProps = { service_customer: `${API_URL}/c`, // service_master_data: `${API_URL}/m` service_master_data: `${API_URL}/t`, - service_transaction: `${API_URL}/tt` + service_transaction: `${API_URL}/tt`, + service_wallet: `${API_URL}/w` }; export { apiConfig }; diff --git a/src/pages/account/home/user-profile/blocks/BasicSettings.tsx b/src/pages/account/home/user-profile/blocks/BasicSettings.tsx index c5d9249..0d3847b 100644 --- a/src/pages/account/home/user-profile/blocks/BasicSettings.tsx +++ b/src/pages/account/home/user-profile/blocks/BasicSettings.tsx @@ -14,7 +14,7 @@ const BasicSettings = () => { // const user = localStorage.getItem('user'); // const parsedUser = user ? JSON.parse(user) : null; const parsedUser = getAuth()?.user; - console.log('parsedUser :', parsedUser); + // console.log('parsedUser :', parsedUser); const [newUsername, setNewUsername] = useState(parsedUser?.username || ''); const [newEmail, setNewEmail] = useState(parsedUser?.email || ''); const [newName, setNewName] = useState(parsedUser?.name || ''); diff --git a/src/pages/account/manage-currency/ManageCurrency.tsx b/src/pages/account/manage-currency/ManageCurrency.tsx index 24147a6..88a37bf 100644 --- a/src/pages/account/manage-currency/ManageCurrency.tsx +++ b/src/pages/account/manage-currency/ManageCurrency.tsx @@ -21,7 +21,6 @@ const ManageCurrency = () => { Manage Currency -
diff --git a/src/pages/groups/ManageGroups.tsx b/src/pages/groups/ManageGroups.tsx index 3be46e2..819ad82 100644 --- a/src/pages/groups/ManageGroups.tsx +++ b/src/pages/groups/ManageGroups.tsx @@ -148,7 +148,7 @@ const ManageGroups = () => { return (
-
+
setDialogOpen(false)} diff --git a/src/pages/master/aldeias/AldeiasMaster.tsx b/src/pages/master/aldeias/AldeiasMaster.tsx index 3ebb197..a3d0ad7 100644 --- a/src/pages/master/aldeias/AldeiasMaster.tsx +++ b/src/pages/master/aldeias/AldeiasMaster.tsx @@ -9,7 +9,7 @@ const AldeiasMaster = () => { return ( -

Aldeias

+

Aldeias

Dashboard diff --git a/src/pages/master/aldeias/blocks/ListToolbar.tsx b/src/pages/master/aldeias/blocks/ListToolbar.tsx index 70ababf..fbf8537 100644 --- a/src/pages/master/aldeias/blocks/ListToolbar.tsx +++ b/src/pages/master/aldeias/blocks/ListToolbar.tsx @@ -20,17 +20,17 @@ const ListToolbar = () => { onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)} /> - + {/* - + */} {/* + */} +
+
+ + + + +
+
+
+ + ); +}; + +export default ListToolbar; diff --git a/src/pages/master/conversion/hooks/ManageConversionContext.tsx b/src/pages/master/conversion/hooks/ManageConversionContext.tsx new file mode 100644 index 0000000..21f8c78 --- /dev/null +++ b/src/pages/master/conversion/hooks/ManageConversionContext.tsx @@ -0,0 +1,167 @@ +import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components'; +import { Toaster } from '@/components/ui/sonner'; +import { apiConfig } from '@/config/api.config'; +import { useCallApi } from '@/hooks'; +import { ColumnDef } from '@tanstack/react-table'; +import { createContext, useCallback, useMemo, useState } from 'react'; +import ListToolbar from '../blocks/ListToolbar'; + +interface ConversionProps { + id: string; + name: string; +} + +interface ContextProps { + conversion: ConversionProps[]; + showAddDialog: boolean; + handleAddDialog: (show: boolean) => void; + showEditDialog: boolean; + handleEditDialog: (show: boolean, selected_conversion: string | null) => void; + showDeleteDialog: boolean; + handleDeleteDialog: (show: boolean, selected_conversion: string | null) => void; + selectedConversion: string | null; + getConversionLists: ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any + ) => Promise<{ data: ConversionProps[]; totalCount: number } | undefined>; +} + +const initialProps: ContextProps = { + conversion: [], + showAddDialog: false, + handleAddDialog: () => {}, + showEditDialog: false, + handleEditDialog: () => {}, + showDeleteDialog: false, + handleDeleteDialog: () => {}, + selectedConversion: null, + getConversionLists: async () => undefined +}; + +const ManageConversionContext = createContext(initialProps); +const API_URL_WALLET = apiConfig.service_wallet; + +const ManageConversionContextProvider = ({ children }: { children: React.ReactNode }) => { + const [conversions, setConversions] = useState([]); + const [showAddDialog, setShowAddDialog] = useState(false); + const [showEditDialog, setShowEditDialog] = useState(false); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const [selectedConversion, setSelectedConversion] = useState(null); + const { GetData } = useCallApi(); + + const handleAddDialog = useCallback((show: boolean) => { + setShowAddDialog(show); + }, []); + + const handleEditDialog = useCallback((show: boolean, selected_conversion: string | null) => { + setShowEditDialog(show); + setSelectedConversion(show ? selected_conversion : null); + }, []); + + const handleDeleteDialog = useCallback((show: boolean, selected_conversion: string | null) => { + setShowEditDialog(show); + setSelectedConversion(show ? selected_conversion : null); + }, []); + + const columns = useMemo[]>( + () => [ + { + accessorFn: (row) => row.name, + id: 'name', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + id: 'actions', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + cell: (data) => { + const row = data.row.original; + return ( + <> + + + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + } + ], + [] + ); + + const getConversionLists = async (page: number, limit: number, sorting: any, filter: any) => { + try { + sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; + filter = filter.length == 0 ? {} : { any: filter[0].value?.toLowerCase() }; + const response = await GetData(`${API_URL_WALLET}/dashboard/conversion`, { + limit, + page: page + 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', + filter: JSON.stringify(filter) + }); + console.log(response?.data); + setConversions(response?.data.list); + return { data: response?.data.list, totalCount: response?.data.total_count }; + } catch (error) { + console.error('Error fetching Conversion', error); + } + }; + + return ( + + + } + layout={{ card: true }} + sorting={[{ id: 'id', desc: false }]} + serverSide={true} + onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => + getConversionLists(pageIndex, pageSize, sorting, columnFilters) + } + > + {children} + + + ); +}; + +export { ManageConversionContext, ManageConversionContextProvider }; +export type { ConversionProps }; diff --git a/src/pages/master/conversion/hooks/useManageConversionContext.tsx b/src/pages/master/conversion/hooks/useManageConversionContext.tsx new file mode 100644 index 0000000..cf6c60b --- /dev/null +++ b/src/pages/master/conversion/hooks/useManageConversionContext.tsx @@ -0,0 +1,12 @@ +import { useContext } from 'react'; +import { ManageConversionContext } from './ManageConversionContext'; + +const useManageConversionContext = () => { + const context = useContext(ManageConversionContext); + + if (!context) throw new Error('useManageConversionContext must be used within AuthProvider'); + + return context; +}; + +export { useManageConversionContext }; diff --git a/src/pages/master/municipios/blocks/ListToolbar.tsx b/src/pages/master/municipios/blocks/ListToolbar.tsx index 68dd8fe..4c5a633 100644 --- a/src/pages/master/municipios/blocks/ListToolbar.tsx +++ b/src/pages/master/municipios/blocks/ListToolbar.tsx @@ -33,17 +33,17 @@ const ListToolbar = () => { onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)} /> - + {/* - + */} {/* - + */} {/* - + */}
@@ -193,7 +183,7 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode } layout={{ card: true }} sorting={[{ id: 'id', desc: false }]} diff --git a/src/pages/master/profession/blocks/EditDialog.tsx b/src/pages/master/profession/blocks/EditDialog.tsx index 7dfc06c..ffdc02a 100644 --- a/src/pages/master/profession/blocks/EditDialog.tsx +++ b/src/pages/master/profession/blocks/EditDialog.tsx @@ -20,7 +20,7 @@ const API_URL = apiConfig.service_master_data; const EditDialog = () => { const { showEditDialog, handleEditDialog, selectedProfession } = useManageProfessionContext(); const { reload } = useDataGrid(); - const { PutData } = useCallApi(); + const { PutData, GetData } = useCallApi(); const parsedUser = getAuth()?.user; const created_time = new Date(); const formattedTime = created_time.toISOString().slice(0, 19).replace('T', ' '); @@ -62,6 +62,19 @@ const EditDialog = () => { [selectedProfession, formField] ); + const doFetchData = useCallback(async (id: string) => { + const response = await GetData(`${API_URL}/profession/getdata/${id}`, { id }); + + if (response?.status) { + setFormField((prev) => ({ + ...prev, + name: response.data.name + })); + } else { + setFormField(initialState); + } + }, []); + const handleUpdate = (e: React.FormEvent) => { e.preventDefault(); @@ -75,6 +88,12 @@ const EditDialog = () => { setAlert({ show: false, message: '' }); }; + useEffect(() => { + if (selectedProfession) { + doFetchData(selectedProfession); + } + }, [selectedProfession]); + useEffect(() => { if (showEditDialog) { setFormField({ @@ -85,6 +104,12 @@ const EditDialog = () => { } }, [formattedTime]); + useEffect(() => { + if (showEditDialog === false) { + resetForm(); + } + }, [showEditDialog]); + return ( handleEditDialog(open, null)}> diff --git a/src/pages/master/profession/blocks/ListToolbar.tsx b/src/pages/master/profession/blocks/ListToolbar.tsx index b578b42..73afd22 100644 --- a/src/pages/master/profession/blocks/ListToolbar.tsx +++ b/src/pages/master/profession/blocks/ListToolbar.tsx @@ -22,17 +22,17 @@ const ListToolbar = () => { } /> - + {/* - + */}
@@ -323,7 +326,7 @@ const EditDialog = () => { onSelect={() => { setFormField({ ...formField, - agentId: customer.msisdn + agent: customer.msisdn }); setOpen(false); }} diff --git a/src/pages/master/provider/blocks/ListToolbar.tsx b/src/pages/master/provider/blocks/ListToolbar.tsx index 8c1ba4d..3d88cbb 100644 --- a/src/pages/master/provider/blocks/ListToolbar.tsx +++ b/src/pages/master/provider/blocks/ListToolbar.tsx @@ -20,17 +20,17 @@ const ListToolbar = () => { onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)} /> - + {/* - + */}
@@ -168,7 +158,7 @@ const ManageProviderContextProvider = ({ children }: { children: React.ReactNode order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', filter: JSON.stringify(filter) }); - // console.log(response?.data); + console.log(response?.data); setProvider(response?.data.list); return { data: response?.data.list, totalCount: response?.data.total_count }; } catch (error) { @@ -194,7 +184,7 @@ const ManageProviderContextProvider = ({ children }: { children: React.ReactNode } layout={{ card: true }} sorting={[{ id: 'id', desc: false }]} diff --git a/src/pages/master/sucos/SucosMaster.tsx b/src/pages/master/sucos/SucosMaster.tsx index ac7b7e5..c698cfa 100644 --- a/src/pages/master/sucos/SucosMaster.tsx +++ b/src/pages/master/sucos/SucosMaster.tsx @@ -10,7 +10,7 @@ const SucosMaster = () => { return ( -

Sucos

+

Sucos

Dashboard diff --git a/src/pages/master/sucos/blocks/ListToolbar.tsx b/src/pages/master/sucos/blocks/ListToolbar.tsx index 7336ae2..9e822bb 100644 --- a/src/pages/master/sucos/blocks/ListToolbar.tsx +++ b/src/pages/master/sucos/blocks/ListToolbar.tsx @@ -30,17 +30,17 @@ const ListToolbar = () => { } /> - + {/* - + */} {/* + */} +
+
+ + + + +
+ + + + ); +}; + +export default ListToolbar; diff --git a/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx b/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx new file mode 100644 index 0000000..819785c --- /dev/null +++ b/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx @@ -0,0 +1,220 @@ +import { DataGridColumnHeader, DataGridProvider, KeenIcon } from '@/components'; +import { Toaster } from '@/components/ui/sonner'; +import { apiConfig } from '@/config/api.config'; +import { useCallApi } from '@/hooks'; +import { ColumnDef } from '@tanstack/react-table'; +import React, { createContext, useCallback, useMemo, useState } from 'react'; +import ListToolbar from '../blocks/ListToolbar'; + +interface WalletRuleProps { + name: string; + id_currency: string; + status: string; +} + +interface ContextProps { + walletRules: WalletRuleProps[]; + showAddDialog: boolean; + handleAddDialog: (show: boolean) => void; + showEditDialog: boolean; + handleEditDialog: (show: boolean, selected_walletRule: string | null) => void; + showDeleteDialog: boolean; + handleDeleteDialog: (show: boolean, selected_walletRule: string | null) => void; + selectedWalletRule: string | null; + getWalletRuleLists: ( + limit: number, + page: number, + with_deleted: boolean, + order_field: any, + order_direction: any + ) => Promise<{ data: WalletRuleProps[]; totalCount: number } | undefined>; +} + +const initialProps: ContextProps = { + walletRules: [], + showAddDialog: false, + handleAddDialog: (show: boolean) => {}, + showEditDialog: false, + handleEditDialog: (show: boolean, selected_walletRule: string | null) => {}, + showDeleteDialog: false, + handleDeleteDialog: (show: boolean, selected_walletRule: string | null) => {}, + selectedWalletRule: null, + getWalletRuleLists: async () => undefined +}; + +const ManageWalletRuleContext = createContext(initialProps); +const API_URL_WALLET = apiConfig.service_wallet; + +const ManageWalletRuleContextProvider = ({ children }: { children: React.ReactNode }) => { + const [walletRules, setWalletRules] = useState([]); + const [showAddDialog, setShowAddDialog] = useState(false); + const [showEditDialog, setShowEditDialog] = useState(false); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + const [selectedWalletRule, setSelectedWalletRule] = useState(null); + const { GetData } = useCallApi(); + + const handleAddDialog = useCallback((show: boolean) => { + setShowAddDialog(show); + }, []); + + const handleEditDialog = useCallback((show: boolean, selected_walletRule: string | null) => { + setShowEditDialog(show); + setSelectedWalletRule(show ? selected_walletRule : null); + }, []); + + const handleDeleteDialog = useCallback((show: boolean, selected_walletRule: string | null) => { + setShowDeleteDialog(show); + setSelectedWalletRule(show ? selected_walletRule : null); + }, []); + + const columns = useMemo[]>( + () => [ + { + accessorFn: (row) => row.balance_minimum, + id: 'balance_minimum', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.balance_maximum, + id: 'balance_maximum', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.credit_limit, + id: 'credit_limit', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.max_transaction_per_day, + id: 'max_transaction_per_day', + header: ({ column }) => ( + + ), + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.monthly_limit, + id: 'monthly_limit', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + accessorFn: (row) => row.status, + id: 'status', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + id: 'actions', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + cell: (data) => { + const row = data.row.original; + return ( + <> + + + + ); + }, + meta: { + headerClassName: 'w-[100px]', + cellClassName: 'text-center' + } + } + ], + [] + ); + + const getWalletRuleLists = async (page: number, limit: number, sorting: any, filter: any) => { + try { + sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; + filter = filter.length == 0 ? {} : { any: filter[0].value?.toLowerCase() }; + const response = await GetData(`${API_URL_WALLET}/dashboard/wallet_rule`, { + limit, + page: page + 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', + filter: JSON.stringify(filter) + }); + console.log(response?.data); + setWalletRules(response?.data.list); + return { data: response?.data.list, totalCount: response?.data.total_count }; + } catch (error) { + console.error('Error fetching Wallet Rule', error); + } + }; + + return ( + + + } + layout={{ card: true }} + sorting={[{ id: 'id', desc: false }]} + serverSide={true} + onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) => + getWalletRuleLists(pageIndex, pageSize, sorting, columnFilters) + } + > + {children} + + + ); +}; + +export { ManageWalletRuleContext, ManageWalletRuleContextProvider }; +export type { WalletRuleProps }; diff --git a/src/pages/master/walletRule/hooks/useManageWalletRuleContext.tsx b/src/pages/master/walletRule/hooks/useManageWalletRuleContext.tsx new file mode 100644 index 0000000..5d1c3a7 --- /dev/null +++ b/src/pages/master/walletRule/hooks/useManageWalletRuleContext.tsx @@ -0,0 +1,16 @@ +import { useContext } from 'react'; +import { ManageWalletRuleContext } from './ManageWalletRuleContext'; + +const useManageWalletRuleContext = () => { + const context = useContext(ManageWalletRuleContext); + + if (!context) { + throw new Error( + 'useManageWalletRuleContext must be used within a ManageWalletRuleContextProvider' + ); + } + + return context; +}; + +export { useManageWalletRuleContext }; diff --git a/src/pages/members/manage-members/CustomerDetailModal.tsx b/src/pages/members/manage-members/CustomerDetailModal.tsx index 1e3abfd..f52e42b 100644 --- a/src/pages/members/manage-members/CustomerDetailModal.tsx +++ b/src/pages/members/manage-members/CustomerDetailModal.tsx @@ -1,18 +1,9 @@ import React, { useState, useEffect } from "react"; import axios from 'axios'; -import { - Dialog, - DialogActions, - DialogContent, - DialogTitle, - TextField, - Button, - MenuItem, - Select, - InputLabel, - FormControl, - Typography +import { Dialog,DialogActions,DialogContent,DialogTitle,TextField,Button,MenuItem,Select,InputLabel,FormControl,Typography, + InputAdornment,Grid,Box } from "@mui/material"; +import UploadFileIcon from "@mui/icons-material/UploadFile"; import Divider from '@mui/material/Divider'; import { initialMember } from "./Columns"; import { apiConfig } from '@/config/api.config'; @@ -25,7 +16,7 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat const [aldeias, setAldeias] = useState([]); const [postoAdm, setPostoAdm] = useState([]); const [sucos, setSucos] = useState([]); - + useEffect(() => { setFormData(initialData || {}); // Sync formData when initialData changes fetchMasterData() @@ -81,7 +72,11 @@ 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); - setFormData({ ...formData, [name]: value }); + if (name === "file_selfie" || name === "photouser") { // FOR FILE ONLY + setFormData({ ...formData, [name]: e.target.files[0] }); + } else { + setFormData({ ...formData, [name]: value }); + } }; async function getMasterAfter(name: string, id: any) { @@ -159,7 +154,7 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat - + {fileTextFile("Photo", formData.photouser, "photouser", handleChange)} @@ -180,8 +175,17 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat Passport + + {/* AGENT & PREMIUM DATA */} + + {fileTextFile("File Selfie", formData.file_selfie, "file_selfie", handleChange)} + {fileTextFile("File Document", formData.file_document_id, "file_document_id", handleChange)} + {fileTextFile("File Document & Selfie", formData.file_document_id_selfie, "file_document_id_selfie", handleChange)} + {fileTextFile("File Commercial License", formData.file_commercial_license, "file_commercial_license", handleChange)} + {/* AGENT & PREMIUM DATA */} + {/* */} {/* */} @@ -239,14 +243,25 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat Bank - + + Bank Name + + - Approval + {getAdmAccess(page)} { page === 'kyc' ? ( - + <> + Approval + + ) : ('') } @@ -267,3 +282,74 @@ const CustomerDialog = ({ open, handleClose, handleSubmit, initialData, viewStat }; export default CustomerDialog; + +function fileTextFile(label: string, value: any, name: string, handleChange: any) { + return ( + + + + + ), + }} + /> + ) +} + +function getAdmAccess(page: string) { + if (page !== "kyc") { + return ( + + Access Administration + + + + Unblock PIN + + + + Reset PIN + + + + + + Change Group + + + + Edit Member + + + + + + ) + } else { + return ('') + } +} \ No newline at end of file diff --git a/src/pages/menu/manage-menu/blocks/AddDIalog.tsx b/src/pages/menu/manage-menu/blocks/AddDIalog.tsx index d79fe8a..15d9a74 100644 --- a/src/pages/menu/manage-menu/blocks/AddDIalog.tsx +++ b/src/pages/menu/manage-menu/blocks/AddDIalog.tsx @@ -143,6 +143,7 @@ const AddDialog = () => { id: 'uncontrolled-native', }} > + { parents ? parents.map((el: any) => ( @@ -175,6 +176,7 @@ const AddDialog = () => {
{ id: 'uncontrolled-native', }} > + diff --git a/src/pages/menu/manage-menu/hooks/ManageMenusContext.tsx b/src/pages/menu/manage-menu/hooks/ManageMenusContext.tsx index 96a82f0..ab46533 100644 --- a/src/pages/menu/manage-menu/hooks/ManageMenusContext.tsx +++ b/src/pages/menu/manage-menu/hooks/ManageMenusContext.tsx @@ -175,7 +175,8 @@ const ManageMenusContextProvider = ({ children }: { children: React.ReactNode }) const flattenChildren = (parent: any, parentIdx: number, depth = 0, parentName = '') => { if (parent.link === '/') { - if (!parents.find((el: any) => el.id === parent.id)) setParents((el: any) => [...el, { id: parent.id, name: parent.name }]) // GET PARENTS + if (!parents.find((el: any) => el.id === parent.id)) + setParents((el: any) => [...el, { id: parent.id, name: parent.name }]); // GET PARENTS } if (!parent.children || parent.children.length === 0) { return []; // Jika tidak ada children, kembalikan array kosong @@ -220,8 +221,9 @@ const ManageMenusContextProvider = ({ children }: { children: React.ReactNode }) const total_count = transformedData.length; + console.log(response.data); setMenus(transformedData); - return { data: transformedData, totalCount: total_count }; + return { data: transformedData, totalCount: response.data.total_count }; } catch (error) { console.error('Error fetching Menus', error); return { data: [], totalCount: 0 }; @@ -248,7 +250,7 @@ const ManageMenusContextProvider = ({ children }: { children: React.ReactNode }) } layout={{ card: true }} sorting={[{ id: 'id', desc: false }]} diff --git a/src/pages/settings/user/manage-position/blocks/AddDialog.tsx b/src/pages/settings/user/manage-position/blocks/AddDialog.tsx index 1c0dd94..6c32480 100644 --- a/src/pages/settings/user/manage-position/blocks/AddDialog.tsx +++ b/src/pages/settings/user/manage-position/blocks/AddDialog.tsx @@ -83,6 +83,12 @@ const AddDialog = () => { const doCreatePosition = useCallback( async (e: React.FormEvent) => { e.preventDefault(); + + if (formField.name.trim() === '') { + setAlert({ show: true, message: 'Please fill in all required fields.' }); + return; + } + const response = await PostData(`${API_URL}/user_role/create`, { name: formField.name, roles: selectMenus, diff --git a/src/pages/settings/user/manage-position/blocks/EditDialog.tsx b/src/pages/settings/user/manage-position/blocks/EditDialog.tsx index 4209f2e..d000fac 100644 --- a/src/pages/settings/user/manage-position/blocks/EditDialog.tsx +++ b/src/pages/settings/user/manage-position/blocks/EditDialog.tsx @@ -91,6 +91,12 @@ const EditDialog = () => { const doEditPosition = useCallback( async (e: React.FormEvent) => { e.preventDefault(); + + if (formField.name.trim() === '') { + setAlert((prev) => ({ ...prev, show: true, message: 'Please fill name field.' })); + return; + } + if (!selectedPosition) { toast.success('Please Select Position'); return; diff --git a/src/pages/transaction/transaction.tsx b/src/pages/transaction/transaction.tsx new file mode 100644 index 0000000..4fcba47 --- /dev/null +++ b/src/pages/transaction/transaction.tsx @@ -0,0 +1,12 @@ +const Transaction = () => { + return ( +
+
+

Transaction

+
+
+ ); + }; + + export default Transaction; + \ No newline at end of file diff --git a/src/routing/AppRoutingSetup.tsx b/src/routing/AppRoutingSetup.tsx index 4730f01..ace6ab8 100644 --- a/src/routing/AppRoutingSetup.tsx +++ b/src/routing/AppRoutingSetup.tsx @@ -33,6 +33,9 @@ import Municipios from '@/pages/master/municipios/Municipios'; import ProfessionMaster from '@/pages/master/profession/ProfessionMaster'; import ProductsMaster from '@/pages/master/products/ProductsMaster'; import ProviderMaster from '@/pages/master/provider/ProviderMaster'; +import Transaction from '@/pages/transaction/transaction'; +import ConversionMaster from '@/pages/master/conversion/ConversionMaster'; +import WalletRuleMaster from '@/pages/master/walletRule/WalletRuleMaster'; const AppRoutingSetup = (): ReactElement => { return ( @@ -49,11 +52,12 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> } /> - } /> + } /> + } /> } /> @@ -61,9 +65,9 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> + } /> } /> - } /> } /> } /> @@ -75,11 +79,9 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> } /> - + } /> } /> - } /> - } /> } />