Browse Source

dashboard

master
Owen Albert Salomo 1 year ago
parent
commit
7c0c8a5960
  1. 2363
      package-lock.json
  2. 18
      package.json
  3. BIN
      public/user.jpg
  4. 38
      src/App.css
  5. 60
      src/App.js
  6. 8
      src/App.test.js
  7. 130
      src/components/BarChart.jsx
  8. 85
      src/components/GeographyChart.jsx
  9. 23
      src/components/Header.jsx
  10. 117
      src/components/LineChart.jsx
  11. 109
      src/components/PieChart.jsx
  12. 22
      src/components/ProgressCircle.jsx
  13. 42
      src/components/StatBox.jsx
  14. 1283
      src/data/mockData.js
  15. 13549
      src/data/mockGeoFeatures.js
  16. 46
      src/index.css
  17. 8
      src/index.js
  18. 1
      src/logo.svg
  19. 13
      src/reportWebVitals.js
  20. 95
      src/scenes/Invoices/index.jsx
  21. 16
      src/scenes/bar/index.jsx
  22. 132
      src/scenes/calender/index.jsx
  23. 105
      src/scenes/contact/index.jsx
  24. 284
      src/scenes/dashboard/index.jsx
  25. 73
      src/scenes/faq/index.jsx
  26. 166
      src/scenes/form/index.jsx
  27. 24
      src/scenes/geography/index.jsx
  28. 234
      src/scenes/global/Sidebar.jsx
  29. 63
      src/scenes/global/Topbar.jsx
  30. 16
      src/scenes/line/index.jsx
  31. 16
      src/scenes/pie/index.jsx
  32. 110
      src/scenes/team/index.jsx
  33. 5
      src/setupTests.js
  34. 214
      src/theme.js

2363
package-lock.json generated

File diff suppressed because it is too large Load Diff

18
package.json

@ -3,13 +3,29 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@fullcalendar/react": "^6.1.8",
"@mui/icons-material": "^5.11.16",
"@mui/material": "^5.13.3",
"@mui/x-data-grid": "^6.5.0",
"@nivo/bar": "^0.83.0",
"@nivo/core": "^0.83.0",
"@nivo/geo": "^0.83.0",
"@nivo/line": "^0.83.0",
"@nivo/pie": "^0.83.0",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"formik": "^2.4.0",
"fullcalendar": "^6.1.8",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-pro-sidebar": "^0.7.1",
"react-router-dom": "^6.11.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4",
"yup": "^1.2.0"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

BIN
public/user.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

38
src/App.css

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

60
src/App.js

@ -1,24 +1,50 @@
import logo from './logo.svg'; import Topbar from "./scenes/global/Topbar";
import './App.css'; import { CssBaseline, ThemeProvider } from "@mui/material";
import { ColorModeContext, useMode } from "./theme";
import { Routes, Route } from "react-router-dom";
import Sidebar from "./scenes/global/Sidebar";
import Dashboard from "./scenes/dashboard";
import Team from "./scenes/team";
import Invoices from "./scenes/Invoices"
import Contacts from "./scenes/contact";
import Bar from "./scenes/bar";
import Form from "./scenes/form";
import Line from "./scenes/line";
import Pie from "./scenes/pie";
import FAQ from "./scenes/faq";
import Geography from "./scenes/geography";
import Calendar from "./scenes/calender";
function App() { function App() {
const [theme, colorMode] = useMode();
return ( return (
<div className="App"> <ColorModeContext.Provider value={colorMode}>
<header className="App-header"> <ThemeProvider theme={theme}>
<img src={logo} className="App-logo" alt="logo" /> <CssBaseline />
<p> <div className="app">
Edit <code>src/App.js</code> and save to reload. <Sidebar />
</p> <main className="content">
<a <Topbar/>
className="App-link" <Routes>
href="https://reactjs.org" <Route path="/" element = {<Dashboard />} />
target="_blank" <Route path="/team" element = {<Team/>} />
rel="noopener noreferrer" <Route path="/contacts" element = {<Contacts />} />
> <Route path="/invoices" element = {<Invoices />} />
Learn React <Route path="/form" element = {<Form />} />
</a> <Route path="/faq" element = {<FAQ/>} />
</header> <Route path="/bar" element = {<Bar />} />
<Route path="/line" element = {<Line />} />
<Route path="/pie" element = {<Pie />} />
<Route path="/geography" element = {<Geography />} />
<Route path="/calendar" element = {<Calendar />} />
</Routes>
</main>
</div> </div>
</ThemeProvider>
</ColorModeContext.Provider>
); );
} }

8
src/App.test.js

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

130
src/components/BarChart.jsx

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

85
src/components/GeographyChart.jsx

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

23
src/components/Header.jsx

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

117
src/components/LineChart.jsx

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

109
src/components/PieChart.jsx

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

22
src/components/ProgressCircle.jsx

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

42
src/components/StatBox.jsx

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

1283
src/data/mockData.js

File diff suppressed because it is too large Load Diff

13549
src/data/mockGeoFeatures.js

File diff suppressed because it is too large Load Diff

46
src/index.css

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

8
src/index.js

@ -2,16 +2,14 @@ import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<BrowserRouter>
<App /> <App />
</BrowserRouter>
</React.StrictMode> </React.StrictMode>
); );
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

1
src/logo.svg

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

13
src/reportWebVitals.js

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

95
src/scenes/Invoices/index.jsx

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

16
src/scenes/bar/index.jsx

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

132
src/scenes/calender/index.jsx

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

105
src/scenes/contact/index.jsx

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

284
src/scenes/dashboard/index.jsx

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

73
src/scenes/faq/index.jsx

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

166
src/scenes/form/index.jsx

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

24
src/scenes/geography/index.jsx

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

234
src/scenes/global/Sidebar.jsx

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

63
src/scenes/global/Topbar.jsx

@ -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'*/

16
src/scenes/line/index.jsx

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

16
src/scenes/pie/index.jsx

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

110
src/scenes/team/index.jsx

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

5
src/setupTests.js

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

214
src/theme.js

@ -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…
Cancel
Save