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/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)} /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} {/* { + const { table, reload } = useDataGrid(); + const { handleAddDialog } = useManageConversionContext(); + + return ( + + + + + + + table.getColumn('name')?.setFilterValue(event.target.value)} + /> + + {/* + + {loadingButton === 'filter' ? : } + + + */} + + + handleAddDialog(true)} + > + Add Data + + + reload()}> + + + + + + + + ); +}; + +export default ListToolbar; 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)} /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} {/* { } /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} {/* { message: '' }); const initialState = { - name: '', - code: '', - type: '', - description: '', - price_point: 0, - price_cash: 0, - cashback_point: 0, - cashback_cash: 0, - status: '', - provider: '', - process_on_third_party: '', + products_name: '', + products_code: '', + products_type: '', + products_description: '', + products_price_point: 0, + products_price_cash: 0, + products_cashback_point: 0, + products_cashback_cash: 0, + products_status: '', + products_provider: '', + products_process_on_third_party: '', created_by: '', created_at: '' }; @@ -104,15 +104,15 @@ const AddDialog = () => { e.preventDefault(); if ( - formField.name.trim() === '' || - formField.type.trim() === '' || - formField.code.trim() === '' || - formField.description.trim() === '' || - formField.price_point === 0 || - formField.price_cash === 0 || - formField.cashback_point === 0 || - formField.cashback_cash === 0 || - formField.status.trim() === '' || + formField.products_name.trim() === '' || + formField.products_type.trim() === '' || + formField.products_code.trim() === '' || + formField.products_description.trim() === '' || + formField.products_price_point === 0 || + formField.products_price_cash === 0 || + formField.products_cashback_point === 0 || + formField.products_cashback_cash === 0 || + formField.products_status.trim() === '' || formField.created_by.trim() === '' || formField.created_at.trim() === '' ) { @@ -152,7 +152,7 @@ const AddDialog = () => { Product - Create - + {alert.show && ( @@ -170,8 +170,10 @@ const AddDialog = () => { setFormField({ ...formField, name: e.target.value })} + value={formField.products_name} + onChange={(e) => + setFormField({ ...formField, products_name: e.target.value }) + } /> @@ -184,8 +186,10 @@ const AddDialog = () => { setFormField({ ...formField, type: e.target.value })} + value={formField.products_type} + onChange={(e) => + setFormField({ ...formField, products_type: e.target.value }) + } /> @@ -198,8 +202,10 @@ const AddDialog = () => { setFormField({ ...formField, code: e.target.value })} + value={formField.products_code} + onChange={(e) => + setFormField({ ...formField, products_code: e.target.value }) + } /> @@ -212,8 +218,10 @@ const AddDialog = () => { setFormField({ ...formField, description: e.target.value })} + value={formField.products_description} + onChange={(e) => + setFormField({ ...formField, products_description: e.target.value }) + } /> @@ -228,10 +236,13 @@ const AddDialog = () => { type="number" min={0} step={0.01} - value={formField.price_point} + value={formField.products_price_point} onChange={(e) => { const value = parseFloat(e.target.value); - setFormField({ ...formField, price_point: isNaN(value) ? 0 : value }); + setFormField({ + ...formField, + products_price_point: isNaN(value) ? 0 : value + }); }} /> @@ -247,10 +258,13 @@ const AddDialog = () => { type="number" min={0} step={0.01} - value={formField.price_cash} + value={formField.products_price_cash} onChange={(e) => { const value = parseFloat(e.target.value); - setFormField({ ...formField, price_cash: isNaN(value) ? 0 : value }); + setFormField({ + ...formField, + products_price_cash: isNaN(value) ? 0 : value + }); }} /> @@ -266,10 +280,13 @@ const AddDialog = () => { type="number" min={0} step={0.01} - value={formField.cashback_point} + value={formField.products_cashback_point} onChange={(e) => { const value = parseFloat(e.target.value); - setFormField({ ...formField, cashback_point: isNaN(value) ? 0 : value }); + setFormField({ + ...formField, + products_cashback_point: isNaN(value) ? 0 : value + }); }} /> @@ -285,10 +302,13 @@ const AddDialog = () => { type="number" min={0} step={0.01} - value={formField.cashback_cash} + value={formField.products_cashback_cash} onChange={(e) => { const value = parseFloat(e.target.value); - setFormField({ ...formField, cashback_cash: isNaN(value) ? 0 : value }); + setFormField({ + ...formField, + products_cashback_cash: isNaN(value) ? 0 : value + }); }} /> @@ -300,8 +320,10 @@ const AddDialog = () => { Status* setFormField({ ...formField, status: value })} + value={formField.products_status} + onValueChange={(value) => + setFormField({ ...formField, products_status: value }) + } > @@ -320,9 +342,9 @@ const AddDialog = () => { Provider ID - setFormField({ ...formField, provider: value.toString() }) + setFormField({ ...formField, products_provider: value.toString() }) } > @@ -330,8 +352,11 @@ const AddDialog = () => { {providers.map((provider) => ( - - {provider.name} + + {provider.provider_name} ))} @@ -345,9 +370,9 @@ const AddDialog = () => { Process on Third Party* - setFormField({ ...formField, process_on_third_party: value }) + setFormField({ ...formField, products_process_on_third_party: value }) } > diff --git a/src/pages/master/products/blocks/EditDialog.tsx b/src/pages/master/products/blocks/EditDialog.tsx index 72aa3bb..d3b9ca2 100644 --- a/src/pages/master/products/blocks/EditDialog.tsx +++ b/src/pages/master/products/blocks/EditDialog.tsx @@ -24,8 +24,8 @@ import { } from '@/components/ui/select'; interface ProviderProps { - id: string; - name: string; + provider_id: string; + provider_name: string; } const API_URL = apiConfig.service_master_data; @@ -114,7 +114,7 @@ const EditDialog = () => { cashback_point: response.data.cashback_point, cashback_cash: response.data.cashback_cash, status: response.data.status, - provider: response.data.provider_id, + provider: response.data.provider.id, process_on_third_party: response.data.process_on_third_party })); } else { @@ -356,8 +356,8 @@ const EditDialog = () => { {providers.map((provider) => ( - - {provider.name} + + {provider.provider_name} ))} diff --git a/src/pages/master/products/blocks/ListToolbar.tsx b/src/pages/master/products/blocks/ListToolbar.tsx index 9e2c916..6eb2507 100644 --- a/src/pages/master/products/blocks/ListToolbar.tsx +++ b/src/pages/master/products/blocks/ListToolbar.tsx @@ -20,17 +20,17 @@ const ListToolbar = () => { onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)} /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} []>( () => [ { - accessorFn: (row) => row.id, + accessorFn: (row) => row.products_id, id: 'id', header: ({ column }) => , enableSorting: true, @@ -83,7 +83,7 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode } }, { - accessorFn: (row) => row.name, + accessorFn: (row) => row.products_name, id: 'name', header: ({ column }) => , enableSorting: true, @@ -93,7 +93,7 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode } }, { - accessorFn: (row) => row.description, + accessorFn: (row) => row.products_description, id: 'description', header: ({ column }) => , enableSorting: true, @@ -103,7 +103,7 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode } }, { - accessorFn: (row) => row.price_point, + accessorFn: (row) => row.products_price_point, id: 'price_point', header: ({ column }) => , enableSorting: true, @@ -113,7 +113,7 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode } }, { - accessorFn: (row) => row.price_cash, + accessorFn: (row) => row.products_price_cash, id: 'price_cash', header: ({ column }) => , enableSorting: true, @@ -133,13 +133,13 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode <> handleEditDialog(true, row.id)} + onClick={() => handleEditDialog(true, row.products_id)} > handleDeleteDialog(true, row.id)} + onClick={() => handleDeleteDialog(true, row.products_id)} > @@ -167,7 +167,7 @@ const ManageProductsContextProvider = ({ children }: { children: React.ReactNode order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', filter: JSON.stringify(filter) }); - // console.log(response?.data); + console.log(response?.data); setProducts(response?.data.list); return { data: response?.data.list, totalCount: response?.data.total_count }; } catch (error) { 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 = () => { } /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} { onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)} /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} { } /> - + {/* - {/* {loadingButton === 'filter' ? : } */} + {loadingButton === 'filter' ? : } - + */} {/* { + return ( + + + Wallet Rule + + + Dashboard + + + + Master Data + + + + Manage Wallet Rule + + + + + + + + + ); +}; + +export default WalletRuleMaster; diff --git a/src/pages/master/walletRule/blocks/ListToolbar.tsx b/src/pages/master/walletRule/blocks/ListToolbar.tsx new file mode 100644 index 0000000..fb78c55 --- /dev/null +++ b/src/pages/master/walletRule/blocks/ListToolbar.tsx @@ -0,0 +1,55 @@ +import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; +import { Button } from '@/components/ui/button'; +import { useManageProductsContext } from '../../products/hooks/useManageProductsContext'; + +const ListToolbar = () => { + const { table, reload } = useDataGrid(); + const { handleAddDialog } = useManageProductsContext(); + + return ( + + + + + + + table.getColumn('name')?.setFilterValue(event.target.value)} + /> + + {/* + + {loadingButton === 'filter' ? : } + + + */} + + + handleAddDialog(true)} + > + Add Data + + + reload()}> + + + + + + + + ); +}; + +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..e196eaa --- /dev/null +++ b/src/pages/master/walletRule/hooks/ManageWalletRuleContext.tsx @@ -0,0 +1,240 @@ +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.ID, + id: 'id', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[100px]' + } + }, + { + accessorFn: (row) => row.IDWallet, + id: 'name', + header: ({ column }) => , + enableSorting: true, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, + { + 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 ( + <> + handleEditDialog(true, row.id)} + > + + + handleDeleteDialog(true, row.id)} + > + + + > + ); + }, + 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/routing/AppRoutingSetup.tsx b/src/routing/AppRoutingSetup.tsx index fa6500f..ace6ab8 100644 --- a/src/routing/AppRoutingSetup.tsx +++ b/src/routing/AppRoutingSetup.tsx @@ -34,6 +34,8 @@ 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 ( @@ -50,7 +52,12 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> } /> - }/> + } + /> + } /> + } /> } /> @@ -77,7 +84,9 @@ const AppRoutingSetup = (): ReactElement => { } /> } /> } /> - } + } />