관리자 메인 디자인

thkim
Lim\jun 2024-02-06 17:35:59 +09:00
parent 7a141fff89
commit 3bf8cb065a
4 changed files with 285 additions and 201 deletions

View File

@ -44,11 +44,11 @@ const AnalyticEcommerce = ({ color, title, count, percentage, isLoss, extra }) =
</Stack>
<Box sx={{ pt: 2.25 }}>
<Typography variant="caption" color="textSecondary">
You made an extra{' '}
지난달{' '}
<Typography component="span" variant="caption" sx={{ color: `${color || 'primary'}.main` }}>
{extra}
</Typography>{' '}
this year
건이 추가되었습니다.
</Typography>
</Box>
</MainCard>

View File

@ -0,0 +1,166 @@
import PropTypes from 'prop-types';
import { useState } from 'react';
import { Link as RouterLink } from 'react-router-dom';
// material-ui
import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
function createData(trackingNo, title, dt, name) {
return { trackingNo, title, dt, name };
}
const rows = [
createData(1, '흙막이 가시설 띠장 전단 설계시 플래지 ...', '2024-02-04 13:22', '홍길동'),
createData(2, '콘크리트 벽체 설계기준 적용 유무 확인 ...', '2024-02-04 13:22', '홍길동'),
createData(3, '한중콘크리트 초기양생 관련', '2024-02-04 13:22', '홍길동'),
createData(4, 'KDS 21 30 00 : 2022가설흙...', '2024-02-04 13:22', '홍길동'),
createData(5, '인테리어필름 시방서 관련', '2024-02-04 13:22', '홍길동'),
createData(6, '고온고압증기양생기포콘크리트(ALC) 구조', '2024-02-04 13:22', '홍길동'),
createData(7, '지반을 최저등급으로 가정한 경우란', '2024-02-04 13:22', '홍길동')
];
function descendingComparator(a, b, orderBy) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
function getComparator(order, orderBy) {
return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy);
}
function stableSort(array, comparator) {
const stabilizedThis = array.map((el, index) => [el, index]);
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0]);
if (order !== 0) {
return order;
}
return a[1] - b[1];
});
return stabilizedThis.map((el) => el[0]);
}
// ==============================|| ORDER TABLE - HEADER CELL ||============================== //
const headCells = [
{
id: 'trackingNo',
align: 'left',
disablePadding: false,
label: 'No.'
},
{
id: 'title',
align: 'center',
disablePadding: true,
label: '제목'
},
{
id: 'dt',
align: 'center',
disablePadding: false,
label: '작성일자'
},
{
id: 'name',
align: 'center',
disablePadding: false,
label: '작성자'
},
];
// ==============================|| ORDER TABLE - HEADER ||============================== //
function OrderTableHead({ order, orderBy }) {
return (
<TableHead>
<TableRow>
{headCells.map((headCell) => (
<TableCell
key={headCell.id}
align={headCell.align}
padding={headCell.disablePadding ? 'none' : 'normal'}
sortDirection={orderBy === headCell.id ? order : false}
sx={{ width:headCell.id === 'trackingNo' ? '10%' :
headCell.id === 'title' ? '50%' :
headCell.id === 'dt' ? '25%' : '15%', }}
>
{headCell.label}
</TableCell>
))}
</TableRow>
</TableHead>
);
}
OrderTableHead.propTypes = {
order: PropTypes.string,
orderBy: PropTypes.string
};
// ==============================|| ORDER TABLE ||============================== //
export default function OrderTable() {
const [order] = useState('asc');
const [orderBy] = useState('trackingNo');
const [selected] = useState([]);
const isSelected = (trackingNo) => selected.indexOf(trackingNo) !== -1;
return (
<Box>
<TableContainer
sx={{
width: '100%',
overflowX: 'auto',
position: 'relative',
display: 'block',
maxWidth: '100%',
'& td, & th': { whiteSpace: 'nowrap' }
}}
>
<Table
aria-labelledby="tableTitle"
sx={{
'& .MuiTableCell-root:first-of-type': {
pl: 2
},
'& .MuiTableCell-root:last-of-type': {
pr: 0
}
}}
>
<OrderTableHead order={order} orderBy={orderBy} />
<TableBody>
{stableSort(rows, getComparator(order, orderBy)).map((row, index) => {
const isItemSelected = isSelected(row.trackingNo);
const labelId = `enhanced-table-checkbox-${index}`;
return (
<TableRow
hover
role="checkbox"
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
aria-checked={isItemSelected}
tabIndex={-1}
key={row.trackingNo}
selected={isItemSelected}
>
<TableCell width="10%" align="left" component="th" id={labelId} scope="row">{row.trackingNo}</TableCell>
<TableCell width="50%" align="left"><Link color="secondary" component={RouterLink} to="" sx={{ overflow: 'hidden', textOverflow: 'ellipsis', display: 'block'}}>{row.title}</Link></TableCell>
<TableCell width="25%" align="center">{row.dt}</TableCell>
<TableCell width="15%" align="center">{row.name}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</Box>
);
}

View File

@ -25,8 +25,10 @@ import {
Typography
} from '@mui/material';
import MainCard from 'components/cards/MainCard';
import BbsTable from './BbsTable';
import IncomeAreaChart from './IncomeAreaChart';
import MonthlyBarChart from './MonthlyBarChart';
import ReportAreaChart from './ReportAreaChart';
import AnalyticEcommerce from 'components/cards/AnalyticEcommerce';
import {default as EgovLeftNav} from 'components/leftmenu/EgovLeftNavAdmin';
@ -374,16 +376,16 @@ function EgovAdminScheduleList(props) {
{/* <Typography variant="h5">Dashboard</Typography>*/}
{/*</Grid>*/}
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title="총접속자수" count="4,42,236" percentage={59.3} extra="35,000" />
<AnalyticEcommerce title="총접속자수 (금월)" count="442,236" percentage={59.3} extra="35,000" />
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title="총 DB구축 건수" count="78,250" percentage={70.5} extra="8,900" />
<AnalyticEcommerce title="건설기준 DB구축 (금월)" count="78,250" percentage={70.5} extra="8,900" />
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title="최근 1달 기준코드 등록건수" count="18,800" percentage={27.4} isLoss color="warning" extra="1,943" />
<AnalyticEcommerce title="기준코드 등록건수 (금월)" count="18,800" percentage={27.4} isLoss color="warning" extra="1,943" />
</Grid>
<Grid item xs={12} sm={6} md={4} lg={3}>
<AnalyticEcommerce title="미답변 민원건수" count="$35,078" percentage={27.4} isLoss color="warning" extra="$20,395" />
<AnalyticEcommerce title="민원건수 (금월)" count="5" percentage={80} isLoss color="warning" extra="1" />
</Grid>
<Grid item md={8} sx={{ display: { sm: 'none', md: 'block', lg: 'none' } }} />
@ -392,7 +394,7 @@ function EgovAdminScheduleList(props) {
<Grid item xs={12} md={7} lg={8}>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="h5">Unique Visitor</Typography>
<Typography variant="h5">방문자</Typography>
</Grid>
<Grid item>
<Stack direction="row" alignItems="center" spacing={0}>
@ -424,213 +426,46 @@ function EgovAdminScheduleList(props) {
<Grid item xs={12} md={5} lg={4}>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="h5">Income Overview</Typography>
<Typography variant="h5">다운로드 현황</Typography>
</Grid>
<Grid item />
</Grid>
<MainCard sx={{ mt: 2 }} content={false}>
<Box sx={{ p: 3, pb: 0 }}>
<Stack spacing={2}>
<Typography variant="h6" color="textSecondary">
This Week Statistics
<Typography variant="h3" color="textSecondary">
주간 현황
</Typography>
<Typography variant="h3">$7,650</Typography>
<Typography variant="h6"> 2,300</Typography>
</Stack>
</Box>
<MonthlyBarChart />
</MainCard>
</Grid>
{/*/!* row 3 *!/*/}
{/*<Grid item xs={12} md={7} lg={8}>*/}
{/* <Grid container alignItems="center" justifyContent="space-between">*/}
{/* <Grid item>*/}
{/* <Typography variant="h5">Recent Orders</Typography>*/}
{/* </Grid>*/}
{/* <Grid item />*/}
{/* </Grid>*/}
{/* <MainCard sx={{ mt: 2 }} content={false}>*/}
{/* <OrdersTable />*/}
{/* </MainCard>*/}
{/*</Grid>*/}
{/*<Grid item xs={12} md={5} lg={4}>*/}
{/* <Grid container alignItems="center" justifyContent="space-between">*/}
{/* <Grid item>*/}
{/* <Typography variant="h5">Analytics Report</Typography>*/}
{/* </Grid>*/}
{/* <Grid item />*/}
{/* </Grid>*/}
{/* <MainCard sx={{ mt: 2 }} content={false}>*/}
{/* <List sx={{ p: 0, '& .MuiListItemButton-root': { py: 2 } }}>*/}
{/* <ListItemButton divider>*/}
{/* <ListItemText primary="Company Finance Growth" />*/}
{/* <Typography variant="h5">+45.14%</Typography>*/}
{/* </ListItemButton>*/}
{/* <ListItemButton divider>*/}
{/* <ListItemText primary="Company Expenses Ratio" />*/}
{/* <Typography variant="h5">0.58%</Typography>*/}
{/* </ListItemButton>*/}
{/* <ListItemButton>*/}
{/* <ListItemText primary="Business Risk Cases" />*/}
{/* <Typography variant="h5">Low</Typography>*/}
{/* </ListItemButton>*/}
{/* </List>*/}
{/* <ReportAreaChart />*/}
{/* </MainCard>*/}
{/*</Grid>*/}
{/*/!* row 4 *!/*/}
{/*<Grid item xs={12} md={7} lg={8}>*/}
{/* <Grid container alignItems="center" justifyContent="space-between">*/}
{/* <Grid item>*/}
{/* <Typography variant="h5">Sales Report</Typography>*/}
{/* </Grid>*/}
{/* <Grid item>*/}
{/* <TextField*/}
{/* id="standard-select-currency"*/}
{/* size="small"*/}
{/* select*/}
{/* value={value}*/}
{/* onChange={(e) => setValue(e.target.value)}*/}
{/* sx={{ '& .MuiInputBase-input': { py: 0.5, fontSize: '0.875rem' } }}*/}
{/* >*/}
{/* {status.map((option) => (*/}
{/* <MenuItem key={option.value} value={option.value}>*/}
{/* {option.label}*/}
{/* </MenuItem>*/}
{/* ))}*/}
{/* </TextField>*/}
{/* </Grid>*/}
{/* </Grid>*/}
{/* <MainCard sx={{ mt: 1.75 }}>*/}
{/* <Stack spacing={1.5} sx={{ mb: -12 }}>*/}
{/* <Typography variant="h6" color="secondary">*/}
{/* Net Profit*/}
{/* </Typography>*/}
{/* <Typography variant="h4">$1560</Typography>*/}
{/* </Stack>*/}
{/* <SalesColumnChart />*/}
{/* </MainCard>*/}
{/*</Grid>*/}
{/*<Grid item xs={12} md={5} lg={4}>*/}
{/* <Grid container alignItems="center" justifyContent="space-between">*/}
{/* <Grid item>*/}
{/* <Typography variant="h5">Transaction History</Typography>*/}
{/* </Grid>*/}
{/* <Grid item />*/}
{/* </Grid>*/}
{/* <MainCard sx={{ mt: 2 }} content={false}>*/}
{/* <List*/}
{/* component="nav"*/}
{/* sx={{*/}
{/* px: 0,*/}
{/* py: 0,*/}
{/* '& .MuiListItemButton-root': {*/}
{/* py: 1.5,*/}
{/* '& .MuiAvatar-root': avatarSX,*/}
{/* '& .MuiListItemSecondaryAction-root': { ...actionSX, position: 'relative' }*/}
{/* }*/}
{/* }}*/}
{/* >*/}
{/* <ListItemButton divider>*/}
{/* <ListItemAvatar>*/}
{/* <Avatar*/}
{/* sx={{*/}
{/* color: 'success.main',*/}
{/* bgcolor: 'success.lighter'*/}
{/* }}*/}
{/* >*/}
{/* <GiftOutlined />*/}
{/* </Avatar>*/}
{/* </ListItemAvatar>*/}
{/* <ListItemText primary={<Typography variant="subtitle1">Order #002434</Typography>} secondary="Today, 2:00 AM" />*/}
{/* <ListItemSecondaryAction>*/}
{/* <Stack alignItems="flex-end">*/}
{/* <Typography variant="subtitle1" noWrap>*/}
{/* + $1,430*/}
{/* </Typography>*/}
{/* <Typography variant="h6" color="secondary" noWrap>*/}
{/* 78%*/}
{/* </Typography>*/}
{/* </Stack>*/}
{/* </ListItemSecondaryAction>*/}
{/* </ListItemButton>*/}
{/* <ListItemButton divider>*/}
{/* <ListItemAvatar>*/}
{/* <Avatar*/}
{/* sx={{*/}
{/* color: 'primary.main',*/}
{/* bgcolor: 'primary.lighter'*/}
{/* }}*/}
{/* >*/}
{/* <MessageOutlined />*/}
{/* </Avatar>*/}
{/* </ListItemAvatar>*/}
{/* <ListItemText primary={<Typography variant="subtitle1">Order #984947</Typography>} secondary="5 August, 1:45 PM" />*/}
{/* <ListItemSecondaryAction>*/}
{/* <Stack alignItems="flex-end">*/}
{/* <Typography variant="subtitle1" noWrap>*/}
{/* + $302*/}
{/* </Typography>*/}
{/* <Typography variant="h6" color="secondary" noWrap>*/}
{/* 8%*/}
{/* </Typography>*/}
{/* </Stack>*/}
{/* </ListItemSecondaryAction>*/}
{/* </ListItemButton>*/}
{/* <ListItemButton>*/}
{/* <ListItemAvatar>*/}
{/* <Avatar*/}
{/* sx={{*/}
{/* color: 'error.main',*/}
{/* bgcolor: 'error.lighter'*/}
{/* }}*/}
{/* >*/}
{/* <SettingOutlined />*/}
{/* </Avatar>*/}
{/* </ListItemAvatar>*/}
{/* <ListItemText primary={<Typography variant="subtitle1">Order #988784</Typography>} secondary="7 hours ago" />*/}
{/* <ListItemSecondaryAction>*/}
{/* <Stack alignItems="flex-end">*/}
{/* <Typography variant="subtitle1" noWrap>*/}
{/* + $682*/}
{/* </Typography>*/}
{/* <Typography variant="h6" color="secondary" noWrap>*/}
{/* 16%*/}
{/* </Typography>*/}
{/* </Stack>*/}
{/* </ListItemSecondaryAction>*/}
{/* </ListItemButton>*/}
{/* </List>*/}
{/* </MainCard>*/}
{/* <MainCard sx={{ mt: 2 }}>*/}
{/* <Stack spacing={3}>*/}
{/* <Grid container justifyContent="space-between" alignItems="center">*/}
{/* <Grid item>*/}
{/* <Stack>*/}
{/* <Typography variant="h5" noWrap>*/}
{/* Help & Support Chat*/}
{/* </Typography>*/}
{/* <Typography variant="caption" color="secondary" noWrap>*/}
{/* Typical replay within 5 min*/}
{/* </Typography>*/}
{/* </Stack>*/}
{/* </Grid>*/}
{/* <Grid item>*/}
{/* <AvatarGroup sx={{ '& .MuiAvatar-root': { width: 32, height: 32 } }}>*/}
{/* <Avatar alt="Remy Sharp" src={avatar1} />*/}
{/* <Avatar alt="Travis Howard" src={avatar2} />*/}
{/* <Avatar alt="Cindy Baker" src={avatar3} />*/}
{/* <Avatar alt="Agnes Walker" src={avatar4} />*/}
{/* </AvatarGroup>*/}
{/* </Grid>*/}
{/* </Grid>*/}
{/* <Button size="small" variant="contained" sx={{ textTransform: 'capitalize' }}>*/}
{/* Need Help?*/}
{/* </Button>*/}
{/* </Stack>*/}
{/* </MainCard>*/}
{/*</Grid>*/}
{/* row 3 */}
<Grid item xs={12} md={7} lg={8}>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="h5">최근 문의사항</Typography>
</Grid>
<Grid item />
</Grid>
<MainCard sx={{ mt: 2 }} content={false}>
<BbsTable />
</MainCard>
</Grid>
<Grid item xs={12} md={5} lg={4}>
<Grid container alignItems="center" justifyContent="space-between">
<Grid item>
<Typography variant="h5">접속 방법</Typography>
</Grid>
<Grid item />
</Grid>
<MainCard sx={{ mt: 2 }} content={false}>
<ReportAreaChart />
</MainCard>
</Grid>
</Grid>

View File

@ -0,0 +1,83 @@
import { useEffect, useState } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
// third-party
import ReactApexChart from 'react-apexcharts';
// chart options
const areaChartOptions = {
chart: {
type: 'donut',
},
plotOptions: {
pie: {
startAngle: -90,
endAngle: 90,
offsetY: 10,
expandOnClick:false,
}
},
dataLabels: {
enabled: true
},
title: {
text: '2024년 2월',
align: 'center'
},
responsive: [{
breakpoint: 480,
options: {
chart: {
width: 200
},
legend: {
position: 'bottom'
}
}
}],
grid: {
padding: {
bottom: -150
}
},
};
// ==============================|| REPORT AREA CHART ||============================== //
const ReportAreaChart = () => {
const theme = useTheme();
const { primary, secondary } = theme.palette.text;
const line = theme.palette.divider;
const [options, setOptions] = useState(areaChartOptions);
useEffect(() => {
setOptions((prevState) => ({
...prevState,
labels: ['PC', 'Mobile'],
colors: ['#448EF7', '#FFC107'],
// colors: [theme.palette.warning.main],
grid: {
borderColor: line
},
tooltip: {
theme: 'light'
},
legend: {
position: 'bottom',
labels: {
colors: 'grey.500'
}
}
}));
}, [primary, secondary, line, theme]);
const [series] = useState([90, 10]);
return <ReactApexChart options={options} series={series} type="donut" />;
};
export default ReportAreaChart;