Dashboard 중간저장
parent
c7440cbc0d
commit
33f3654222
File diff suppressed because it is too large
Load Diff
|
|
@ -3,6 +3,8 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons": "^4.7.0",
|
||||
"@emotion/react": "^11.11.3",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@material-ui/core": "^4.12.4",
|
||||
|
|
@ -13,16 +15,20 @@
|
|||
"bootstrap": "^5.3.2",
|
||||
"date-fns": "^3.2.0",
|
||||
"qs": "^6.11.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.9.0",
|
||||
"react-csv": "^2.2.2",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-datepicker": "^4.8.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-element-to-jsx-string": "^15.0.0",
|
||||
"react-icons": "^4.11.0",
|
||||
"react-loader-spinner": "^5.4.5",
|
||||
"react-quill": "^2.0.0",
|
||||
"react-router-dom": "^6.4.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"recharts": "^2.10.3",
|
||||
"styled-components": "^6.0.9",
|
||||
"web-vitals": "^2.1.4"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import RootRoutes from './routes';
|
||||
import ThemeCustomization from 'themes';
|
||||
import ScrollTop from 'components/ScrollTop';
|
||||
import React from 'react';
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
|
@ -12,9 +14,11 @@ import './css/Custom/customMain.css'
|
|||
function App() {
|
||||
|
||||
return (
|
||||
<div className="wrap">
|
||||
<RootRoutes />
|
||||
</div>
|
||||
<ThemeCustomization>
|
||||
<ScrollTop>
|
||||
<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