Owen Albert Salomo
2 years ago
34 changed files with 19332 additions and 144 deletions
After Width: | Height: | Size: 108 KiB |
@ -1,38 +0,0 @@ |
|||||||
.App { |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
|
|
||||||
.App-logo { |
|
||||||
height: 40vmin; |
|
||||||
pointer-events: none; |
|
||||||
} |
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) { |
|
||||||
.App-logo { |
|
||||||
animation: App-logo-spin infinite 20s linear; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.App-header { |
|
||||||
background-color: #282c34; |
|
||||||
min-height: 100vh; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
align-items: center; |
|
||||||
justify-content: center; |
|
||||||
font-size: calc(10px + 2vmin); |
|
||||||
color: white; |
|
||||||
} |
|
||||||
|
|
||||||
.App-link { |
|
||||||
color: #61dafb; |
|
||||||
} |
|
||||||
|
|
||||||
@keyframes App-logo-spin { |
|
||||||
from { |
|
||||||
transform: rotate(0deg); |
|
||||||
} |
|
||||||
to { |
|
||||||
transform: rotate(360deg); |
|
||||||
} |
|
||||||
} |
|
@ -1,8 +0,0 @@ |
|||||||
import { render, screen } from '@testing-library/react'; |
|
||||||
import App from './App'; |
|
||||||
|
|
||||||
test('renders learn react link', () => { |
|
||||||
render(<App />); |
|
||||||
const linkElement = screen.getByText(/learn react/i); |
|
||||||
expect(linkElement).toBeInTheDocument(); |
|
||||||
}); |
|
@ -0,0 +1,130 @@ |
|||||||
|
import { useTheme } from "@mui/material"; |
||||||
|
import { ResponsiveBar } from "@nivo/bar"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
import { mockBarData as data } from "../data/mockData"; |
||||||
|
|
||||||
|
const BarChart = ({ isDashboard = false }) => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
|
||||||
|
return ( |
||||||
|
<ResponsiveBar |
||||||
|
data={data} |
||||||
|
theme={{ |
||||||
|
// added |
||||||
|
axis: { |
||||||
|
domain: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
ticks: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
strokeWidth: 1, |
||||||
|
}, |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
legends: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}} |
||||||
|
keys={["hot dog", "burger", "sandwich", "kebab", "fries", "donut"]} |
||||||
|
indexBy="country" |
||||||
|
margin={{ top: 50, right: 130, bottom: 50, left: 60 }} |
||||||
|
padding={0.3} |
||||||
|
valueScale={{ type: "linear" }} |
||||||
|
indexScale={{ type: "band", round: true }} |
||||||
|
colors={{ scheme: "nivo" }} |
||||||
|
defs={[ |
||||||
|
{ |
||||||
|
id: "dots", |
||||||
|
type: "patternDots", |
||||||
|
background: "inherit", |
||||||
|
color: "#38bcb2", |
||||||
|
size: 4, |
||||||
|
padding: 1, |
||||||
|
stagger: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "lines", |
||||||
|
type: "patternLines", |
||||||
|
background: "inherit", |
||||||
|
color: "#eed312", |
||||||
|
rotation: -45, |
||||||
|
lineWidth: 6, |
||||||
|
spacing: 10, |
||||||
|
}, |
||||||
|
]} |
||||||
|
borderColor={{ |
||||||
|
from: "color", |
||||||
|
modifiers: [["darker", "1.6"]], |
||||||
|
}} |
||||||
|
axisTop={null} |
||||||
|
axisRight={null} |
||||||
|
axisBottom={{ |
||||||
|
tickSize: 5, |
||||||
|
tickPadding: 5, |
||||||
|
tickRotation: 0, |
||||||
|
legend: isDashboard ? undefined : "country", // changed |
||||||
|
legendPosition: "middle", |
||||||
|
legendOffset: 32, |
||||||
|
}} |
||||||
|
axisLeft={{ |
||||||
|
tickSize: 5, |
||||||
|
tickPadding: 5, |
||||||
|
tickRotation: 0, |
||||||
|
legend: isDashboard ? undefined : "food", // changed |
||||||
|
legendPosition: "middle", |
||||||
|
legendOffset: -40, |
||||||
|
}} |
||||||
|
enableLabel={false} |
||||||
|
labelSkipWidth={12} |
||||||
|
labelSkipHeight={12} |
||||||
|
labelTextColor={{ |
||||||
|
from: "color", |
||||||
|
modifiers: [["darker", 1.6]], |
||||||
|
}} |
||||||
|
legends={[ |
||||||
|
{ |
||||||
|
dataFrom: "keys", |
||||||
|
anchor: "bottom-right", |
||||||
|
direction: "column", |
||||||
|
justify: false, |
||||||
|
translateX: 120, |
||||||
|
translateY: 0, |
||||||
|
itemsSpacing: 2, |
||||||
|
itemWidth: 100, |
||||||
|
itemHeight: 20, |
||||||
|
itemDirection: "left-to-right", |
||||||
|
itemOpacity: 0.85, |
||||||
|
symbolSize: 20, |
||||||
|
effects: [ |
||||||
|
{ |
||||||
|
on: "hover", |
||||||
|
style: { |
||||||
|
itemOpacity: 1, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
]} |
||||||
|
role="application" |
||||||
|
barAriaLabel={function (e) { |
||||||
|
return e.id + ": " + e.formattedValue + " in country: " + e.indexValue; |
||||||
|
}} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default BarChart; |
@ -0,0 +1,85 @@ |
|||||||
|
import { useTheme } from "@mui/material"; |
||||||
|
import { ResponsiveChoropleth } from "@nivo/geo"; |
||||||
|
import { geoFeatures } from "../data/mockGeoFeatures"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
import { mockGeographyData as data } from "../data/mockData"; |
||||||
|
|
||||||
|
const GeographyChart = ({ isDashboard = false }) => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
return ( |
||||||
|
<ResponsiveChoropleth |
||||||
|
data={data} |
||||||
|
theme={{ |
||||||
|
axis: { |
||||||
|
domain: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
ticks: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
strokeWidth: 1, |
||||||
|
}, |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
legends: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}} |
||||||
|
features={geoFeatures.features} |
||||||
|
margin={{ top: 0, right: 0, bottom: 0, left: 0 }} |
||||||
|
domain={[0, 1000000]} |
||||||
|
unknownColor="#666666" |
||||||
|
label="properties.name" |
||||||
|
valueFormat=".2s" |
||||||
|
projectionScale={isDashboard ? 40 : 150} |
||||||
|
projectionTranslation={isDashboard ? [0.49, 0.6] : [0.5, 0.5]} |
||||||
|
projectionRotation={[0, 0, 0]} |
||||||
|
borderWidth={1.5} |
||||||
|
borderColor="#ffffff" |
||||||
|
legends={ |
||||||
|
!isDashboard |
||||||
|
? [ |
||||||
|
{ |
||||||
|
anchor: "bottom-left", |
||||||
|
direction: "column", |
||||||
|
justify: true, |
||||||
|
translateX: 20, |
||||||
|
translateY: -100, |
||||||
|
itemsSpacing: 0, |
||||||
|
itemWidth: 94, |
||||||
|
itemHeight: 18, |
||||||
|
itemDirection: "left-to-right", |
||||||
|
itemTextColor: colors.grey[100], |
||||||
|
itemOpacity: 0.85, |
||||||
|
symbolSize: 18, |
||||||
|
effects: [ |
||||||
|
{ |
||||||
|
on: "hover", |
||||||
|
style: { |
||||||
|
itemTextColor: "#ffffff", |
||||||
|
itemOpacity: 1, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
] |
||||||
|
: undefined |
||||||
|
} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default GeographyChart; |
@ -0,0 +1,23 @@ |
|||||||
|
import { Typography, Box, useTheme } from "@mui/material"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
|
||||||
|
const Header = ({ title, subtitle}) => { |
||||||
|
const theme = useTheme (); |
||||||
|
const colors = tokens (theme.palette.mode); |
||||||
|
return <Box> |
||||||
|
<Typography variant="h2" |
||||||
|
color={colors.grey[100]} |
||||||
|
fontWeight="bold" |
||||||
|
sx={{ mb: "5px"}} |
||||||
|
> |
||||||
|
{title} |
||||||
|
</Typography> |
||||||
|
<Typography variants="h5" |
||||||
|
color={colors.greenAccent[400]}> |
||||||
|
|
||||||
|
{subtitle} |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
} |
||||||
|
|
||||||
|
export default Header; |
@ -0,0 +1,117 @@ |
|||||||
|
import { ResponsiveLine } from "@nivo/line"; |
||||||
|
import { useTheme } from "@mui/material"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
import { mockLineData as data } from "../data/mockData"; |
||||||
|
|
||||||
|
const LineChart = ({ isCustomLineColors = false, isDashboard = false }) => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
|
||||||
|
return ( |
||||||
|
<ResponsiveLine |
||||||
|
data={data} |
||||||
|
theme={{ |
||||||
|
axis: { |
||||||
|
domain: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
ticks: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
strokeWidth: 1, |
||||||
|
}, |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
legends: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
tooltip: { |
||||||
|
container: { |
||||||
|
color: colors.primary[500], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}} |
||||||
|
colors={isDashboard ? { datum: "color" } : { scheme: "nivo" }} // added |
||||||
|
margin={{ top: 50, right: 110, bottom: 50, left: 60 }} |
||||||
|
xScale={{ type: "point" }} |
||||||
|
yScale={{ |
||||||
|
type: "linear", |
||||||
|
min: "auto", |
||||||
|
max: "auto", |
||||||
|
stacked: true, |
||||||
|
reverse: false, |
||||||
|
}} |
||||||
|
yFormat=" >-.2f" |
||||||
|
curve="catmullRom" |
||||||
|
axisTop={null} |
||||||
|
axisRight={null} |
||||||
|
axisBottom={{ |
||||||
|
orient: "bottom", |
||||||
|
tickSize: 0, |
||||||
|
tickPadding: 5, |
||||||
|
tickRotation: 0, |
||||||
|
legend: isDashboard ? undefined : "transportation", // added |
||||||
|
legendOffset: 36, |
||||||
|
legendPosition: "middle", |
||||||
|
}} |
||||||
|
axisLeft={{ |
||||||
|
orient: "left", |
||||||
|
tickValues: 5, // added |
||||||
|
tickSize: 3, |
||||||
|
tickPadding: 5, |
||||||
|
tickRotation: 0, |
||||||
|
legend: isDashboard ? undefined : "count", // added |
||||||
|
legendOffset: -40, |
||||||
|
legendPosition: "middle", |
||||||
|
}} |
||||||
|
enableGridX={false} |
||||||
|
enableGridY={false} |
||||||
|
pointSize={8} |
||||||
|
pointColor={{ theme: "background" }} |
||||||
|
pointBorderWidth={2} |
||||||
|
pointBorderColor={{ from: "serieColor" }} |
||||||
|
pointLabelYOffset={-12} |
||||||
|
useMesh={true} |
||||||
|
legends={[ |
||||||
|
{ |
||||||
|
anchor: "bottom-right", |
||||||
|
direction: "column", |
||||||
|
justify: false, |
||||||
|
translateX: 100, |
||||||
|
translateY: 0, |
||||||
|
itemsSpacing: 0, |
||||||
|
itemDirection: "left-to-right", |
||||||
|
itemWidth: 80, |
||||||
|
itemHeight: 20, |
||||||
|
itemOpacity: 0.75, |
||||||
|
symbolSize: 12, |
||||||
|
symbolShape: "circle", |
||||||
|
symbolBorderColor: "rgba(0, 0, 0, .5)", |
||||||
|
effects: [ |
||||||
|
{ |
||||||
|
on: "hover", |
||||||
|
style: { |
||||||
|
itemBackground: "rgba(0, 0, 0, .03)", |
||||||
|
itemOpacity: 1, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
]} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default LineChart; |
@ -0,0 +1,109 @@ |
|||||||
|
import { ResponsivePie } from "@nivo/pie"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
import { useTheme } from "@mui/material"; |
||||||
|
import { mockPieData as data } from "../data/mockData"; |
||||||
|
|
||||||
|
const PieChart = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
return ( |
||||||
|
<ResponsivePie |
||||||
|
data={data} |
||||||
|
theme={{ |
||||||
|
axis: { |
||||||
|
domain: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
ticks: { |
||||||
|
line: { |
||||||
|
stroke: colors.grey[100], |
||||||
|
strokeWidth: 1, |
||||||
|
}, |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
legends: { |
||||||
|
text: { |
||||||
|
fill: colors.grey[100], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}} |
||||||
|
margin={{ top: 40, right: 80, bottom: 80, left: 80 }} |
||||||
|
innerRadius={0.5} |
||||||
|
padAngle={0.7} |
||||||
|
cornerRadius={3} |
||||||
|
activeOuterRadiusOffset={8} |
||||||
|
borderColor={{ |
||||||
|
from: "color", |
||||||
|
modifiers: [["darker", 0.2]], |
||||||
|
}} |
||||||
|
arcLinkLabelsSkipAngle={10} |
||||||
|
arcLinkLabelsTextColor={colors.grey[100]} |
||||||
|
arcLinkLabelsThickness={2} |
||||||
|
arcLinkLabelsColor={{ from: "color" }} |
||||||
|
enableArcLabels={false} |
||||||
|
arcLabelsRadiusOffset={0.4} |
||||||
|
arcLabelsSkipAngle={7} |
||||||
|
arcLabelsTextColor={{ |
||||||
|
from: "color", |
||||||
|
modifiers: [["darker", 2]], |
||||||
|
}} |
||||||
|
defs={[ |
||||||
|
{ |
||||||
|
id: "dots", |
||||||
|
type: "patternDots", |
||||||
|
background: "inherit", |
||||||
|
color: "rgba(255, 255, 255, 0.3)", |
||||||
|
size: 4, |
||||||
|
padding: 1, |
||||||
|
stagger: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "lines", |
||||||
|
type: "patternLines", |
||||||
|
background: "inherit", |
||||||
|
color: "rgba(255, 255, 255, 0.3)", |
||||||
|
rotation: -45, |
||||||
|
lineWidth: 6, |
||||||
|
spacing: 10, |
||||||
|
}, |
||||||
|
]} |
||||||
|
legends={[ |
||||||
|
{ |
||||||
|
anchor: "bottom", |
||||||
|
direction: "row", |
||||||
|
justify: false, |
||||||
|
translateX: 0, |
||||||
|
translateY: 56, |
||||||
|
itemsSpacing: 0, |
||||||
|
itemWidth: 100, |
||||||
|
itemHeight: 18, |
||||||
|
itemTextColor: "#999", |
||||||
|
itemDirection: "left-to-right", |
||||||
|
itemOpacity: 1, |
||||||
|
symbolSize: 18, |
||||||
|
symbolShape: "circle", |
||||||
|
effects: [ |
||||||
|
{ |
||||||
|
on: "hover", |
||||||
|
style: { |
||||||
|
itemTextColor: "#000", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
]} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default PieChart; |
@ -0,0 +1,22 @@ |
|||||||
|
import { Box, useTheme } from "@mui/material"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
|
||||||
|
const ProgressCircle = ({ progress = "0.75", size = "40" }) => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
const angle = progress * 360; |
||||||
|
return ( |
||||||
|
<Box |
||||||
|
sx={{ |
||||||
|
background: `radial-gradient(${colors.primary[400]} 55%, transparent 56%), |
||||||
|
conic-gradient(transparent 0deg ${angle}deg, ${colors.blueAccent[500]} ${angle}deg 360deg), |
||||||
|
${colors.greenAccent[500]}`, |
||||||
|
borderRadius: "50%", |
||||||
|
width: `${size}px`, |
||||||
|
height: `${size}px`, |
||||||
|
}} |
||||||
|
/> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default ProgressCircle; |
@ -0,0 +1,42 @@ |
|||||||
|
import { Box, Typography, useTheme } from "@mui/material"; |
||||||
|
import { tokens } from "../theme"; |
||||||
|
import ProgressCircle from "./ProgressCircle"; |
||||||
|
|
||||||
|
const StatBox = ({ title, subtitle, icon, progress, increase }) => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
|
||||||
|
return ( |
||||||
|
<Box width="100%" m="0 30px"> |
||||||
|
<Box display="flex" justifyContent="space-between"> |
||||||
|
<Box> |
||||||
|
{icon} |
||||||
|
<Typography |
||||||
|
variant="h4" |
||||||
|
fontWeight="bold" |
||||||
|
sx={{ color: colors.grey[100] }} |
||||||
|
> |
||||||
|
{title} |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
<Box> |
||||||
|
<ProgressCircle progress={progress} /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
<Box display="flex" justifyContent="space-between" mt="2px"> |
||||||
|
<Typography variant="h5" sx={{ color: colors.greenAccent[500] }}> |
||||||
|
{subtitle} |
||||||
|
</Typography> |
||||||
|
<Typography |
||||||
|
variant="h5" |
||||||
|
fontStyle="italic" |
||||||
|
sx={{ color: colors.greenAccent[600] }} |
||||||
|
> |
||||||
|
{increase} |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default StatBox; |
@ -1,13 +1,35 @@ |
|||||||
body { |
@import url('https://fonts.googleapis.com/css2?family=Public+Sans:wght@300;400;500;600;700&family=Source+Sans+Pro:wght@400;600;700&display=swap'); |
||||||
margin: 0; |
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', |
html, |
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', |
body, |
||||||
sans-serif; |
#root, |
||||||
-webkit-font-smoothing: antialiased; |
.app, |
||||||
-moz-osx-font-smoothing: grayscale; |
.content { |
||||||
} |
height: 100%; |
||||||
|
width:100%; |
||||||
code { |
font-family:Verdana, Geneva, Tahoma, sans-serif; |
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', |
} |
||||||
monospace; |
|
||||||
|
.app{ |
||||||
|
display: flex; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-scrollbar { |
||||||
|
width: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
/* Track */ |
||||||
|
::-webkit-scrollbar-track{ |
||||||
|
background: #e0e0e0; ; |
||||||
|
} |
||||||
|
|
||||||
|
/* Handle */ |
||||||
|
::-webkit-scrollbar-thumb { |
||||||
|
background: #888; |
||||||
|
} |
||||||
|
|
||||||
|
/* Handle on Hover */ |
||||||
|
::-webkit-scrollbar-track:hover{ |
||||||
|
background: #555; |
||||||
} |
} |
@ -1,13 +0,0 @@ |
|||||||
const reportWebVitals = onPerfEntry => { |
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) { |
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { |
|
||||||
getCLS(onPerfEntry); |
|
||||||
getFID(onPerfEntry); |
|
||||||
getFCP(onPerfEntry); |
|
||||||
getLCP(onPerfEntry); |
|
||||||
getTTFB(onPerfEntry); |
|
||||||
}); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
export default reportWebVitals; |
|
@ -0,0 +1,95 @@ |
|||||||
|
import { Box, Typography, useTheme } from "@mui/material"; |
||||||
|
import { DataGrid } from "@mui/x-data-grid"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
import { mockDataInvoices } from "../../data/mockData"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
|
||||||
|
|
||||||
|
const Invoices = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens (theme.palette.mode); |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{field: "id", headerName: "ID"}, |
||||||
|
|
||||||
|
{ |
||||||
|
field : "name", |
||||||
|
headerName: "Name", |
||||||
|
flex: 1, |
||||||
|
CellClassName: "name-column--cell", |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "phone", |
||||||
|
headerName: "Phone Number", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "email", |
||||||
|
headerName: "Email", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "cost", |
||||||
|
headerName: "Cost", |
||||||
|
flex: 1, |
||||||
|
renderCell: (params) => ( |
||||||
|
<Typography color={ colors.greenAccent[500]}> |
||||||
|
${params.row.cost} |
||||||
|
</Typography> |
||||||
|
) |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "date", |
||||||
|
headerName: "Date", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]; |
||||||
|
|
||||||
|
return( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Invoices" subtitle="Daftar Invoice Balances" /> |
||||||
|
<Box |
||||||
|
m= "40px 0 0 0" height="75vh" |
||||||
|
sx = {{ |
||||||
|
"& .MuiDataGrid-root": { |
||||||
|
border:"none" |
||||||
|
}, |
||||||
|
"&. Mui DataGrid-cell": { |
||||||
|
borderBottom:"none" |
||||||
|
}, |
||||||
|
"& .name-column--cell": { |
||||||
|
color: colors.greenAccent[300] |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-columnHeaders": { |
||||||
|
backgroundColor: colors.blueAccent[700], |
||||||
|
borderBottom:"none" |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-virtualScroller": { |
||||||
|
backgroundColor: colors.primary[400] |
||||||
|
}, |
||||||
|
"&. MuiDataGrid-footerContainer": { |
||||||
|
borderTop: "none", |
||||||
|
backgroundColor: colors.blueAccent[700] |
||||||
|
}, |
||||||
|
"& .MuiCheckbox-root": { |
||||||
|
color: `${colors.greenAccent[200]} !important`, |
||||||
|
}, |
||||||
|
|
||||||
|
}} |
||||||
|
> |
||||||
|
<DataGrid |
||||||
|
checkboxSelection |
||||||
|
rows={mockDataInvoices} |
||||||
|
columns={columns} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
|
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Invoices; |
@ -0,0 +1,16 @@ |
|||||||
|
import { Box } from "@mui/material"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import BarChart from "../../components/BarChart"; |
||||||
|
|
||||||
|
const Bar = () => { |
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Bar Chart" subtitle="Simple Bar Chart" /> |
||||||
|
<Box height="75vh"> |
||||||
|
<BarChart /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Bar; |
@ -0,0 +1,132 @@ |
|||||||
|
import { useState } from "react"; |
||||||
|
import FullCalendar from "@fullcalendar/react"; |
||||||
|
import{ formatDate } from "@fullcalendar/core"; |
||||||
|
import dayGridPlugin from "@fullcalendar/daygrid"; |
||||||
|
import timeGridPlugin from "@fullcalendar/timegrid"; |
||||||
|
import interactionPlugin from "@fullcalendar/interaction"; |
||||||
|
import listPlugin from "@fullcalendar/list"; |
||||||
|
import { |
||||||
|
Box, |
||||||
|
List, |
||||||
|
ListItem, |
||||||
|
ListItemText, |
||||||
|
Typography, |
||||||
|
useTheme, |
||||||
|
} from "@mui/material"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
|
||||||
|
const Calendar = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
const [currentEvents, setCurrentEvents] = useState([]); |
||||||
|
|
||||||
|
const handleDateClick = (selected) => { |
||||||
|
const title = prompt("Please enter a new title for your event"); |
||||||
|
const calendarApi = selected.view.calendar; |
||||||
|
calendarApi.unselect(); |
||||||
|
|
||||||
|
if (title) { |
||||||
|
calendarApi.addEvent({ |
||||||
|
id: `${selected.dateStr}-${title}`, |
||||||
|
title, |
||||||
|
start: selected.startStr, |
||||||
|
end: selected.endStr, |
||||||
|
allDay: selected.allDay, |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const handleEventClick = (selected) => { |
||||||
|
if ( |
||||||
|
window.confirm( |
||||||
|
`Are you sure you want to delete the event '${selected.event.title}'` |
||||||
|
) |
||||||
|
) { |
||||||
|
selected.event.remove(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Calendar" subtitle="Full Calendar Interactive Page" /> |
||||||
|
|
||||||
|
<Box display="flex" justifyContent="space-between"> |
||||||
|
{/* CALENDAR SIDEBAR */} |
||||||
|
<Box |
||||||
|
flex="1 1 20%" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
p="15px" |
||||||
|
borderRadius="4px" |
||||||
|
> |
||||||
|
<Typography variant="h5">Events</Typography> |
||||||
|
<List> |
||||||
|
{currentEvents.map((event) => ( |
||||||
|
<ListItem |
||||||
|
key={event.id} |
||||||
|
sx={{ |
||||||
|
backgroundColor: colors.greenAccent[500], |
||||||
|
margin: "10px 0", |
||||||
|
borderRadius: "2px", |
||||||
|
}} |
||||||
|
> |
||||||
|
<ListItemText |
||||||
|
primary={event.title} |
||||||
|
secondary={ |
||||||
|
<Typography> |
||||||
|
{formatDate(event.start, { |
||||||
|
year: "numeric", |
||||||
|
month: "short", |
||||||
|
day: "numeric", |
||||||
|
})} |
||||||
|
</Typography> |
||||||
|
} |
||||||
|
/> |
||||||
|
</ListItem> |
||||||
|
))} |
||||||
|
</List> |
||||||
|
</Box> |
||||||
|
|
||||||
|
{/* CALENDAR */} |
||||||
|
<Box flex="1 1 100%" ml="15px"> |
||||||
|
<FullCalendar |
||||||
|
height="75vh" |
||||||
|
plugins={[ |
||||||
|
dayGridPlugin, |
||||||
|
timeGridPlugin, |
||||||
|
interactionPlugin, |
||||||
|
listPlugin, |
||||||
|
]} |
||||||
|
headerToolbar={{ |
||||||
|
left: "prev,next today", |
||||||
|
center: "title", |
||||||
|
right: "dayGridMonth,timeGridWeek,timeGridDay,listMonth", |
||||||
|
}} |
||||||
|
initialView="dayGridMonth" |
||||||
|
editable={true} |
||||||
|
selectable={true} |
||||||
|
selectMirror={true} |
||||||
|
dayMaxEvents={true} |
||||||
|
select={handleDateClick} |
||||||
|
eventClick={handleEventClick} |
||||||
|
eventsSet={(events) => setCurrentEvents(events)} |
||||||
|
initialEvents={[ |
||||||
|
{ |
||||||
|
id: "12315", |
||||||
|
title: "All-day event", |
||||||
|
date: "2022-09-14", |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "5123", |
||||||
|
title: "Timed event", |
||||||
|
date: "2022-09-28", |
||||||
|
}, |
||||||
|
]} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Calendar; |
@ -0,0 +1,105 @@ |
|||||||
|
import { Box } from "@mui/material"; |
||||||
|
import { DataGrid , GridToolbar} from "@mui/x-data-grid"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
import { mockDataContacts } from "../../data/mockData" |
||||||
|
import { useTheme } from "@mui/material"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
|
||||||
|
|
||||||
|
const Contacts = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens (theme.palette.mode); |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{field: "id", headerName: "ID", flex: 0.5}, |
||||||
|
{field: "registrarId", headerName: "Registrar ID"}, |
||||||
|
{ |
||||||
|
field : "name", |
||||||
|
headerName: "Name", |
||||||
|
flex: 1, |
||||||
|
CellClassName: "name-column--cell", |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "age", |
||||||
|
HeaderName: "Age", |
||||||
|
type: "number", |
||||||
|
headerAlign: "left", |
||||||
|
align: "left", |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "phone", |
||||||
|
headerName: "Phone Number", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "email", |
||||||
|
headerName: "Email", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "address", |
||||||
|
headerName: "Address", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "city", |
||||||
|
headerName: "City", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field: "zipCode", |
||||||
|
headerName: "Zip Code", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]; |
||||||
|
|
||||||
|
return( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Kontak" subtitle="Daftar Kontak Team" /> |
||||||
|
<Box |
||||||
|
m= "40px 0 0 0" height="75vh" |
||||||
|
sx = {{ |
||||||
|
"& .MuiDataGrid-root": { |
||||||
|
border:"none" |
||||||
|
}, |
||||||
|
"&. Mui DataGrid-cell": { |
||||||
|
borderBottom:"none" |
||||||
|
}, |
||||||
|
"& .name-column--cell": { |
||||||
|
color: colors.greenAccent[300] |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-columnHeaders": { |
||||||
|
backgroundColor: colors.blueAccent[700], |
||||||
|
borderBottom:"none" |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-virtualScroller": { |
||||||
|
backgroundColor: colors.primary[400] |
||||||
|
}, |
||||||
|
"&. MuiDataGrid-footerContainer": { |
||||||
|
borderTop: "none", |
||||||
|
backgroundColor: colors.blueAccent[700] |
||||||
|
}, |
||||||
|
"& .MuiCheckbox-root": { |
||||||
|
color: `${colors.greenAccent[200]} !important`, |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-toolbarContainer .MuiButton-text": { |
||||||
|
colors: `${colors.grey[100]} !important`, |
||||||
|
}, |
||||||
|
|
||||||
|
}} |
||||||
|
> |
||||||
|
<DataGrid |
||||||
|
rows={mockDataContacts} |
||||||
|
columns={columns} |
||||||
|
components={{ Toolbar: GridToolbar}}/> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
|
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Contacts; |
@ -0,0 +1,284 @@ |
|||||||
|
import { Box, Button, IconButton, Typography, useTheme } from "@mui/material"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
import { mockTransactions } from "../../data/mockData"; |
||||||
|
import DownloadOutlinedIcon from "@mui/icons-material/DownloadOutlined"; |
||||||
|
import EmailIcon from "@mui/icons-material/Email"; |
||||||
|
import PointOfSaleIcon from "@mui/icons-material/PointOfSale"; |
||||||
|
import PersonAddIcon from "@mui/icons-material/PersonAdd"; |
||||||
|
import TrafficIcon from "@mui/icons-material/Traffic"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import LineChart from "../../components/LineChart"; |
||||||
|
import GeographyChart from "../../components/GeographyChart"; |
||||||
|
import BarChart from "../../components/BarChart"; |
||||||
|
import StatBox from "../../components/StatBox"; |
||||||
|
import ProgressCircle from "../../components/ProgressCircle"; |
||||||
|
|
||||||
|
const Dashboard = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
|
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
{/* HEADER */} |
||||||
|
<Box display="flex" justifyContent="space-between" alignItems="center"> |
||||||
|
<Header title="DASHBOARD" subtitle="Welcome to your dashboard" /> |
||||||
|
<Box> |
||||||
|
|
||||||
|
<Button |
||||||
|
sx={{ |
||||||
|
backgroundColor: colors.blueAccent[700], |
||||||
|
color: colors.grey[100], |
||||||
|
fontSize: "14px", |
||||||
|
fontWeight: "bold", |
||||||
|
padding: "10px 20px", |
||||||
|
}} |
||||||
|
> |
||||||
|
<DownloadOutlinedIcon sx={{ mr: "10px" }} /> |
||||||
|
Download Reports |
||||||
|
</Button> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
|
||||||
|
{/* GRID & CHARTS */} |
||||||
|
<Box |
||||||
|
display="grid" |
||||||
|
gridTemplateColumns="repeat(12, 1fr)" |
||||||
|
gridAutoRows="140px" |
||||||
|
gap="20px" |
||||||
|
> |
||||||
|
{/* ROW 1 */} |
||||||
|
<Box |
||||||
|
gridColumn="span 3" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
display="flex" |
||||||
|
alignItems="center" |
||||||
|
justifyContent="center" |
||||||
|
> |
||||||
|
<StatBox |
||||||
|
title="12,361" |
||||||
|
subtitle="Emails Sent" |
||||||
|
progress="0.75" |
||||||
|
increase="+14%" |
||||||
|
icon={ |
||||||
|
<EmailIcon |
||||||
|
sx={{ color: colors.greenAccent[600], fontSize: "26px" }} |
||||||
|
/> |
||||||
|
} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
<Box |
||||||
|
gridColumn="span 3" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
display="flex" |
||||||
|
alignItems="center" |
||||||
|
justifyContent="center" |
||||||
|
> |
||||||
|
<StatBox |
||||||
|
title="431,225" |
||||||
|
subtitle="Sales Obtained" |
||||||
|
progress="0.50" |
||||||
|
increase="+21%" |
||||||
|
icon={ |
||||||
|
<PointOfSaleIcon |
||||||
|
sx={{ color: colors.greenAccent[600], fontSize: "26px" }} |
||||||
|
/> |
||||||
|
} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
<Box |
||||||
|
gridColumn="span 3" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
display="flex" |
||||||
|
alignItems="center" |
||||||
|
justifyContent="center" |
||||||
|
> |
||||||
|
<StatBox |
||||||
|
title="32,441" |
||||||
|
subtitle="New Clients" |
||||||
|
progress="0.30" |
||||||
|
increase="+5%" |
||||||
|
icon={ |
||||||
|
<PersonAddIcon |
||||||
|
sx={{ color: colors.greenAccent[600], fontSize: "26px" }} |
||||||
|
/> |
||||||
|
} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
<Box |
||||||
|
gridColumn="span 3" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
display="flex" |
||||||
|
alignItems="center" |
||||||
|
justifyContent="center" |
||||||
|
> |
||||||
|
<StatBox |
||||||
|
title="1,325,134" |
||||||
|
subtitle="Traffic Received" |
||||||
|
progress="0.80" |
||||||
|
increase="+43%" |
||||||
|
icon={ |
||||||
|
<TrafficIcon |
||||||
|
sx={{ color: colors.greenAccent[600], fontSize: "26px" }} |
||||||
|
/> |
||||||
|
} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
|
||||||
|
{/* ROW 2 */} |
||||||
|
<Box |
||||||
|
gridColumn="span 8" |
||||||
|
gridRow="span 2" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
> |
||||||
|
<Box |
||||||
|
mt="25px" |
||||||
|
p="0 30px" |
||||||
|
display="flex " |
||||||
|
justifyContent="space-between" |
||||||
|
alignItems="center" |
||||||
|
> |
||||||
|
<Box> |
||||||
|
<Typography |
||||||
|
variant="h5" |
||||||
|
fontWeight="600" |
||||||
|
color={colors.grey[100]} |
||||||
|
> |
||||||
|
Revenue Generated |
||||||
|
</Typography> |
||||||
|
<Typography |
||||||
|
variant="h3" |
||||||
|
fontWeight="bold" |
||||||
|
color={colors.greenAccent[500]} |
||||||
|
> |
||||||
|
$59,342.32 |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
<Box> |
||||||
|
<IconButton> |
||||||
|
<DownloadOutlinedIcon |
||||||
|
sx={{ fontSize: "26px", color: colors.greenAccent[500] }} |
||||||
|
/> |
||||||
|
</IconButton> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
<Box height="250px" m="-20px 0 0 0"> |
||||||
|
<LineChart isDashboard={true} /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
<Box |
||||||
|
gridColumn="span 4" |
||||||
|
gridRow="span 2" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
overflow="auto" |
||||||
|
> |
||||||
|
<Box |
||||||
|
display="flex" |
||||||
|
justifyContent="space-between" |
||||||
|
alignItems="center" |
||||||
|
borderBottom={`4px solid ${colors.primary[500]}`} |
||||||
|
colors={colors.grey[100]} |
||||||
|
p="15px" |
||||||
|
> |
||||||
|
<Typography color={colors.grey[100]} variant="h5" fontWeight="600"> |
||||||
|
Recent Transactions |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
{mockTransactions.map((transaction, i) => ( |
||||||
|
<Box |
||||||
|
key={`${transaction.txId}-${i}`} |
||||||
|
display="flex" |
||||||
|
justifyContent="space-between" |
||||||
|
alignItems="center" |
||||||
|
borderBottom={`4px solid ${colors.primary[500]}`} |
||||||
|
p="15px" |
||||||
|
> |
||||||
|
<Box> |
||||||
|
<Typography |
||||||
|
color={colors.greenAccent[500]} |
||||||
|
variant="h5" |
||||||
|
fontWeight="600" |
||||||
|
> |
||||||
|
{transaction.txId} |
||||||
|
</Typography> |
||||||
|
<Typography color={colors.grey[100]}> |
||||||
|
{transaction.user} |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
<Box color={colors.grey[100]}>{transaction.date}</Box> |
||||||
|
<Box |
||||||
|
backgroundColor={colors.greenAccent[500]} |
||||||
|
p="5px 10px" |
||||||
|
borderRadius="4px" |
||||||
|
> |
||||||
|
${transaction.cost} |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
))} |
||||||
|
</Box> |
||||||
|
|
||||||
|
{/* ROW 3 */} |
||||||
|
<Box |
||||||
|
gridColumn="span 4" |
||||||
|
gridRow="span 2" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
p="30px" |
||||||
|
> |
||||||
|
<Typography variant="h5" fontWeight="600"> |
||||||
|
Campaign |
||||||
|
</Typography> |
||||||
|
<Box |
||||||
|
display="flex" |
||||||
|
flexDirection="column" |
||||||
|
alignItems="center" |
||||||
|
mt="25px" |
||||||
|
> |
||||||
|
<ProgressCircle size="125" /> |
||||||
|
<Typography |
||||||
|
variant="h5" |
||||||
|
color={colors.greenAccent[500]} |
||||||
|
sx={{ mt: "15px" }} |
||||||
|
> |
||||||
|
$48,352 revenue generated |
||||||
|
</Typography> |
||||||
|
<Typography>Includes extra misc expenditures and costs</Typography> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
<Box |
||||||
|
gridColumn="span 4" |
||||||
|
gridRow="span 2" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
> |
||||||
|
<Typography |
||||||
|
variant="h5" |
||||||
|
fontWeight="600" |
||||||
|
sx={{ padding: "30px 30px 0 30px" }} |
||||||
|
> |
||||||
|
Sales Quantity |
||||||
|
</Typography> |
||||||
|
<Box height="250px" mt="-20px"> |
||||||
|
<BarChart isDashboard={true} /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
<Box |
||||||
|
gridColumn="span 4" |
||||||
|
gridRow="span 2" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
padding="30px" |
||||||
|
> |
||||||
|
<Typography |
||||||
|
variant="h5" |
||||||
|
fontWeight="600" |
||||||
|
sx={{ marginBottom: "15px" }} |
||||||
|
> |
||||||
|
Geography Based Traffic |
||||||
|
</Typography> |
||||||
|
<Box height="200px"> |
||||||
|
<GeographyChart isDashboard={true} /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Dashboard; |
@ -0,0 +1,73 @@ |
|||||||
|
import { Box, useTheme } from "@mui/material"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import Accordion from "@mui/material/Accordion"; |
||||||
|
import AccordionSummary from "@mui/material/AccordionSummary"; |
||||||
|
import AccordionDetails from "@mui/material/AccordionDetails"; |
||||||
|
import Typography from "@mui/material/Typography"; |
||||||
|
import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
|
||||||
|
const FAQ = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="FAQ" subtitle="Frequently Asked Questions Page" /> |
||||||
|
|
||||||
|
<Accordion defaultExpanded> |
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}> |
||||||
|
<Typography color={colors.greenAccent[500]} variant="h5"> |
||||||
|
An Important Question |
||||||
|
</Typography> |
||||||
|
</AccordionSummary> |
||||||
|
<AccordionDetails> |
||||||
|
<Typography> |
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse |
||||||
|
malesuada lacus ex, sit amet blandit leo lobortis eget. |
||||||
|
</Typography> |
||||||
|
</AccordionDetails> |
||||||
|
</Accordion> |
||||||
|
<Accordion defaultExpanded> |
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}> |
||||||
|
<Typography color={colors.greenAccent[500]} variant="h5"> |
||||||
|
Another Important Question |
||||||
|
</Typography> |
||||||
|
</AccordionSummary> |
||||||
|
<AccordionDetails> |
||||||
|
<Typography> |
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse |
||||||
|
malesuada lacus ex, sit amet blandit leo lobortis eget. |
||||||
|
</Typography> |
||||||
|
</AccordionDetails> |
||||||
|
</Accordion> |
||||||
|
<Accordion defaultExpanded> |
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}> |
||||||
|
<Typography color={colors.greenAccent[500]} variant="h5"> |
||||||
|
Your Favorite Question |
||||||
|
</Typography> |
||||||
|
</AccordionSummary> |
||||||
|
<AccordionDetails> |
||||||
|
<Typography> |
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse |
||||||
|
malesuada lacus ex, sit amet blandit leo lobortis eget. |
||||||
|
</Typography> |
||||||
|
</AccordionDetails> |
||||||
|
</Accordion> |
||||||
|
<Accordion defaultExpanded> |
||||||
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}> |
||||||
|
<Typography color={colors.greenAccent[500]} variant="h5"> |
||||||
|
Some Random Question |
||||||
|
</Typography> |
||||||
|
</AccordionSummary> |
||||||
|
<AccordionDetails> |
||||||
|
<Typography> |
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse |
||||||
|
malesuada lacus ex, sit amet blandit leo lobortis eget. |
||||||
|
</Typography> |
||||||
|
</AccordionDetails> |
||||||
|
</Accordion> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default FAQ; |
@ -0,0 +1,166 @@ |
|||||||
|
import { Box, Button, TextField } from "@mui/material"; |
||||||
|
import { Formik } from "formik"; |
||||||
|
import * as yup from "yup"; |
||||||
|
import useMediaQuery from "@mui/material/useMediaQuery"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
|
||||||
|
const initialValues = { |
||||||
|
firstName: "", |
||||||
|
lastName: "", |
||||||
|
email: "", |
||||||
|
contact: "", |
||||||
|
address1: "", |
||||||
|
address2: "", |
||||||
|
}; |
||||||
|
|
||||||
|
const phoneRegExp = |
||||||
|
/^((\+[1-9]{1,4}[ -]?)|(\([0-9]{2,3}\)[ -]?)|([0-9]{2,4})[ -]?)*?[0-9]{3,4}[ -]?[0-9]{3,4}$/; |
||||||
|
|
||||||
|
|
||||||
|
const checkoutSchema = yup.object().shape({ |
||||||
|
firstName: yup.string().required("required"), |
||||||
|
lastName: yup.string().required("required"), |
||||||
|
email: yup.string().email("invalid email").required("required"), |
||||||
|
contact: yup |
||||||
|
.string() |
||||||
|
.matches(phoneRegExp, "Phone number is not valid") |
||||||
|
.required("required"), |
||||||
|
address1: yup.string().required("required"), |
||||||
|
address2: yup.string().required("required"), |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
const Form = () => { |
||||||
|
const isNonMobile = useMediaQuery ("(min-width:600px)"); |
||||||
|
|
||||||
|
const handleFormSubmit = (values) => { |
||||||
|
console.log(values); |
||||||
|
}; |
||||||
|
|
||||||
|
return( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Create User" subtitle="Create a New User Profile" /> |
||||||
|
<br></br> |
||||||
|
|
||||||
|
<Formik |
||||||
|
onSubmit={handleFormSubmit} |
||||||
|
initialValues={initialValues} |
||||||
|
validationSchema={checkoutSchema} |
||||||
|
> |
||||||
|
{({ |
||||||
|
values, |
||||||
|
errors, |
||||||
|
touched, |
||||||
|
handleBlur, |
||||||
|
handleChange, |
||||||
|
handleSubmit, |
||||||
|
}) => ( |
||||||
|
<form onSubmit={handleSubmit}> |
||||||
|
<Box |
||||||
|
display="grid" |
||||||
|
gap="30px" |
||||||
|
gridTemplateColumns="repeat(4, minmax(0, 1fr))" |
||||||
|
sx={{ |
||||||
|
"& > div": {gridColumn: isNonMobile ? undefined : "span 4"}, |
||||||
|
}} |
||||||
|
> |
||||||
|
<TextField |
||||||
|
fullWidth |
||||||
|
variant="filled" |
||||||
|
type="text" |
||||||
|
label="First Name" |
||||||
|
onBlur={handleBlur} |
||||||
|
onChange={handleChange} |
||||||
|
value={values.firstName} |
||||||
|
name="firstName" |
||||||
|
error={!!touched.firstName && !!errors.firstName} |
||||||
|
helperText={touched.firstName && errors.firstName} |
||||||
|
sx={{ gridColumn: "span 2" }} |
||||||
|
/> |
||||||
|
<TextField |
||||||
|
fullWidth |
||||||
|
variant="filled" |
||||||
|
type="text" |
||||||
|
label="Last Name" |
||||||
|
onBlur={handleBlur} |
||||||
|
onChange={handleChange} |
||||||
|
value={values.lastName} |
||||||
|
name="lastName" |
||||||
|
error={!!touched.lastName && !!errors.lastName} |
||||||
|
helperText={touched.lastName && errors.lastName} |
||||||
|
sx={{ gridColumn: "span 2" }} |
||||||
|
/> |
||||||
|
<TextField |
||||||
|
fullWidth |
||||||
|
variant="filled" |
||||||
|
type="text" |
||||||
|
label="Email" |
||||||
|
onBlur={handleBlur} |
||||||
|
onChange={handleChange} |
||||||
|
value={values.email} |
||||||
|
name="email" |
||||||
|
error={!!touched.email && !!errors.email} |
||||||
|
helperText={touched.email && errors.email} |
||||||
|
sx={{ gridColumn: "span 4"}} |
||||||
|
/> |
||||||
|
<TextField |
||||||
|
fullWidth |
||||||
|
variant="filled" |
||||||
|
type="text" |
||||||
|
label="Contact Number" |
||||||
|
onBlur={handleBlur} |
||||||
|
onChange={handleChange} |
||||||
|
value={values.contact} |
||||||
|
name="contact" |
||||||
|
error={!!touched.contact && !!errors.contact} |
||||||
|
helperText={touched.contact && errors.contact} |
||||||
|
sx={{ gridColumn: "span 4"}} |
||||||
|
/> |
||||||
|
<TextField |
||||||
|
fullWidth |
||||||
|
variant="filled" |
||||||
|
type="text" |
||||||
|
label="Address 1" |
||||||
|
onBlur={handleBlur} |
||||||
|
onChange={handleChange} |
||||||
|
value={values.address1} |
||||||
|
name="address1" |
||||||
|
error={!!touched.address1 && !!errors.address1} |
||||||
|
helperText={touched.address1 && errors.address1} |
||||||
|
sx={{ gridColumn: "span 4"}} |
||||||
|
/> |
||||||
|
<TextField |
||||||
|
fullWidth |
||||||
|
variant="filled" |
||||||
|
type="text" |
||||||
|
label="Address 2" |
||||||
|
onBlur={handleBlur} |
||||||
|
onChange={handleChange} |
||||||
|
value={values.address2} |
||||||
|
name="address2" |
||||||
|
error={!!touched.address2 && !!errors.address2} |
||||||
|
helperText={touched.address2 && errors.address2} |
||||||
|
sx={{ gridColumn: "span 4"}} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
<Box display="flex" justifyContent="end" mt="20px"> |
||||||
|
<Button type="submit" color="secondary" variant="contained"> |
||||||
|
Create New User |
||||||
|
</Button> |
||||||
|
|
||||||
|
</Box> |
||||||
|
</form> |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
</Formik> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
export default Form; |
@ -0,0 +1,24 @@ |
|||||||
|
import { Box, useTheme } from "@mui/material"; |
||||||
|
import GeographyChart from "../../components/GeographyChart"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
|
||||||
|
const Geography = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Geography" subtitle="Simple Geography Chart" /> |
||||||
|
|
||||||
|
<Box |
||||||
|
height="75vh" |
||||||
|
border={`1px solid ${colors.grey[100]}`} |
||||||
|
borderRadius="4px" |
||||||
|
> |
||||||
|
<GeographyChart /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Geography; |
@ -0,0 +1,234 @@ |
|||||||
|
import { useState } from "react"; |
||||||
|
import { ProSidebar, Menu, MenuItem } from "react-pro-sidebar"; |
||||||
|
import 'react-pro-sidebar/dist/css/styles.css'; |
||||||
|
import { Box, IconButton, Typography, useTheme } from "@mui/material"; |
||||||
|
import { Link } from "react-router-dom"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
import HomeIcon from '@mui/icons-material/Home'; |
||||||
|
import ManIcon from '@mui/icons-material/Man'; |
||||||
|
import LocalPhoneIcon from '@mui/icons-material/LocalPhone'; |
||||||
|
import ReceiptLongIcon from '@mui/icons-material/ReceiptLong'; |
||||||
|
import PersonIcon from '@mui/icons-material/Person'; |
||||||
|
import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; |
||||||
|
import HelpIcon from '@mui/icons-material/Help'; |
||||||
|
import BarChartIcon from '@mui/icons-material/BarChart'; |
||||||
|
import PieChartIcon from '@mui/icons-material/PieChart'; |
||||||
|
import TimelineIcon from '@mui/icons-material/Timeline'; |
||||||
|
import MenuIcon from '@mui/icons-material/Menu'; |
||||||
|
import MapIcon from '@mui/icons-material/Map'; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const Item = ({ title, to, icon, selected, setSelected }) => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
return ( |
||||||
|
<MenuItem |
||||||
|
active={selected === title} |
||||||
|
style={{ |
||||||
|
color: colors.grey[100], |
||||||
|
}} |
||||||
|
onClick={() => setSelected(title)} |
||||||
|
icon={icon} |
||||||
|
> |
||||||
|
<Typography>{title}</Typography> |
||||||
|
<Link to={to} /> |
||||||
|
</MenuItem> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
const Sidebar = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
const [isCollapsed, setIsCollapsed] = useState(false); |
||||||
|
const [selected, setSelected] = useState("Dashboard"); |
||||||
|
|
||||||
|
return ( |
||||||
|
<Box |
||||||
|
sx={{ |
||||||
|
"& .pro-sidebar-inner": { |
||||||
|
background: `${colors.primary[400]} !important`, |
||||||
|
}, |
||||||
|
"& .pro-icon-wrapper": { |
||||||
|
backgroundColor: "transparent !important", |
||||||
|
}, |
||||||
|
"& .pro-inner-item": { |
||||||
|
padding: "5px 35px 5px 20px !important", |
||||||
|
}, |
||||||
|
"& .pro-inner-item:hover": { |
||||||
|
color: "#868dfb !important", |
||||||
|
}, |
||||||
|
"& .pro-menu-item.active": { |
||||||
|
color: "#6870fa !important", |
||||||
|
}, |
||||||
|
height:" 130vh !Important", |
||||||
|
}} |
||||||
|
> |
||||||
|
<ProSidebar collapsed={isCollapsed}> |
||||||
|
<Menu iconShape="square"> |
||||||
|
{/* LOGO AND MENU ICON */} |
||||||
|
<MenuItem |
||||||
|
onClick={() => setIsCollapsed(!isCollapsed)} |
||||||
|
icon={isCollapsed ? <MenuIcon /> : undefined} |
||||||
|
style={{ |
||||||
|
margin: "10px 0 20px 0", |
||||||
|
color: colors.grey[100], |
||||||
|
}} |
||||||
|
> |
||||||
|
{!isCollapsed && ( |
||||||
|
<Box |
||||||
|
display="flex" |
||||||
|
justifyContent="space-between" |
||||||
|
alignItems="center" |
||||||
|
ml="15px" |
||||||
|
> |
||||||
|
<Typography variant="h3" color={colors.grey[100]}> |
||||||
|
Integrasia Utama |
||||||
|
</Typography> |
||||||
|
<IconButton onClick={() => setIsCollapsed(!isCollapsed)}> |
||||||
|
<MenuIcon /> |
||||||
|
</IconButton> |
||||||
|
</Box> |
||||||
|
)} |
||||||
|
</MenuItem> |
||||||
|
|
||||||
|
{!isCollapsed && ( |
||||||
|
<Box mb="25px"> |
||||||
|
<Box display="flex" justifyContent="center" alignItems="center"> |
||||||
|
<img |
||||||
|
alt="profile-user" |
||||||
|
width="115px" |
||||||
|
height="120px" |
||||||
|
src="../../user.jpg" |
||||||
|
style={{ cursor: "pointer", borderRadius: "50%" }} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
<Box textAlign="center"> |
||||||
|
<Typography |
||||||
|
variant="h2" |
||||||
|
color={colors.grey[100]} |
||||||
|
fontWeight="bold" |
||||||
|
sx={{ m: "10px 0 0 0" }} |
||||||
|
> |
||||||
|
Owen A.S |
||||||
|
</Typography> |
||||||
|
<Typography variant="h5" color={colors.greenAccent[500]}> |
||||||
|
CEO Administrator |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
)} |
||||||
|
|
||||||
|
<Box paddingLeft={isCollapsed ? undefined : "10%"}> |
||||||
|
<Item |
||||||
|
title="Dashboard" |
||||||
|
to="/" |
||||||
|
icon={<HomeIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
|
||||||
|
<Typography |
||||||
|
variant="h6" |
||||||
|
color={colors.grey[300]} |
||||||
|
sx={{ m: "15px 0 5px 20px" }} |
||||||
|
> |
||||||
|
Data |
||||||
|
</Typography> |
||||||
|
<Item |
||||||
|
title="Manage Team" |
||||||
|
to="/team" |
||||||
|
icon={<ManIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="Contacts Information" |
||||||
|
to="/contacts" |
||||||
|
icon={<LocalPhoneIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="Invoices Balances" |
||||||
|
to="/invoices" |
||||||
|
icon={<ReceiptLongIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
|
||||||
|
<Typography |
||||||
|
variant="h6" |
||||||
|
color={colors.grey[300]} |
||||||
|
sx={{ m: "15px 0 5px 20px" }} |
||||||
|
> |
||||||
|
Pages |
||||||
|
</Typography> |
||||||
|
<Item |
||||||
|
title="Profile Form" |
||||||
|
to="/form" |
||||||
|
icon={<PersonIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="Calendar" |
||||||
|
to="/calendar" |
||||||
|
icon={<CalendarTodayIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="FAQ Page" |
||||||
|
to="/faq" |
||||||
|
icon={<HelpIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
|
||||||
|
<Typography |
||||||
|
variant="h6" |
||||||
|
color={colors.grey[300]} |
||||||
|
sx={{ m: "15px 0 5px 20px" }} |
||||||
|
> |
||||||
|
Charts |
||||||
|
</Typography> |
||||||
|
<Item |
||||||
|
title="Bar Chart" |
||||||
|
to="/bar" |
||||||
|
icon={<BarChartIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="Pie Chart" |
||||||
|
to="/pie" |
||||||
|
icon={<PieChartIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="Line Chart" |
||||||
|
to="/line" |
||||||
|
icon={<TimelineIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
<Item |
||||||
|
title="Geography Chart" |
||||||
|
to="/geography" |
||||||
|
icon={<MapIcon />} |
||||||
|
selected={selected} |
||||||
|
setSelected={setSelected} |
||||||
|
/> |
||||||
|
</Box> |
||||||
|
</Menu> |
||||||
|
</ProSidebar> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default Sidebar; |
@ -0,0 +1,63 @@ |
|||||||
|
import { Box, IconButton, useTheme } from "@mui/material"; |
||||||
|
import { useContext } from "react"; |
||||||
|
import { ColorModeContext, tokens } from "../../theme"; |
||||||
|
import InputBase from "@mui/material/InputBase"; |
||||||
|
import BrightnessHighRoundedIcon from '@mui/icons-material/BrightnessHighRounded'; |
||||||
|
import BedtimeRoundedIcon from '@mui/icons-material/BedtimeRounded'; |
||||||
|
import NotificationsActiveRoundedIcon from '@mui/icons-material/NotificationsActiveRounded'; |
||||||
|
import SettingsIcon from '@mui/icons-material/Settings'; |
||||||
|
import PersonIcon from '@mui/icons-material/Person'; |
||||||
|
import SearchOutlinedIcon from '@mui/icons-material/SearchOutlined'; |
||||||
|
|
||||||
|
const Topbar = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens(theme.palette.mode); |
||||||
|
const colorMode = useContext(ColorModeContext); |
||||||
|
|
||||||
|
return ( |
||||||
|
<Box display="flex" justifyContent="space-between" p={2}> |
||||||
|
{/* SEARCH BAR */} |
||||||
|
<Box |
||||||
|
display="flex" |
||||||
|
backgroundColor={colors.primary[400]} |
||||||
|
borderRadius="3px" |
||||||
|
> |
||||||
|
<InputBase sx={{ ml: 2, flex: 1 }} placeholder="Pencarian" /> |
||||||
|
<IconButton type="button" sx={{ p: 1 }}> |
||||||
|
<SearchOutlinedIcon /> |
||||||
|
</IconButton> |
||||||
|
</Box> |
||||||
|
|
||||||
|
{/* ICONS */} |
||||||
|
<Box display="flex"> |
||||||
|
<IconButton onClick={colorMode.toggleColorMode}> |
||||||
|
{theme.palette.mode === "dark" ? ( |
||||||
|
<BedtimeRoundedIcon /> |
||||||
|
) : ( |
||||||
|
<BrightnessHighRoundedIcon /> |
||||||
|
)} |
||||||
|
</IconButton> |
||||||
|
<IconButton> |
||||||
|
<NotificationsActiveRoundedIcon /> |
||||||
|
</IconButton> |
||||||
|
<IconButton> |
||||||
|
<SettingsIcon /> |
||||||
|
</IconButton> |
||||||
|
<IconButton> |
||||||
|
<PersonIcon /> |
||||||
|
</IconButton> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Topbar; |
||||||
|
|
||||||
|
|
||||||
|
/*import InputBase from "@mui/material/InputBase"; |
||||||
|
import BrightnessHighRoundedIcon from '@mui/icons-material/BrightnessHighRounded'; |
||||||
|
import BedtimeRoundedIcon from '@mui/icons-material/BedtimeRounded'; |
||||||
|
import NotificationsActiveRoundedIcon from '@mui/icons-material/NotificationsActiveRounded'; |
||||||
|
import SettingsIcon from '@mui/icons-material/Settings'; |
||||||
|
import PersonIcon from '@mui/icons-material/Person'; |
||||||
|
import SearchOutlinedIcon from '@mui/icons-material/SearchOutlined'*/ |
@ -0,0 +1,16 @@ |
|||||||
|
import { Box } from "@mui/material"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import LineChart from "../../components/LineChart"; |
||||||
|
|
||||||
|
const Line = () => { |
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Line Chart" subtitle="Simple Line Chart" /> |
||||||
|
<Box height="75vh"> |
||||||
|
<LineChart /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Line; |
@ -0,0 +1,16 @@ |
|||||||
|
import { Box } from "@mui/material"; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
import PieChart from "../../components/PieChart"; |
||||||
|
|
||||||
|
const Pie = () => { |
||||||
|
return ( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="Pie Chart" subtitle="Simple Pie Chart" /> |
||||||
|
<Box height="75vh"> |
||||||
|
<PieChart /> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default Pie; |
@ -0,0 +1,110 @@ |
|||||||
|
import { Box, Typography, useTheme } from "@mui/material"; |
||||||
|
import { DataGrid } from "@mui/x-data-grid"; |
||||||
|
import { tokens } from "../../theme"; |
||||||
|
import { mockDataTeam } from "../../data/mockData"; |
||||||
|
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings'; |
||||||
|
import LockOpenIcon from '@mui/icons-material/LockOpen'; |
||||||
|
import SecurityIcon from '@mui/icons-material/Security'; |
||||||
|
import Header from "../../components/Header"; |
||||||
|
|
||||||
|
const Team = () => { |
||||||
|
const theme = useTheme(); |
||||||
|
const colors = tokens (theme.palette.mode); |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{field: "id", headerName: "ID"}, |
||||||
|
{ |
||||||
|
field : "name", |
||||||
|
headerName: "Name", |
||||||
|
flex: 1, |
||||||
|
CellClassName: "name-column--cell", |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "age", |
||||||
|
HeaderName: "Age", |
||||||
|
type: "number", |
||||||
|
headerAlign: "left", |
||||||
|
align: "left", |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "phone", |
||||||
|
headerName: "Phone Number", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "email", |
||||||
|
headerName: "Email", |
||||||
|
flex: 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
field : "access", |
||||||
|
headerName: "Access Level", |
||||||
|
flex: 1, |
||||||
|
renderCell:({ row: { access }}) => { |
||||||
|
return( |
||||||
|
<Box |
||||||
|
width="60%" |
||||||
|
m = "0 auto" |
||||||
|
p = "5px" |
||||||
|
display="flex" |
||||||
|
justifyContent="center" |
||||||
|
backgroundColor={ |
||||||
|
access === "admin" |
||||||
|
? colors.greenAccent[600] |
||||||
|
: colors.greenAccent[700] |
||||||
|
} |
||||||
|
borderRadius="4px" |
||||||
|
> |
||||||
|
{access === "admin" && <AdminPanelSettingsIcon />} |
||||||
|
{access === "manager" && <SecurityIcon />} |
||||||
|
{access === "user" && <LockOpenIcon/>} |
||||||
|
<Typography color={colors.grey[100]} sx={{ ml : "5px"}}> |
||||||
|
{access} |
||||||
|
</Typography> |
||||||
|
</Box> |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]; |
||||||
|
|
||||||
|
return( |
||||||
|
<Box m="20px"> |
||||||
|
<Header title="TEAM" subtitle="Managing the Team Members" /> |
||||||
|
<Box |
||||||
|
m= "40px 0 0 0" height="75vh" |
||||||
|
sx = {{ |
||||||
|
"& .MuiDataGrid-root": { |
||||||
|
border:"none" |
||||||
|
}, |
||||||
|
"&. Mui DataGrid-cell": { |
||||||
|
borderBottom:"none" |
||||||
|
}, |
||||||
|
"& .name-column--cell": { |
||||||
|
color: colors.greenAccent[300] |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-columnHeaders": { |
||||||
|
backgroundColor: colors.blueAccent[700], |
||||||
|
borderBottom:"none" |
||||||
|
}, |
||||||
|
"& .MuiDataGrid-virtualScroller": { |
||||||
|
backgroundColor: colors.primary[400] |
||||||
|
}, |
||||||
|
"&. MuiDataGrid-footerContainer": { |
||||||
|
borderTop: "none", |
||||||
|
backgroundColor: colors.blueAccent[700] |
||||||
|
}, |
||||||
|
}} |
||||||
|
> |
||||||
|
<DataGrid rows={mockDataTeam} columns={columns}/> |
||||||
|
</Box> |
||||||
|
</Box> |
||||||
|
|
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Team; |
@ -1,5 +0,0 @@ |
|||||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
|
||||||
// allows you to do things like:
|
|
||||||
// expect(element).toHaveTextContent(/react/i)
|
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
|
||||||
import '@testing-library/jest-dom'; |
|
@ -0,0 +1,214 @@ |
|||||||
|
import { createContext, useState, useMemo } from "react"; |
||||||
|
import { createTheme } from "@mui/material/styles"; |
||||||
|
|
||||||
|
// color design tokens export
|
||||||
|
export const tokens = (mode) => ({ |
||||||
|
...(mode === "dark" |
||||||
|
? { |
||||||
|
grey: { |
||||||
|
100: "#e0e0e0", |
||||||
|
200: "#c2c2c2", |
||||||
|
300: "#a3a3a3", |
||||||
|
400: "#858585", |
||||||
|
500: "#666666", |
||||||
|
600: "#525252", |
||||||
|
700: "#3d3d3d", |
||||||
|
800: "#292929", |
||||||
|
900: "#141414", |
||||||
|
}, |
||||||
|
primary: { |
||||||
|
100: "#d0d1d5", |
||||||
|
200: "#a1a4ab", |
||||||
|
300: "#727681", |
||||||
|
400: "#1F2A40", |
||||||
|
500: "#141b2d", |
||||||
|
600: "#101624", |
||||||
|
700: "#0c101b", |
||||||
|
800: "#080b12", |
||||||
|
900: "#040509", |
||||||
|
}, |
||||||
|
greenAccent: { |
||||||
|
100: "#dbf5ee", |
||||||
|
200: "#b7ebde", |
||||||
|
300: "#94e2cd", |
||||||
|
400: "#70d8bd", |
||||||
|
500: "#4cceac", |
||||||
|
600: "#3da58a", |
||||||
|
700: "#2e7c67", |
||||||
|
800: "#1e5245", |
||||||
|
900: "#0f2922", |
||||||
|
}, |
||||||
|
redAccent: { |
||||||
|
100: "#f8dcdb", |
||||||
|
200: "#f1b9b7", |
||||||
|
300: "#e99592", |
||||||
|
400: "#e2726e", |
||||||
|
500: "#db4f4a", |
||||||
|
600: "#af3f3b", |
||||||
|
700: "#832f2c", |
||||||
|
800: "#58201e", |
||||||
|
900: "#2c100f", |
||||||
|
}, |
||||||
|
blueAccent: { |
||||||
|
100: "#e1e2fe", |
||||||
|
200: "#c3c6fd", |
||||||
|
300: "#a4a9fc", |
||||||
|
400: "#868dfb", |
||||||
|
500: "#6870fa", |
||||||
|
600: "#535ac8", |
||||||
|
700: "#3e4396", |
||||||
|
800: "#2a2d64", |
||||||
|
900: "#151632", |
||||||
|
}, |
||||||
|
} |
||||||
|
: { |
||||||
|
grey: { |
||||||
|
100: "#141414", |
||||||
|
200: "#292929", |
||||||
|
300: "#3d3d3d", |
||||||
|
400: "#525252", |
||||||
|
500: "#666666", |
||||||
|
600: "#858585", |
||||||
|
700: "#a3a3a3", |
||||||
|
800: "#c2c2c2", |
||||||
|
900: "#e0e0e0", |
||||||
|
}, |
||||||
|
primary: { |
||||||
|
100: "#040509", |
||||||
|
200: "#080b12", |
||||||
|
300: "#0c101b", |
||||||
|
400: "#f2f0f0", // manually changed
|
||||||
|
500: "#141b2d", |
||||||
|
600: "#1F2A40", |
||||||
|
700: "#727681", |
||||||
|
800: "#a1a4ab", |
||||||
|
900: "#d0d1d5", |
||||||
|
}, |
||||||
|
greenAccent: { |
||||||
|
100: "#0f2922", |
||||||
|
200: "#1e5245", |
||||||
|
300: "#2e7c67", |
||||||
|
400: "#3da58a", |
||||||
|
500: "#4cceac", |
||||||
|
600: "#70d8bd", |
||||||
|
700: "#94e2cd", |
||||||
|
800: "#b7ebde", |
||||||
|
900: "#dbf5ee", |
||||||
|
}, |
||||||
|
redAccent: { |
||||||
|
100: "#2c100f", |
||||||
|
200: "#58201e", |
||||||
|
300: "#832f2c", |
||||||
|
400: "#af3f3b", |
||||||
|
500: "#db4f4a", |
||||||
|
600: "#e2726e", |
||||||
|
700: "#e99592", |
||||||
|
800: "#f1b9b7", |
||||||
|
900: "#f8dcdb", |
||||||
|
}, |
||||||
|
blueAccent: { |
||||||
|
100: "#151632", |
||||||
|
200: "#2a2d64", |
||||||
|
300: "#3e4396", |
||||||
|
400: "#535ac8", |
||||||
|
500: "#6870fa", |
||||||
|
600: "#868dfb", |
||||||
|
700: "#a4a9fc", |
||||||
|
800: "#c3c6fd", |
||||||
|
900: "#e1e2fe", |
||||||
|
}, |
||||||
|
}), |
||||||
|
}); |
||||||
|
|
||||||
|
// mui theme settings
|
||||||
|
export const themeSettings = (mode) => { |
||||||
|
const colors = tokens(mode); |
||||||
|
return { |
||||||
|
palette: { |
||||||
|
mode: mode, |
||||||
|
...(mode === "dark" |
||||||
|
? { |
||||||
|
// palette values for dark mode
|
||||||
|
primary: { |
||||||
|
main: colors.primary[500], |
||||||
|
}, |
||||||
|
secondary: { |
||||||
|
main: colors.greenAccent[500], |
||||||
|
}, |
||||||
|
neutral: { |
||||||
|
dark: colors.grey[700], |
||||||
|
main: colors.grey[500], |
||||||
|
light: colors.grey[100], |
||||||
|
}, |
||||||
|
background: { |
||||||
|
default: colors.primary[500], |
||||||
|
}, |
||||||
|
} |
||||||
|
: { |
||||||
|
// palette values for light mode
|
||||||
|
primary: { |
||||||
|
main: colors.primary[100], |
||||||
|
}, |
||||||
|
secondary: { |
||||||
|
main: colors.greenAccent[500], |
||||||
|
}, |
||||||
|
neutral: { |
||||||
|
dark: colors.grey[700], |
||||||
|
main: colors.grey[500], |
||||||
|
light: colors.grey[100], |
||||||
|
}, |
||||||
|
background: { |
||||||
|
default: "#fcfcfc", |
||||||
|
}, |
||||||
|
}), |
||||||
|
}, |
||||||
|
typography: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 12, |
||||||
|
h1: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 40, |
||||||
|
}, |
||||||
|
h2: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 32, |
||||||
|
}, |
||||||
|
h3: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 24, |
||||||
|
}, |
||||||
|
h4: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 20, |
||||||
|
}, |
||||||
|
h5: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 16, |
||||||
|
}, |
||||||
|
h6: { |
||||||
|
fontFamily: ["Source Sans Pro", "sans-serif"].join(","), |
||||||
|
fontSize: 14, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
// context for color mode
|
||||||
|
export const ColorModeContext = createContext({ |
||||||
|
toggleColorMode: () => {}, |
||||||
|
}); |
||||||
|
|
||||||
|
export const useMode = () => { |
||||||
|
const [mode, setMode] = useState("dark"); |
||||||
|
|
||||||
|
const colorMode = useMemo( |
||||||
|
() => ({ |
||||||
|
toggleColorMode: () => |
||||||
|
setMode((prev) => (prev === "light" ? "dark" : "light")), |
||||||
|
}), |
||||||
|
[] |
||||||
|
); |
||||||
|
|
||||||
|
const theme = useMemo(() => createTheme(themeSettings(mode)), [mode]); |
||||||
|
return [theme, colorMode]; |
||||||
|
}; |
Loading…
Reference in new issue