Dashboard 중간저장
parent
c7440cbc0d
commit
33f3654222
File diff suppressed because it is too large
Load Diff
|
|
@ -3,6 +3,8 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ant-design/colors": "^6.0.0",
|
||||||
|
"@ant-design/icons": "^4.7.0",
|
||||||
"@emotion/react": "^11.11.3",
|
"@emotion/react": "^11.11.3",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
|
|
@ -13,16 +15,20 @@
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
"date-fns": "^3.2.0",
|
"date-fns": "^3.2.0",
|
||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.9.0",
|
"react-bootstrap": "^2.9.0",
|
||||||
"react-csv": "^2.2.2",
|
"react-csv": "^2.2.2",
|
||||||
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-datepicker": "^4.8.0",
|
"react-datepicker": "^4.8.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-element-to-jsx-string": "^15.0.0",
|
||||||
"react-icons": "^4.11.0",
|
"react-icons": "^4.11.0",
|
||||||
"react-loader-spinner": "^5.4.5",
|
"react-loader-spinner": "^5.4.5",
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-router-dom": "^6.4.0",
|
"react-router-dom": "^6.4.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
"recharts": "^2.10.3",
|
"recharts": "^2.10.3",
|
||||||
"styled-components": "^6.0.9",
|
"styled-components": "^6.0.9",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import RootRoutes from './routes';
|
import RootRoutes from './routes';
|
||||||
|
import ThemeCustomization from 'themes';
|
||||||
|
import ScrollTop from 'components/ScrollTop';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
@ -12,9 +14,11 @@ import './css/Custom/customMain.css'
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="wrap">
|
<ThemeCustomization>
|
||||||
<RootRoutes />
|
<ScrollTop>
|
||||||
</div>
|
<RootRoutes />
|
||||||
|
</ScrollTop>
|
||||||
|
</ThemeCustomization>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
// material-ui
|
||||||
|
import { Box, Chip, Grid, Stack, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
// project import
|
||||||
|
import MainCard from 'components/cards/MainCard';
|
||||||
|
|
||||||
|
// assets
|
||||||
|
import { RiseOutlined, FallOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
|
// ==============================|| STATISTICS - ECOMMERCE CARD ||============================== //
|
||||||
|
|
||||||
|
const AnalyticEcommerce = ({ color, title, count, percentage, isLoss, extra }) => (
|
||||||
|
<MainCard contentSX={{ p: 2.25 }}>
|
||||||
|
<Stack spacing={0.5}>
|
||||||
|
<Typography variant="h6" color="textSecondary">
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
<Grid container alignItems="center">
|
||||||
|
<Grid item>
|
||||||
|
<Typography variant="h4" color="inherit">
|
||||||
|
{count}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
{percentage && (
|
||||||
|
<Grid item>
|
||||||
|
<Chip
|
||||||
|
variant="combined"
|
||||||
|
color={color}
|
||||||
|
icon={
|
||||||
|
<>
|
||||||
|
{!isLoss && <RiseOutlined style={{ fontSize: '0.75rem', color: 'inherit' }} />}
|
||||||
|
{isLoss && <FallOutlined style={{ fontSize: '0.75rem', color: 'inherit' }} />}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
label={`${percentage}%`}
|
||||||
|
sx={{ ml: 1.25, pl: 1 }}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</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>
|
||||||
|
);
|
||||||
|
|
||||||
|
AnalyticEcommerce.propTypes = {
|
||||||
|
color: PropTypes.string,
|
||||||
|
title: PropTypes.string,
|
||||||
|
count: PropTypes.string,
|
||||||
|
percentage: PropTypes.number,
|
||||||
|
isLoss: PropTypes.bool,
|
||||||
|
extra: PropTypes.oneOfType([PropTypes.node, PropTypes.string])
|
||||||
|
};
|
||||||
|
|
||||||
|
AnalyticEcommerce.defaultProps = {
|
||||||
|
color: 'primary'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AnalyticEcommerce;
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { forwardRef } from 'react';
|
||||||
|
|
||||||
|
// material-ui
|
||||||
|
import { useTheme } from '@mui/material/styles';
|
||||||
|
import { Card, CardContent, CardHeader, Divider, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
// project import
|
||||||
|
import Highlighter from '../third-party/Highlighter';
|
||||||
|
|
||||||
|
// header style
|
||||||
|
const headerSX = {
|
||||||
|
p: 2.5,
|
||||||
|
'& .MuiCardHeader-action': { m: '0px auto', alignSelf: 'center' }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ==============================|| CUSTOM - MAIN CARD ||============================== //
|
||||||
|
|
||||||
|
const MainCard = forwardRef(
|
||||||
|
(
|
||||||
|
{
|
||||||
|
border = true,
|
||||||
|
boxShadow,
|
||||||
|
children,
|
||||||
|
content = true,
|
||||||
|
contentSX = {},
|
||||||
|
darkTitle,
|
||||||
|
elevation,
|
||||||
|
secondary,
|
||||||
|
shadow,
|
||||||
|
sx = {},
|
||||||
|
title,
|
||||||
|
codeHighlight,
|
||||||
|
...others
|
||||||
|
},
|
||||||
|
ref
|
||||||
|
) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
boxShadow = theme.palette.mode === 'dark' ? boxShadow || true : boxShadow;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
elevation={elevation || 0}
|
||||||
|
ref={ref}
|
||||||
|
{...others}
|
||||||
|
sx={{
|
||||||
|
border: border ? '1px solid' : 'none',
|
||||||
|
borderRadius: 2,
|
||||||
|
borderColor: theme.palette.mode === 'dark' ? theme.palette.divider : theme.palette.grey.A800,
|
||||||
|
boxShadow: boxShadow && (!border || theme.palette.mode === 'dark') ? shadow || theme.customShadows.z1 : 'inherit',
|
||||||
|
':hover': {
|
||||||
|
boxShadow: boxShadow ? shadow || theme.customShadows.z1 : 'inherit'
|
||||||
|
},
|
||||||
|
'& pre': {
|
||||||
|
m: 0,
|
||||||
|
p: '16px !important',
|
||||||
|
fontFamily: theme.typography.fontFamily,
|
||||||
|
fontSize: '0.75rem'
|
||||||
|
},
|
||||||
|
...sx
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* card header and action */}
|
||||||
|
{!darkTitle && title && (
|
||||||
|
<CardHeader sx={headerSX} titleTypographyProps={{ variant: 'subtitle1' }} title={title} action={secondary} />
|
||||||
|
)}
|
||||||
|
{darkTitle && title && <CardHeader sx={headerSX} title={<Typography variant="h3">{title}</Typography>} action={secondary} />}
|
||||||
|
|
||||||
|
{/* card content */}
|
||||||
|
{content && <CardContent sx={contentSX}>{children}</CardContent>}
|
||||||
|
{!content && children}
|
||||||
|
|
||||||
|
{/* card footer - clipboard & highlighter */}
|
||||||
|
{codeHighlight && (
|
||||||
|
<>
|
||||||
|
<Divider sx={{ borderStyle: 'dashed' }} />
|
||||||
|
<Highlighter codeHighlight={codeHighlight} main>
|
||||||
|
{children}
|
||||||
|
</Highlighter>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
MainCard.propTypes = {
|
||||||
|
border: PropTypes.bool,
|
||||||
|
boxShadow: PropTypes.bool,
|
||||||
|
contentSX: PropTypes.object,
|
||||||
|
darkTitle: PropTypes.bool,
|
||||||
|
divider: PropTypes.bool,
|
||||||
|
elevation: PropTypes.number,
|
||||||
|
secondary: PropTypes.node,
|
||||||
|
shadow: PropTypes.string,
|
||||||
|
sx: PropTypes.object,
|
||||||
|
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
codeHighlight: PropTypes.bool,
|
||||||
|
content: PropTypes.bool,
|
||||||
|
children: PropTypes.node
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MainCard;
|
||||||
65
egovframe-template-simple-react-contribution/src/components/third-party/Highlighter.js
vendored
Normal file
65
egovframe-template-simple-react-contribution/src/components/third-party/Highlighter.js
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
// material-ui
|
||||||
|
import { Box, CardActions, Collapse, Divider, IconButton, Tooltip } from '@mui/material';
|
||||||
|
|
||||||
|
// third-party
|
||||||
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
|
import reactElementToJSXString from 'react-element-to-jsx-string';
|
||||||
|
|
||||||
|
// project import
|
||||||
|
import SyntaxHighlight from 'utils/SyntaxHighlight';
|
||||||
|
|
||||||
|
// assets
|
||||||
|
import { CodeOutlined, CopyOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
|
// ==============================|| CLIPBOARD & HIGHLIGHTER ||============================== //
|
||||||
|
|
||||||
|
const Highlighter = ({ children }) => {
|
||||||
|
const [highlight, setHighlight] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ position: 'relative' }}>
|
||||||
|
<CardActions sx={{ justifyContent: 'flex-end', p: 1, mb: highlight ? 1 : 0 }}>
|
||||||
|
<Box sx={{ display: 'flex', position: 'inherit', right: 0, top: 6 }}>
|
||||||
|
<CopyToClipboard text={reactElementToJSXString(children, { showFunctions: true, maxInlineAttributesLineLength: 100 })}>
|
||||||
|
<Tooltip title="Copy the source" placement="top-end">
|
||||||
|
<IconButton color="secondary" size="small" sx={{ fontSize: '0.875rem' }}>
|
||||||
|
<CopyOutlined />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</CopyToClipboard>
|
||||||
|
<Divider orientation="vertical" variant="middle" flexItem sx={{ mx: 1 }} />
|
||||||
|
<Tooltip title="Show the source" placement="top-end">
|
||||||
|
<IconButton
|
||||||
|
sx={{ fontSize: '0.875rem' }}
|
||||||
|
size="small"
|
||||||
|
color={highlight ? 'primary' : 'secondary'}
|
||||||
|
onClick={() => setHighlight(!highlight)}
|
||||||
|
>
|
||||||
|
<CodeOutlined />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</CardActions>
|
||||||
|
<Collapse in={highlight}>
|
||||||
|
{highlight && (
|
||||||
|
<SyntaxHighlight>
|
||||||
|
{reactElementToJSXString(children, {
|
||||||
|
showFunctions: true,
|
||||||
|
showDefaultProps: false,
|
||||||
|
maxInlineAttributesLineLength: 100
|
||||||
|
})}
|
||||||
|
</SyntaxHighlight>
|
||||||
|
)}
|
||||||
|
</Collapse>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Highlighter.propTypes = {
|
||||||
|
children: PropTypes.node
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Highlighter;
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
// third-party
|
||||||
|
import SyntaxHighlighter from 'react-syntax-highlighter';
|
||||||
|
import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/hljs';
|
||||||
|
|
||||||
|
// ==============================|| CODE HIGHLIGHTER ||============================== //
|
||||||
|
|
||||||
|
export default function SyntaxHighlight({ children, ...others }) {
|
||||||
|
return (
|
||||||
|
<SyntaxHighlighter language="javacript" showLineNumbers style={a11yDark} {...others}>
|
||||||
|
{children}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SyntaxHighlight.propTypes = {
|
||||||
|
children: PropTypes.node
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue