feat: dashboard 적용

main
minuk926 2 years ago
parent f0181e84ea
commit befc5e479f

@ -17,12 +17,22 @@ import {
REMOVE_ADMIN_JUDGE_DATA,
GET_JUDGE_LIST,
SAVE_JUDGE_RESULT,
SAVE_ADMIN_JUDGE_STDS
SAVE_ADMIN_JUDGE_STDS,
GET_DASHBOARD
} from 'commons/ApiUrl';
import { setRowId } from './common';
import FileSaver from 'file-saver';
import _ from 'lodash';
export async function findDashboard() {
const res = await axios.get(GET_DASHBOARD);
if (res.success) {
// res.data = res.data.map((d, idx) => ({ ...d, rowId: setRowId(params, idx) }));
return res;
}
return res;
}
// eslint-disable-next-line no-return-await
export async function findJudgeDatas(params) {
const res = await axios.get(GET_ADMIN_JUDGE_DATA_LIST, { params });

@ -4,9 +4,10 @@ export const LOGIN_URL = '/api/v1/ctgy/account/login';
export const GET_CMM_CODE_LIST = '/api/v1/biz/cmm/combo';
export const GET_FILE_DOWNLOAD = '/api/v1/ctgy/file/download/';
export const GET_DASHBOARD = '/api/v1/ctgy/dashboard';
// 공지사항
export const GET_PUBLIC_BOARD_LIST = '/api/v1/ctgy/pboard';
export const GET_PUBLIC_BOARD = '/api/v1/ctgy/pboard/';
export const SAVE_PUBLIC_BOARD_HIT_CNT = '/api/v1/ctgy/pboard/hit/';
export const SAVE_PUBLIC_BOARD = '/api/v1/ctgy/file/pboard';
export const REMOVE_PUBLIC_BOARD = '/api/v1/ctgy/file/pboard/';

@ -7,7 +7,7 @@ export const JWT_API = {
// like '/berry-material-react/react/default'
export const BASE_PATH = '';
export const DASHBOARD_PATH = '/dashboard/default';
export const DASHBOARD_PATH = '/dashboard';
const config = {
fontFamily: `'Roboto', sans-serif`,

@ -7,7 +7,6 @@ import LogoSection from '../LogoSection';
import ProfileSection from './ProfileSection';
import { useDispatch, useSelector } from 'store';
import { openDrawer } from 'store/slices/menu';
import useAuth from 'hooks/useAuth';
// assets
import { IconMenu2 } from '@tabler/icons';

@ -70,7 +70,6 @@ const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })(({
const MainLayout = () => {
const { accesstype } = useAuth();
console.log(`###############`, accesstype);
const theme = useTheme();
const matchDownMd = useMediaQuery(theme.breakpoints.down('lg'));
@ -119,8 +118,7 @@ const MainLayout = () => {
<Container maxWidth="lg">
<Breadcrumbs
separator={IconChevronRight}
navigation={accesstype === '001' ? { items: [admin] } : { items: [judge] }}
// navigation={accesstype === '001' ? { items: [dashboard, admin] } : { items: [judge] }}
navigation={accesstype === '001' ? { items: [dashboard, admin] } : { items: [dashboard, judge] }}
icon
title
rightAlign
@ -132,7 +130,7 @@ const MainLayout = () => {
<>
<Breadcrumbs
separator={IconChevronRight}
navigation={accesstype === '001' ? { items: [dashboard, admin] } : { items: [judge] }}
navigation={accesstype === '001' ? { items: [dashboard, admin] } : { items: [dashboard, judge] }}
icon
title
rightAlign

@ -58,8 +58,7 @@ const admin = {
title: <FormattedMessage id="admin-1" />,
type: 'item',
icon: icons.IconClipboardCheck,
url: '/publicBoard',
breadcrumbs: true
url: '/publicBoard'
},
{
/* 주정차 의견 진술 */
@ -160,14 +159,6 @@ const admin = {
url: '/user/management',
icon: icons.IconUserCheck
},
// {
// /* SMS 관리 */
// id: 'admin-6',
// title: <FormattedMessage id="admin-6" />,
// type: 'item',
// url: '/sms/management',
// icon: icons.IconMessage
// },
{
/* 게시판 관리 */
id: 'admin-7',

@ -1,39 +1,19 @@
// // third-party
// import { FormattedMessage } from 'react-intl';
//
// // assets
// import { IconDashboard, IconDeviceAnalytics } from '@tabler/icons';
//
// // constant
// const icons = {
// IconDashboard,
// IconDeviceAnalytics
// };
//
// // ==============================|| DASHBOARD MENU ITEMS ||============================== //
//
// const dashboard = {
// id: 'dashboard',
// title: <FormattedMessage id="dashboard" />,
// type: 'group',
// children: [
// {
// id: 'default',
// title: <FormattedMessage id="default" />,
// type: 'item',
// url: '/dashboard/default',
// icon: icons.IconDashboard,
// breadcrumbs: false
// },
// {
// id: 'analytics',
// title: <FormattedMessage id="analytics" />,
// type: 'item',
// url: '/dashboard/analytics',
// icon: icons.IconDeviceAnalytics,
// breadcrumbs: false
// }
// ]
// };
//
// export default dashboard;
// ==============================|| DASHBOARD MENU ITEMS ||============================== //
import { FormattedMessage } from 'react-intl';
const dashboard = {
id: 'dashboard',
// title: <FormattedMessage id="admin" />,
type: 'group',
children: [
{
id: 'dashboard',
title: <FormattedMessage id="dashboard" />,
type: 'item',
url: '/dashboard'
// breadcrumbs: true
}
]
};
export default dashboard;

@ -7,8 +7,7 @@ import AuthGuard from 'utils/route-guard/AuthGuard';
// sample page routing
const SamplePage = Loadable(lazy(() => import('views/sample-page')));
const DashboardDefault = Loadable(lazy(() => import('views/dashboard/Default')));
const DashboardAnalytics = Loadable(lazy(() => import('views/dashboard/Analytics')));
const Dashboard = Loadable(lazy(() => import('views/dashboard')));
// admin page routing
const PublicBoard = Loadable(lazy(() => import('views/biz/pboard/PublicBoard')));
@ -42,12 +41,8 @@ const MainRoutes = {
children: [
/* Dashboard */
{
path: '/dashboard/default',
element: <DashboardDefault />
},
{
path: '/dashboard/analytics',
element: <DashboardAnalytics />
path: '/dashboard',
element: <Dashboard />
},
/* 공지사항 */
{

@ -19,8 +19,7 @@ const GuestGuard = ({ children }) => {
useEffect(() => {
if (isLoggedIn) {
navigate('/publicBoard', { replace: true });
// navigate(DASHBOARD_PATH, { replace: true });
navigate(DASHBOARD_PATH, { replace: true });
}
}, [isLoggedIn, navigate]);

@ -109,6 +109,7 @@ EnhancedTableToolbar.propTypes = {
// project imports
const MuiDataGrid = ({
// apiRef = () => {},
gridHeight = 645,
isToolbar = false,
children = <div />,
isCheckbox = false,
@ -137,7 +138,7 @@ const MuiDataGrid = ({
return (
<Box
sx={{
height: 645,
height: gridHeight,
width: '100%',
marginTop: '10px',
'& .MuiDataGrid-root': {

@ -1,309 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Avatar, Button, CardActions, CardContent, Divider, Grid, Menu, MenuItem, Typography } from '@mui/material';
// project imports
import BajajAreaChartCard from './BajajAreaChartCard';
import MainCard from 'ui-component/cards/MainCard';
import SkeletonPopularCard from 'ui-component/cards/Skeleton/PopularCard';
import { gridSpacing } from 'store/constant';
// assets
import ChevronRightOutlinedIcon from '@mui/icons-material/ChevronRightOutlined';
import MoreHorizOutlinedIcon from '@mui/icons-material/MoreHorizOutlined';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
// ==============================|| DASHBOARD DEFAULT - POPULAR CARD ||============================== //
const PopularCard = ({ isLoading }) => {
const theme = useTheme();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<>
{isLoading ? (
<SkeletonPopularCard />
) : (
<MainCard content={false}>
<CardContent>
<Grid container spacing={gridSpacing}>
<Grid item xs={12}>
<Grid container alignContent="center" justifyContent="space-between">
<Grid item>
<Typography variant="h4">Popular Stocks</Typography>
</Grid>
<Grid item>
<MoreHorizOutlinedIcon
fontSize="small"
sx={{
color: theme.palette.primary[200],
cursor: 'pointer'
}}
aria-controls="menu-popular-card"
aria-haspopup="true"
onClick={handleClick}
/>
<Menu
id="menu-popular-card"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
variant="selectedMenu"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right'
}}
>
<MenuItem onClick={handleClose}> Today</MenuItem>
<MenuItem onClick={handleClose}> This Month</MenuItem>
<MenuItem onClick={handleClose}> This Year </MenuItem>
</Menu>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} sx={{ pt: '16px !important' }}>
<BajajAreaChartCard />
</Grid>
<Grid item xs={12}>
<Grid container direction="column">
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
Bajaj Finery
</Typography>
</Grid>
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
$1839.00
</Typography>
</Grid>
<Grid item>
<Avatar
variant="rounded"
sx={{
width: 16,
height: 16,
borderRadius: '5px',
backgroundColor: theme.palette.success.light,
color: theme.palette.success.dark,
ml: 2
}}
>
<KeyboardArrowUpOutlinedIcon fontSize="small" color="inherit" />
</Avatar>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<Typography variant="subtitle2" sx={{ color: 'success.dark' }}>
10% Profit
</Typography>
</Grid>
</Grid>
<Divider sx={{ my: 1.5 }} />
<Grid container direction="column">
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
TTML
</Typography>
</Grid>
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
$100.00
</Typography>
</Grid>
<Grid item>
<Avatar
variant="rounded"
sx={{
width: 16,
height: 16,
borderRadius: '5px',
backgroundColor: theme.palette.orange.light,
color: theme.palette.orange.dark,
marginLeft: 1.875
}}
>
<KeyboardArrowDownOutlinedIcon fontSize="small" color="inherit" />
</Avatar>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<Typography variant="subtitle2" sx={{ color: theme.palette.orange.dark }}>
10% loss
</Typography>
</Grid>
</Grid>
<Divider sx={{ my: 1.5 }} />
<Grid container direction="column">
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
Reliance
</Typography>
</Grid>
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
$200.00
</Typography>
</Grid>
<Grid item>
<Avatar
variant="rounded"
sx={{
width: 16,
height: 16,
borderRadius: '5px',
backgroundColor: theme.palette.success.light,
color: theme.palette.success.dark,
ml: 2
}}
>
<KeyboardArrowUpOutlinedIcon fontSize="small" color="inherit" />
</Avatar>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<Typography variant="subtitle2" sx={{ color: theme.palette.success.dark }}>
10% Profit
</Typography>
</Grid>
</Grid>
<Divider sx={{ my: 1.5 }} />
<Grid container direction="column">
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
TTML
</Typography>
</Grid>
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
$189.00
</Typography>
</Grid>
<Grid item>
<Avatar
variant="rounded"
sx={{
width: 16,
height: 16,
borderRadius: '5px',
backgroundColor: theme.palette.orange.light,
color: theme.palette.orange.dark,
ml: 2
}}
>
<KeyboardArrowDownOutlinedIcon fontSize="small" color="inherit" />
</Avatar>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<Typography variant="subtitle2" sx={{ color: theme.palette.orange.dark }}>
10% loss
</Typography>
</Grid>
</Grid>
<Divider sx={{ my: 1.5 }} />
<Grid container direction="column">
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
Stolon
</Typography>
</Grid>
<Grid item>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="subtitle1" color="inherit">
$189.00
</Typography>
</Grid>
<Grid item>
<Avatar
variant="rounded"
sx={{
width: 16,
height: 16,
borderRadius: '5px',
backgroundColor: theme.palette.orange.light,
color: theme.palette.orange.dark,
ml: 2
}}
>
<KeyboardArrowDownOutlinedIcon fontSize="small" color="inherit" />
</Avatar>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<Typography variant="subtitle2" sx={{ color: theme.palette.orange.dark }}>
10% loss
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
</CardContent>
<CardActions sx={{ p: 1.25, pt: 0, justifyContent: 'center' }}>
<Button size="small" disableElevation>
View All
<ChevronRightOutlinedIcon />
</Button>
</CardActions>
</MainCard>
)}
</>
);
};
PopularCard.propTypes = {
isLoading: PropTypes.bool
};
export default PopularCard;

@ -1,134 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Grid, MenuItem, TextField, Typography } from '@mui/material';
// third-party
import ApexCharts from 'apexcharts';
import Chart from 'react-apexcharts';
// project imports
import useConfig from 'hooks/useConfig';
import SkeletonTotalGrowthBarChart from 'ui-component/cards/Skeleton/TotalGrowthBarChart';
import MainCard from 'ui-component/cards/MainCard';
import { gridSpacing } from 'store/constant';
// chart data
import chartData from './chart-data/total-growth-bar-chart';
const status = [
{
value: 'today',
label: 'Today'
},
{
value: 'month',
label: 'This Month'
},
{
value: 'year',
label: 'This Year'
}
];
// ==============================|| DASHBOARD DEFAULT - TOTAL GROWTH BAR CHART ||============================== //
const TotalGrowthBarChart = ({ isLoading }) => {
const [value, setValue] = React.useState('today');
const theme = useTheme();
const { navType } = useConfig();
const { primary } = theme.palette.text;
const darkLight = theme.palette.dark.light;
const grey200 = theme.palette.grey[200];
const grey500 = theme.palette.grey[500];
const primary200 = theme.palette.primary[200];
const primaryDark = theme.palette.primary.dark;
const secondaryMain = theme.palette.secondary.main;
const secondaryLight = theme.palette.secondary.light;
React.useEffect(() => {
const newChartData = {
...chartData.options,
colors: [primary200, primaryDark, secondaryMain, secondaryLight],
xaxis: {
labels: {
style: {
colors: [primary, primary, primary, primary, primary, primary, primary, primary, primary, primary, primary, primary]
}
}
},
yaxis: {
labels: {
style: {
colors: [primary]
}
}
},
grid: {
borderColor: navType === 'dark' ? darkLight + 20 : grey200
},
tooltip: {
theme: navType === 'dark' ? 'dark' : 'light'
},
legend: {
labels: {
colors: grey500
}
}
};
// do not load chart when loading
if (!isLoading) {
ApexCharts.exec(`bar-chart`, 'updateOptions', newChartData);
}
}, [navType, primary200, primaryDark, secondaryMain, secondaryLight, primary, darkLight, grey200, isLoading, grey500]);
return (
<>
{isLoading ? (
<SkeletonTotalGrowthBarChart />
) : (
<MainCard>
<Grid container spacing={gridSpacing}>
<Grid item xs={12}>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Grid container direction="column" spacing={1}>
<Grid item>
<Typography variant="subtitle2">Total Growth</Typography>
</Grid>
<Grid item>
<Typography variant="h3">$2,324.00</Typography>
</Grid>
</Grid>
</Grid>
<Grid item>
<TextField id="standard-select-currency" select value={value} onChange={(e) => setValue(e.target.value)}>
{status.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<Chart {...chartData} />
</Grid>
</Grid>
</MainCard>
)}
</>
);
};
TotalGrowthBarChart.propTypes = {
isLoading: PropTypes.bool
};
export default TotalGrowthBarChart;

@ -0,0 +1,93 @@
import { useEffect, useState, useCallback } from 'react';
// material-ui
import { Grid, Link, Typography } from '@mui/material';
// project imports
import { gridSpacing } from 'store/constant';
import { findDashboard } from 'apis/judge';
import MuiDataGrid from 'views/cmm/mui-grid/MuiDataGrid';
import { IconFileText } from '@tabler/icons';
// ==============================|| DEFAULT DASHBOARD ||============================== //
const Dashboard = () => {
const [isLoading, setLoading] = useState(true);
const [totalCount, setTotalCount] = useState(0);
const [rowsState, setRowsState] = useState({
page: 0,
pageSize: 6,
rows: []
// loading: false
});
const columns = [
{ headerName: 'No.', headerAlign: 'center', field: 'rowId', align: 'center', width: 80 },
{
headerName: '업무구분',
headerAlign: 'center',
field: 'inDept',
align: 'center',
width: 120
},
{
headerName: '제목',
headerAlign: 'center',
field: 'inTitle',
width: 400,
renderCell: (params) => (
<Link underline="hover" href="#">
{params.value}
</Link>
)
},
{
headerName: '첨부파일',
headerAlign: 'center',
field: 'inFile',
align: 'center',
width: 100,
renderCell: (params) => (
// console.log(params.row.inFilename);
<>{params.row.inFilename ? <IconFileText stroke={1.5} size="1rem" /> : ''}</>
)
},
{ headerName: '작성일자', headerAlign: 'center', field: 'inNalja', align: 'center', width: 130 },
{ headerName: '조회수', headerAlign: 'center', field: 'inHit', align: 'right', width: 100 }
];
const search = useCallback(() => {
// const params = {
// page: rowsState.page,
// size: rowsState.pageSize
// };
findDashboard().then((res) => {
console.log(res);
if (res && res.data) {
const rows = res.data?.pBoardList.content.map((d, idx) => ({ ...d, rowId: idx + 1 }));
setTotalCount(rows.count);
setRowsState((prevState) => ({ ...prevState, rows }));
}
});
}, []);
useEffect(() => {
setLoading(false);
search();
}, [search]);
return (
<Grid container spacing={gridSpacing}>
<Grid item xs={12}>
<Typography variant="h3">공지사항</Typography>
<MuiDataGrid columns={columns} rowsState={rowsState} totalCount={totalCount || 0} setRowsState={setRowsState} gridHeight={300} />
</Grid>
<Grid item xs={12}>
<Typography variant="h3">심사자현황</Typography>
</Grid>
</Grid>
);
};
export default Dashboard;
Loading…
Cancel
Save