Dashboard 중간저장

thkim
Lim\jun 2024-01-31 16:20:36 +09:00
parent c7440cbc0d
commit 33f3654222
7 changed files with 1414 additions and 31 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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>
)
}

View File

@ -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;

View File

@ -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;

View 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;

View File

@ -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
};