diff --git a/src/pages/master/aldeias/blocks/AddDialog.tsx b/src/pages/master/aldeias/blocks/AddDialog.tsx index a1c566c..7d33c9b 100644 --- a/src/pages/master/aldeias/blocks/AddDialog.tsx +++ b/src/pages/master/aldeias/blocks/AddDialog.tsx @@ -27,8 +27,8 @@ import { import { doSaveLogActivity } from '@/actions/GlobalActions'; interface SucosProps { - sucos_id: number; - sucos_name: string; + id: number; + name: string; } const API_URL = apiConfig.service_master_data; @@ -181,7 +181,7 @@ const AddDialog = () => { className="input col-span-5 text-left" style={{ color: 'inherit' }} > - {sucos.find((suco) => suco.sucos_id === formField.sucosId)?.sucos_name || + {sucos.find((suco) => suco.id === formField.sucosId)?.name || 'Select Sucos'} @@ -196,17 +196,17 @@ const AddDialog = () => { {sucos.map((suco) => ( { setFormField({ ...formField, - sucosId: suco.sucos_id + sucosId: suco.id }); setOpen(false); }} > - {suco.sucos_name} + {suco.name} ))} diff --git a/src/pages/master/aldeias/blocks/DeleteDialog.tsx b/src/pages/master/aldeias/blocks/DeleteDialog.tsx index 44f0a81..e98df8c 100644 --- a/src/pages/master/aldeias/blocks/DeleteDialog.tsx +++ b/src/pages/master/aldeias/blocks/DeleteDialog.tsx @@ -4,7 +4,14 @@ import { Alert, useDataGrid } from '@/components'; import { useCallApi } from '@/hooks'; import { useCallback, useState } from 'react'; import { toast } from 'sonner'; -import { Dialog, DialogContent, DialogFooter, DialogHeader } from '@/components/ui/dialog'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle +} from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { doSaveLogActivity } from '@/actions/GlobalActions'; @@ -52,6 +59,8 @@ const DeleteDialog = () => { handleDeleteDialog(open, null)}> + +

Are you sure?

You will delete this data! diff --git a/src/pages/master/aldeias/blocks/EditDialog.tsx b/src/pages/master/aldeias/blocks/EditDialog.tsx index 76c7c10..a7bcb66 100644 --- a/src/pages/master/aldeias/blocks/EditDialog.tsx +++ b/src/pages/master/aldeias/blocks/EditDialog.tsx @@ -98,7 +98,7 @@ const EditDialog = () => { }); setSucos(response?.data.list); - console.log(sucos); + // console.log(sucos); } catch (error) { console.error('Error fetching Sucos', error); setAlert({ show: true, message: 'Failed to get Sucos. Please try again.' }); @@ -107,7 +107,10 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/aldeias/getdata/${id}`, { id }); + + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/aldeias/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ @@ -221,8 +224,8 @@ const EditDialog = () => { className="input col-span-5 text-left" style={{ color: 'inherit' }} > - {sucos.find((suco) => suco.id === formField.sucosId) - ?.name || 'Select Sucos'} + {sucos.find((suco) => suco.id === formField.sucosId)?.name || + 'Select Sucos'} diff --git a/src/pages/master/conversion/blocks/EditDialog.tsx b/src/pages/master/conversion/blocks/EditDialog.tsx index 48daf9c..f32f8f2 100644 --- a/src/pages/master/conversion/blocks/EditDialog.tsx +++ b/src/pages/master/conversion/blocks/EditDialog.tsx @@ -120,7 +120,10 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/dashboard/conversion/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/dashboard/conversion/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); + console.log('Transaction Type: ', response?.data); if (response?.status) { setFormField((prev) => ({ @@ -302,9 +305,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/master/currency/blocks/EditDialog.tsx b/src/pages/master/currency/blocks/EditDialog.tsx index 96fb0c4..faee892 100644 --- a/src/pages/master/currency/blocks/EditDialog.tsx +++ b/src/pages/master/currency/blocks/EditDialog.tsx @@ -101,7 +101,10 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/dashboard/currency/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/dashboard/currency/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); + // console.log('Transaction Type: ', response?.data); if (response?.status) { setFormField((prev) => ({ @@ -232,9 +235,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/master/municipios/blocks/EditDialog.tsx b/src/pages/master/municipios/blocks/EditDialog.tsx index ceeac80..ef7b3d3 100644 --- a/src/pages/master/municipios/blocks/EditDialog.tsx +++ b/src/pages/master/municipios/blocks/EditDialog.tsx @@ -77,7 +77,9 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/municipios/getdata/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/municipios/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ diff --git a/src/pages/master/postoadms/blocks/EditDialog.tsx b/src/pages/master/postoadms/blocks/EditDialog.tsx index c5f165f..93e73a8 100644 --- a/src/pages/master/postoadms/blocks/EditDialog.tsx +++ b/src/pages/master/postoadms/blocks/EditDialog.tsx @@ -114,7 +114,9 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/postoadms/getdata/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = await GetData(`${API_URL}/postoadms/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ @@ -259,9 +261,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/master/products/blocks/EditDialog.tsx b/src/pages/master/products/blocks/EditDialog.tsx index a6395cd..bf6d741 100644 --- a/src/pages/master/products/blocks/EditDialog.tsx +++ b/src/pages/master/products/blocks/EditDialog.tsx @@ -125,7 +125,11 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/product/getdata/${id}`, { id }); + + const minDelay = new Promise((resolve) => setTimeout(resolve, 500)); + const fetchData = GetData(`${API_URL}/product/getdata/${id}`, { id }); + + const [response] = await Promise.all([fetchData, minDelay]); // console.log(response); if (response?.status) { @@ -445,9 +449,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/master/profession/blocks/EditDialog.tsx b/src/pages/master/profession/blocks/EditDialog.tsx index fc8a83f..ea012e4 100644 --- a/src/pages/master/profession/blocks/EditDialog.tsx +++ b/src/pages/master/profession/blocks/EditDialog.tsx @@ -74,7 +74,9 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/profession/getdata/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/profession/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); if (response?.status) { setFormField((prev) => ({ diff --git a/src/pages/master/provider/blocks/EditDialog.tsx b/src/pages/master/provider/blocks/EditDialog.tsx index 5c33f37..73a06fa 100644 --- a/src/pages/master/provider/blocks/EditDialog.tsx +++ b/src/pages/master/provider/blocks/EditDialog.tsx @@ -148,7 +148,9 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL_MASTERDATA}/provider/getdata/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL_MASTERDATA}/provider/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); // console.log(response); if (response?.status) { setFormField((prev) => ({ @@ -157,7 +159,7 @@ const EditDialog = () => { description: response?.data.description, type: response?.data.type, status: response?.data.status, - transaction_type: response?.data.transaction_type.id, + transaction_type: response?.data.transaction_type?.id || '', agent: response?.data.agent?.id || null })); } @@ -172,7 +174,8 @@ const EditDialog = () => { formField.description.trim() === '' || formField.type.trim() === '' || formField.status.trim() === '' || - formField.transaction_type.trim() === '' + formField.transaction_type.trim() === '' || + formField.agent === null ) { setAlert({ show: true, message: 'Please fill in all required fields.' }); return; @@ -324,7 +327,7 @@ const EditDialog = () => { setFormField({ ...formField, transaction_type: value }) } > - + diff --git a/src/pages/master/reward/blocks/EditDialog.tsx b/src/pages/master/reward/blocks/EditDialog.tsx index d61ec96..d748cf2 100644 --- a/src/pages/master/reward/blocks/EditDialog.tsx +++ b/src/pages/master/reward/blocks/EditDialog.tsx @@ -95,8 +95,9 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - // console.log('Ini datanya:', id); - const response = await GetData(`${API_URL}/reward/getdata/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/reward/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); // console.log('API Response:', response); if (response?.status) { @@ -260,9 +261,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/master/sucos/blocks/EditDialog.tsx b/src/pages/master/sucos/blocks/EditDialog.tsx index fabdbf2..42d1dd8 100644 --- a/src/pages/master/sucos/blocks/EditDialog.tsx +++ b/src/pages/master/sucos/blocks/EditDialog.tsx @@ -113,7 +113,9 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL}/sucos/getdata/${id}`, { id }); + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL}/sucos/getdata/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); // console.log('Data Sucos:', response?.data); if (response?.status) { @@ -258,9 +260,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/master/sucos/hooks/ManageSucosContext.tsx b/src/pages/master/sucos/hooks/ManageSucosContext.tsx index 2d106a7..605a2a9 100644 --- a/src/pages/master/sucos/hooks/ManageSucosContext.tsx +++ b/src/pages/master/sucos/hooks/ManageSucosContext.tsx @@ -163,7 +163,6 @@ const ManageSucosContextProvider = ({ children }: { children: React.ReactNode }) order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', filter: JSON.stringify(filter) }); - console.log('Sucos List Response:', response?.data); setSucos(response?.data.list || []); return { data: response?.data.list, totalCount: response?.data.total_count }; } catch (error) { diff --git a/src/pages/master/wallet/blocks/EditDialog.tsx b/src/pages/master/wallet/blocks/EditDialog.tsx index de4f5dc..ffcc1e5 100644 --- a/src/pages/master/wallet/blocks/EditDialog.tsx +++ b/src/pages/master/wallet/blocks/EditDialog.tsx @@ -117,11 +117,12 @@ const EditDialog = () => { const doFetchData = useCallback(async (id: string) => { setIsLoading(true); - const response = await GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, { + const minDelay = new Promise((resolve) => setTimeout(resolve, 300)); + const fetchData = GetData(`${API_URL_MASTER_DATA}/wallet/detail/${id}`, { id }); + const [response] = await Promise.all([fetchData, minDelay]); - console.log(response); if (response?.status) { setFormField((prev) => ({ ...prev, diff --git a/src/pages/master/walletRule/blocks/EditDialog.tsx b/src/pages/master/walletRule/blocks/EditDialog.tsx index b555d06..9c5a132 100644 --- a/src/pages/master/walletRule/blocks/EditDialog.tsx +++ b/src/pages/master/walletRule/blocks/EditDialog.tsx @@ -402,9 +402,6 @@ const EditDialog = () => {
-
diff --git a/src/pages/members/kyc/Kyc.tsx b/src/pages/members/kyc/Kyc.tsx index d9036d4..1473bab 100644 --- a/src/pages/members/kyc/Kyc.tsx +++ b/src/pages/members/kyc/Kyc.tsx @@ -1,8 +1,13 @@ -import { Container, DataGridInner, DataGridProvider, TDataGridProps } from '@/components'; +import { + Container, + DataGridInner, + DataGridProvider, + TDataGridProps, + useDataGrid +} from '@/components'; import { DataTable } from '@/components/ui/DataTable'; import { Table } from '@tanstack/react-table'; import React, { createContext, useContext, useState, useEffect } from 'react'; -import { ManageKycContextProvider } from './hooks'; import { getColumns, initialMember } from './Columns'; import { useAuthContext } from '@/auth'; import { LoaderTransparant } from '@/components'; @@ -17,6 +22,7 @@ import DetailMember from '../manage-members/blocks/DetailMember'; import { Breadcrumbs, Link } from '@mui/material'; import { Helmet } from 'react-helmet'; import { ListToolBar } from './blocks/ListToolBar'; +import { RefreshCw } from 'lucide-react'; const Kyc = () => { const [loading, setLoading] = useState(false); @@ -26,6 +32,7 @@ const Kyc = () => { const [isDialogOpen, setIsDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState(''); + const [isReloading, setIsReloading] = useState(false); const closeDialog = () => setIsDialogOpen(false); const { getUser } = useAuthContext(); @@ -65,6 +72,9 @@ const Kyc = () => { } catch (error: any) { toast.error(error.message); console.log(error); + } finally { + setLoading(false); + setIsReloading(false); } } @@ -85,6 +95,15 @@ const Kyc = () => { setDialogOpen(true); } + const resetForm = () => { + setMember(initialMember); + }; + + const handleReload = () => { + setIsReloading(true); + fetchCustomers(); + }; + const handleYes = async () => { setLoading(true); const userLogin: any = await getUser(); @@ -165,6 +184,7 @@ const Kyc = () => { setIsDialogOpen(false); await fetchCustomers(); setLoading(false); + setIsReloading(false); } }; @@ -227,12 +247,20 @@ const Kyc = () => { {/*
*/} -
+
+ {isReloading && ( +
+
+ + Refreshing data... +
+
+ )} } + toolbar={} layout={{ card: true }} sorting={[{ id: 'created_at', desc: true }]} serverSide={false} diff --git a/src/pages/members/kyc/blocks/ListToolBar.tsx b/src/pages/members/kyc/blocks/ListToolBar.tsx index 180e68b..804c008 100644 --- a/src/pages/members/kyc/blocks/ListToolBar.tsx +++ b/src/pages/members/kyc/blocks/ListToolBar.tsx @@ -1,40 +1,44 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; -import { useKycContext } from '../hooks'; +import { useState } from 'react'; -const ListToolBar = () => { +interface ListToolbarProps { + onReload: () => void; + isReloading: boolean; +} + +const ListToolBar = ({ onReload, isReloading }: ListToolbarProps) => { const { table, reload } = useDataGrid(); + const [usernameFilter, setUsernameFilter] = useState(''); + + const handleUsernameChange = (e: React.ChangeEvent) => { + setUsernameFilter(e.target.value); + table.getColumn('username')?.setFilterValue(e.target.value); + }; return (
-
- - - - +
+
- -
diff --git a/src/pages/members/kyc/hooks/ManageKycContext.tsx b/src/pages/members/kyc/hooks/ManageKycContext.tsx deleted file mode 100644 index 2a63fe1..0000000 --- a/src/pages/members/kyc/hooks/ManageKycContext.tsx +++ /dev/null @@ -1,145 +0,0 @@ -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'; - -interface SelectedUser { - id: string; - name: string; - email: string; - role: string; - description: string; - created_date: Date; -} - -interface ContextProps { - showDetailDialog: boolean; - handleDetailDialog: (show: boolean, selected_user: SelectedUser | null) => void; - showAddDialog: boolean; - handleAddDialog: (show: boolean) => void; - selectedUser: SelectedUser | null; -} - -const initialProps: ContextProps = { - showDetailDialog: false, - handleDetailDialog: () => {}, - showAddDialog: false, - handleAddDialog: () => {}, - selectedUser: null -}; - -const ManageKycContext = createContext(initialProps); -const API_URL = apiConfig.service_dashboard; - -const ManageKycContextProvider = ({ children }: { children: React.ReactNode }) => { - const [showDetailDialog, setShowDetailDialog] = useState(false); - const [showAddDialog, setShowAddDialog] = useState(false); - const [selectedUser, setSelectedUser] = useState(null); - - const handleDetailDialog = useCallback((show: boolean, selected_user: SelectedUser | 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_date, - id: 'created_date', - header: ({ column }) => , - enableSorting: true, - enableHiding: false, - meta: { - headerClassName: 'w-[250px]' - } - }, - { - accessorFn: (row) => row.name, - id: 'name', - header: ({ column }) => , - enableSorting: true, - enableHiding: false, - meta: { - headerClassName: 'w-[350px]' - } - }, - { - accessorFn: (row) => row.description, - id: 'description', - header: ({ column }) => , - enableSorting: true, - meta: { - headerClassName: 'w-[350px]' - } - }, - { - 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} - > - {children} - - - ); -}; - -export { ManageKycContextProvider, ManageKycContext }; -export type { SelectedUser }; diff --git a/src/pages/members/kyc/hooks/index.ts b/src/pages/members/kyc/hooks/index.ts deleted file mode 100644 index 246dfa8..0000000 --- a/src/pages/members/kyc/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './ManageKycContext'; -export * from './useKycContext'; diff --git a/src/pages/members/kyc/hooks/useKycContext.tsx b/src/pages/members/kyc/hooks/useKycContext.tsx deleted file mode 100644 index 1043f87..0000000 --- a/src/pages/members/kyc/hooks/useKycContext.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { useContext } from 'react'; -import { ManageKycContext } from './ManageKycContext'; - -const useKycContext = () => { - const context = useContext(ManageKycContext); - - if (!context) throw new Error('useKycContext must be used within AuthProvider'); - - return context; -}; - -export { useKycContext }; diff --git a/src/pages/members/manage-members/ManageMembers.tsx b/src/pages/members/manage-members/ManageMembers.tsx index 1412693..3dedff3 100644 --- a/src/pages/members/manage-members/ManageMembers.tsx +++ b/src/pages/members/manage-members/ManageMembers.tsx @@ -3,7 +3,6 @@ import { apiConfig } from '@/config/api.config'; import { getColumns, Members, initialMember } from './Columns'; import { useState, useEffect } from 'react'; import axios from 'axios'; -// import CustomerDialog from './CustomerDetailModal'; import DetailMember from './blocks/DetailMember'; import ConfirmDialog from '@/components/confirm'; import { useAuthContext } from '@/auth'; @@ -15,7 +14,7 @@ const BASE_URL_MASTER_DATA = apiConfig.service_master_data; const BASE_URL = apiConfig.service_customer; import { Helmet } from 'react-helmet'; import ListToolbar from './blocks/ListToolBar'; - +import { RefreshCw } from 'lucide-react'; const ManageMembers = () => { const [loading, setLoading] = useState(false); const [members, setMembers] = useState([]); @@ -25,6 +24,7 @@ const ManageMembers = () => { const [isDialogOpen, setIsDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState(''); + const [isReloading, setIsReloading] = useState(false); const closeDialog = () => { setIsDialogOpen(false); setMember(initialMember); @@ -37,7 +37,7 @@ const ManageMembers = () => { setLoading(false); }, []); - async function fetchCustomers() { + async function fetchCustomers(): Promise { try { let customers = await axios.get(`${BASE_URL}/customer/list`, { params: { @@ -72,6 +72,9 @@ const ManageMembers = () => { } catch (error: any) { toast.error(error.message); console.log(error); + } finally { + setLoading(false); + setIsReloading(false); } } @@ -93,7 +96,10 @@ const ManageMembers = () => { setMember(data); setDialogOpen(true); } - + const handleReload = () => { + setIsReloading(true); + fetchCustomers(); + }; const handleYes = async () => { setLoading(true); const userLogin: any = await getUser(); @@ -226,14 +232,29 @@ const ManageMembers = () => { {/*
*/} -
+ +
+ {isReloading && ( +
+
+ + Refreshing data... +
+
+ )} } + toolbar={ + + } onRowSelectionChange={(selected, table: any) => { const selectedRow = table.getSelectedRowModel().rows[0]; if (selectedRow) handleUpdate(selectedRow.original); diff --git a/src/pages/members/manage-members/blocks/ListToolBar.tsx b/src/pages/members/manage-members/blocks/ListToolBar.tsx index 77742b8..dbf32bb 100644 --- a/src/pages/members/manage-members/blocks/ListToolBar.tsx +++ b/src/pages/members/manage-members/blocks/ListToolBar.tsx @@ -1,12 +1,20 @@ -import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; +import { UserPlus } from 'lucide-react'; +import { KeenIcon, useDataGrid } from '@/components'; +import { DefaultTooltip } from '@/components'; import { useState } from 'react'; -const ListToolbar = ({ createMember }: { createMember: () => void }) => { - const { table, reload } = useDataGrid(); - const [ usernameFilter, setUsernameFilter] = useState(''); - const [emailFilter, setEmailFilter] = useState(''); +interface ListToolbarProps { + createMember: () => void; + onReload: () => void; + isReloading: boolean; +} +const ListToolbar = ({ createMember, onReload, isReloading }: ListToolbarProps) => { + + const [emailFilter, setEmailFilter] = useState(''); + const [usernameFilter, setUsernameFilter] = useState(''); + const {table}=useDataGrid(); const handleUsernameChange = (e: React.ChangeEvent) => { setUsernameFilter(e.target.value); table.getColumn('username')?.setFilterValue(e.target.value); @@ -31,16 +39,23 @@ const ListToolbar = ({ createMember }: { createMember: () => void }) => { />
- - -
@@ -50,4 +65,4 @@ const ListToolbar = ({ createMember }: { createMember: () => void }) => { ); }; -export default ListToolbar; +export default ListToolbar; \ No newline at end of file diff --git a/src/pages/notification/blocks/AddDialog.tsx b/src/pages/notification/blocks/AddDialog.tsx index a857439..9146d6a 100644 --- a/src/pages/notification/blocks/AddDialog.tsx +++ b/src/pages/notification/blocks/AddDialog.tsx @@ -32,14 +32,14 @@ const API_URL_CUSTOMER = apiConfig.service_customer; const API_URL_NOTIFICATION = apiConfig.service_notification; const AddDialog = () => { - const parentRef = useRef(null); const { handleAddDialog, showAddDialog } = useManageNotificationContext(); const { reload } = useDataGrid(); const { GetData, PostData } = useCallApi(); const [alert, setAlert] = useState({ show: false, message: '' }); const initialState = { - customers: [], + customers: [] as string[], + all_customer: '', type: '', via: '', subject: '', @@ -56,12 +56,25 @@ const AddDialog = () => { const handleChange = (e: React.ChangeEvent) => { setFormField({ ...formField, [e.target.name]: e.target.value }); + + if (e.target.name === 'all_customer' && e.target.value === 'true') { + setFormField((prev) => ({ ...prev, customers: [] })); + } }; const doCreateNotification = async (e: React.FormEvent) => { e.preventDefault(); + + // const payload = { + // ...formField, + // subject: + // formField.subject.trim() === '' && formField.via === 'sms' + // ? 'SMS Notification' + // : formField.subject + // }; + const response = await PostData(`${API_URL_NOTIFICATION}/send`, formField); - console.log('API Response :', response); + // console.log('send response :', response); if (response?.status) { handleAddDialog(false); @@ -80,44 +93,53 @@ const AddDialog = () => { } }; - // const getCustomerList = async (sorting: any) => { - // try { - // sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; - // const response = await GetData(`${API_URL_CUSTOMER}/customer/list`, { - // limit: 100, - // page: 1, - // with_deleted: false, - // order_field: sorting[0].id, - // order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' - // }); + const getCustomerList = async (sorting: any) => { + try { + sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; + const response = await GetData(`${API_URL_CUSTOMER}/customer/list`, { + limit: 100, + page: 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' + }); - // setCustomers(response?.data.list); - // } catch (error) { - // console.error('Error fetching customer', error); - // } - // }; + setCustomers(response?.data.list); + } catch (error) { + console.error('Error fetching customer', error); + } + }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if ( - formField.type.trim() === '' || + formField.all_customer.trim() === '' || formField.via.trim() === '' || - formField.subject.trim() === '' || formField.content.trim() === '' ) { setAlert({ show: true, message: 'Please fill all required fields.' }); return; } + if (formField.via === 'email' && formField.subject.trim() === '') { + setAlert({ show: true, message: 'Subject is required for E-Mail' }); + return; + } + + if (formField.via === 'fcm' && formField.subject.trim() === '') { + setAlert({ show: true, message: 'Subject is required form FCM' }); + return; + } + doCreateNotification(e); // console.log(formField); setAlert({ show: false, message: '' }); }; - // useEffect(() => { - // getCustomerList([{ id: 'id', desc: false }]); - // }, []); + useEffect(() => { + getCustomerList([{ id: 'id', desc: false }]); + }, []); useEffect(() => { if (showAddDialog === false) { @@ -140,7 +162,7 @@ const AddDialog = () => { )} - {/*
+
-
*/} +
- {/*
+
@@ -181,10 +203,12 @@ const AddDialog = () => { type="button" className="input col-span-5 text-left flex justify-between" style={{ color: 'inherit' }} + disabled={formField.all_customer !== 'false'} > - {customers.find((customer) => customer.id === formField.customers) - ?.username || 'Select Customer'} + {formField.customers.length === 0 + ? 'Select Customers' + : `${formField.customers.length} Customers Selected`} @@ -206,11 +230,16 @@ const AddDialog = () => { key={customer.id} value={customer.username} onSelect={() => { - setFormField({ - ...formField, - customers: customer.id + const customerId = customer.id; + setFormField((prev) => { + const isSelected = prev.customers.includes(customerId); + return { + ...prev, + customers: isSelected + ? prev.customers.filter((id) => id !== customerId) + : [...prev.customers, customerId] + }; }); - setOpen(false); }} > {customer.username} @@ -222,13 +251,11 @@ const AddDialog = () => {
-
*/} +
- +
{['info', 'promo'].map((type) => (
diff --git a/src/pages/notification/blocks/ListToolbar.tsx b/src/pages/notification/blocks/ListToolbar.tsx index 2f4c918..4406253 100644 --- a/src/pages/notification/blocks/ListToolbar.tsx +++ b/src/pages/notification/blocks/ListToolbar.tsx @@ -1,14 +1,16 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManageNotificationContext } from '../hooks/useManageNotificationContext'; import { Button } from '@/components/ui/button'; -import React, { useState } from 'react'; +import { useEffect, useState } from 'react'; const ListToolBar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useManageNotificationContext(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState( + (table.getColumn('content')?.getFilterValue() as string) ?? '' + ); - const handleKeydown = (event: React.KeyboardEvent) => { + const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { handleSearch(); } @@ -16,8 +18,18 @@ const ListToolBar = () => { const handleSearch = () => { table.getColumn('content')?.setFilterValue(searchValue); + table.setPageIndex(0); }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('content')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -27,13 +39,12 @@ const ListToolBar = () => { setSearchValue(event.target.value)} - onKeyDown={handleKeydown} /> - + {/* - + */}
- // - // - // ); - // } - // } ], [handleEditDialog, handleDeleteDialog] ); @@ -146,7 +118,7 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode }) order_direction: sorting[0].desc == false ? 'ASC' : 'DESC', filter: JSON.stringify(filter) }); - console.log('API Response notif: ', response); + // console.log('API Response notif: ', response); return { data: response?.data.list, totalCount: response?.data.total_count }; } catch (error) { console.error('Error fetching notification', error); diff --git a/src/pages/settings/user/manage-position/blocks/ListToolBar.tsx b/src/pages/settings/user/manage-position/blocks/ListToolBar.tsx index b310bd8..3ee35a7 100644 --- a/src/pages/settings/user/manage-position/blocks/ListToolBar.tsx +++ b/src/pages/settings/user/manage-position/blocks/ListToolBar.tsx @@ -1,16 +1,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useManagePositionContext } from '../hooks'; import { Button } from '@/components/ui/button'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; const ListToolBar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useManagePositionContext(); - const [searchValue, setSearchValue] = useState(''); - - const handleSearch = () => { - table.getColumn('name')?.setFilterValue(searchValue); - }; + const [searchValue, setSearchValue] = useState( + (table.getColumn('name')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -18,6 +16,19 @@ const ListToolBar = () => { } }; + const handleSearch = () => { + table.getColumn('username')?.setFilterValue(searchValue); + table.setPageIndex(0); + }; + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('username')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -30,10 +41,9 @@ const ListToolBar = () => { placeholder="Search roles" value={searchValue} onChange={(event) => setSearchValue(event.target.value)} - onKeyDown={handleKeyDown} /> - + {/* - + */}
diff --git a/src/pages/settings/user/manage-user/blocks/ListToolBar.tsx b/src/pages/settings/user/manage-user/blocks/ListToolBar.tsx index daa8cec..ae55333 100644 --- a/src/pages/settings/user/manage-user/blocks/ListToolBar.tsx +++ b/src/pages/settings/user/manage-user/blocks/ListToolBar.tsx @@ -1,16 +1,14 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { useUserContext } from '../hooks'; import { Button } from '@/components/ui/button'; -import React, { useState } from 'react'; +import { useEffect, useState } from 'react'; const ListToolBar = () => { const { table, reload } = useDataGrid(); const { handleAddDialog } = useUserContext(); - const [searchValue, setSearchValue] = useState(''); - - const handleSearch = () => { - table.getColumn('username')?.setFilterValue(searchValue); - }; + const [searchValue, setSearchValue] = useState( + (table.getColumn('username')?.getFilterValue() as string) ?? '' + ); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter') { @@ -18,6 +16,19 @@ const ListToolBar = () => { } }; + const handleSearch = () => { + table.getColumn('username')?.setFilterValue(searchValue); + table.setPageIndex(0); + }; + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('username')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + return () => clearTimeout(timer); + }, [searchValue, table]); + return (
@@ -30,10 +41,9 @@ const ListToolBar = () => { placeholder="Search Username" value={searchValue} onChange={(event) => setSearchValue(event.target.value)} - onKeyDown={handleKeyDown} /> - + {/* - + */}
diff --git a/src/pages/transfer/transfertype/blocks/EditDialog.tsx b/src/pages/transfer/transfertype/blocks/EditDialog.tsx index 1d9803b..28e2296 100644 --- a/src/pages/transfer/transfertype/blocks/EditDialog.tsx +++ b/src/pages/transfer/transfertype/blocks/EditDialog.tsx @@ -174,7 +174,7 @@ const EditDialog = () => { updated_at: formattedTime })); } - }, [showEditDialog, parsedUser]); + }, [showEditDialog]); const selectedPermissionNames = groups .filter((g) => formField.permission.includes(g.id)) @@ -238,7 +238,7 @@ const EditDialog = () => { }); return false; } - }, [formField, selectedTransferType, PutData]); + }, [formField, selectedTransferType]); useEffect(() => { if (!showEditDialog) return; @@ -263,7 +263,7 @@ const EditDialog = () => { }; getCustomerList(); - }, [showEditDialog, GetData]); + }, [showEditDialog]); useEffect(() => { if (!showEditDialog) return; @@ -287,7 +287,7 @@ const EditDialog = () => { }; getGroupList(); - }, [showEditDialog, GetData]); + }, [showEditDialog]); useEffect(() => { if (!showEditDialog) return; @@ -365,6 +365,7 @@ const EditDialog = () => { return () => clearTimeout(timer); }, [showEditDialog, selectedTransferType, GetData]); + useEffect(() => { if (showEditDialog === false) { resetForm(); @@ -589,7 +590,7 @@ const EditDialog = () => { - Disbursement + Disbursement Other Change Group Emoney Customer to Agent Change Group Emoney Agent to Customer @@ -603,6 +604,7 @@ const EditDialog = () => { Top Up Escrow Top Up Master Agent Top Up Agent + Purchase Loja
diff --git a/src/pages/transfer/transfertype/blocks/ListToolBar.tsx b/src/pages/transfer/transfertype/blocks/ListToolBar.tsx index 7d9e413..47833ba 100644 --- a/src/pages/transfer/transfertype/blocks/ListToolBar.tsx +++ b/src/pages/transfer/transfertype/blocks/ListToolBar.tsx @@ -12,6 +12,7 @@ const ListToolbar = () => { useEffect(() => { const timer = setTimeout(() => { table.getColumn('name')?.setFilterValue(searchValue); + table.setPageIndex(0); }, 200); return () => clearTimeout(timer); diff --git a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx index dfdd72d..a21febf 100644 --- a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx +++ b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx @@ -185,7 +185,8 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React R: 'Reward Point', TE:'Top Up Escrow', TM:'Top Up Master Agent', - TA:'Top Up Agent' + TA:'Top Up Agent', + PL:'Purchase Loja' }; return mapping[row.type] || 'Unknown';