diff --git a/src/pages/master/wallet/WalletMaster.tsx b/src/pages/master/wallet/WalletMaster.tsx index 3190787..d319707 100644 --- a/src/pages/master/wallet/WalletMaster.tsx +++ b/src/pages/master/wallet/WalletMaster.tsx @@ -3,6 +3,7 @@ import { ManageWalletContextProvider } from './hooks/ManageWalletContext'; import { Breadcrumbs, Link } from '@mui/material'; import AddDialog from './blocks/AddDialog'; import EditDialog from './blocks/EditDialog'; +import DeleteDialog from './blocks/DeleteDialog'; const WalletMaster = () => { return ( @@ -27,6 +28,7 @@ const WalletMaster = () => { + ); diff --git a/src/pages/master/wallet/blocks/AddDialog.tsx b/src/pages/master/wallet/blocks/AddDialog.tsx new file mode 100644 index 0000000..b8100ba --- /dev/null +++ b/src/pages/master/wallet/blocks/AddDialog.tsx @@ -0,0 +1,298 @@ +import { useCallApi } from '@/hooks'; +import { useManageWalletContext } from '../hooks/useManageWalletContext'; +import { Alert, useDataGrid } from '@/components'; +import React, { useCallback, useEffect, useState } from 'react'; +import { apiConfig } from '@/config/api.config'; +import { toast } from 'sonner'; +import { + Dialog, + DialogBody, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/components/ui/select'; +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; + +interface CurrencyProps { + ID: string; + code: string; + name: string; + prefix: string; + status: string; +} + +interface GroupProps { + id: string; + name: string; + description: string; + status: string; +} + +const API_URL_WALLET = apiConfig.service_wallet; +const API_URL_MASTER_DATA = apiConfig.service_master_data; + +const AddDialog = () => { + const { showAddDialog, handleAddDialog } = useManageWalletContext(); + const { GetData, PostData } = useCallApi(); + const { reload } = useDataGrid(); + const [alert, setAlert] = useState({ + show: false, + message: '' + }); + const initialState: { + name: string; + description: string; + status: string; + group: string[]; + currency_id: string; + } = { + name: '', + description: '', + status: '', + group: [], + currency_id: '' + }; + const [formField, setFormField] = useState(initialState); + const [currencies, setCurrencies] = useState([]); + const [groups, setGroups] = useState([]); + + const resetForm = () => { + setFormField(initialState); + setAlert({ show: false, message: '' }); + }; + + const handleGroupChange = (groupId: string) => { + setFormField((prevState) => { + const isSelected = prevState.group.includes(groupId); + + if (isSelected) { + // Remove the group if already selected + return { + ...prevState, + group: prevState.group.filter((id) => id !== groupId) + }; + } else { + // Add the group if not selected + return { + ...prevState, + group: [...prevState.group, groupId] + }; + } + }); + }; + + const doCreateWallet = useCallback( + async (e: React.FormEvent) => { + e.preventDefault(); + + const response = await PostData(`${API_URL_MASTER_DATA}/wallet/create`, formField); + + if (response?.status) { + handleAddDialog(false); + toast.success('Success Create Wallet'); + reload(); + } else { + toast.error('Failed Create Wallet'); + setAlert({ show: true, message: 'Failed Create Wallet' }); + } + }, + [formField] + ); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + if ( + formField.name.trim() === '' || + formField.description.trim() === '' || + formField.status.trim() === '' || + formField.group.length === 0 || + formField.currency_id.trim() === '' + ) { + setAlert({ show: true, message: 'Please fill in all required fields.' }); + return; + } + + console.log(formField); + doCreateWallet(e); + setAlert({ show: false, message: '' }); + }; + + const getCurrencyLists = async (sorting: any) => { + try { + const response = await GetData(`${API_URL_WALLET}/dashboard/currency`, { + limit: 100, + page: 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' + }); + // console.log('Currency: ', response?.data); + setCurrencies(response?.data.list); + } catch (error) { + console.error('Error fetching currency', error); + } + }; + + const getGroupLists = async (sorting: any) => { + try { + const response = await GetData(`${API_URL_MASTER_DATA}/groups/list`, { + limit: 100, + page: 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' + }); + // console.log('Group: ', response?.data); + setGroups(response?.data.list); + } catch (error) { + console.error('Error fetching group', error); + } + }; + + useEffect(() => { + getCurrencyLists([{ id: 'name', desc: false }]); + getGroupLists([{ id: 'name', desc: false }]); + }, []); + + useEffect(() => { + if (showAddDialog === false) { + resetForm(); + } + }, [showAddDialog]); + + return ( + handleAddDialog(open)}> + + + Wallet - Create + + + +
+ {alert.show && ( + +

{alert.message}

+
+ )} + +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + placeholder="Wallet Name" + /> +
+
+ +
+
+ + setFormField({ ...formField, description: e.target.value })} + placeholder="Description" + /> +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
+ {groups.map((group) => ( + + ))} +
+
+
+ +
+ + +
+
+
+
+
+
+
+ ); +}; + +export default AddDialog; diff --git a/src/pages/master/wallet/blocks/DeleteDialog.tsx b/src/pages/master/wallet/blocks/DeleteDialog.tsx new file mode 100644 index 0000000..9166356 --- /dev/null +++ b/src/pages/master/wallet/blocks/DeleteDialog.tsx @@ -0,0 +1,78 @@ +import { useCallApi } from '@/hooks'; +import { useManageWalletContext } from '../hooks/useManageWalletContext'; +import { Alert, useDataGrid } from '@/components'; +import { useCallback, useState } from 'react'; +import { toast } from 'sonner'; +import { apiConfig } from '@/config/api.config'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; + +const API_URL = apiConfig.service_master_data; + +const DeleteDialog = () => { + const { showDeleteDialog, handleDeleteDialog, selectedWallet } = useManageWalletContext(); + const { DeleteData } = useCallApi(); + const { reload } = useDataGrid(); + const [alert, setAlert] = useState({ show: false, message: '' }); + + const doDeleteWallet = useCallback(async () => { + if (!selectedWallet) { + toast.error('No wallet selected'); + return; + } + + const response = await DeleteData( + `${API_URL}/wallet/delete/${selectedWallet.Wallet_id}/false`, + { + id: selectedWallet.Wallet_id + } + ); + + if (response?.status) { + setAlert({ show: false, message: '' }); + handleDeleteDialog(false, null); + toast.success('Success Delete Wallet'); + reload(); + } else { + setAlert({ show: true, message: response?.message }); + toast.error('Failed Delete Wallet'); + } + }, [selectedWallet, handleDeleteDialog, DeleteData, reload]); + + return ( + handleDeleteDialog(open, null)}> + + + + + +

Are you sure?

+ You will delete this data! +
+ {alert.show && ( + +

{alert.message}

+
+ )} +
+ + + + +
+
+ ); +}; + +export default DeleteDialog; diff --git a/src/pages/master/wallet/blocks/EditDialog.tsx b/src/pages/master/wallet/blocks/EditDialog.tsx new file mode 100644 index 0000000..9f8573b --- /dev/null +++ b/src/pages/master/wallet/blocks/EditDialog.tsx @@ -0,0 +1,334 @@ +import { Alert, useDataGrid } from '@/components'; +import { useManageWalletContext } from '../hooks/useManageWalletContext'; +import { useCallApi } from '@/hooks'; +import React, { useCallback, useEffect, useState } from 'react'; +import { apiConfig } from '@/config/api.config'; +import { toast } from 'sonner'; +import { + Dialog, + DialogBody, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/components/ui/select'; +import { Button } from '@/components/ui/button'; + +interface CurrencyProps { + ID: string; + code: string; + name: string; + prefix: string; + status: string; +} + +interface GroupProps { + id: string; + name: string; + description: string; + status: string; +} + +const API_URL_WALLET = apiConfig.service_wallet; +const API_URL_MASTER_DATA = apiConfig.service_master_data; + +const EditDialog = () => { + const { showEditDialog, handleEditDialog, selectedWallet } = useManageWalletContext(); + const { reload } = useDataGrid(); + const { GetData, PutData } = useCallApi(); + const [alert, setAlert] = useState({ + show: false, + message: '' + }); + const initialState: { + name: string; + description: string; + status: string; + group: string[]; + currency_id: string; + } = { + name: '', + description: '', + status: '', + group: [], + currency_id: '' + }; + const [formField, setFormField] = useState(initialState); + const [currencies, setCurrencies] = useState([]); + const [groups, setGroups] = useState([]); + + const resetForm = () => { + setFormField(initialState); + setAlert({ show: false, message: '' }); + }; + + const handleGroupChange = (groupId: string) => { + setFormField((prevState) => { + const isSelected = prevState.group.includes(groupId); + + if (isSelected) { + // Remove the group if already selected + return { + ...prevState, + group: prevState.group.filter((id) => id !== groupId) + }; + } else { + // Add the group if not selected + return { + ...prevState, + group: [...prevState.group, groupId] + }; + } + }); + }; + + const doUpdateWallet = useCallback( + async (e: React.FormEvent) => { + e.preventDefault(); + + const response = await PutData( + `${API_URL_MASTER_DATA}/wallet/update/${selectedWallet?.Wallet_id}`, + formField + ); + + if (response?.status) { + handleEditDialog(false, null); + toast.success('Success Update Wallet'); + reload(); + } else { + toast.error('Failed Update Wallet'); + setAlert({ show: true, message: 'Failed Update Wallet' }); + } + }, + [formField] + ); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + if ( + formField.name.trim() === '' || + formField.description.trim() === '' || + formField.status.trim() === '' || + formField.currency_id.trim() === '' || + formField.group.length === 0 + ) { + setAlert({ show: true, message: 'Please fill in all required fields.' }); + return; + } + + console.log(formField); + doUpdateWallet(e); + setAlert({ show: false, message: '' }); + }; + + const doFetchData = useCallback(async (id: string) => { + const response = await GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, { + id + }); + + console.log(response); + if (response?.status) { + setFormField((prev) => ({ + ...prev, + name: response?.data.name, + description: response?.data.description, + status: response?.data.status, + currency_id: response?.data.currency_id, + groups: Array.isArray(response?.data.groups) + ? response?.data.group.map((group: any) => group.id) + : [] + })); + } + }, []); + + const getCurrencyLists = async (sorting: any) => { + try { + const response = await GetData(`${API_URL_WALLET}/dashboard/currency`, { + limit: 100, + page: 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' + }); + // console.log('Currency: ', response?.data); + setCurrencies(response?.data.list); + } catch (error) { + console.error('Error fetching currency', error); + } + }; + + const getGroupLists = async (sorting: any) => { + try { + const response = await GetData(`${API_URL_MASTER_DATA}/groups/list`, { + limit: 100, + page: 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' + }); + // console.log('Group: ', response?.data); + setGroups(response?.data.list); + } catch (error) { + console.error('Error fetching group', error); + } + }; + + useEffect(() => { + getCurrencyLists([{ id: 'name', desc: false }]); + getGroupLists([{ id: 'name', desc: false }]); + }, []); + + useEffect(() => { + if (selectedWallet) { + // setFormField((prev) => ({ + // ...prev, + // name: selectedWallet?.Wallet_name, + // description: selectedWallet?.Wallet_description, + // status: selectedWallet?.Wallet_status, + // currency_id: selectedWallet?.Wallet_currency_id, + // group: selectedWallet?.Wallet_group + // })); + doFetchData(selectedWallet?.Wallet_id); + } + }, [selectedWallet]); + + useEffect(() => { + if (showEditDialog === false) { + resetForm(); + } + }, [showEditDialog]); + // console.log(selectedWallet); + return ( + handleEditDialog(open, null)}> + + + Wallet - Update + + + +
+ {alert.show && ( + +

{alert.message}

+
+ )} + +
+
+
+
+ + setFormField({ ...formField, name: e.target.value })} + placeholder="Wallet Name" + /> +
+
+ +
+
+ + setFormField({ ...formField, description: e.target.value })} + placeholder="Description" + /> +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
+ {groups.map((group) => ( + + ))} +
+
+
+ +
+ + +
+
+
+
+
+
+
+ ); +}; + +export default EditDialog; diff --git a/src/pages/master/wallet/hooks/ManageWalletContext.tsx b/src/pages/master/wallet/hooks/ManageWalletContext.tsx index 7369367..a1ea097 100644 --- a/src/pages/master/wallet/hooks/ManageWalletContext.tsx +++ b/src/pages/master/wallet/hooks/ManageWalletContext.tsx @@ -7,12 +7,12 @@ import { Toaster } from 'sonner'; import ListToolbar from '../blocks/ListToolbar'; interface WalletProps { - id: string; - name: string; - status: string; - description: string; - group: string[]; - currency_id: string; + Wallet_id: string; + Wallet_name: string; + Wallet_status: string; + Wallet_description: string; + Wallet_group: string[]; + Wallet_currency_id: string; } interface ContextProps {