Merge branch 'master' of https://git.shiblysolution.id/TPAY/dashboard
This commit is contained in:
@ -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 { DataTable } from '@/components/ui/DataTable';
|
||||||
import { Table } from '@tanstack/react-table';
|
import { Table } from '@tanstack/react-table';
|
||||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||||
import { ManageKycContextProvider } from './hooks';
|
|
||||||
import { getColumns, initialMember } from './Columns';
|
import { getColumns, initialMember } from './Columns';
|
||||||
import { useAuthContext } from '@/auth';
|
import { useAuthContext } from '@/auth';
|
||||||
import { LoaderTransparant } from '@/components';
|
import { LoaderTransparant } from '@/components';
|
||||||
@ -17,6 +22,7 @@ import DetailMember from '../manage-members/blocks/DetailMember';
|
|||||||
import { Breadcrumbs, Link } from '@mui/material';
|
import { Breadcrumbs, Link } from '@mui/material';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import { ListToolBar } from './blocks/ListToolBar';
|
import { ListToolBar } from './blocks/ListToolBar';
|
||||||
|
import { RefreshCw } from 'lucide-react';
|
||||||
|
|
||||||
const Kyc = () => {
|
const Kyc = () => {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@ -26,6 +32,7 @@ const Kyc = () => {
|
|||||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const [dialogType, setDialogType] = useState('');
|
const [dialogType, setDialogType] = useState('');
|
||||||
|
const [isReloading, setIsReloading] = useState(false);
|
||||||
const closeDialog = () => setIsDialogOpen(false);
|
const closeDialog = () => setIsDialogOpen(false);
|
||||||
const { getUser } = useAuthContext();
|
const { getUser } = useAuthContext();
|
||||||
|
|
||||||
@ -65,6 +72,9 @@ const Kyc = () => {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(error.message);
|
toast.error(error.message);
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
setIsReloading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,12 +99,16 @@ const Kyc = () => {
|
|||||||
setMember(initialMember);
|
setMember(initialMember);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleReload = () => {
|
||||||
|
setIsReloading(true);
|
||||||
|
fetchCustomers();
|
||||||
|
};
|
||||||
|
|
||||||
const handleYes = async () => {
|
const handleYes = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const userLogin: any = await getUser();
|
const userLogin: any = await getUser();
|
||||||
const updateData: any = member;
|
const updateData: any = member;
|
||||||
const customerId = member.id;
|
const customerId = member.id;
|
||||||
const description = member.description;
|
|
||||||
const destinationGroup = updateData.destinationGroup;
|
const destinationGroup = updateData.destinationGroup;
|
||||||
updateData.updated_by = userLogin.data ? userLogin.data.id : '';
|
updateData.updated_by = userLogin.data ? userLogin.data.id : '';
|
||||||
let today = new Date();
|
let today = new Date();
|
||||||
@ -161,17 +175,16 @@ const Kyc = () => {
|
|||||||
description: updateData.approval_description_agent
|
description: updateData.approval_description_agent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setDialogOpen(false);
|
|
||||||
setIsDialogOpen(false);
|
|
||||||
toast.success(`Success Update & ${dialogType} Kyc Member`);
|
toast.success(`Success Update & ${dialogType} Kyc Member`);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error?.response?.data?.error) error.message = error?.response?.data?.error;
|
if (error?.response?.data?.error) error.message = error?.response?.data?.error;
|
||||||
setDialogOpen(false);
|
|
||||||
setIsDialogOpen(false);
|
|
||||||
toast.error(error.message);
|
toast.error(error.message);
|
||||||
} finally {
|
} finally {
|
||||||
|
setDialogOpen(false);
|
||||||
|
setIsDialogOpen(false);
|
||||||
await fetchCustomers();
|
await fetchCustomers();
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
setIsReloading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -179,11 +192,15 @@ const Kyc = () => {
|
|||||||
setIsDialogOpen(el);
|
setIsDialogOpen(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading) return <LoaderTransparant />;
|
// const resetForm = () => {
|
||||||
|
// setMember(initialMember);
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (!isDialogOpen) resetForm();
|
// if (!isDialogOpen) resetForm();
|
||||||
}, [isDialogOpen]);
|
// }, [isDialogOpen]);
|
||||||
|
|
||||||
|
if (loading) return <LoaderTransparant />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -200,14 +217,6 @@ const Kyc = () => {
|
|||||||
onNo={() => setDialogOpen(false)}
|
onNo={() => setDialogOpen(false)}
|
||||||
/>
|
/>
|
||||||
{member.id ? (
|
{member.id ? (
|
||||||
// <CustomerDialog
|
|
||||||
// open={isDialogOpen}
|
|
||||||
// handleClose={closeDialog}
|
|
||||||
// handleSubmit={handleSubmit}
|
|
||||||
// initialData={member}
|
|
||||||
// viewStats={true}
|
|
||||||
// page={'kyc'}
|
|
||||||
// />
|
|
||||||
<DetailMember
|
<DetailMember
|
||||||
showAddDialog={isDialogOpen}
|
showAddDialog={isDialogOpen}
|
||||||
setShowAddDialog={setShowAddDialog}
|
setShowAddDialog={setShowAddDialog}
|
||||||
@ -217,6 +226,7 @@ const Kyc = () => {
|
|||||||
initialData={member}
|
initialData={member}
|
||||||
fetchCustomers={fetchCustomers}
|
fetchCustomers={fetchCustomers}
|
||||||
profession={profession}
|
profession={profession}
|
||||||
|
dialogType={dialogType}
|
||||||
page={'kyc'}
|
page={'kyc'}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@ -237,12 +247,20 @@ const Kyc = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
{/* <div className="w-full overflow-x-auto"> */}
|
{/* <div className="w-full overflow-x-auto"> */}
|
||||||
<div className="grid gap-5 lg:gap-7.5 mt-5">
|
<div className="grid gap-5 lg:gap-7.5 mt-5 relative">
|
||||||
|
{isReloading && (
|
||||||
|
<div className="absolute inset-0 bg-white/70 z-10 flex items-center justify-center">
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<RefreshCw className="animate-spin h-8 w-8 text-slate-500 mb-2" />
|
||||||
|
<span className="text-slate-500 font-medium">Refreshing data...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<DataGridProvider
|
<DataGridProvider
|
||||||
data={members}
|
data={members}
|
||||||
columns={getColumns(handleUpdate)}
|
columns={getColumns(handleUpdate)}
|
||||||
pagination={{ size: 25 }}
|
pagination={{ size: 25 }}
|
||||||
toolbar={<ListToolBar />}
|
toolbar={<ListToolBar onReload={handleReload} isReloading={isReloading} />}
|
||||||
layout={{ card: true }}
|
layout={{ card: true }}
|
||||||
sorting={[{ id: 'created_at', desc: true }]}
|
sorting={[{ id: 'created_at', desc: true }]}
|
||||||
serverSide={false}
|
serverSide={false}
|
||||||
|
|||||||
@ -1,40 +1,44 @@
|
|||||||
import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components';
|
import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components';
|
||||||
import { Button } from '@/components/ui/button';
|
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 { table, reload } = useDataGrid();
|
||||||
|
const [usernameFilter, setUsernameFilter] = useState('');
|
||||||
|
|
||||||
|
const handleUsernameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setUsernameFilter(e.target.value);
|
||||||
|
table.getColumn('username')?.setFilterValue(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card-header flex-wrap gap-2 border-b-0 px-5">
|
<div className="card-header flex-wrap gap-2 border-b-0 px-5">
|
||||||
<div className="flex flex-wrap gap-2 lg:gap-5 w-full">
|
<div className="flex flex-wrap gap-2 lg:gap-5 w-full">
|
||||||
<div className="flex justify-between w-full items-center">
|
<div className="flex justify-between w-full items-center">
|
||||||
<div className="flex w-[50%] gap-3 items-center">
|
<div className="flex gap-3 items-center">
|
||||||
<label className="input input-sm w-1/3">
|
|
||||||
<KeenIcon icon="magnifier" />
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search users"
|
placeholder="Search Username"
|
||||||
value={(table.getColumn('name')?.getFilterValue() as string) ?? ''}
|
value={usernameFilter}
|
||||||
onChange={(event) => table.getColumn('name')?.setFilterValue(event.target.value)}
|
onChange={handleUsernameChange}
|
||||||
|
className="input input-sm w-40"
|
||||||
/>
|
/>
|
||||||
</label>
|
|
||||||
<DefaultTooltip title={'Filter'} placement={'top'}>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
className="h-7.5 disabled:bg-gray-400"
|
|
||||||
// disabled={isLoading}
|
|
||||||
// onClick={handleFilterData}
|
|
||||||
>
|
|
||||||
{/* {loadingButton === 'filter' ? <ContentLoader /> : <KeenIcon icon="filter" />} */}
|
|
||||||
<KeenIcon icon="filter" />
|
|
||||||
</Button>
|
|
||||||
</DefaultTooltip>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-3 items-center">
|
<div className="flex gap-3 items-center">
|
||||||
<DefaultTooltip title={'Refresh'} placement={'top'}>
|
<DefaultTooltip title={isReloading ? 'Refreshing...' : 'Refresh'} placement={'top'}>
|
||||||
<Button variant="outline" className="h-7.5" onClick={() => reload()}>
|
<Button variant="outline" className="h-7.5" onClick={onReload} disabled={isReloading}>
|
||||||
|
{isReloading ? (
|
||||||
|
<div className="animate-spin">
|
||||||
<KeenIcon icon="arrows-circle" />
|
<KeenIcon icon="arrows-circle" />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<KeenIcon icon="arrows-circle" />
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</DefaultTooltip>
|
</DefaultTooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -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<ContextProps>(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<SelectedUser | null>(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<ColumnDef<any>[]>(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
accessorFn: (row) => row.id,
|
|
||||||
id: 'id',
|
|
||||||
header: ({ column }) => <DataGridColumnHeader title="ID" column={column} />,
|
|
||||||
enableSorting: true,
|
|
||||||
enableHiding: false,
|
|
||||||
meta: {
|
|
||||||
headerClassName: 'w-[100px]'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorFn: (row) => row.created_date,
|
|
||||||
id: 'created_date',
|
|
||||||
header: ({ column }) => <DataGridColumnHeader title="Created Date" column={column} />,
|
|
||||||
enableSorting: true,
|
|
||||||
enableHiding: false,
|
|
||||||
meta: {
|
|
||||||
headerClassName: 'w-[250px]'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorFn: (row) => row.name,
|
|
||||||
id: 'name',
|
|
||||||
header: ({ column }) => <DataGridColumnHeader title="Name" column={column} />,
|
|
||||||
enableSorting: true,
|
|
||||||
enableHiding: false,
|
|
||||||
meta: {
|
|
||||||
headerClassName: 'w-[350px]'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorFn: (row) => row.description,
|
|
||||||
id: 'description',
|
|
||||||
header: ({ column }) => <DataGridColumnHeader title="Description" column={column} />,
|
|
||||||
enableSorting: true,
|
|
||||||
meta: {
|
|
||||||
headerClassName: 'w-[350px]'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'actions',
|
|
||||||
enableSorting: false,
|
|
||||||
header: ({ column }) => <DataGridColumnHeader title="Action" column={column} />,
|
|
||||||
cell: (data: any) => {
|
|
||||||
const row = data.row.original;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<button
|
|
||||||
className="btn btn-sm btn-icon btn-clear btn-light"
|
|
||||||
onClick={() => handleDetailDialog(true, row.id)}
|
|
||||||
>
|
|
||||||
<KeenIcon icon="notepad-edit" />
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
headerClassName: 'w-[100px]',
|
|
||||||
cellClassName: 'text-center'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[handleDetailDialog]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ManageKycContext.Provider
|
|
||||||
value={{
|
|
||||||
showDetailDialog,
|
|
||||||
handleDetailDialog,
|
|
||||||
showAddDialog,
|
|
||||||
handleAddDialog,
|
|
||||||
selectedUser
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Toaster expand visibleToasts={9} duration={3000} />
|
|
||||||
|
|
||||||
<DataGridProvider
|
|
||||||
columns={columns}
|
|
||||||
pagination={{ size: 10 }}
|
|
||||||
toolbar={<ListToolBar />}
|
|
||||||
layout={{ card: true }}
|
|
||||||
sorting={[{ id: 'name', desc: false }]}
|
|
||||||
serverSide={true}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</DataGridProvider>
|
|
||||||
</ManageKycContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { ManageKycContextProvider, ManageKycContext };
|
|
||||||
export type { SelectedUser };
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
export * from './ManageKycContext';
|
|
||||||
export * from './useKycContext';
|
|
||||||
@ -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 };
|
|
||||||
@ -3,7 +3,6 @@ import { apiConfig } from '@/config/api.config';
|
|||||||
import { getColumns, Members, initialMember } from './Columns';
|
import { getColumns, Members, initialMember } from './Columns';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
// import CustomerDialog from './CustomerDetailModal';
|
|
||||||
import DetailMember from './blocks/DetailMember';
|
import DetailMember from './blocks/DetailMember';
|
||||||
import ConfirmDialog from '@/components/confirm';
|
import ConfirmDialog from '@/components/confirm';
|
||||||
import { useAuthContext } from '@/auth';
|
import { useAuthContext } from '@/auth';
|
||||||
@ -15,6 +14,7 @@ const BASE_URL_MASTER_DATA = apiConfig.service_master_data;
|
|||||||
const BASE_URL = apiConfig.service_customer;
|
const BASE_URL = apiConfig.service_customer;
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import ListToolbar from './blocks/ListToolBar';
|
import ListToolbar from './blocks/ListToolBar';
|
||||||
|
import { RefreshCw } from 'lucide-react';
|
||||||
const ManageMembers = () => {
|
const ManageMembers = () => {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [members, setMembers] = useState([]);
|
const [members, setMembers] = useState([]);
|
||||||
@ -24,6 +24,7 @@ const ManageMembers = () => {
|
|||||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const [dialogType, setDialogType] = useState('');
|
const [dialogType, setDialogType] = useState('');
|
||||||
|
const [isReloading, setIsReloading] = useState(false);
|
||||||
const closeDialog = () => {
|
const closeDialog = () => {
|
||||||
setIsDialogOpen(false);
|
setIsDialogOpen(false);
|
||||||
setMember(initialMember);
|
setMember(initialMember);
|
||||||
@ -36,7 +37,7 @@ const ManageMembers = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
async function fetchCustomers() {
|
async function fetchCustomers(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
let customers = await axios.get(`${BASE_URL}/customer/list`, {
|
let customers = await axios.get(`${BASE_URL}/customer/list`, {
|
||||||
params: {
|
params: {
|
||||||
@ -71,6 +72,9 @@ const ManageMembers = () => {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(error.message);
|
toast.error(error.message);
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
setIsReloading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +96,12 @@ const ManageMembers = () => {
|
|||||||
setMember(data);
|
setMember(data);
|
||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
}
|
}
|
||||||
|
const handleReload = () => {
|
||||||
|
setIsReloading(true);
|
||||||
|
fetchCustomers();
|
||||||
|
};
|
||||||
const handleYes = async () => {
|
const handleYes = async () => {
|
||||||
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const userLogin: any = await getUser();
|
const userLogin: any = await getUser();
|
||||||
const updateData: any = member;
|
const updateData: any = member;
|
||||||
@ -132,14 +140,13 @@ const ManageMembers = () => {
|
|||||||
delete updateData.group_deleted_by;
|
delete updateData.group_deleted_by;
|
||||||
delete updateData.group_deleted_at;
|
delete updateData.group_deleted_at;
|
||||||
delete updateData.updated_at;
|
delete updateData.updated_at;
|
||||||
try {
|
const formUpdate = new FormData();
|
||||||
const form = new FormData();
|
|
||||||
for (const property in updateData) {
|
for (const property in updateData) {
|
||||||
if (updateData[property]) form.append(property, updateData[property]);
|
if (updateData[property]) formUpdate.append(property, updateData[property]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogType === 'update') {
|
if (dialogType === 'update') {
|
||||||
await axios.put(`${BASE_URL}/customer/update/${selectedMember}`, form, {
|
await axios.put(`${BASE_URL}/customer/update/${selectedMember}`, formUpdate, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data'
|
||||||
}
|
}
|
||||||
@ -164,11 +171,16 @@ const ManageMembers = () => {
|
|||||||
delete createMember.approval_description_premium;
|
delete createMember.approval_description_premium;
|
||||||
delete createMember.approval_description_agent;
|
delete createMember.approval_description_agent;
|
||||||
delete createMember.language;
|
delete createMember.language;
|
||||||
await axios.post(`${BASE_URL}/customers/create`, member);
|
const formCreate = new FormData();
|
||||||
|
for (const property in createMember) {
|
||||||
|
if (createMember[property]) formCreate.append(property, createMember[property]);
|
||||||
|
}
|
||||||
|
await axios.post(`${BASE_URL}/customers/create`, formCreate);
|
||||||
toast.success('Success Create Member. PIN sent to email');
|
toast.success('Success Create Member. PIN sent to email');
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.error(error.message);
|
if (error?.response?.data?.message) toast.error(error?.response?.data?.message)
|
||||||
|
else toast.error(error.message);
|
||||||
} finally {
|
} finally {
|
||||||
setDialogOpen(false);
|
setDialogOpen(false);
|
||||||
closeDialog();
|
closeDialog();
|
||||||
@ -225,14 +237,29 @@ const ManageMembers = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
{/* <div className="w-full overflow-x-auto px-4"> */}
|
{/* <div className="w-full overflow-x-auto px-4"> */}
|
||||||
<div className="grid gap-5 lg:gap-7.5 mt-5">
|
|
||||||
|
<div className="grid gap-5 lg:gap-7.5 mt-5 relative">
|
||||||
|
{isReloading && (
|
||||||
|
<div className="absolute inset-0 bg-white/70 z-10 flex items-center justify-center">
|
||||||
|
<div className="flex flex-col items-center">
|
||||||
|
<RefreshCw className="animate-spin h-8 w-8 text-slate-500 mb-2" />
|
||||||
|
<span className="text-slate-500 font-medium">Refreshing data...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<DataGridProvider
|
<DataGridProvider
|
||||||
data={members}
|
data={members}
|
||||||
pagination={{ size: 25 }}
|
pagination={{ size: 25 }}
|
||||||
columns={getColumns(handleUpdate)}
|
columns={getColumns(handleUpdate)}
|
||||||
layout={{ card: true }}
|
layout={{ card: true }}
|
||||||
serverSide={false}
|
serverSide={false}
|
||||||
toolbar={<ListToolbar createMember={createMember} />}
|
toolbar={
|
||||||
|
<ListToolbar
|
||||||
|
createMember={createMember}
|
||||||
|
onReload={handleReload}
|
||||||
|
isReloading={isReloading}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onRowSelectionChange={(selected, table: any) => {
|
onRowSelectionChange={(selected, table: any) => {
|
||||||
const selectedRow = table.getSelectedRowModel().rows[0];
|
const selectedRow = table.getSelectedRowModel().rows[0];
|
||||||
if (selectedRow) handleUpdate(selectedRow.original);
|
if (selectedRow) handleUpdate(selectedRow.original);
|
||||||
|
|||||||
@ -26,29 +26,10 @@ export default function AdmAccess({page,groups,formData,handleClose,fetchCustome
|
|||||||
const [dialogType, setDialogType] = useState('');
|
const [dialogType, setDialogType] = useState('');
|
||||||
const [changeGroup, setChangeGroup] = useState('');
|
const [changeGroup, setChangeGroup] = useState('');
|
||||||
const [changeGroupD, setChangeGroupD] = useState(false);
|
const [changeGroupD, setChangeGroupD] = useState(false);
|
||||||
// const [groups, setGroups] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// fetchGroups();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// const fetchGroups = async () => {
|
|
||||||
// try {
|
|
||||||
// let getGroups = await axios.get(`${BASE_URL_CUSTOMER}/groups/list`, {
|
|
||||||
// params: {
|
|
||||||
// limit: 50,
|
|
||||||
// page: 1,
|
|
||||||
// with_deleted: false,
|
|
||||||
// order_field: 'name',
|
|
||||||
// order_direction: 'ASC'
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// setGroups(getGroups.data.data.list);
|
|
||||||
// } catch (error: any) {
|
|
||||||
// toast.error(error.message);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
const handleYes = async () => {
|
const handleYes = async () => {
|
||||||
try {
|
try {
|
||||||
if (dialogType === 'update status') {
|
if (dialogType === 'update status') {
|
||||||
|
|||||||
@ -41,6 +41,10 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa
|
|||||||
const [sucos, setSucos] = useState<any>([]);
|
const [sucos, setSucos] = useState<any>([]);
|
||||||
const [groups, setGroups] = useState([]);
|
const [groups, setGroups] = useState([]);
|
||||||
const [genders] = useState([ { name: 'Male',id: 'M' }, { name: 'Female',id: 'F' }])
|
const [genders] = useState([ { name: 'Male',id: 'M' }, { name: 'Female',id: 'F' }])
|
||||||
|
const [previewImg, setPreviewImg] = useState({
|
||||||
|
status: false,
|
||||||
|
img: ''
|
||||||
|
});
|
||||||
const [banks] = useState([
|
const [banks] = useState([
|
||||||
{ name: 'BNCTL',id: 'BNCTL' }, { name: 'BRI',id: 'BRI' }, { name: 'BNU',id: 'BNU' }, { name: 'Mandiri',id: 'Mandiri' }
|
{ name: 'BNCTL',id: 'BNCTL' }, { name: 'BRI',id: 'BRI' }, { name: 'BNU',id: 'BNU' }, { name: 'Mandiri',id: 'Mandiri' }
|
||||||
])
|
])
|
||||||
@ -183,7 +187,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={showAddDialog} onOpenChange={(open) => handleAddDialog(open)}>
|
<Dialog open={showAddDialog} onOpenChange={(open) => handleAddDialog(open)}>
|
||||||
<DialogContent className="container-fixed max-w-[768px] flex flex-col p-5">
|
<DialogContent className="container-fixed max-w-[85%] flex flex-col p-2">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Member - {dialogType ==='create' ? "Create" : "View/Edit"}</DialogTitle>
|
<DialogTitle>Member - {dialogType ==='create' ? "Create" : "View/Edit"}</DialogTitle>
|
||||||
<DialogDescription></DialogDescription>
|
<DialogDescription></DialogDescription>
|
||||||
@ -196,18 +200,22 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="card-body grid gap-5">
|
{/* <div className="card-body grid gap-5"> */}
|
||||||
|
<div className="card-body grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||||
|
|
||||||
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, groups, 'group_id', 'Group', true, dialogType === "update"||false): ''}
|
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, groups, 'group_id', 'Group', true, dialogType === "update"||false): ''}
|
||||||
{/* {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Group', 'group_name', 'text', true, true): ''} */}
|
{/* {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Group', 'group_name', 'text', true, true): ''} */}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Username', 'username', 'text', true, dialogType==='create'?false:true): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Username', 'username', 'text', true, dialogType==='create'?false:true): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Full Name', 'fullname', 'text', true, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Full Name', 'fullname', 'text', true, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'Photo', 'photouser'): ''}
|
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'Photo', 'photouser', previewImg, setPreviewImg): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, genders, 'gender', 'Gender', true, false): ''}
|
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, genders, 'gender', 'Gender', true, false): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Date of Birth', 'date_birth', 'date', true, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Date of Birth', 'date_birth', 'date', true, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Phone Number', 'msisdn', 'text', true, dialogType === "update"||false): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Phone Number', 'msisdn', 'text', true, dialogType === "update"||false): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Email', 'email', 'text', true, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Email', 'email', 'text', true, viewOnly): ''}
|
||||||
{/* {generateList(formData, handleChange, status, 'status', 'Status', null, true)} */}
|
{/* {generateList(formData, handleChange, status, 'status', 'Status', null, true)} */}
|
||||||
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Mother Fullname', 'mother_fullname', 'text', true, viewOnly): ''}
|
||||||
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Identity Number', 'identity_number', 'text', false, viewOnly): ''}
|
||||||
|
<div className="bg-white space-y-6">
|
||||||
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, profession, 'profession', 'Profession', false, false): ''}
|
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, profession, 'profession', 'Profession', false, false): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, municipios, 'municipio_id', 'Municipio', false, false): ''}
|
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, municipios, 'municipio_id', 'Municipio', false, false): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, postoAdm, 'posto_adms_id', 'Posto', false, false): ''}
|
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, postoAdm, 'posto_adms_id', 'Posto', false, false): ''}
|
||||||
@ -230,22 +238,28 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Address', 'address', 'text', true, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Address', 'address', 'text', true, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Mother Fullname', 'mother_fullname', 'text', true, viewOnly): ''}
|
<div className="bg-white p-6 rounded-md shadow-md space-y-6">
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Identity Number', 'identity_number', 'text', false, viewOnly): ''}
|
<h2 className="text-lg font-semibold">Bank Information</h2>
|
||||||
|
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, banks, 'bank_name', 'Bank Name', false, false): ''}
|
||||||
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Bank Account', 'bank_account', 'text', false, viewOnly): ''}
|
||||||
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'iBank Number', 'ibank_number', 'text', false, viewOnly): ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-white p-6 rounded-md shadow-md space-y-6">
|
||||||
|
<h2 className="text-lg font-semibold">Agent Information</h2>
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'License Number', 'license_number', 'text', false, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'License Number', 'license_number', 'text', false, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Merchant Name', 'agent_name', 'text', false, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Merchant Name', 'agent_name', 'text', false, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Merchant Address', 'merchantaddress', 'text', false, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Merchant Address', 'merchantaddress', 'text', false, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Longitude Merchant', 'longitudemerchant', 'text', false, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Longitude Merchant', 'longitudemerchant', 'text', false, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Latitude Merchant', 'latitudemerchant', 'text', false, viewOnly): ''}
|
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Latitude Merchant', 'latitudemerchant', 'text', false, viewOnly): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Selfie', 'file_selfie'): ''}
|
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Selfie', 'file_selfie', previewImg, setPreviewImg): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Document', 'file_document_id'): ''}
|
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Document', 'file_document_id', previewImg, setPreviewImg): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Document & Selfie', 'file_document_id_selfie'): ''}
|
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Document & Selfie', 'file_document_id_selfie', previewImg, setPreviewImg): ''}
|
||||||
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Commercial License', 'file_commercial_license'): ''}
|
{(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'File Commercial License', 'file_commercial_license', previewImg, setPreviewImg): ''}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{(formData.id || dialogType === "create") ? generateList(formData, handleChange, banks, 'bank_name', 'Bank Name', false, false): ''}
|
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Bank Account', 'bank_account', 'text', false, viewOnly): ''}
|
|
||||||
{(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'iBank Number', 'ibank_number', 'text', false, viewOnly): ''}
|
|
||||||
|
|
||||||
{(formData.id&&(!page||formData.destinationGroup === "Premium")) ? generateInput(formData, handleChange, 'Approval Premium Description', 'approval_description_premium', 'text', false, viewOnly): ''}
|
{(formData.id&&(!page||formData.destinationGroup === "Premium")) ? generateInput(formData, handleChange, 'Approval Premium Description', 'approval_description_premium', 'text', false, viewOnly): ''}
|
||||||
{(formData.id&&(!page||formData.destinationGroup === "Agent")) ? generateInput(formData, handleChange, 'Approval Agent Description', 'approval_description_agent', 'text', false, viewOnly): ''}
|
{(formData.id&&(!page||formData.destinationGroup === "Agent")) ? generateInput(formData, handleChange, 'Approval Agent Description', 'approval_description_agent', 'text', false, viewOnly): ''}
|
||||||
@ -257,7 +271,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa
|
|||||||
<CustomerWallet customerid={formData.id}/>
|
<CustomerWallet customerid={formData.id}/>
|
||||||
) : ""}
|
) : ""}
|
||||||
|
|
||||||
<div className="flex justify-end gap-5">
|
<div className="col-span-1 md:col-span-2 flex justify-end gap-5">
|
||||||
<Button onClick={(e:any) => btnPrevDef(e)} color="secondary">{ viewOnly ? (`Open Edit`) : (`Close Edit`) }</Button>
|
<Button onClick={(e:any) => btnPrevDef(e)} color="secondary">{ viewOnly ? (`Open Edit`) : (`Close Edit`) }</Button>
|
||||||
<Button type="button" variant="outline" onClick={() => handleAddDialog(false)}>Cancel</Button>
|
<Button type="button" variant="outline" onClick={() => handleAddDialog(false)}>Cancel</Button>
|
||||||
{/* <Button onClick={(e) => buttonOnSubmit(e, formData)} variant="default">Save Changes</Button> */}
|
{/* <Button onClick={(e) => buttonOnSubmit(e, formData)} variant="default">Save Changes</Button> */}
|
||||||
@ -333,7 +347,7 @@ function generateList(formData:any, handleChange: any, list:any, name:string, la
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ON DEV (UPDATENYA)
|
// ON DEV (UPDATENYA)
|
||||||
function generateImage(formData:any, handleChange:any, label:string, name:string) {
|
function generateImage(formData:any, handleChange:any, label:string, name:string, previewImg: any, setPreviewImg:any) {
|
||||||
const imagePreview = (file:any) => {
|
const imagePreview = (file:any) => {
|
||||||
if (file && file.type && file.type.startsWith('image/')) {
|
if (file && file.type && file.type.startsWith('image/')) {
|
||||||
const previewURL = URL.createObjectURL(file);
|
const previewURL = URL.createObjectURL(file);
|
||||||
@ -342,8 +356,21 @@ function generateImage(formData:any, handleChange:any, label:string, name:string
|
|||||||
return file
|
return file
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handlePrevImg(par: boolean) {
|
||||||
|
if (par) setPreviewImg({ status: true, img: ''})
|
||||||
|
if (!par) setPreviewImg({ status: false, img: '' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickImg(img: any) {
|
||||||
|
setPreviewImg({ status: true, img })
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{previewImg.status ? (
|
||||||
|
<PreviewImage previewImgDialog={previewImg.status} handlePreviewImgDialog={handlePrevImg}
|
||||||
|
modalImage={previewImg.img}/>
|
||||||
|
):''}
|
||||||
<div className="flex items-center justify-between w-full max-w-xl">
|
<div className="flex items-center justify-between w-full max-w-xl">
|
||||||
<label className="form-label flex items-center gap-1 max-w-56">
|
<label className="form-label flex items-center gap-1 max-w-56">
|
||||||
{label}<span className="text-red-500"></span>
|
{label}<span className="text-red-500"></span>
|
||||||
@ -351,7 +378,8 @@ function generateImage(formData:any, handleChange:any, label:string, name:string
|
|||||||
<div className="flex items-center space-x-4 w-3/4 justify-end">
|
<div className="flex items-center space-x-4 w-3/4 justify-end">
|
||||||
{ formData[name] ? (
|
{ formData[name] ? (
|
||||||
<div className="border-2 border-dashed border-red-300 rounded-md p-2">
|
<div className="border-2 border-dashed border-red-300 rounded-md p-2">
|
||||||
<img width={300} height={250} srcSet={imagePreview(formData[name])} src={imagePreview(formData[name])} alt={name} style={{borderRadius: 10}}/>
|
<img width={300} height={250} srcSet={imagePreview(formData[name])} src={imagePreview(formData[name])}
|
||||||
|
alt={name} style={{borderRadius: 10, cursor: 'pointer' }} onClick={() => onClickImg(imagePreview(formData[name]))}/>
|
||||||
{/* <img width={300} height={250} srcSet={formData[name]} src={formData[name]} alt={name} style={{borderRadius: 10}}/> */}
|
{/* <img width={300} height={250} srcSet={formData[name]} src={formData[name]} alt={name} style={{borderRadius: 10}}/> */}
|
||||||
</div>
|
</div>
|
||||||
) : (<span>No Data</span>)}
|
) : (<span>No Data</span>)}
|
||||||
@ -364,3 +392,29 @@ function generateImage(formData:any, handleChange:any, label:string, name:string
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function PreviewImage({previewImgDialog, handlePreviewImgDialog, modalImage}:any) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Dialog open={previewImgDialog} onOpenChange={(open) => handlePreviewImgDialog(open)}>
|
||||||
|
<DialogContent className="">
|
||||||
|
<DialogTitle aria-describedby={''}></DialogTitle>
|
||||||
|
<DialogBody>
|
||||||
|
<button
|
||||||
|
onClick={() => handlePreviewImgDialog(false)}
|
||||||
|
className="absolute top-2 right-2 text-white bg-red-600 hover:bg-red-800 rounded-full px-3 py-1 text-xl font-bold"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<img
|
||||||
|
src={modalImage}
|
||||||
|
alt="Preview"
|
||||||
|
className="max-w-full max-h-[80vh] rounded-lg"
|
||||||
|
/>
|
||||||
|
</DialogBody>
|
||||||
|
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,20 @@
|
|||||||
import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components';
|
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { UserPlus } from 'lucide-react';
|
||||||
|
import { KeenIcon, useDataGrid } from '@/components';
|
||||||
|
import { DefaultTooltip } from '@/components';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
const ListToolbar = ({ createMember }: { createMember: () => void }) => {
|
interface ListToolbarProps {
|
||||||
const { table, reload } = useDataGrid();
|
createMember: () => void;
|
||||||
const [usernameFilter, setUsernameFilter] = useState('');
|
onReload: () => void;
|
||||||
const [emailFilter, setEmailFilter] = useState('');
|
isReloading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListToolbar = ({ createMember, onReload, isReloading }: ListToolbarProps) => {
|
||||||
|
|
||||||
|
const [emailFilter, setEmailFilter] = useState('');
|
||||||
|
const [usernameFilter, setUsernameFilter] = useState('');
|
||||||
|
const {table}=useDataGrid();
|
||||||
const handleUsernameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleUsernameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setUsernameFilter(e.target.value);
|
setUsernameFilter(e.target.value);
|
||||||
table.getColumn('username')?.setFilterValue(e.target.value);
|
table.getColumn('username')?.setFilterValue(e.target.value);
|
||||||
@ -34,9 +42,20 @@ const ListToolbar = ({ createMember }: { createMember: () => void }) => {
|
|||||||
<Button variant="outline" className="h-7.5 text-[0.8rem]" onClick={createMember}>
|
<Button variant="outline" className="h-7.5 text-[0.8rem]" onClick={createMember}>
|
||||||
Add Data
|
Add Data
|
||||||
</Button>
|
</Button>
|
||||||
<DefaultTooltip title={'Refresh'} placement={'top'}>
|
<DefaultTooltip title={isReloading ? 'Refreshing...' : 'Refresh'} placement={'top'}>
|
||||||
<Button variant="outline" className="h-7.5" onClick={() => reload()}>
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
className="h-7.5"
|
||||||
|
onClick={onReload}
|
||||||
|
disabled={isReloading}
|
||||||
|
>
|
||||||
|
{isReloading ? (
|
||||||
|
<div className="animate-spin">
|
||||||
<KeenIcon icon="arrows-circle" />
|
<KeenIcon icon="arrows-circle" />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<KeenIcon icon="arrows-circle" />
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</DefaultTooltip>
|
</DefaultTooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -470,6 +470,7 @@ const AddDialog = () => {
|
|||||||
<SelectItem value="TE">Top Up Escrow </SelectItem>
|
<SelectItem value="TE">Top Up Escrow </SelectItem>
|
||||||
<SelectItem value="TM">Top Up Master Agent </SelectItem>
|
<SelectItem value="TM">Top Up Master Agent </SelectItem>
|
||||||
<SelectItem value="TA">Top Up Agent </SelectItem>
|
<SelectItem value="TA">Top Up Agent </SelectItem>
|
||||||
|
<SelectItem value="PL">Purchase Loja</SelectItem>
|
||||||
|
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
@ -604,6 +604,7 @@ const EditDialog = () => {
|
|||||||
<SelectItem value="TE">Top Up Escrow </SelectItem>
|
<SelectItem value="TE">Top Up Escrow </SelectItem>
|
||||||
<SelectItem value="TM">Top Up Master Agent </SelectItem>
|
<SelectItem value="TM">Top Up Master Agent </SelectItem>
|
||||||
<SelectItem value="TA">Top Up Agent </SelectItem>
|
<SelectItem value="TA">Top Up Agent </SelectItem>
|
||||||
|
<SelectItem value="PL">Purchase Loja</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ const ListToolbar = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
table.getColumn('name')?.setFilterValue(searchValue);
|
table.getColumn('name')?.setFilterValue(searchValue);
|
||||||
|
table.setPageIndex(0);
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
|
|||||||
@ -185,7 +185,8 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React
|
|||||||
R: 'Reward Point',
|
R: 'Reward Point',
|
||||||
TE:'Top Up Escrow',
|
TE:'Top Up Escrow',
|
||||||
TM:'Top Up Master Agent',
|
TM:'Top Up Master Agent',
|
||||||
TA:'Top Up Agent'
|
TA:'Top Up Agent',
|
||||||
|
PL:'Purchase Loja'
|
||||||
};
|
};
|
||||||
|
|
||||||
return mapping[row.type] || 'Unknown';
|
return mapping[row.type] || 'Unknown';
|
||||||
|
|||||||
Reference in New Issue
Block a user