Dashboard Client - Portal
This commit is contained in:
@@ -1,276 +1,130 @@
|
||||
// @mui
|
||||
import { Typography, Container, Grid, Button, SelectChangeEvent } from '@mui/material';
|
||||
import { CardContent,Button, Container, Grid, styled, Typography, Card, Stack } from '@mui/material';
|
||||
// hooks
|
||||
import useSettings from '../../hooks/useSettings';
|
||||
// components
|
||||
import Page from '../../components/Page';
|
||||
// theme
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import axios from '../../utils/axios';
|
||||
import { Stack } from '@mui/system';
|
||||
import useAuth from '../../hooks/useAuth';
|
||||
import SomethingUsage from '../../sections/dashboard/SomethingUsage';
|
||||
import { fCurrency } from '../../utils/formatNumber';
|
||||
import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet';
|
||||
import TrendingUpIcon from '@mui/icons-material/TrendingUp';
|
||||
import MonetizationOnIcon from '@mui/icons-material/MonetizationOn';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
||||
import Table from '../../components/Table';
|
||||
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import palette from '../../theme/palette';
|
||||
|
||||
export default function Index() {
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export default function Dashboard() {
|
||||
const { themeStretch } = useSettings();
|
||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||
const controller = new AbortController();
|
||||
|
||||
const [memberData, setMemberData] = useState([]);
|
||||
const { logout } = useAuth();
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* setting up for the table */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const loadings = {
|
||||
isLoading: isLoading,
|
||||
setIsLoading: setIsLoading,
|
||||
const loadSomething = () => {
|
||||
axios.get('/user')
|
||||
};
|
||||
|
||||
/* ------------------------------ handle params ----------------------------- */
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [appliedParams, setAppliedParams] = useState({});
|
||||
const Wallet = styled(AccountBalanceWalletIcon)(({ theme }) => ({
|
||||
color: 'orange',
|
||||
marginRight: theme.spacing(1),
|
||||
}));
|
||||
|
||||
const params = {
|
||||
searchParams: searchParams,
|
||||
setSearchParams: setSearchParams,
|
||||
appliedParams: appliedParams,
|
||||
setAppliedParams: setAppliedParams,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
const TrendUp = styled(TrendingUpIcon)(({ theme }) => ({
|
||||
color: 'blue',
|
||||
marginRight: theme.spacing(1),
|
||||
}));
|
||||
|
||||
/* ------------------------------ handle order ------------------------------ */
|
||||
const [order, setOrder] = useState<Order>('asc');
|
||||
const [orderBy, setOrderBy] = useState('fullName');
|
||||
const Monet = styled(MonetizationOnIcon)(({ theme }) => ({
|
||||
color: 'orange',
|
||||
marginRight: theme.spacing(1),
|
||||
}));
|
||||
|
||||
const orders = {
|
||||
order: order,
|
||||
setOrder: setOrder,
|
||||
orderBy: orderBy,
|
||||
setOrderBy: setOrderBy,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
const DangerCard = styled(Card)(({ theme }) => ({
|
||||
boxShadow: 'none',
|
||||
padding: theme.spacing(3),
|
||||
color: theme.palette.error.main,
|
||||
backgroundColor: theme.palette.error.lighter,
|
||||
}));
|
||||
|
||||
/* ---------------------------- handle pagination --------------------------- */
|
||||
const [page, setPage] = useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(10);
|
||||
const SuccessCard = styled(Card)(({ theme }) => ({
|
||||
boxShadow: 'none',
|
||||
padding: theme.spacing(3),
|
||||
color: theme.palette.success.darker,
|
||||
backgroundColor: theme.palette.success.lighter,
|
||||
}));
|
||||
|
||||
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
|
||||
current_page: 0,
|
||||
from: 0,
|
||||
last_page: 0,
|
||||
links: [],
|
||||
path: '',
|
||||
per_page: 0,
|
||||
to: 0,
|
||||
total: 0,
|
||||
});
|
||||
const DefaultCard = styled(Card)(({ theme }) => ({
|
||||
boxShadow: theme.shadows[3], // Menggunakan bayangan standar dari tema
|
||||
padding: theme.spacing(3),
|
||||
color: theme.palette.text.primary,
|
||||
backgroundColor: theme.palette.background.paper, // Latar belakang putih
|
||||
}));
|
||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||
|
||||
const paginations = {
|
||||
page: page,
|
||||
setPage: setPage,
|
||||
rowsPerPage: rowsPerPage,
|
||||
setRowsPerPage: setRowsPerPage,
|
||||
paginationTable: paginationTable,
|
||||
setPaginationTable: setPaginationTable,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
const [depositData, setDepositData] = useState({ deposit: 0, limit: 0, usage: 0 });
|
||||
|
||||
/* ------------------------------ handle search ----------------------------- */
|
||||
const [searchText, setSearchText] = useState('');
|
||||
useEffect(() => {
|
||||
const fetchDepositData = async () => {
|
||||
try {
|
||||
const response = await axios.get(`${corporateValue}/get-deposits`);
|
||||
setDepositData(response.data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch deposit data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (searchText === '') {
|
||||
searchParams.delete('search');
|
||||
const params = Object.fromEntries([...searchParams.entries()]);
|
||||
setAppliedParams(params);
|
||||
} else {
|
||||
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
|
||||
setAppliedParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
const searchs = {
|
||||
useSearchs: false,
|
||||
searchText: searchText,
|
||||
setSearchText: setSearchText,
|
||||
handleSearchSubmit: handleSearchSubmit,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------ handle filter ----------------------------- */
|
||||
const [divisionValue, setDivisionValue] = useState('all');
|
||||
const [divisionData, setDivisionData] = useState([]);
|
||||
|
||||
const handleDivisionChange = (event: SelectChangeEvent) => {
|
||||
setDivisionValue(event.target.value as string);
|
||||
|
||||
if (event.target.value === 'all') {
|
||||
searchParams.delete('division');
|
||||
const params = Object.fromEntries([...searchParams.entries()]);
|
||||
setAppliedParams(params);
|
||||
} else {
|
||||
const params = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['division', event.target.value as string],
|
||||
]);
|
||||
setAppliedParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
const filters = {
|
||||
useFilter: true,
|
||||
config: {
|
||||
label: 'Division',
|
||||
divisionValue: divisionValue,
|
||||
divisionData: divisionData,
|
||||
handleDivisionChange: handleDivisionChange,
|
||||
},
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------- headCell -------------------------------- */
|
||||
const headCells: HeadCell<never>[] = [
|
||||
{
|
||||
id: 'memberId',
|
||||
align: 'left',
|
||||
label: 'Member ID',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'fullName',
|
||||
align: 'center',
|
||||
label: 'Name',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'division',
|
||||
align: 'center',
|
||||
label: 'Divisi',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
align: 'center',
|
||||
label: 'Status',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'action',
|
||||
align: 'right',
|
||||
label: '',
|
||||
isSort: false,
|
||||
},
|
||||
];
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const parameters =
|
||||
Object.keys(appliedParams).length !== 0
|
||||
? appliedParams
|
||||
: Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['order', order],
|
||||
['orderBy', orderBy],
|
||||
]);
|
||||
|
||||
const [divisionResponse, membersResponse] = await Promise.all([
|
||||
axios.get(`${corporateValue}/division`, { signal: controller.signal }),
|
||||
axios.get(`${corporateValue}/members`, {
|
||||
params: { ...parameters },
|
||||
signal: controller.signal,
|
||||
}),
|
||||
]);
|
||||
|
||||
setSearchParams(parameters);
|
||||
setDivisionData(divisionResponse.data);
|
||||
setMemberData(
|
||||
membersResponse.data.data.map((obj: any) => ({
|
||||
...obj,
|
||||
status:
|
||||
obj.status === 1 ? (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.16)',
|
||||
color: palette.dark.success.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.32)',
|
||||
color: palette.dark.success.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Active
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.16)',
|
||||
color: palette.dark.error.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.32)',
|
||||
color: palette.dark.error.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Inactive
|
||||
</Button>
|
||||
),
|
||||
}))
|
||||
);
|
||||
setPaginationTable(membersResponse.data);
|
||||
setRowsPerPage(membersResponse.data.per_page);
|
||||
|
||||
if (searchParams.get('page')) {
|
||||
// @ts-ignore
|
||||
const currentPage = parseInt(searchParams.get('page')) - 1;
|
||||
paginationTable.current_page = currentPage;
|
||||
setPage(currentPage);
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching data:', error.message);
|
||||
}
|
||||
})();
|
||||
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);
|
||||
fetchDepositData();
|
||||
}, [corporateValue]);
|
||||
|
||||
return (
|
||||
<Page title="Dashboard">
|
||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||
<Stack direction="row" justifyContent="space-between">
|
||||
<Typography variant="h3" component="h1" paragraph>
|
||||
Dashboard
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography variant="h3" component="h1" paragraph>
|
||||
Dashboard
|
||||
</Typography>
|
||||
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} lg={12} md={12}>
|
||||
<Table
|
||||
headCells={headCells}
|
||||
rows={memberData}
|
||||
orders={orders}
|
||||
paginations={paginations}
|
||||
loadings={loadings}
|
||||
params={params}
|
||||
searchs={searchs}
|
||||
filters={filters}
|
||||
/>
|
||||
<Grid item xs={4}>
|
||||
{/* <SomethingUsage /> */}
|
||||
<DefaultCard>
|
||||
<CardContent>
|
||||
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
|
||||
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
|
||||
<Typography variant='h4'>{fCurrency(depositData.deposit)}</Typography>
|
||||
<Wallet />
|
||||
</Stack>
|
||||
<Typography variant='h6'>Deposit</Typography>
|
||||
</Stack>
|
||||
</CardContent>
|
||||
</DefaultCard>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<DefaultCard>
|
||||
<CardContent>
|
||||
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
|
||||
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
|
||||
<Typography variant='h4'>{fCurrency(depositData.limit)}</Typography>
|
||||
<TrendUp />
|
||||
</Stack>
|
||||
<Typography variant='h6'>Limit</Typography>
|
||||
</Stack>
|
||||
</CardContent>
|
||||
</DefaultCard>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<DefaultCard>
|
||||
<CardContent>
|
||||
<Stack direction="column" alignItems="flex-start" justifyContent="space-between" sx={{ mb: 0.6 }}>
|
||||
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: '100%' }}>
|
||||
<Typography variant='h4'>{fCurrency(depositData.usage)}</Typography>
|
||||
<Monet />
|
||||
</Stack>
|
||||
<Typography variant='h6'>This Year Usage</Typography>
|
||||
</Stack>
|
||||
</CardContent>
|
||||
</DefaultCard>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
|
||||
279
frontend/client-portal/src/pages/Dashboard/Index_.tsx
Normal file
279
frontend/client-portal/src/pages/Dashboard/Index_.tsx
Normal file
@@ -0,0 +1,279 @@
|
||||
// @mui
|
||||
import { Typography, Container, Grid, Button, SelectChangeEvent } from '@mui/material';
|
||||
// hooks
|
||||
import useSettings from '../../hooks/useSettings';
|
||||
// components
|
||||
import Page from '../../components/Page';
|
||||
// theme
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import axios from '../../utils/axios';
|
||||
import { Stack } from '@mui/system';
|
||||
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
|
||||
import Table from '../../components/Table';
|
||||
import { HeadCell, Order, PaginationTableProps } from '../../@types/table';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import palette from '../../theme/palette';
|
||||
|
||||
export default function Index_() {
|
||||
const { themeStretch } = useSettings();
|
||||
const { corporateValue } = useContext(UserCurrentCorporateContext);
|
||||
const controller = new AbortController();
|
||||
|
||||
const [memberData, setMemberData] = useState([]);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* setting up for the table */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const loadings = {
|
||||
isLoading: isLoading,
|
||||
setIsLoading: setIsLoading,
|
||||
};
|
||||
|
||||
/* ------------------------------ handle params ----------------------------- */
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [appliedParams, setAppliedParams] = useState({});
|
||||
|
||||
const params = {
|
||||
searchParams: searchParams,
|
||||
setSearchParams: setSearchParams,
|
||||
appliedParams: appliedParams,
|
||||
setAppliedParams: setAppliedParams,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------ handle order ------------------------------ */
|
||||
const [order, setOrder] = useState<Order>('asc');
|
||||
const [orderBy, setOrderBy] = useState('fullName');
|
||||
|
||||
const orders = {
|
||||
order: order,
|
||||
setOrder: setOrder,
|
||||
orderBy: orderBy,
|
||||
setOrderBy: setOrderBy,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ---------------------------- handle pagination --------------------------- */
|
||||
const [page, setPage] = useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(10);
|
||||
|
||||
const [paginationTable, setPaginationTable] = useState<PaginationTableProps>({
|
||||
current_page: 0,
|
||||
from: 0,
|
||||
last_page: 0,
|
||||
links: [],
|
||||
path: '',
|
||||
per_page: 0,
|
||||
to: 0,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const paginations = {
|
||||
page: page,
|
||||
setPage: setPage,
|
||||
rowsPerPage: rowsPerPage,
|
||||
setRowsPerPage: setRowsPerPage,
|
||||
paginationTable: paginationTable,
|
||||
setPaginationTable: setPaginationTable,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------ handle search ----------------------------- */
|
||||
const [searchText, setSearchText] = useState('');
|
||||
|
||||
const handleSearchSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (searchText === '') {
|
||||
searchParams.delete('search');
|
||||
const params = Object.fromEntries([...searchParams.entries()]);
|
||||
setAppliedParams(params);
|
||||
} else {
|
||||
const params = Object.fromEntries([...searchParams.entries(), ['search', searchText]]);
|
||||
setAppliedParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
const searchs = {
|
||||
useSearchs: false,
|
||||
searchText: searchText,
|
||||
setSearchText: setSearchText,
|
||||
handleSearchSubmit: handleSearchSubmit,
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ------------------------------ handle filter ----------------------------- */
|
||||
const [divisionValue, setDivisionValue] = useState('all');
|
||||
const [divisionData, setDivisionData] = useState([]);
|
||||
|
||||
const handleDivisionChange = (event: SelectChangeEvent) => {
|
||||
setDivisionValue(event.target.value as string);
|
||||
|
||||
if (event.target.value === 'all') {
|
||||
searchParams.delete('division');
|
||||
const params = Object.fromEntries([...searchParams.entries()]);
|
||||
setAppliedParams(params);
|
||||
} else {
|
||||
const params = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['division', event.target.value as string],
|
||||
]);
|
||||
setAppliedParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
const filters = {
|
||||
useFilter: true,
|
||||
config: {
|
||||
label: 'Division',
|
||||
divisionValue: divisionValue,
|
||||
divisionData: divisionData,
|
||||
handleDivisionChange: handleDivisionChange,
|
||||
},
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------- headCell -------------------------------- */
|
||||
const headCells: HeadCell<never>[] = [
|
||||
{
|
||||
id: 'memberId',
|
||||
align: 'left',
|
||||
label: 'Member ID',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'fullName',
|
||||
align: 'center',
|
||||
label: 'Name',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'division',
|
||||
align: 'center',
|
||||
label: 'Divisi',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
align: 'center',
|
||||
label: 'Status',
|
||||
isSort: true,
|
||||
},
|
||||
{
|
||||
id: 'action',
|
||||
align: 'right',
|
||||
label: '',
|
||||
isSort: false,
|
||||
},
|
||||
];
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const parameters =
|
||||
Object.keys(appliedParams).length !== 0
|
||||
? appliedParams
|
||||
: Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['order', order],
|
||||
['orderBy', orderBy],
|
||||
]);
|
||||
|
||||
const [divisionResponse, membersResponse] = await Promise.all([
|
||||
axios.get(`${corporateValue}/division`, { signal: controller.signal }),
|
||||
axios.get(`${corporateValue}/members`, {
|
||||
params: { ...parameters },
|
||||
signal: controller.signal,
|
||||
}),
|
||||
]);
|
||||
|
||||
setSearchParams(parameters);
|
||||
setDivisionData(divisionResponse.data);
|
||||
setMemberData(
|
||||
membersResponse.data.data.map((obj: any) => ({
|
||||
...obj,
|
||||
status:
|
||||
obj.status === 1 ? (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.16)',
|
||||
color: palette.dark.success.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(84, 214, 44, 0.32)',
|
||||
color: palette.dark.success.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Active
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
sx={{
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.16)',
|
||||
color: palette.dark.error.dark,
|
||||
paddingY: 0,
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgba(255, 72, 66, 0.32)',
|
||||
color: palette.dark.error.darker,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Inactive
|
||||
</Button>
|
||||
),
|
||||
}))
|
||||
);
|
||||
setPaginationTable(membersResponse.data);
|
||||
setRowsPerPage(membersResponse.data.per_page);
|
||||
|
||||
if (searchParams.get('page')) {
|
||||
// @ts-ignore
|
||||
const currentPage = parseInt(searchParams.get('page')) - 1;
|
||||
paginationTable.current_page = currentPage;
|
||||
setPage(currentPage);
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching data:', error.message);
|
||||
}
|
||||
})();
|
||||
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, [appliedParams, searchParams, order, orderBy, setSearchParams, corporateValue]);
|
||||
|
||||
return (
|
||||
<Page title="Dashboard">
|
||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||
<Stack direction="row" justifyContent="space-between">
|
||||
<Typography variant="h3" component="h1" paragraph>
|
||||
Dashboard
|
||||
</Typography>
|
||||
</Stack>
|
||||
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} lg={12} md={12}>
|
||||
<Table
|
||||
headCells={headCells}
|
||||
rows={memberData}
|
||||
orders={orders}
|
||||
paginations={paginations}
|
||||
loadings={loadings}
|
||||
params={params}
|
||||
searchs={searchs}
|
||||
filters={filters}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user