├── .yarnrc.yml
├── src
├── vite-env.d.js
├── assets
│ └── images
│ │ ├── users
│ │ ├── avatar-1.jpg
│ │ ├── avatar-2.jpg
│ │ ├── avatar-3.jpg
│ │ └── avatar-4.jpg
│ │ ├── social-google.svg
│ │ ├── logo-dark.svg
│ │ └── logo.svg
├── config.js
├── layouts
│ ├── minimalLayout
│ │ └── index.jsx
│ └── MainLayout
│ │ ├── Drawer
│ │ ├── DrawerContent
│ │ │ ├── Navigation
│ │ │ │ ├── index.jsx
│ │ │ │ ├── NavGroup.jsx
│ │ │ │ ├── NavItem.jsx
│ │ │ │ └── NavCollapse.jsx
│ │ │ └── index.jsx
│ │ └── index.jsx
│ │ ├── index.jsx
│ │ └── Header
│ │ ├── index.jsx
│ │ ├── Search.jsx
│ │ ├── Profile.jsx
│ │ └── Notification.jsx
├── themes
│ ├── overrides
│ │ ├── CardActions.js
│ │ ├── CardContent.js
│ │ ├── ListItem.js
│ │ ├── Chip.js
│ │ ├── ListItemIcon.js
│ │ ├── Popper.js
│ │ ├── Checkbox.js
│ │ ├── CardHeader.js
│ │ ├── FormHelperText.js
│ │ ├── SvgIcon.js
│ │ ├── Paper.js
│ │ ├── ListItemButton.js
│ │ ├── index.js
│ │ └── Avatar.js
│ ├── shadow.js
│ ├── index.jsx
│ ├── typography.js
│ └── palette.js
├── views
│ ├── dashboard
│ │ └── default
│ │ │ ├── data
│ │ │ ├── small-flat-card-data.jsx
│ │ │ ├── traffic-source-card-data.jsx
│ │ │ ├── sales-line-chart-card-data.jsx
│ │ │ ├── revenue-card-data.jsx
│ │ │ └── report-card-data.jsx
│ │ │ └── index.jsx
│ ├── auth
│ │ ├── Register.jsx
│ │ ├── Login.jsx
│ │ └── CommonAuthLayout.jsx
│ ├── pages
│ │ └── SamplePage.jsx
│ └── components
│ │ └── Typography.jsx
├── App.jsx
├── menu-items
│ ├── index.js
│ ├── other.js
│ ├── dashboard.js
│ ├── ui-component.js
│ └── pages.js
├── routes
│ ├── index.jsx
│ ├── PagesRoutes.jsx
│ └── MainRoutes.jsx
├── components
│ ├── loader
│ │ └── index.jsx
│ ├── Loadable.jsx
│ ├── cards
│ │ ├── TrafficSourceCard.jsx
│ │ ├── ReportCard.jsx
│ │ ├── SmallFlatCard.jsx
│ │ └── MainCard.jsx
│ ├── third-party
│ │ ├── SimpleBar.jsx
│ │ ├── SalesLineChartCard.jsx
│ │ └── RevenuChartCard.jsx
│ └── Breadcrumbs.jsx
├── main.jsx
├── sections
│ ├── dashboard
│ │ └── chart
│ │ │ ├── card-data
│ │ │ └── revenue-card-data.jsx
│ │ │ └── chart-data
│ │ │ ├── revenue-chart-data.js
│ │ │ └── sales-line-chart.js
│ └── auth
│ │ ├── AuthLogin.jsx
│ │ └── AuthRegister.jsx
├── enum.js
├── index.css
├── utils
│ ├── passwordStrength.js
│ └── validationSchema.js
└── states
│ └── menu.js
├── .prettierrc
├── .env
├── jsconfig.node.json
├── .env.qa
├── .gitignore
├── support.html
├── discord.html
├── documentation.html
├── index.html
├── jsconfig.json
├── vite.config.mjs
├── LICENSE
├── .github
└── workflows
│ ├── prod.yml
│ └── stage.yml
├── package.json
├── eslint.config.mjs
├── favicon.svg
├── public
└── favicon.svg
└── README.md
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/src/vite-env.d.js:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/materially-free-react-admin-template/HEAD/src/assets/images/users/avatar-1.jpg
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/materially-free-react-admin-template/HEAD/src/assets/images/users/avatar-2.jpg
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/materially-free-react-admin-template/HEAD/src/assets/images/users/avatar-3.jpg
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/materially-free-react-admin-template/HEAD/src/assets/images/users/avatar-4.jpg
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "bracketSpacing": true,
3 | "printWidth": 140,
4 | "singleQuote": true,
5 | "trailingComma": "none",
6 | "tabWidth": 2,
7 | "useTabs": false
8 | }
9 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | VITE_APP_VERSION = v4.0.0
2 | GENERATE_SOURCEMAP = false
3 |
4 | PUBLIC_URL = https://codedthemes.com/demos/admin-templates/materially/react/free
5 | VITE_APP_BASE_URL=/demos/admin-templates/materially/react/free
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | // ==============================|| THEME CONSTANT ||============================== //
2 |
3 | export const APP_DEFAULT_PATH = 'dashboard/default';
4 | export const GRID_SPACING = 3;
5 | export const DRAWER_WIDTH = 280;
6 |
--------------------------------------------------------------------------------
/jsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.mjs"]
9 | }
10 |
--------------------------------------------------------------------------------
/.env.qa:
--------------------------------------------------------------------------------
1 | VITE_APP_VERSION=v4.0.0
2 | GENERATE_SOURCEMAP=false
3 |
4 | PUBLIC_URL = https://codedthemes.com/demos/admin-templates/materially/react/free/stage
5 | VITE_APP_BASE_URL=/demos/admin-templates/materially/react/free/stage
6 |
7 | ## Backend API URL
8 | VITE_APP_API_URL=https://mock-data-api-nextjs.vercel.app/
9 |
--------------------------------------------------------------------------------
/src/layouts/minimalLayout/index.jsx:
--------------------------------------------------------------------------------
1 | import { Outlet } from 'react-router-dom';
2 |
3 | // ==============================|| MINIMAL LAYOUT ||============================== //
4 |
5 | export default function MinimalLayout() {
6 | return (
7 | <>
8 |
9 | >
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/src/themes/overrides/CardActions.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - CARD ACTIONS ||============================== //
2 |
3 | export default function CardActions() {
4 | return {
5 | MuiCardActions: {
6 | styleOverrides: {
7 | root: {
8 | padding: 24
9 | }
10 | }
11 | }
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/src/themes/overrides/CardContent.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - CARD CONTENT ||============================== //
2 |
3 | export default function CardContent() {
4 | return {
5 | MuiCardContent: {
6 | styleOverrides: {
7 | root: {
8 | padding: 24
9 | }
10 | }
11 | }
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/src/views/dashboard/default/data/small-flat-card-data.jsx:
--------------------------------------------------------------------------------
1 | export const smallFlatCardData = [
2 | {
3 | value: '-0.99',
4 | label: 'REALTY',
5 | color: 'error.main',
6 | type: 'dashboard'
7 | },
8 | {
9 | value: '-7.66',
10 | label: 'INFRA',
11 | color: 'success.main',
12 | type: 'dashboard'
13 | }
14 | ];
15 |
--------------------------------------------------------------------------------
/src/themes/overrides/ListItem.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - LISTITEM ||============================== //
2 |
3 | export default function ListItem(theme) {
4 | return {
5 | MuiListItem: {
6 | styleOverrides: {
7 | root: {
8 | color: theme.palette.text.primary
9 | }
10 | }
11 | }
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { RouterProvider } from 'react-router-dom';
2 |
3 | // project imports
4 | import ThemeCustomization from './themes';
5 |
6 | import router from 'routes';
7 |
8 | function App() {
9 | return (
10 |
11 |
12 |
13 | );
14 | }
15 |
16 | export default App;
17 |
--------------------------------------------------------------------------------
/src/themes/overrides/Chip.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - CHIP ||============================== //
2 |
3 | export default function Chip(theme) {
4 | return {
5 | MuiChip: {
6 | styleOverrides: {
7 | avatar: { color: theme.palette.background.paper },
8 | icon: { color: theme.palette.text.primary }
9 | }
10 | }
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 | .yarn
10 |
11 | node_modules
12 | dist
13 | dist-ssr
14 | *.local
15 |
16 | # Editor directories and files
17 | .vscode/*
18 | !.vscode/extensions.json
19 | .idea
20 | .DS_Store
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw?
26 |
--------------------------------------------------------------------------------
/src/menu-items/index.js:
--------------------------------------------------------------------------------
1 | // type
2 | import dashboard from './dashboard';
3 | import pages from './pages';
4 | import other from './other';
5 | import uiComponent from './ui-component';
6 | // ==============================|| MENU ITEMS ||============================== //
7 |
8 | const menuItems = {
9 | items: [dashboard, pages, uiComponent, other]
10 | };
11 |
12 | export default menuItems;
13 |
--------------------------------------------------------------------------------
/src/themes/overrides/ListItemIcon.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - LISTITEM ICON ||============================== //
2 |
3 | export default function ListItemIcon(theme) {
4 | return {
5 | MuiListItemIcon: {
6 | styleOverrides: {
7 | root: {
8 | minWidth: '36px',
9 | color: theme.palette.text.primary
10 | }
11 | }
12 | }
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/support.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Support
5 |
6 |
7 |
8 |
9 | If you do not redirect please visit:
10 | https://codedthemes.support-hub.io/tickets
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/routes/index.jsx:
--------------------------------------------------------------------------------
1 | import { createBrowserRouter } from 'react-router-dom';
2 |
3 | // routes
4 | import MainRoutes from './MainRoutes';
5 | import PagesRoutes from './PagesRoutes';
6 |
7 | // ==============================|| ROUTING RENDER ||============================== //
8 |
9 | const router = createBrowserRouter([MainRoutes, PagesRoutes], {
10 | basename: import.meta.env.VITE_APP_BASE_URL
11 | });
12 |
13 | export default router;
14 |
--------------------------------------------------------------------------------
/src/themes/overrides/Popper.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - POPPER ||============================== //
2 |
3 | export default function Popper(theme) {
4 | return {
5 | MuiPopper: {
6 | styleOverrides: {
7 | root: {
8 | zIndex: 1201,
9 | '& .MuiPaper-root': {
10 | border: `1px solid ${theme.palette.divider}`
11 | }
12 | }
13 | }
14 | }
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/discord.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Discord Community | Materially - Admin Dashboard Template
5 |
6 |
7 |
8 |
9 | If you do not redirect please visit :
10 | https://discord.com/invite/p2E2WhCb6s
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/components/loader/index.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import LinearProgress from '@mui/material/LinearProgress';
3 | import Box from '@mui/material/Box';
4 |
5 | // ==============================|| LOADER ||============================== //
6 |
7 | export default function Loader() {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/themes/overrides/Checkbox.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - CHECKBOX ||============================== //
2 |
3 | export default function Checkbox(theme) {
4 | return {
5 | MuiCheckbox: {
6 | styleOverrides: {
7 | root: {
8 | color: theme.palette.text.secondary
9 | },
10 | indeterminate: {
11 | color: theme.palette.text.primary
12 | }
13 | }
14 | }
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react';
2 | import { createRoot } from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 |
6 | // google-fonts
7 | import '@fontsource/poppins/400.css';
8 | import '@fontsource/poppins/500.css';
9 | import '@fontsource/poppins/600.css';
10 | import '@fontsource/poppins/700.css';
11 |
12 | createRoot(document.getElementById('root')).render(
13 |
14 |
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/src/themes/overrides/CardHeader.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - CARD HEADER ||============================== //
2 |
3 | export default function CardHeader(theme) {
4 | return {
5 | MuiCardHeader: {
6 | styleOverrides: {
7 | root: {
8 | padding: 24
9 | },
10 | title: {
11 | ...theme.typography.h6,
12 | color: theme.palette.text.dark
13 | }
14 | }
15 | }
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/src/themes/overrides/FormHelperText.js:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import { alpha } from '@mui/material/styles';
3 |
4 | // ==============================|| OVERRIDES - FORM HELPER TEXT ||============================== //
5 |
6 | export default function FormHelperText(theme) {
7 | return {
8 | MuiFormHelperText: {
9 | styleOverrides: {
10 | root: {
11 | color: alpha(theme.palette.text.secondary, 0.73)
12 | }
13 | }
14 | }
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/src/sections/dashboard/chart/card-data/revenue-card-data.jsx:
--------------------------------------------------------------------------------
1 | // chart data
2 | import { revenueChartData } from '../chart-data/revenue-chart-data';
3 |
4 | export const revenueCardData = {
5 | title: 'Total Revenue',
6 | chartData: revenueChartData,
7 | bottomData: [
8 | { label: 'Youtube', value: '+16.85', color: 'primary.main' },
9 | { label: 'Facebook', value: '+45.36', color: 'success.main' },
10 | { label: 'Twitter', value: '-50.69', color: 'warning.main' }
11 | ]
12 | };
13 |
--------------------------------------------------------------------------------
/src/themes/shadow.js:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import { alpha } from '@mui/material/styles';
3 |
4 | // ==============================|| DEFAULT THEME - SHADOWS ||============================== //
5 |
6 | export default function Shadows(theme) {
7 | const secondaryDarker = theme.palette.secondary.darker;
8 | console.log('secondaryDarker:', secondaryDarker);
9 | return {
10 | posterShadow: `0px 16px 32px ${alpha(secondaryDarker, 0.15)}, 0px 8px 16px ${alpha(secondaryDarker, 0.1)}`
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/src/themes/overrides/SvgIcon.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - SVGICON ||============================== //
2 |
3 | export default function CardHeader() {
4 | return {
5 | MuiSvgIcon: {
6 | styleOverrides: {
7 | root: {
8 | fontSize: '1.3rem'
9 | },
10 | fontSizeInherit: {
11 | fontSize: 'inherit'
12 | },
13 | fontSizeLarge: {
14 | fontSize: '2.1875rem'
15 | }
16 | }
17 | }
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/documentation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Documentation
5 |
6 |
7 |
8 |
9 | If you do not redirect please visit :
10 | https://codedthemes.gitbook.io/materially-react-material-documentation/
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/views/auth/Register.jsx:
--------------------------------------------------------------------------------
1 | // project imports
2 | import CommonAuthLayout from './CommonAuthLayout';
3 | import AuthRegister from 'sections/auth/AuthRegister';
4 |
5 | // ==============================|| REGISTER ||============================== //
6 |
7 | export default function Register() {
8 | return (
9 |
10 | {/* Register form */}
11 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/src/views/auth/Login.jsx:
--------------------------------------------------------------------------------
1 | // project imports
2 | import CommonAuthLayout from './CommonAuthLayout';
3 | import AuthLogin from 'sections/auth/AuthLogin';
4 |
5 | // ==============================|| LOGIN ||============================== //
6 |
7 | export default function Login() {
8 | return (
9 |
14 | {/* Login form */}
15 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/src/views/dashboard/default/data/traffic-source-card-data.jsx:
--------------------------------------------------------------------------------
1 | export const trafficSourceData = {
2 | cardTitle: 'Traffic Sources',
3 | items: [
4 | { label: 'Direct', percentage: 80, progressValue: 80, progressColor: 'primary' },
5 | { label: 'Social', percentage: 50, progressValue: 50, progressColor: 'secondary' },
6 | { label: 'Referral', percentage: 20, progressValue: 20, progressColor: 'primary' },
7 | { label: 'Bounce', percentage: 60, progressValue: 60, progressColor: 'secondary' },
8 | { label: 'Internet', percentage: 40, progressValue: 40, progressColor: 'primary' }
9 | ]
10 | };
11 |
--------------------------------------------------------------------------------
/src/sections/dashboard/chart/chart-data/revenue-chart-data.js:
--------------------------------------------------------------------------------
1 | export const revenueChartData = {
2 | options: {
3 | dataLabels: {
4 | enabled: false
5 | },
6 | yaxis: {
7 | min: 0,
8 | max: 100
9 | },
10 | labels: ['YouTube', 'Facebook', 'Twitter'],
11 | legend: {
12 | show: true,
13 | position: 'bottom',
14 | fontFamily: 'inherit',
15 | labels: {
16 | colors: 'inherit'
17 | },
18 | itemMargin: {
19 | horizontal: 10,
20 | vertical: 5
21 | }
22 | }
23 | },
24 | series: [1258, 975, 500]
25 | };
26 |
--------------------------------------------------------------------------------
/src/enum.js:
--------------------------------------------------------------------------------
1 | /** Avatar custom props `size` enum */
2 | export let AvatarSize;
3 |
4 | (function (AvatarSize) {
5 | AvatarSize['BADGE'] = 'badge';
6 | AvatarSize['XS'] = 'xs';
7 | AvatarSize['SM'] = 'sm';
8 | AvatarSize['MD'] = 'md';
9 | AvatarSize['LG'] = 'lg';
10 | AvatarSize['XL'] = 'xl';
11 | })(AvatarSize || (AvatarSize = {}));
12 |
13 | /** Main Card type enum */
14 | export let CardVariant;
15 |
16 | (function (CardVariant) {
17 | CardVariant['DEFAULT'] = 'default';
18 | CardVariant['FILLED'] = 'filled';
19 | CardVariant['OUTLINED'] = 'outlined';
20 | })(CardVariant || (CardVariant = {}));
21 |
--------------------------------------------------------------------------------
/src/components/Loadable.jsx:
--------------------------------------------------------------------------------
1 | import { Suspense } from 'react';
2 |
3 | // project imports
4 | import Loader from './loader';
5 |
6 | // ==============================|| LOADABLE - LAZY LOADING ||============================== //
7 |
8 | /**
9 | * Higher-order component for lazy loading with suspense.
10 | *
11 | * @param Component - The component to be lazily loaded.
12 | * @returns A wrapped component with suspense fallback.
13 | */
14 | export default function Loadable(Component) {
15 | return (props) => (
16 | }>
17 |
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/src/views/dashboard/default/data/sales-line-chart-card-data.jsx:
--------------------------------------------------------------------------------
1 | // assets
2 | import TrendingDownIcon from '@mui/icons-material/TrendingDown';
3 |
4 | // chart data
5 | import { salesLineChart } from 'sections/dashboard/chart/chart-data/sales-line-chart';
6 |
7 | export const salesLineCardData = {
8 | chartData: salesLineChart,
9 | footerData: [
10 | {
11 | value: '$4230',
12 | label: 'Total Revenue'
13 | },
14 | {
15 | value: '321',
16 | label: 'Today Sales'
17 | }
18 | ],
19 | title: 'Sales Per Day',
20 | percentage: '3%',
21 | icon: TrendingDownIcon,
22 | bgColor: 'primary.main'
23 | };
24 |
--------------------------------------------------------------------------------
/src/menu-items/other.js:
--------------------------------------------------------------------------------
1 | // assets
2 | import ContactSupportOutlinedIcon from '@mui/icons-material/ContactSupportOutlined';
3 | import BlockOutlinedIcon from '@mui/icons-material/BlockOutlined';
4 |
5 | // ==============================|| MENU ITEMS - SUPPORT ||============================== //
6 |
7 | const other = {
8 | id: 'support',
9 | title: 'support',
10 | type: 'group',
11 | icon: ContactSupportOutlinedIcon,
12 | children: [
13 | {
14 | id: 'disabled-menu',
15 | title: 'Disabled Menu',
16 | type: 'item',
17 | icon: BlockOutlinedIcon,
18 | disabled: true
19 | }
20 | ]
21 | };
22 |
23 | export default other;
24 |
--------------------------------------------------------------------------------
/src/themes/overrides/Paper.js:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import { alpha } from '@mui/material/styles';
3 |
4 | // ==============================|| OVERRIDES - PAPER ||============================== //
5 |
6 | export default function Paper(theme) {
7 | const shadowColor = theme.palette.text.primary;
8 |
9 | return {
10 | MuiPaper: {
11 | styleOverrides: {
12 | root: { backgroundImage: 'none' },
13 | elevation1: {
14 | boxShadow: `0 4px 6px -2px ${alpha(shadowColor, 0.12)}, 0 2px 2px -1px ${alpha(shadowColor, 0.05)}`
15 | },
16 | rounded: {
17 | borderRadius: 10
18 | }
19 | }
20 | }
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Materially | Material UI React Dashboard Template
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/menu-items/dashboard.js:
--------------------------------------------------------------------------------
1 | // assets
2 | import NavigationOutlinedIcon from '@mui/icons-material/NavigationOutlined';
3 | import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined';
4 |
5 | // ==============================|| MENU ITEMS - DASHBOARD ||============================== //
6 |
7 | const dashboard = {
8 | id: 'dashboard',
9 | title: 'materially',
10 | caption: 'Dashboard',
11 | icon: NavigationOutlinedIcon,
12 | type: 'group',
13 | children: [
14 | {
15 | id: 'dashboards',
16 | title: 'Dashboard',
17 | type: 'item',
18 | icon: HomeOutlinedIcon,
19 | url: '/dashboard/default',
20 | breadcrumbs: false
21 | }
22 | ]
23 | };
24 |
25 | export default dashboard;
26 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "baseUrl": "src"
19 | },
20 | "exclude": ["node_modules", "eslint.config.mjs"],
21 | "include": ["src", "**/*.js", "**/*.jsx", "src/**/*"],
22 | "references": [{ "path": "./jsconfig.node.json" }]
23 | }
24 |
--------------------------------------------------------------------------------
/vite.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig, loadEnv } from 'vite';
2 | import react from '@vitejs/plugin-react';
3 | import jsconfigPaths from 'vite-jsconfig-paths';
4 |
5 | export default defineConfig(({ mode }) => {
6 | const env = loadEnv(mode, process.cwd(), '');
7 | const APP_BASE_URL = `${env.VITE_APP_BASE_URL}`;
8 | const PORT = 3000;
9 |
10 | return {
11 | server: {
12 | // this ensures that the browser opens upon server start
13 | open: true,
14 | // this sets a default port to 3000
15 | port: PORT,
16 | host: true
17 | },
18 | preview: {
19 | open: true,
20 | host: true
21 | },
22 | define: {
23 | global: 'window'
24 | },
25 | base: APP_BASE_URL,
26 | plugins: [react(), jsconfigPaths()]
27 | };
28 | });
29 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | /* simpebar styles */
2 | @import 'simplebar-react/dist/simplebar.min.css';
3 |
4 | @import 'simplebar-react/dist/simplebar.min.css';
5 |
6 | /* apex chart styles */
7 | .apexcharts-legend-marker {
8 | margin-right: 8px !important;
9 | }
10 |
11 | .apexcharts-legend-text {
12 | padding-right: 4px;
13 | }
14 |
15 | .apexcharts-canvas .apexcharts-svg {
16 | background: transparent !important;
17 | }
18 |
19 | /* If .apexcharts-tooltip-title is missing */
20 | .apexcharts-tooltip:not(:has(.apexcharts-tooltip-title)) > .apexcharts-active {
21 | padding-bottom: 0;
22 | }
23 |
24 | /* If .apexcharts-tooltip-title is present but empty */
25 | .apexcharts-tooltip:has(.apexcharts-tooltip-title:empty) > .apexcharts-active {
26 | padding-bottom: 0;
27 | }
28 |
29 | .apexcharts-tooltip-text-y-label:empty + .apexcharts-tooltip-text-y-value {
30 | margin-left: 0;
31 | }
32 |
--------------------------------------------------------------------------------
/src/routes/PagesRoutes.jsx:
--------------------------------------------------------------------------------
1 | import { lazy } from 'react';
2 |
3 | // project imports
4 | import Loadable from 'components/Loadable';
5 | import MinimalLayout from 'layouts/minimalLayout';
6 |
7 | // pages
8 | const LoginPage = Loadable(lazy(() => import('views/auth/Login')));
9 | const RegisterPage = Loadable(lazy(() => import('views/auth/Register')));
10 |
11 | // ==============================|| PAGES ROUTES ||============================== //
12 |
13 | const PagesRoutes = {
14 | path: 'pages',
15 | element: ,
16 | children: [
17 | {
18 | path: 'auth',
19 | children: [
20 | {
21 | path: 'login',
22 | element:
23 | },
24 | {
25 | path: 'register',
26 | element:
27 | }
28 | ]
29 | }
30 | ]
31 | };
32 |
33 | export default PagesRoutes;
34 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Drawer/DrawerContent/Navigation/index.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import Typography from '@mui/material/Typography';
3 | import Box from '@mui/material/Box';
4 |
5 | // project imports
6 | import menuItems from 'menu-items';
7 | import NavGroup from './NavGroup';
8 |
9 | // ==============================|| DRAWER CONTENT - RESPONSIVE DRAWER ||============================== //
10 |
11 | export default function NavigationDrawer() {
12 | const navGroups = menuItems.items.map((item, index) => {
13 | switch (item.type) {
14 | case 'group':
15 | return ;
16 | default:
17 | return (
18 |
19 | Fix - Navigation Group
20 |
21 | );
22 | }
23 | });
24 |
25 | return {navGroups};
26 | }
27 |
--------------------------------------------------------------------------------
/src/views/pages/SamplePage.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import Typography from '@mui/material/Typography';
3 |
4 | // project imports
5 | import MainCard from 'components/cards/MainCard';
6 |
7 | // ==============================|| SAMPLE PAGE ||============================== //
8 |
9 | export default function SamplePage() {
10 | return (
11 |
12 |
13 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
14 | ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
15 | reprehenderit in voluptate velit esse cillum dolore eu fugiatnulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
16 | culpa qui officia deserunt mollitanim id est laborum.
17 |
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/src/menu-items/ui-component.js:
--------------------------------------------------------------------------------
1 | // assets
2 | import HardwareOutlinedIcon from '@mui/icons-material/HardwareOutlined';
3 | import AppsOutlinedIcon from '@mui/icons-material/AppsOutlined';
4 | import FontDownloadIcon from '@mui/icons-material/FontDownload';
5 |
6 | // ==============================|| MENU ITEMS - UI COMPONENT ||============================== //
7 |
8 | const uiComponent = {
9 | id: 'utils',
10 | title: 'utils',
11 | type: 'group',
12 | icon: HardwareOutlinedIcon,
13 | children: [
14 | {
15 | id: 'util-icons',
16 | title: 'Icons',
17 | type: 'item',
18 | url: 'https://mui.com/material-ui/material-icons/',
19 | icon: AppsOutlinedIcon,
20 | external: true,
21 | target: '_blank'
22 | },
23 | {
24 | id: 'typography',
25 | title: 'Typography',
26 | type: 'item',
27 | url: '/components/typography',
28 | icon: FontDownloadIcon
29 | }
30 | ]
31 | };
32 |
33 | export default uiComponent;
34 |
--------------------------------------------------------------------------------
/src/views/dashboard/default/data/revenue-card-data.jsx:
--------------------------------------------------------------------------------
1 | // assets
2 | import AccountCircleTwoTone from '@mui/icons-material/AccountCircleTwoTone';
3 | import LocalMallTwoToneIcon from '@mui/icons-material/LocalMallTwoTone';
4 | import MonetizationOnTwoToneIcon from '@mui/icons-material/MonetizationOnTwoTone';
5 |
6 | export const revenueCardData = [
7 | {
8 | title: 'Revenue',
9 | value: '$42,562',
10 | content: '$50,032 Last Month',
11 | iconPrimary: MonetizationOnTwoToneIcon,
12 | color: 'warning.main',
13 | fullWidth: true
14 | },
15 | {
16 | title: 'Orders Received',
17 | value: '486',
18 | content: '20% Increase',
19 | iconPrimary: AccountCircleTwoTone,
20 | color: 'primary.main',
21 | fullWidth: false
22 | },
23 | {
24 | title: 'Total Sales',
25 | value: '1641',
26 | content: '$1,055 Revenue Generated',
27 | iconPrimary: LocalMallTwoToneIcon,
28 | color: 'success.main',
29 | fullWidth: false
30 | }
31 | ];
32 |
--------------------------------------------------------------------------------
/src/sections/dashboard/chart/chart-data/sales-line-chart.js:
--------------------------------------------------------------------------------
1 | export const salesLineChart = {
2 | options: {
3 | chart: {
4 | type: 'line',
5 | height: 115,
6 | sparkline: {
7 | enabled: true
8 | }
9 | },
10 | dataLabels: {
11 | enabled: false
12 | },
13 | stroke: {
14 | curve: 'smooth',
15 | width: 3
16 | },
17 | yaxis: {
18 | min: 20,
19 | max: 100,
20 | labels: {
21 | show: false
22 | }
23 | },
24 | tooltip: {
25 | theme: 'dark',
26 | fixed: {
27 | enabled: false
28 | },
29 | x: {
30 | show: false
31 | },
32 | y: {
33 | title: {
34 | formatter: () => 'Sales/Order Per Day'
35 | }
36 | },
37 | marker: {
38 | show: false
39 | }
40 | }
41 | },
42 | series: [
43 | {
44 | name: 'series1',
45 | data: [55, 35, 75, 25, 90, 50]
46 | }
47 | ]
48 | };
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 CodedThemes
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/themes/overrides/ListItemButton.js:
--------------------------------------------------------------------------------
1 | // ==============================|| OVERRIDES - LISTITEM BUTTON ||============================== //
2 |
3 | export default function ListItemButton(theme) {
4 | return {
5 | MuiListItemButton: {
6 | styleOverrides: {
7 | root: {
8 | color: theme.palette.text.primary,
9 | paddingTop: '12px',
10 | paddingBottom: '12px',
11 | '&.Mui-selected': {
12 | '& .MuiListItemIcon-root': {
13 | color: theme.palette.menu.selected
14 | },
15 | color: theme.palette.menu.selected,
16 | backgroundColor: theme.palette.menu.hover
17 | },
18 | '&:hover': {
19 | backgroundColor: theme.palette.menu.hover,
20 | color: theme.palette.menu.selected,
21 | '& .MuiListItemIcon-root': {
22 | color: theme.palette.menu.selected
23 | }
24 | },
25 | button: {
26 | '&:hover': {
27 | backgroundColor: theme.palette.menu.hover
28 | }
29 | }
30 | }
31 | }
32 | }
33 | };
34 | }
35 |
--------------------------------------------------------------------------------
/src/themes/overrides/index.js:
--------------------------------------------------------------------------------
1 | // third party
2 | import { merge } from 'lodash-es';
3 |
4 | // project imports
5 | import Avatar from './Avatar';
6 | import CardActions from './CardActions';
7 | import CardContent from './CardContent';
8 | import CardHeader from './CardHeader';
9 | import Checkbox from './Checkbox';
10 | import Chip from './Chip';
11 | import FormHelperText from './FormHelperText';
12 | import ListItem from './ListItem';
13 | import ListItemButton from './ListItemButton';
14 | import ListItemIcon from './ListItemIcon';
15 | import Paper from './Paper';
16 | import Popper from './Popper';
17 | import SvgIcon from './SvgIcon';
18 |
19 | // ==============================|| OVERRIDES - MAIN ||============================== //
20 |
21 | export default function ComponentsOverrides(theme) {
22 | return merge(
23 | Avatar(theme),
24 | CardActions(),
25 | CardContent(),
26 | CardHeader(theme),
27 | Checkbox(theme),
28 | Chip(theme),
29 | FormHelperText(theme),
30 | ListItem(theme),
31 | ListItemButton(theme),
32 | ListItemIcon(theme),
33 | Paper(theme),
34 | Popper(theme),
35 | SvgIcon()
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Drawer/DrawerContent/index.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import Stack from '@mui/material/Stack';
3 |
4 | // project imports
5 | import NavigationDrawer from './Navigation';
6 | import SimpleBar from 'components/third-party/SimpleBar';
7 | import { AppBar, CardMedia, Toolbar } from '@mui/material';
8 |
9 | // assets
10 | import logo from 'assets/images/logo.svg';
11 |
12 | // ==============================|| DRAWER - CONTENT ||============================== //
13 |
14 | export default function DrawerContent() {
15 | const contentHeight = `calc(100vh - 64px)`;
16 |
17 | return (
18 | <>
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | >
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/src/routes/MainRoutes.jsx:
--------------------------------------------------------------------------------
1 | import { lazy } from 'react';
2 |
3 | // project imports
4 | import Loadable from 'components/Loadable';
5 | import MainLayout from 'layouts/MainLayout';
6 |
7 | // pages
8 | const DashboardDefault = Loadable(lazy(() => import('views/dashboard/default')));
9 | const SamplePage = Loadable(lazy(() => import('views/pages/SamplePage')));
10 |
11 | // utils
12 | const UtilsTypography = Loadable(lazy(() => import('views/components/Typography')));
13 |
14 | // ==============================|| MAIN ROUTES ||============================== //
15 |
16 | const MainRoutes = {
17 | path: '/',
18 | element: ,
19 | children: [
20 | {
21 | path: '/',
22 | element:
23 | },
24 | {
25 | path: '/dashboard/default',
26 | element:
27 | },
28 | {
29 | path: '/sample-page',
30 | element:
31 | },
32 | {
33 | path: 'components',
34 | children: [
35 | {
36 | path: 'typography',
37 | element:
38 | }
39 | ]
40 | }
41 | ]
42 | };
43 |
44 | export default MainRoutes;
45 |
--------------------------------------------------------------------------------
/src/themes/index.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useMemo } from 'react';
3 |
4 | // material-ui
5 | import { createTheme, ThemeProvider } from '@mui/material/styles';
6 | import CssBaseline from '@mui/material/CssBaseline';
7 |
8 | // project imports
9 | import palette from './palette';
10 | import componentsOverride from './overrides';
11 | import typography from './typography';
12 |
13 | // ==============================|| DEFAULT THEME - MAIN ||============================== //
14 |
15 | export default function ThemeCustomization({ children }) {
16 | const themePalette = useMemo(() => palette('light'), []);
17 |
18 | const themeDefault = createTheme({
19 | palette: themePalette
20 | });
21 |
22 | // create duplicate theme due to responsive typography and fontFamily
23 | const theme = createTheme({
24 | ...themeDefault,
25 | typography: typography()
26 | });
27 |
28 | theme.components = componentsOverride(theme);
29 |
30 | return (
31 |
32 |
33 | {children}
34 |
35 | );
36 | }
37 |
38 | ThemeCustomization.propTypes = { children: PropTypes.any };
39 |
--------------------------------------------------------------------------------
/src/utils/passwordStrength.js:
--------------------------------------------------------------------------------
1 | // has number
2 | const hasNumber = (number) => new RegExp(/[0-9]/).test(number);
3 |
4 | // has mix of small and capitals
5 | const hasMixed = (number) => new RegExp(/[a-z]/).test(number) && new RegExp(/[A-Z]/).test(number);
6 |
7 | // has special chars
8 | const hasSpecial = (number) => new RegExp(/[!#@$%^&*)(+=._-]/).test(number);
9 |
10 | // set color based on password strength
11 | export const strengthColor = (count) => {
12 | if (count < 2) return { label: 'Poor', color: 'error.main' };
13 | if (count < 3) return { label: 'Weak', color: 'warning.main' };
14 | if (count < 4) return { label: 'Normal', color: 'warning.dark' };
15 | if (count < 5) return { label: 'Good', color: 'success.main' };
16 | if (count < 6) return { label: 'Strong', color: 'success.dark' };
17 | return { label: 'Poor', color: 'error.main' };
18 | };
19 |
20 | // password strength indicator
21 | export const strengthIndicator = (number = '') => {
22 | let strengths = 0;
23 | if (number.length > 5) strengths += 1;
24 | if (number.length > 7) strengths += 1;
25 | if (hasNumber(number)) strengths += 1;
26 | if (hasSpecial(number)) strengths += 1;
27 | if (hasMixed(number)) strengths += 1;
28 | return strengths;
29 | };
30 |
--------------------------------------------------------------------------------
/src/assets/images/social-google.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/.github/workflows/prod.yml:
--------------------------------------------------------------------------------
1 | name: Node - SSH deploy
2 |
3 | # Controls when the action will run.
4 | on:
5 | # Triggers the workflow on push or pull request events but only for the master branch
6 | push:
7 | branches:
8 | - main
9 |
10 | jobs:
11 | SFTP-deploy:
12 | name: 🎉 Deploy
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: 🚚 Get latest code
17 | uses: actions/checkout@v4
18 |
19 | - name: Use Node.js 22
20 | uses: actions/setup-node@v4
21 | with:
22 | node-version: '22'
23 |
24 | - name: 🔨 Build Project
25 | run: |
26 | corepack enable
27 | yarn set version 4.9.1
28 | yarn
29 | yarn build
30 |
31 | - name: 📂 Deploy to Server
32 | uses: easingthemes/ssh-deploy@main
33 | env:
34 | SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
35 | # ARGS: "-rltgoDzvO --delete"
36 | SOURCE: 'dist/'
37 | REMOTE_HOST: 82.29.156.38
38 | REMOTE_USER: u106957989
39 | REMOTE_PORT: '65002'
40 | TARGET: domains/codedthemes.com/public_html/demos/admin-templates/materially/react/free
41 | EXCLUDE: '/dist/, /node_modules/'
42 |
--------------------------------------------------------------------------------
/.github/workflows/stage.yml:
--------------------------------------------------------------------------------
1 | name: Node - SSH deploy
2 |
3 | # Controls when the action will run.
4 | on:
5 | # Triggers the workflow on push or pull request events but only for the master branch
6 | push:
7 | branches:
8 | - stage*
9 |
10 | jobs:
11 | SFTP-deploy:
12 | name: 🎉 Deploy
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: 🚚 Get latest code
17 | uses: actions/checkout@v4
18 |
19 | - name: Use Node.js 22
20 | uses: actions/setup-node@v4
21 | with:
22 | node-version: '22'
23 |
24 | - name: 🔨 Build Project
25 | run: |
26 | corepack enable
27 | yarn set version 4.9.1
28 | yarn
29 | yarn build-stage
30 |
31 | - name: 📂 Deploy to Server
32 | uses: easingthemes/ssh-deploy@main
33 | env:
34 | SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
35 | # ARGS: "-rltgoDzvO --delete"
36 | SOURCE: 'dist/'
37 | REMOTE_HOST: 82.29.156.38
38 | REMOTE_USER: u106957989
39 | REMOTE_PORT: '65002'
40 | TARGET: domains/codedthemes.com/public_html/demos/admin-templates/materially/react/free/stage
41 | EXCLUDE: '/dist/, /node_modules/'
42 |
--------------------------------------------------------------------------------
/src/components/cards/TrafficSourceCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | // material-ui
3 | import LinearProgress from '@mui/material/LinearProgress';
4 | import Stack from '@mui/material/Stack';
5 | import Typography from '@mui/material/Typography';
6 |
7 | // project imports
8 | import { GRID_SPACING } from 'config';
9 | import MainCard from './MainCard';
10 |
11 | // ==============================|| TRAFFIC SOURCE CARD ||============================== //
12 |
13 | export default function TrafficSourceCard({ cardTitle, items }) {
14 | return (
15 |
16 |
17 | {items.map((item, index) => (
18 |
19 |
20 | {item.label}
21 |
22 | {item.percentage}%
23 |
24 |
25 |
26 |
27 | ))}
28 |
29 |
30 | );
31 | }
32 |
33 | TrafficSourceCard.propTypes = { cardTitle: PropTypes.string, items: PropTypes.object };
34 |
--------------------------------------------------------------------------------
/src/states/menu.js:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react';
2 |
3 | // third party
4 | import useSWR, { mutate } from 'swr';
5 |
6 | const initialState = {
7 | openedItem: '',
8 | isDashboardDrawerOpened: false
9 | };
10 |
11 | export const endpoints = {
12 | key: 'api/menu',
13 | master: 'master'
14 | };
15 |
16 | export function useGetMenuMaster() {
17 | // to fetch initial state based on endpoints
18 |
19 | const { data, isLoading } = useSWR(endpoints.key + endpoints.master, () => initialState, {
20 | revalidateIfStale: false,
21 | revalidateOnFocus: false,
22 | revalidateOnReconnect: false
23 | });
24 |
25 | const memoizedValue = useMemo(
26 | () => ({
27 | menuMaster: data ?? initialState,
28 | menuMasterLoading: isLoading
29 | }),
30 | [data, isLoading]
31 | );
32 |
33 | return memoizedValue;
34 | }
35 |
36 | export function handlerDrawerOpen(isDashboardDrawerOpened) {
37 | // to update `isDashboardDrawerOpened` local state based on key
38 |
39 | mutate(
40 | endpoints.key + endpoints.master,
41 | (currentMenuMaster = initialState) => {
42 | return { ...currentMenuMaster, isDashboardDrawerOpened };
43 | },
44 | false
45 | );
46 | }
47 |
48 | export function handlerActiveItem(openedItem) {
49 | // to update `openedItem` local state based on key
50 |
51 | mutate(
52 | endpoints.key + endpoints.master,
53 | (currentMenuMaster = initialState) => {
54 | return { ...currentMenuMaster, openedItem };
55 | },
56 | false
57 | );
58 | }
59 |
--------------------------------------------------------------------------------
/src/views/dashboard/default/data/report-card-data.jsx:
--------------------------------------------------------------------------------
1 | // assets
2 | import CalendarTodayOutlinedIcon from '@mui/icons-material/CalendarTodayOutlined';
3 | import DescriptionOutlinedIcon from '@mui/icons-material/DescriptionOutlined';
4 | import MonetizationOnTwoToneIcon from '@mui/icons-material/MonetizationOnTwoTone';
5 | import ThumbUpAltTwoToneIcon from '@mui/icons-material/ThumbUpAltTwoTone';
6 | import TrendingDownIcon from '@mui/icons-material/TrendingDown';
7 | import TrendingUpIcon from '@mui/icons-material/TrendingUp';
8 |
9 | export const reportCardData = [
10 | {
11 | counter: '$30200',
12 | title: 'All Earnings',
13 | color: 'warning.main',
14 | footerData: '10% changes on profit',
15 | iconPrimary: MonetizationOnTwoToneIcon,
16 | iconFooter: TrendingUpIcon,
17 | coloredIcon: true
18 | },
19 | {
20 | counter: '145',
21 | title: 'Task',
22 | color: 'error.main',
23 | footerData: '28% task performance',
24 | iconPrimary: CalendarTodayOutlinedIcon,
25 | iconFooter: TrendingDownIcon,
26 | coloredIcon: true
27 | },
28 | {
29 | counter: '290+',
30 | title: 'Page Views',
31 | color: 'success.main',
32 | footerData: '10k daily views',
33 | iconPrimary: DescriptionOutlinedIcon,
34 | iconFooter: TrendingUpIcon,
35 | coloredIcon: true
36 | },
37 | {
38 | counter: '500',
39 | title: 'Downloads',
40 | color: 'primary.main',
41 | footerData: '1k download in App store',
42 | iconPrimary: ThumbUpAltTwoToneIcon,
43 | iconFooter: TrendingUpIcon,
44 | coloredIcon: true
45 | }
46 | ];
47 |
--------------------------------------------------------------------------------
/src/themes/typography.js:
--------------------------------------------------------------------------------
1 | // ==============================|| DEFAULT - TYPOGRAPHY ||============================== //
2 |
3 | export default function typography() {
4 | return {
5 | fontFamily: `'Poppins', sans-serif`,
6 | h6: {
7 | fontWeight: 600,
8 | fontSize: '0.875rem'
9 | },
10 | h5: {
11 | fontSize: '1.125rem',
12 | fontWeight: 600
13 | },
14 | h4: {
15 | fontSize: '1.25rem',
16 | fontWeight: 500
17 | },
18 | h3: {
19 | fontSize: '1.5rem',
20 | fontWeight: 600
21 | },
22 | h2: {
23 | fontSize: '2rem',
24 | fontWeight: 600
25 | },
26 | h1: {
27 | fontSize: '2.2rem',
28 | fontWeight: 600
29 | },
30 | subtitle1: {
31 | fontSize: '0.875rem',
32 | fontWeight: 500,
33 | lineHeight: '1.643em'
34 | },
35 | subtitle2: {
36 | fontSize: '0.8125rem',
37 | fontWeight: 400
38 | },
39 | caption: {
40 | fontSize: '0.68rem',
41 | fontWeight: 500
42 | },
43 | body1: {
44 | fontSize: '0.875rem',
45 | fontWeight: 400,
46 | lineHeight: '1.643em'
47 | },
48 | body2: {
49 | letterSpacing: '0em',
50 | fontWeight: 400,
51 | lineHeight: '1.643em'
52 | },
53 | menuCaption: {
54 | fontSize: '0.6875rem',
55 | fontWeight: 600,
56 | padding: '5px 15px 5px',
57 | textTransform: 'uppercase',
58 | marginTop: '10px'
59 | },
60 | subMenuCaption: {
61 | fontSize: '0.6875rem',
62 | fontWeight: 400,
63 | textTransform: 'capitalize'
64 | }
65 | };
66 | }
67 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/index.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useMemo } from 'react';
2 | import { Outlet } from 'react-router-dom';
3 |
4 | // material-ui
5 | import useMediaQuery from '@mui/material/useMediaQuery';
6 | import Stack from '@mui/material/Stack';
7 | import Toolbar from '@mui/material/Toolbar';
8 | import Box from '@mui/material/Box';
9 |
10 | // project imports
11 | import Drawer from './Drawer';
12 | import Header from './Header';
13 | import Breadcrumbs from 'components/Breadcrumbs';
14 |
15 | import { DRAWER_WIDTH } from 'config';
16 | import { handlerDrawerOpen, useGetMenuMaster } from 'states/menu';
17 |
18 | // ==============================|| MAIN LAYOUT ||============================== //
19 |
20 | export default function MainLayout() {
21 | const upLG = useMediaQuery((theme) => theme.breakpoints.up('lg'));
22 |
23 | const { menuMaster } = useGetMenuMaster();
24 | const drawerOpen = menuMaster.isDashboardDrawerOpened;
25 |
26 | useEffect(() => {
27 | handlerDrawerOpen(upLG);
28 | }, [upLG]);
29 |
30 | // drawer toggle handler on resize window
31 | // eslint-disable-next-line react-hooks/exhaustive-deps
32 | const drawer = useMemo(() => , [drawerOpen]);
33 |
34 | return (
35 |
36 |
37 | {drawer}
38 |
46 |
47 |
48 |
49 |
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/cards/ReportCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import Stack from '@mui/material/Stack';
5 | import Typography from '@mui/material/Typography';
6 |
7 | // project imports
8 | import MainCard from './MainCard';
9 |
10 | // ==============================|| REPORT CARD ||============================== //
11 |
12 | export default function ReportCard({ counter, title, iconPrimary: IconPrimary, footerData, color, iconFooter: IconFooter, coloredIcon }) {
13 | return (
14 |
17 | {footerData}
18 | {IconFooter && }
19 |
20 | }
21 | actionsDivider={false}
22 | cardActionsSX={{ bgcolor: color, py: 1.5 }}
23 | >
24 |
25 |
26 |
27 | {counter}
28 |
29 | {title}
30 |
31 | {IconPrimary && }
32 |
33 |
34 | );
35 | }
36 |
37 | ReportCard.propTypes = {
38 | counter: PropTypes.string,
39 | title: PropTypes.string,
40 | iconPrimary: PropTypes.any,
41 | footerData: PropTypes.string,
42 | color: PropTypes.string,
43 | iconFooter: PropTypes.any,
44 | coloredIcon: PropTypes.bool
45 | };
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "materially-free-react-admin-template",
3 | "version": "4.0.0",
4 | "license": "MIT",
5 | "type": "module",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview",
10 | "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
11 | "lint:fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\"",
12 | "prettier": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\""
13 | },
14 | "dependencies": {
15 | "@emotion/cache": "11.14.0",
16 | "@emotion/react": "11.14.0",
17 | "@emotion/styled": "11.14.0",
18 | "@fontsource/poppins": "5.2.6",
19 | "@mui/icons-material": "7.1.0",
20 | "@mui/material": "7.1.0",
21 | "@vitejs/plugin-react": "4.4.1",
22 | "apexcharts": "4.7.0",
23 | "lodash-es": "4.17.21",
24 | "react": "19.1.0",
25 | "react-apexcharts": "1.7.0",
26 | "react-device-detect": "2.2.3",
27 | "react-dom": "19.1.0",
28 | "react-hook-form": "7.56.4",
29 | "react-router-dom": "7.6.0",
30 | "simplebar-react": "3.3.1",
31 | "swr": "2.3.3",
32 | "vite": "6.3.5",
33 | "vite-jsconfig-paths": "2.0.1"
34 | },
35 | "devDependencies": {
36 | "@eslint/compat": "1.2.9",
37 | "@eslint/eslintrc": "3.3.1",
38 | "@eslint/js": "9.27.0",
39 | "env-cmd": "10.1.0",
40 | "eslint": "9.27.0",
41 | "eslint-config-prettier": "10.1.5",
42 | "eslint-plugin-jsx-a11y": "6.10.2",
43 | "eslint-plugin-prettier": "5.4.0",
44 | "eslint-plugin-react": "7.37.5",
45 | "eslint-plugin-react-hooks": "5.2.0",
46 | "prettier": "3.5.3",
47 | "prettier-eslint-cli": "8.0.1",
48 | "sass-embedded": "1.89.0"
49 | },
50 | "packageManager": "yarn@4.9.1"
51 | }
52 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Drawer/DrawerContent/Navigation/NavGroup.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import List from '@mui/material/List';
3 | import Typography from '@mui/material/Typography';
4 |
5 | // project imports
6 | import NavCollapse from './NavCollapse';
7 | import NavItem from './NavItem';
8 |
9 | // ==============================|| RESPONSIVE DRAWER - GROUP ||============================== //
10 |
11 | export default function NavGroup({ item }) {
12 | const renderNavItem = (menuItem) => {
13 | // Render items based on the type
14 | switch (menuItem.type) {
15 | case 'collapse':
16 | return ;
17 | case 'item':
18 | return ;
19 | default:
20 | return (
21 |
22 | Fix - Group Collapse or Items
23 |
24 | );
25 | }
26 | };
27 |
28 | return (
29 | ({ ...theme.typography.menuCaption, color: 'primary.main' })} gutterBottom>
33 | {item.title}
34 | {item.caption && (
35 | ({ ...theme.typography.subMenuCaption, color: 'text.primary' })} gutterBottom>
36 | {item.caption}
37 |
38 | )}
39 |
40 | }
41 | >
42 | {item.children?.map((menuItem) => renderNavItem(menuItem))}
43 |
44 | );
45 | }
46 |
47 | NavGroup.propTypes = { item: PropTypes.any };
48 |
--------------------------------------------------------------------------------
/src/components/third-party/SimpleBar.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import { alpha, styled } from '@mui/material/styles';
5 | import Box from '@mui/material/Box';
6 |
7 | // third party
8 | import SimpleBar from 'simplebar-react';
9 | import { BrowserView, MobileView } from 'react-device-detect';
10 |
11 | // root style
12 | const RootStyle = styled(BrowserView)({
13 | flexGrow: 1,
14 | height: '100%',
15 | overflow: 'hidden'
16 | });
17 |
18 | // scroll bar wrapper
19 | const SimpleBarStyle = styled(SimpleBar)(({ theme }) => ({
20 | maxHeight: '100%',
21 | '& .simplebar-scrollbar': {
22 | '&:before': {
23 | background: alpha(theme.palette.grey[500], 0.48)
24 | },
25 | '&.simplebar-visible:before': {
26 | opacity: 1
27 | }
28 | },
29 | '& .simplebar-track': {
30 | zIndex: 1201,
31 | '&.simplebar-vertical': {
32 | width: 10
33 | }
34 | },
35 | '& .simplebar-track.simplebar-horizontal .simplebar-scrollbar': {
36 | height: 6
37 | },
38 | '& .simplebar-mask': {
39 | zIndex: 'inherit'
40 | }
41 | }));
42 |
43 | // ==============================|| SIMPLE SCROLL BAR ||============================== //
44 |
45 | export default function SimpleBarScroll({ children, sx, ...other }) {
46 | return (
47 | <>
48 |
49 |
50 | {children}
51 |
52 |
53 |
54 |
55 | {children}
56 |
57 |
58 | >
59 | );
60 | }
61 |
62 | SimpleBarScroll.propTypes = { children: PropTypes.any, sx: PropTypes.any, other: PropTypes.any };
63 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Drawer/index.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | // material-ui
3 | import { alpha } from '@mui/material/styles';
4 | import useMediaQuery from '@mui/material/useMediaQuery';
5 | import Drawer from '@mui/material/Drawer';
6 | import Box from '@mui/material/Box';
7 |
8 | // project imports
9 | import DrawerContent from './DrawerContent';
10 |
11 | import { DRAWER_WIDTH } from 'config';
12 | import { handlerDrawerOpen, useGetMenuMaster } from 'states/menu';
13 |
14 | // ==============================|| MAIN LAYOUT - DRAWER ||============================== //
15 |
16 | export default function MainDrawer({ window }) {
17 | const downLG = useMediaQuery((theme) => theme.breakpoints.down('lg'));
18 |
19 | const { menuMaster } = useGetMenuMaster();
20 | const drawerOpen = menuMaster.isDashboardDrawerOpened;
21 |
22 | // Define container for drawer when window is specified
23 | const container = window !== undefined ? () => window().document.body : undefined;
24 |
25 | return (
26 |
27 | handlerDrawerOpen(false)}
32 | slotProps={{
33 | paper: {
34 | sx: (theme) => ({
35 | boxSizing: 'border-box',
36 | width: DRAWER_WIDTH,
37 | backgroundImage: 'none',
38 | boxShadow: `0 0.15rem 1.75rem 0 ${alpha(theme.palette.common.black, 0.15)}`,
39 | borderRight: 'none'
40 | })
41 | }
42 | }}
43 | >
44 |
45 |
46 |
47 | );
48 | }
49 |
50 | MainDrawer.propTypes = { window: PropTypes.func };
51 |
--------------------------------------------------------------------------------
/src/themes/palette.js:
--------------------------------------------------------------------------------
1 | // ==============================|| DEFAULT - PALETTE ||============================== //
2 |
3 | export default function palette(mode) {
4 | const lightPalette = {
5 | common: {
6 | black: '#232b38'
7 | },
8 | primary: {
9 | lighter: '#cbe2ff',
10 | light: '#4f8ef5',
11 | main: '#3366ff',
12 | dark: '#0043a9',
13 | darker: '#002d75',
14 | 100: '#4c6fff'
15 | },
16 | secondary: {
17 | lighter: '#d3d8db',
18 | light: '#727b80',
19 | main: '#5d646e',
20 | dark: '#272f33',
21 | darker: '#161a1c'
22 | },
23 | error: {
24 | lighter: '#fde4e2',
25 | light: '#ff625b',
26 | main: '#ec4333',
27 | dark: '#a20e00',
28 | darker: '#750800'
29 | },
30 | warning: {
31 | lighter: '#fef3d4',
32 | light: '#f8c256',
33 | main: '#f4a100',
34 | dark: '#aa7000',
35 | darker: '#754c00'
36 | },
37 | info: {
38 | lighter: '#d4f7f8',
39 | light: '#4de3e8',
40 | main: '#00cfd5',
41 | dark: '#009095',
42 | darker: '#005f63'
43 | },
44 | success: {
45 | lighter: '#d4f2e4',
46 | light: '#4fd29e',
47 | main: '#00ac69',
48 | dark: '#007849',
49 | darker: '#004e2e'
50 | },
51 | grey: {
52 | 300: '#425466'
53 | },
54 | bg: {
55 | 100: '#f8f8f9'
56 | },
57 | text: {
58 | primary: '#242c3a',
59 | secondary: '#a1a1a1',
60 | dark: '#12171e'
61 | },
62 | divider: '#dcdcdc',
63 | background: {
64 | paper: '#ffffff',
65 | default: '#f0f2f8'
66 | },
67 | menu: {
68 | hover: '#cbe2ff',
69 | selected: '#3366ff'
70 | }
71 | };
72 |
73 | return {
74 | mode,
75 | ...lightPalette
76 | };
77 | }
78 |
--------------------------------------------------------------------------------
/src/views/dashboard/default/index.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import Grid from '@mui/material/Grid';
3 | import Stack from '@mui/material/Stack';
4 |
5 | // project imports
6 | import ReportCard from 'components/cards/ReportCard';
7 | import SmallFlatCard from 'components/cards/SmallFlatCard';
8 | import TrafficSourceCard from 'components/cards/TrafficSourceCard';
9 | import RevenuChartCard from 'components/third-party/RevenuChartCard';
10 | import SalesLineChartCard from 'components/third-party/SalesLineChartCard';
11 | import { GRID_SPACING } from 'config';
12 |
13 | // data
14 | import { reportCardData } from './data/report-card-data';
15 | import { revenueCardData } from 'sections/dashboard/chart/card-data/revenue-card-data';
16 | import { salesLineCardData } from './data/sales-line-chart-card-data';
17 | import { smallFlatCardData } from './data/small-flat-card-data';
18 | import { trafficSourceData } from './data/traffic-source-card-data';
19 |
20 | // ==============================|| DASHBOARD DEFAULT ||============================== //
21 |
22 | export default function Default() {
23 | return (
24 |
25 | {reportCardData.map((data, index) => (
26 |
27 |
28 |
29 | ))}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Header/index.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import AppBar from '@mui/material/AppBar';
3 | import CardMedia from '@mui/material/CardMedia';
4 | import IconButton from '@mui/material/IconButton';
5 | import Stack from '@mui/material/Stack';
6 | import Toolbar from '@mui/material/Toolbar';
7 | import Box from '@mui/material/Box';
8 |
9 | // project imports
10 | import Notification from './Notification';
11 | import Profile from './Profile';
12 | import Search from './Search';
13 |
14 | import { DRAWER_WIDTH } from 'config';
15 | import { handlerDrawerOpen, useGetMenuMaster } from 'states/menu';
16 |
17 | // assets
18 | import logo from 'assets/images/logo.svg';
19 | import MenuTwoToneIcon from '@mui/icons-material/MenuTwoTone';
20 |
21 | // AppBar props, including styles that vary based on drawer state and screen size
22 | const appBar = { color: 'primary', position: 'fixed', sx: { width: 1, zIndex: { xs: 1100, lg: 1201 } } };
23 |
24 | // ==============================|| MAIN LAYOUT - HEADER ||============================== //
25 |
26 | export default function Header() {
27 | const { menuMaster } = useGetMenuMaster();
28 | const drawerOpen = menuMaster.isDashboardDrawerOpened;
29 |
30 | // Common header content
31 | const mainHeader = (
32 |
33 |
34 |
35 | handlerDrawerOpen(!drawerOpen)}
40 | size="large"
41 | >
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | );
53 |
54 | return {mainHeader};
55 | }
56 |
--------------------------------------------------------------------------------
/src/themes/overrides/Avatar.js:
--------------------------------------------------------------------------------
1 | // project imports
2 | import { AvatarSize } from 'enum';
3 |
4 | const colors = ['primary', 'secondary', 'success', 'error', 'warning', 'info'];
5 |
6 | // ==============================|| AVATAR - SIZE ||============================== //
7 |
8 | const avatarSizes = () => ({
9 | [AvatarSize.BADGE]: { width: 28, height: 28 },
10 | [AvatarSize.XS]: { width: 34, height: 34 },
11 | [AvatarSize.SM]: { width: 40, height: 40 },
12 | [AvatarSize.MD]: { width: 60, height: 60 },
13 | [AvatarSize.LG]: { width: 72, height: 72 },
14 | [AvatarSize.XL]: { width: 82, height: 82 }
15 | });
16 |
17 | // ==============================|| OVERRIDES - AVATAR ||============================== //
18 |
19 | export default function Avatar(theme) {
20 | const sizeVariants = () => {
21 | const styles = avatarSizes();
22 |
23 | return Object.values(AvatarSize).map((size) => ({
24 | props: { size },
25 | style: styles[size]
26 | }));
27 | };
28 |
29 | const colorVariants = colors.map((color) => {
30 | const paletteColor = theme.palette[color];
31 |
32 | return {
33 | props: { color },
34 | style: {
35 | color: theme.palette.background.paper,
36 | backgroundColor: paletteColor.main
37 | }
38 | };
39 | });
40 |
41 | return {
42 | MuiAvatar: {
43 | defaultProps: {
44 | color: 'default' // Set the default color here
45 | },
46 | styleOverrides: {
47 | root: {
48 | variants: [
49 | {
50 | props: { color: 'default' },
51 | style: {
52 | color: theme.palette.background.paper,
53 | backgroundColor: theme.palette.grey[500]
54 | }
55 | },
56 | ...colorVariants,
57 | ...sizeVariants(),
58 | {
59 | props: { type: 'outlined' },
60 | style: ({ color }) => {
61 | const paletteColor = color ? theme.palette[color] : null;
62 |
63 | return {
64 | border: `2px solid ${paletteColor ? paletteColor.main : theme.palette.grey[500]}`,
65 | backgroundColor: 'transparent',
66 | color: paletteColor ? paletteColor.main : theme.palette.grey[500]
67 | };
68 | }
69 | }
70 | ]
71 | }
72 | }
73 | }
74 | };
75 | }
76 |
--------------------------------------------------------------------------------
/src/menu-items/pages.js:
--------------------------------------------------------------------------------
1 | // assets
2 | import NavigationOutlinedIcon from '@mui/icons-material/NavigationOutlined';
3 | import ChromeReaderModeOutlinedIcon from '@mui/icons-material/ChromeReaderModeOutlined';
4 | import TranslateIcon from '@mui/icons-material/Translate';
5 | import SecurityOutlinedIcon from '@mui/icons-material/SecurityOutlined';
6 | import MonetizationOnOutlinedIcon from '@mui/icons-material/MonetizationOnOutlined';
7 | import ErrorOutlineRoundedIcon from '@mui/icons-material/ErrorOutlineRounded';
8 | import HourglassEmptyRoundedIcon from '@mui/icons-material/HourglassEmptyRounded';
9 | import HelpOutlineOutlinedIcon from '@mui/icons-material/HelpOutlineOutlined';
10 |
11 | const icons = {
12 | NavigationOutlinedIcon,
13 | ChromeReaderModeOutlinedIcon,
14 | TranslateIcon,
15 | SecurityOutlinedIcon,
16 | MonetizationOnOutlinedIcon,
17 | ErrorOutlineRoundedIcon,
18 | HourglassEmptyRoundedIcon,
19 | HelpOutlineOutlinedIcon
20 | };
21 |
22 | // ==============================|| MENU ITEMS - PAGES ||============================== //
23 |
24 | const pages = {
25 | id: 'pages',
26 | title: 'pages',
27 | caption: 'prebuild-pages',
28 | type: 'group',
29 | icon: icons.NavigationOutlinedIcon,
30 | children: [
31 | {
32 | id: 'sample-page',
33 | title: 'Sample Page',
34 | type: 'item',
35 | url: '/sample-page',
36 | icon: icons.ChromeReaderModeOutlinedIcon
37 | },
38 | {
39 | id: 'auth',
40 | title: 'Authentication',
41 | type: 'collapse',
42 | icon: icons.SecurityOutlinedIcon,
43 | children: [
44 | {
45 | id: 'login-1',
46 | title: 'login',
47 | type: 'item',
48 | url: '/pages/auth/login',
49 | target: '_blank'
50 | },
51 | {
52 | id: 'register',
53 | title: 'register',
54 | type: 'item',
55 | url: '/pages/auth/register',
56 | target: '_blank'
57 | }
58 | ]
59 | },
60 | {
61 | id: 'documentation',
62 | title: 'Documentation',
63 | type: 'item',
64 | url: 'https://codedthemes.gitbook.io/materially-react-material-documentation/',
65 | icon: icons.HelpOutlineOutlinedIcon,
66 | chip: {
67 | label: 'Help?',
68 | color: 'primary'
69 | },
70 | external: true,
71 | target: '_blank'
72 | }
73 | ]
74 | };
75 |
76 | export default pages;
77 |
--------------------------------------------------------------------------------
/src/views/components/Typography.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import Stack from '@mui/material/Stack';
3 | import Typography from '@mui/material/Typography';
4 |
5 | // project imports
6 | import MainCard from 'components/cards/MainCard';
7 |
8 | // ==============================|| UTILS - TYPOGRAPHY ||============================== //
9 |
10 | export default function UtilsTypography() {
11 | return (
12 |
13 |
14 |
15 | h1. Heading
16 |
17 |
18 | h2. Heading
19 |
20 |
21 | h3. Heading
22 |
23 |
24 | h4. Heading
25 |
26 |
27 | h5. Heading
28 |
29 |
30 | h6. Heading
31 |
32 |
33 | subtitle1. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur
34 |
35 |
36 | subtitle2. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur
37 |
38 |
39 | body1. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur unde suscipit, quam beatae rerum
40 | inventore consectetur, neque doloribus, cupiditate numquam dignissimos laborum fugiat deleniti? Eum quasi quidem quibusdam.
41 |
42 |
43 | body2. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quos blanditiis tenetur unde suscipit, quam beatae rerum
44 | inventore consectetur, neque doloribus, cupiditate numquam dignissimos laborum fugiat deleniti? Eum quasi quidem quibusdam.
45 |
46 |
47 | button text
48 |
49 |
50 | caption text
51 |
52 |
53 | overline text
54 |
55 |
56 |
57 | );
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/cards/SmallFlatCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import Grid from '@mui/material/Grid';
5 | import Stack from '@mui/material/Stack';
6 | import Typography from '@mui/material/Typography';
7 |
8 | // project imports
9 | import MainCard from './MainCard';
10 |
11 | // ==============================|| FLAT CARD ||============================== //
12 |
13 | export default function SmallFlatCard({ items }) {
14 | return (
15 |
16 | {
20 | const cols = { xs: 1, sm: 3, lg: 6 }; // Number of columns per row at each breakpoint
21 | return {
22 | alignItems: 'center',
23 | '& > *': { borderLeft: 1, borderBottom: 1, borderColor: 'divider' },
24 | // Remove left border for the first item in each row
25 | [`& > *:nth-of-type(${cols.xs}n + 1)`]: {
26 | [theme.breakpoints.down('sm')]: { borderLeft: 'none' }
27 | },
28 | [`& > *:nth-of-type(${cols.sm}n + 1)`]: {
29 | [theme.breakpoints.between('sm', 'lg')]: { borderLeft: 'none' }
30 | },
31 | [`& > *:nth-of-type(${cols.lg}n + 1)`]: {
32 | [theme.breakpoints.up('lg')]: { borderLeft: 'none' }
33 | },
34 | // Remove bottom border for last row
35 | [`& > *:nth-last-of-type(-n+${cols.xs})`]: {
36 | [theme.breakpoints.down('sm')]: { borderBottom: 'none' }
37 | },
38 | [`& > *:nth-last-of-type(-n+${cols.sm})`]: {
39 | [theme.breakpoints.between('sm', 'lg')]: { borderBottom: 'none' }
40 | },
41 | [`& > *:nth-last-of-type(-n+${cols.lg})`]: {
42 | [theme.breakpoints.up('lg')]: { borderBottom: 'none' }
43 | }
44 | };
45 | }}
46 | >
47 | {items.map((item, index) => (
48 |
49 |
50 | {item.label}
51 |
52 | {item.value}
53 |
54 |
55 |
56 | ))}
57 |
58 |
59 | );
60 | }
61 |
62 | SmallFlatCard.propTypes = { items: PropTypes.object };
63 |
--------------------------------------------------------------------------------
/src/views/auth/CommonAuthLayout.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { Link } from 'react-router-dom';
3 |
4 | // material-ui
5 | import CardMedia from '@mui/material/CardMedia';
6 | import Grid from '@mui/material/Grid';
7 | import Stack from '@mui/material/Stack';
8 | import Typography from '@mui/material/Typography';
9 | import Box from '@mui/material/Box';
10 |
11 | // project imports
12 | import MainCard from 'components/cards/MainCard';
13 |
14 | // assets
15 | import Logo from 'assets/images/logo-dark.svg';
16 |
17 | // ==============================|| COMMON AUTH LAYOUT ||============================== //
18 |
19 | export default function CommonAuthLayout({ title, subHeading, footerLink, children }) {
20 | return (
21 |
22 |
23 |
34 |
35 |
39 |
40 |
41 | {title}
42 |
43 |
44 | {subHeading}
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {children}
53 |
54 | {footerLink && (
55 |
56 | {footerLink.title}
57 |
58 | )}
59 |
60 |
61 |
62 | );
63 | }
64 |
65 | CommonAuthLayout.propTypes = {
66 | title: PropTypes.string,
67 | subHeading: PropTypes.string,
68 | footerLink: PropTypes.object,
69 | children: PropTypes.node
70 | };
71 |
--------------------------------------------------------------------------------
/src/components/third-party/SalesLineChartCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect, useState } from 'react';
3 |
4 | // material-ui
5 | import { useTheme } from '@mui/material/styles';
6 | import Stack from '@mui/material/Stack';
7 | import Typography from '@mui/material/Typography';
8 | import Box from '@mui/material/Box';
9 |
10 | // third party
11 | import ReactApexChart from 'react-apexcharts';
12 |
13 | // project imports
14 | import MainCard from 'components/cards/MainCard';
15 |
16 | // ==============================|| SALES LINE CHART CARD ||============================== //
17 |
18 | export default function SalesLineChartCard({ bgColor, chartData, footerData, icon: Icon, title, percentage }) {
19 | const theme = useTheme();
20 |
21 | const [chartDatas, setChartDatas] = useState(chartData);
22 | const chartColor = theme.palette.common.white;
23 |
24 | useEffect(() => {
25 | setChartDatas((prevState) => ({
26 | ...prevState,
27 | options: {
28 | ...prevState.options,
29 | tooltip: {
30 | theme: 'light'
31 | },
32 | colors: [chartColor]
33 | }
34 | }));
35 | }, [chartColor]);
36 |
37 | return (
38 |
42 | {footerData.map((data, index) => (
43 |
44 | {data.value}
45 | {data.label}
46 |
47 | ))}
48 |
49 | }
50 | >
51 |
52 |
53 |
54 |
55 | {title}
56 |
57 |
58 | {Icon && }
59 |
60 | {percentage}
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | );
69 | }
70 |
71 | SalesLineChartCard.propTypes = {
72 | bgColor: PropTypes.string,
73 | chartData: PropTypes.any,
74 | footerData: PropTypes.object,
75 | icon: PropTypes.any,
76 | title: PropTypes.string,
77 | percentage: PropTypes.string
78 | };
79 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { fixupConfigRules } from '@eslint/compat';
2 | import prettier from 'eslint-plugin-prettier';
3 | import react from 'eslint-plugin-react';
4 | import reactHooks from 'eslint-plugin-react-hooks';
5 | import jsxA11y from 'eslint-plugin-jsx-a11y';
6 | import js from '@eslint/js';
7 | import path from 'node:path';
8 | import { fileURLToPath } from 'node:url';
9 | import { FlatCompat } from '@eslint/eslintrc';
10 |
11 | const __filename = fileURLToPath(import.meta.url);
12 | const __dirname = path.dirname(__filename);
13 | const compat = new FlatCompat({
14 | baseDirectory: __dirname,
15 | recommendedConfig: js.configs.recommended,
16 | allConfig: js.configs.all
17 | });
18 |
19 | export default [
20 | ...fixupConfigRules(compat.extends('prettier')),
21 |
22 | {
23 | plugins: {
24 | prettier,
25 | react,
26 | 'react-hooks': reactHooks,
27 | 'jsx-a11y': jsxA11y
28 | },
29 |
30 | languageOptions: {
31 | ecmaVersion: 2020,
32 | sourceType: 'module',
33 | parserOptions: {
34 | ecmaFeatures: {
35 | jsx: true
36 | }
37 | }
38 | },
39 |
40 | settings: {
41 | react: {
42 | version: 'detect'
43 | }
44 | },
45 |
46 | rules: {
47 | 'react/jsx-filename-extension': 'off',
48 | 'no-param-reassign': 'off',
49 | 'react/prop-types': 'off',
50 | 'react/require-default-props': 'off',
51 | 'react/no-array-index-key': 'off',
52 | 'react/react-in-jsx-scope': 'off',
53 | 'react/jsx-props-no-spreading': 'off',
54 | 'import/order': 'off',
55 | 'no-console': 'off',
56 | 'no-shadow': 'off',
57 | 'import/no-cycle': 'off',
58 | 'import/no-extraneous-dependencies': 'off',
59 | 'jsx-a11y/label-has-associated-control': 'off',
60 | 'jsx-a11y/no-autofocus': 'off',
61 | 'react/jsx-uses-react': 'off',
62 | 'react/jsx-uses-vars': 'error',
63 | 'react-hooks/rules-of-hooks': 'error',
64 | 'react-hooks/exhaustive-deps': 'warn',
65 | 'no-unused-vars': 'off',
66 |
67 | 'no-restricted-imports': [
68 | 'error',
69 | {
70 | patterns: ['@mui/*/*/*', '!@mui/material/test-utils/*']
71 | }
72 | ],
73 |
74 | 'no-unused-vars': [
75 | 'error',
76 | {
77 | vars: 'all',
78 | args: 'none'
79 | }
80 | ],
81 |
82 | 'prettier/prettier': [
83 | 'warn',
84 | {
85 | bracketSpacing: true,
86 | printWidth: 140,
87 | singleQuote: true,
88 | trailingComma: 'none',
89 | tabWidth: 2,
90 | useTabs: false
91 | }
92 | ]
93 | }
94 | },
95 | {
96 | ignores: ['node_modules/**'],
97 | files: ['src/**/*.{js,jsx}']
98 | }
99 | ];
--------------------------------------------------------------------------------
/src/components/third-party/RevenuChartCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect, useState } from 'react';
3 |
4 | // material-ui
5 | import { useTheme } from '@mui/material/styles';
6 | import useMediaQuery from '@mui/material/useMediaQuery';
7 | import Divider from '@mui/material/Divider';
8 | import Grid from '@mui/material/Grid';
9 | import Stack from '@mui/material/Stack';
10 | import Typography from '@mui/material/Typography';
11 |
12 | // third party
13 | import ReactApexChart from 'react-apexcharts';
14 |
15 | // project imports
16 | import MainCard from 'components/cards/MainCard';
17 |
18 | // ==============================|| REVENUE CHART CARD ||============================== //
19 |
20 | export default function RevenuChartCard({ title, bottomData, chartData }) {
21 | const theme = useTheme();
22 |
23 | const onlySM = useMediaQuery(theme.breakpoints.only('sm'));
24 |
25 | const [chartDatas, setChartDatas] = useState(chartData);
26 |
27 | const primaryMain = theme.palette.primary.main;
28 | const infoMain = theme.palette.info.main;
29 | const errorMain = theme.palette.error.main;
30 | const divider = theme.palette.background.paper;
31 |
32 | useEffect(() => {
33 | setChartDatas((prevState) => ({
34 | ...prevState,
35 | options: {
36 | ...prevState.options,
37 | tooltip: {
38 | theme: 'light'
39 | },
40 | theme: {
41 | mode: 'light'
42 | },
43 | colors: [errorMain, primaryMain, infoMain],
44 | stroke: {
45 | colors: divider
46 | }
47 | }
48 | }));
49 | }, [errorMain, primaryMain, infoMain, divider]);
50 |
51 | return (
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | {bottomData?.map((data, index) => (
63 |
64 | {data.label}
65 |
66 | {data.value}%
67 |
68 |
69 | ))}
70 |
71 |
72 |
73 |
74 | );
75 | }
76 |
77 | RevenuChartCard.propTypes = { title: PropTypes.string, bottomData: PropTypes.object, chartData: PropTypes.any };
78 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Header/Search.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | // material-ui
4 | import { useTheme, useMediaQuery, alpha } from '@mui/material';
5 | import IconButton from '@mui/material/IconButton';
6 | import InputAdornment from '@mui/material/InputAdornment';
7 | import Popper from '@mui/material/Popper';
8 | import TextField from '@mui/material/TextField';
9 | import Box from '@mui/material/Box';
10 |
11 | // assets
12 | import CloseIcon from '@mui/icons-material/Close';
13 | import SearchIcon from '@mui/icons-material/Search';
14 |
15 | const color = 'grey.100';
16 |
17 | // ==============================|| SEARCH ||============================== //
18 |
19 | export default function Search() {
20 | const theme = useTheme();
21 | const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
22 |
23 | const [anchorEl, setAnchorEl] = useState(null);
24 |
25 | const handleClick = (event) => {
26 | setAnchorEl(anchorEl ? null : event.currentTarget);
27 | };
28 |
29 | const open = Boolean(anchorEl);
30 | const id = open ? 'simple-popper' : undefined;
31 |
32 | useEffect(() => {
33 | if (!isMobile && anchorEl) {
34 | setAnchorEl(null);
35 | }
36 | }, [isMobile, anchorEl]);
37 |
38 | return isMobile ? (
39 | <>
40 |
41 |
42 |
43 |
51 |
52 |
53 |
60 |
61 |
62 |
63 |
64 |
65 | >
66 | ) : (
67 |
75 |
76 |
77 | )
78 | }
79 | }}
80 | sx={{
81 | mr: 3,
82 | bgcolor: alpha(theme.palette.common.white, 0.15),
83 | ':hover': { bgcolor: alpha(theme.palette.common.white, 0.25) },
84 | borderRadius: 1,
85 | '& .MuiInputBase-input': {
86 | transition: theme.transitions.create('width'),
87 | color: 'grey.100',
88 | width: { sm: 100, md: 125 },
89 | mr: { md: 3 },
90 | '&:focus': { width: { md: 225 } }
91 | },
92 | '& .MuiOutlinedInput-notchedOutline': { border: 'none' }
93 | }}
94 | />
95 | );
96 | }
97 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Drawer/DrawerContent/Navigation/NavItem.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect } from 'react';
3 | import { Link, useLocation } from 'react-router-dom';
4 |
5 | // material-ui
6 | import { useTheme } from '@mui/material/styles';
7 | import useMediaQuery from '@mui/material/useMediaQuery';
8 | import Avatar from '@mui/material/Avatar';
9 | import Chip from '@mui/material/Chip';
10 | import ListItemButton from '@mui/material/ListItemButton';
11 | import ListItemIcon from '@mui/material/ListItemIcon';
12 | import ListItemText from '@mui/material/ListItemText';
13 | import Typography from '@mui/material/Typography';
14 |
15 | // project imports
16 | import { handlerActiveItem, handlerDrawerOpen, useGetMenuMaster } from 'states/menu';
17 |
18 | // assets
19 | import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
20 |
21 | // ==============================|| RESPONSIVE DRAWER - ITEM ||============================== //
22 |
23 | export default function NavItem({ item, level = 0 }) {
24 | const theme = useTheme();
25 | const { menuMaster } = useGetMenuMaster();
26 | const openItem = menuMaster.openedItem;
27 |
28 | const downLG = useMediaQuery(theme.breakpoints.down('lg'));
29 |
30 | const location = useLocation();
31 |
32 | useEffect(() => {
33 | if (location.pathname === item.url) handlerActiveItem(item.id);
34 | // eslint-disable-next-line react-hooks/exhaustive-deps
35 | }, [location.pathname]);
36 |
37 | const itemHandler = () => {
38 | if (downLG) handlerDrawerOpen(false);
39 | };
40 |
41 | const Icon = item.icon;
42 | const itemIcon = item.icon ? : 0 ? 'inherit' : 'medium'} />;
43 |
44 | return (
45 | 1 && { bgcolor: 'transparent !important', py: 1 })
59 | }}
60 | >
61 | {itemIcon}
62 | 1 ? 2 : 1.4 }} variant={openItem === item.id ? 'subtitle1' : 'body1'} color="inherit">
65 | {item.title}
66 |
67 | }
68 | secondary={
69 | item.caption && (
70 |
71 | {item.caption}
72 |
73 | )
74 | }
75 | />
76 | {item.chip && (
77 | {item.chip.avatar} : item.chip.avatar}
83 | />
84 | )}
85 |
86 | );
87 | }
88 |
89 | NavItem.propTypes = { item: PropTypes.any, level: PropTypes.number };
90 |
--------------------------------------------------------------------------------
/src/components/cards/MainCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useMemo } from 'react';
3 |
4 | // material-ui
5 | import { useTheme } from '@mui/material/styles';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import CardHeader from '@mui/material/CardHeader';
10 | import Divider from '@mui/material/Divider';
11 |
12 | // project imports
13 | import { CardVariant } from 'enum';
14 |
15 | function MainCard({
16 | title,
17 | content = true,
18 | actions,
19 | headerAction,
20 | headerDivider = true,
21 | headerSX = {},
22 | actionsDivider = true,
23 | contentSX = {},
24 | cardActionsSX = {},
25 | children,
26 | variant = { type: CardVariant.DEFAULT },
27 | sx = {},
28 | ref,
29 | ...others
30 | }) {
31 | const theme = useTheme();
32 |
33 | const cardColors = useMemo(
34 | () => ({
35 | primary: theme.palette.primary.main,
36 | secondary: theme.palette.secondary.main,
37 | error: theme.palette.error.main,
38 | warning: theme.palette.warning.main,
39 | info: theme.palette.info.main,
40 | success: theme.palette.success.main
41 | }),
42 | [theme]
43 | );
44 |
45 | function CardDivider() {
46 | return (
47 |
55 | );
56 | }
57 |
58 | return (
59 |
71 | {title && (
72 | <>
73 |
81 | {headerDivider && }
82 | >
83 | )}
84 |
85 | {/* card content */}
86 | {content ? {children} : children}
87 |
88 | {/* card actions */}
89 | {actions && (
90 | <>
91 | {actionsDivider && }
92 | {actions}
93 | >
94 | )}
95 |
96 | );
97 | }
98 |
99 | export default MainCard;
100 |
101 | MainCard.propTypes = {
102 | title: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
103 | content: PropTypes.bool,
104 | actions: PropTypes.node,
105 | headerAction: PropTypes.any,
106 | headerDivider: PropTypes.bool,
107 | headerSX: PropTypes.object,
108 | actionsDivider: PropTypes.bool,
109 | contentSX: PropTypes.object,
110 | cardActionsSX: PropTypes.object,
111 | children: PropTypes.any,
112 | variant: PropTypes.object,
113 | sx: PropTypes.object,
114 | ref: PropTypes.object,
115 | others: PropTypes.any
116 | };
117 |
--------------------------------------------------------------------------------
/src/sections/auth/AuthLogin.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useState } from 'react';
3 | import { Link as RouterLink } from 'react-router-dom';
4 |
5 | // material-ui
6 | import Button from '@mui/material/Button';
7 | import FormControl from '@mui/material/FormControl';
8 | import FormHelperText from '@mui/material/FormHelperText';
9 | import InputAdornment from '@mui/material/InputAdornment';
10 | import InputLabel from '@mui/material/InputLabel';
11 | import Link from '@mui/material/Link';
12 | import OutlinedInput from '@mui/material/OutlinedInput';
13 | import Stack from '@mui/material/Stack';
14 | import TextField from '@mui/material/TextField';
15 | import Box from '@mui/material/Box';
16 |
17 | // third party
18 | import { useForm } from 'react-hook-form';
19 |
20 | // project imports
21 | import { emailSchema, passwordSchema } from 'utils/validationSchema';
22 |
23 | // assets
24 | import Visibility from '@mui/icons-material/Visibility';
25 | import VisibilityOff from '@mui/icons-material/VisibilityOff';
26 |
27 | // ==============================|| AUTH - LOGIN ||============================== //
28 |
29 | export default function AuthLogin({ inputSx }) {
30 | const [isPasswordVisible, setIsPasswordVisible] = useState(false);
31 |
32 | // Initialize react-hook-form
33 | const {
34 | register,
35 | formState: { errors }
36 | } = useForm();
37 |
38 | return (
39 |
96 | );
97 | }
98 |
99 | AuthLogin.propTypes = { inputSx: PropTypes.any };
100 |
--------------------------------------------------------------------------------
/src/utils/validationSchema.js:
--------------------------------------------------------------------------------
1 | export const emailSchema = {
2 | required: 'Email is required',
3 | pattern: {
4 | value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
5 | message: 'Invalid email address'
6 | }
7 | };
8 |
9 | export const passwordSchema = {
10 | required: 'Password is required',
11 | minLength: { value: 8, message: 'Password must be at least 8 characters' },
12 | validate: {
13 | noSpaces: (value) => (value?.includes(' ') ? 'Password cannot contain spaces' : true),
14 | hasUpperCase: (value) => (/[A-Z]/.test(value || '') ? true : 'Password must have at least one uppercase letter'),
15 | hasNumber: (value) => (/[0-9]/.test(value || '') ? true : 'Password must have at least one number'),
16 | hasSpecialChar: (value) => (/[^A-Za-z0-9]/.test(value || '') ? true : 'Password must have at least one special character')
17 | }
18 | };
19 |
20 | export const firstNameSchema = {
21 | required: 'First name is required',
22 | pattern: { value: /^[a-zA-Z\s]+$/, message: 'Invalid first name' },
23 | validate: {
24 | trim: (value) => {
25 | const trimmedValue = value.trim();
26 | return trimmedValue.length > 0 || 'First name cannot be empty or contain only spaces';
27 | }
28 | },
29 | onBlur: (e) => {
30 | e.target.value = e.target.value.trim();
31 | }
32 | };
33 |
34 | export const lastNameSchema = {
35 | required: 'Last name is required',
36 | pattern: { value: /^[a-zA-Z\s]+$/, message: 'Invalid last name' },
37 | validate: {
38 | trim: (value) => {
39 | const trimmedValue = value.trim();
40 | return trimmedValue.length > 0 || 'Last name cannot be empty or contain only spaces';
41 | }
42 | },
43 | onBlur: (e) => {
44 | e.target.value = e.target.value.trim();
45 | }
46 | };
47 |
48 | export const contactSchema = {
49 | required: 'Contact number is required',
50 | pattern: { value: /^[0-9().-]{7,15}$/, message: 'Invalid contact number' }
51 | };
52 |
53 | export const otpSchema = {
54 | required: 'OTP is required',
55 | minLength: { value: 6, message: 'OTP must be exactly 6 characters' }
56 | };
57 |
58 | export const radioBoxSchema = {
59 | required: 'Option selection is required'
60 | };
61 |
62 | export const colorSchema = {
63 | validate: (value) => (value.length > 0 ? true : 'At least one color is required')
64 | };
65 |
66 | export const cardSchema = {
67 | cardName: { required: 'Card name is required' },
68 | cardNumber: { required: 'Card number is required' }
69 | };
70 |
71 | export const roleSchema = {
72 | role: {
73 | required: 'Role selection is required',
74 | maxLength: { value: 50, message: 'Role must be at most 50 characters' },
75 | pattern: { value: /^[a-z\d\-/#_\s]+$/i, message: 'Only alphanumerics are allowed' }
76 | },
77 | skills: {
78 | required: 'Skill selection is required',
79 | validate: (value) => {
80 | if (value.length < 3) return 'Skill tags field must have at least 3 items';
81 | if (value.length > 15) return 'Please select a maximum of 15 skills.';
82 | return true;
83 | }
84 | }
85 | };
86 |
87 | export const addressSchema = {
88 | country: {
89 | required: 'Country is required'
90 | },
91 | region: {
92 | required: 'Region required'
93 | },
94 | city: {
95 | required: 'City is required'
96 | },
97 | address: {
98 | required: 'Address is required'
99 | },
100 | postCode: {
101 | required: 'Postcode is required'
102 | }
103 | };
104 |
105 | export const nameSchema = {
106 | required: 'Name is required',
107 | pattern: { value: /^[a-zA-Z\s]+$/, message: 'Invalid name' },
108 | validate: {
109 | trim: (value) => {
110 | const trimmedValue = value.trim();
111 | return trimmedValue.length > 0 || 'Name cannot be empty or contain only spaces';
112 | }
113 | },
114 | onBlur: (e) => {
115 | e.target.value = e.target.value?.trim();
116 | }
117 | };
118 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Header/Profile.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | // material-ui
4 | import ClickAwayListener from '@mui/material/ClickAwayListener';
5 | import Fade from '@mui/material/Fade';
6 | import IconButton from '@mui/material/IconButton';
7 | import List from '@mui/material/List';
8 | import ListItemButton from '@mui/material/ListItemButton';
9 | import ListItemIcon from '@mui/material/ListItemIcon';
10 | import ListItemText from '@mui/material/ListItemText';
11 | import Popper from '@mui/material/Popper';
12 | import Box from '@mui/material/Box';
13 |
14 | // third party
15 | import { useLocation, useNavigate } from 'react-router-dom';
16 |
17 | // project imports
18 | import MainCard from 'components/cards/MainCard';
19 |
20 | // assets
21 | import AccountCircleTwoToneIcon from '@mui/icons-material/AccountCircleTwoTone';
22 | import DraftsTwoToneIcon from '@mui/icons-material/DraftsTwoTone';
23 | import LockOpenTwoTone from '@mui/icons-material/LockOpenTwoTone';
24 | import MeetingRoomTwoToneIcon from '@mui/icons-material/MeetingRoomTwoTone';
25 | import PersonTwoToneIcon from '@mui/icons-material/PersonTwoTone';
26 | import SettingsTwoToneIcon from '@mui/icons-material/SettingsTwoTone';
27 |
28 | const menuItems = [
29 | { icon: , label: 'Settings' },
30 | { icon: , label: 'Profile' },
31 | { icon: , label: 'My Messages' },
32 | { icon: , label: 'Lock Screen' },
33 | { icon: , label: 'Logout' }
34 | ];
35 |
36 | // ==============================|| PROFILE ||============================== //
37 |
38 | export default function Profile() {
39 | const [open, setOpen] = useState(false);
40 | const [anchorEl, setAnchorEl] = useState(null);
41 | const [selectedIndex, setSelectedIndex] = useState(null);
42 | const navigate = useNavigate();
43 | const location = useLocation();
44 |
45 | const handleClick = (event) => {
46 | setAnchorEl(event.currentTarget);
47 | setOpen((prev) => !prev);
48 | };
49 |
50 | const handleClickAway = () => setOpen(false);
51 |
52 | useEffect(() => {
53 | const index = menuItems.findIndex((item) => item.path && location.pathname.startsWith(item.path));
54 | setSelectedIndex(index !== -1 ? index : null);
55 | }, [location.pathname]);
56 |
57 | const handleMenuItemClick = (index, item) => {
58 | setSelectedIndex(index);
59 |
60 | if (item.path) {
61 | navigate(item.path);
62 | } else if (item.action) {
63 | item.action();
64 | }
65 | };
66 |
67 | const canBeOpen = open && Boolean(anchorEl);
68 | const id = canBeOpen ? 'profile-popper' : undefined;
69 |
70 | return (
71 |
72 |
73 |
74 |
75 |
76 |
77 |
86 | {({ TransitionProps }) => (
87 |
88 |
89 |
90 | {menuItems.map((item, index) => (
91 | handleMenuItemClick(index, item)}>
92 | {item.icon}
93 |
94 |
95 | ))}
96 |
97 |
98 |
99 | )}
100 |
101 |
102 |
103 | );
104 | }
105 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Drawer/DrawerContent/Navigation/NavCollapse.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect, useState } from 'react';
3 | import { useLocation } from 'react-router-dom';
4 |
5 | // material-ui
6 | import Collapse from '@mui/material/Collapse';
7 | import List from '@mui/material/List';
8 | import ListItemButton from '@mui/material/ListItemButton';
9 | import ListItemIcon from '@mui/material/ListItemIcon';
10 | import ListItemText from '@mui/material/ListItemText';
11 | import Typography from '@mui/material/Typography';
12 |
13 | // project imports
14 | import NavItem from './NavItem';
15 |
16 | // assets
17 | import ExpandLess from '@mui/icons-material/ExpandLess';
18 | import ExpandMore from '@mui/icons-material/ExpandMore';
19 | import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
20 |
21 | // ==============================|| RESPONSIVE DRAWER - COLLAPSE ||============================== //
22 |
23 | function NavCollapseLoop({ item, level }) {
24 | return item.children?.map((item) => {
25 | switch (item.type) {
26 | case 'collapse':
27 | return ;
28 | case 'item':
29 | return ;
30 | default:
31 | return (
32 |
33 | Fix - Collapse or Item
34 |
35 | );
36 | }
37 | });
38 | }
39 |
40 | // ==============================|| RESPONSIVE DRAWER - COLLAPSE ||============================== //
41 |
42 | export default function NavCollapse({ item, level }) {
43 | const [open, setOpen] = useState(false);
44 | const [selected, setSelected] = useState(null);
45 |
46 | // Active item collapse on page load with sub-levels
47 | const { pathname } = useLocation();
48 |
49 | const checkOpenForParent = (child, id) => {
50 | child.forEach((list) => {
51 | if (list.url === pathname) {
52 | setOpen(true);
53 | setSelected(id);
54 | }
55 | });
56 | };
57 |
58 | useEffect(() => {
59 | setOpen(false);
60 | setSelected(null);
61 | if (item.children) {
62 | item.children.forEach((list) => {
63 | if (list.children?.length) {
64 | checkOpenForParent(list.children, item.id);
65 | }
66 |
67 | if (list.url === pathname) {
68 | setSelected(item.id);
69 | setOpen(true);
70 | }
71 | });
72 | }
73 |
74 | // eslint-disable-next-line react-hooks/exhaustive-deps
75 | }, [pathname, item.children]);
76 |
77 | const handleClick = () => {
78 | setOpen(!open);
79 | };
80 |
81 | const Icon = item.icon;
82 | const menuIcon = item.icon ? : 0 ? 'inherit' : 'medium'} />;
83 |
84 | return (
85 | <>
86 | 1 && { bgcolor: 'transparent !important', py: 1 })
94 | }}
95 | onClick={handleClick}
96 | >
97 | {{menuIcon}}
98 |
101 | {item.title}
102 |
103 | }
104 | secondary={
105 | item.caption && (
106 | ({ ...theme.typography.subMenuCaption, pl: 2 })} display="block" gutterBottom>
107 | {item.caption}
108 |
109 | )
110 | }
111 | />
112 | {open ? : }
113 |
114 |
115 |
116 |
117 |
118 |
119 | >
120 | );
121 | }
122 |
123 | NavCollapseLoop.propTypes = { item: PropTypes.any, level: PropTypes.number };
124 |
125 | NavCollapse.propTypes = { item: PropTypes.any, level: PropTypes.number };
126 |
--------------------------------------------------------------------------------
/src/components/Breadcrumbs.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect, useState } from 'react';
3 | import { Link, useLocation } from 'react-router-dom';
4 |
5 | import MuiBreadcrumbs from '@mui/material/Breadcrumbs';
6 | import Divider from '@mui/material/Divider';
7 | import Stack from '@mui/material/Stack';
8 | import Typography from '@mui/material/Typography';
9 |
10 | // project imports
11 | import { APP_DEFAULT_PATH } from 'config';
12 | import menuItems from 'menu-items';
13 |
14 | //assets
15 | import HomeTwoToneIcon from '@mui/icons-material/HomeTwoTone';
16 |
17 | const homeBreadcrumb = { title: 'Home', url: APP_DEFAULT_PATH, icon: HomeTwoToneIcon };
18 | const flexStyle = { display: 'flex', alignItems: 'center', gap: 0.5 };
19 |
20 | // ==============================|| BREADCRUMBS ||============================== //
21 |
22 | export default function Breadcrumbs({ data, divider = true, title, icons = false, sx, ...rest }) {
23 | const location = useLocation();
24 |
25 | const [breadcrumbItems, setBreadcrumbItems] = useState([]);
26 | const [activeItem, setActiveItem] = useState();
27 |
28 | useEffect(() => {
29 | if (data?.length) {
30 | dataHandler(data);
31 | } else {
32 | for (const menu of menuItems?.items ?? []) {
33 | if (menu.type && menu.type === 'group') {
34 | const matchedParents = findParentElements(menu.children || [], location.pathname);
35 | dataHandler(matchedParents || []);
36 | if (matchedParents) break;
37 | }
38 | }
39 | }
40 | // eslint-disable-next-line react-hooks/exhaustive-deps
41 | }, [data, location]);
42 |
43 | const dataHandler = (data) => {
44 | const filtered = data;
45 | // display breadcrumbs if breadcrumbs is set to false
46 | // const filtered = data.filter((item) => item.breadcrumbs !== false);
47 | const active = filtered.at(-1);
48 | const linkItems = filtered.slice(0, -1);
49 | if (active && active.url != homeBreadcrumb.url) {
50 | const home = { ...homeBreadcrumb };
51 | linkItems.unshift(home);
52 | }
53 | setActiveItem(active);
54 | setBreadcrumbItems(linkItems);
55 | };
56 |
57 | function findParentElements(navItems, targetUrl, parents = []) {
58 | for (const item of navItems) {
59 | // Add the current item to the parents array
60 | const newParents = [...parents, item];
61 |
62 | // Check if the current item matches the target URL
63 | if (item.url && item.url === targetUrl && targetUrl.includes(item.url)) {
64 | return newParents; // Return the array of parent elements
65 | }
66 |
67 | // If the item has children, recurse into them
68 | if (item.children) {
69 | const result = findParentElements(item.children, targetUrl, newParents);
70 | if (result) {
71 | return result; // Return the result if found in children
72 | }
73 | }
74 | }
75 |
76 | return null; // Return null if no match is found
77 | }
78 |
79 | if (!activeItem || activeItem.breadcrumbs === false) {
80 | return null;
81 | }
82 |
83 | function CoreBreadcrumb() {
84 | return (
85 |
86 |
87 | {breadcrumbItems.length &&
88 | breadcrumbItems.map((item, index) => (
89 |
101 | {icons && item.icon && } {item.title}
102 |
103 | ))}
104 | {activeItem && (
105 |
106 | {icons && activeItem.icon && }
107 | {activeItem.title}
108 |
109 | )}
110 |
111 |
112 |
113 | {title || activeItem?.title}
114 |
115 |
116 | );
117 | }
118 |
119 | return (
120 |
121 |
122 | {divider && }
123 |
124 | );
125 | }
126 |
127 | Breadcrumbs.propTypes = {
128 | data: PropTypes.array,
129 | divider: PropTypes.bool,
130 | title: PropTypes.string,
131 | icons: PropTypes.bool,
132 | sx: PropTypes.any,
133 | rest: PropTypes.any
134 | };
135 |
--------------------------------------------------------------------------------
/src/layouts/MainLayout/Header/Notification.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useState } from 'react';
3 |
4 | // material-ui
5 | import Avatar from '@mui/material/Avatar';
6 | import Chip from '@mui/material/Chip';
7 | import ClickAwayListener from '@mui/material/ClickAwayListener';
8 | import Fade from '@mui/material/Fade';
9 | import IconButton from '@mui/material/IconButton';
10 | import List from '@mui/material/List';
11 | import ListItemAvatar from '@mui/material/ListItemAvatar';
12 | import ListItemButton from '@mui/material/ListItemButton';
13 | import ListItemText from '@mui/material/ListItemText';
14 | import ListSubheader from '@mui/material/ListSubheader';
15 | import Popper from '@mui/material/Popper';
16 | import Stack from '@mui/material/Stack';
17 | import Typography from '@mui/material/Typography';
18 | import Box from '@mui/material/Box';
19 |
20 | // project imports
21 | import MainCard from 'components/cards/MainCard';
22 | import SimpleBar from 'components/third-party/SimpleBar';
23 |
24 | // assets
25 | import avatar1 from 'assets/images/users/avatar-1.jpg';
26 | import avatar2 from 'assets/images/users/avatar-2.jpg';
27 | import avatar3 from 'assets/images/users/avatar-3.jpg';
28 | import avatar4 from 'assets/images/users/avatar-4.jpg';
29 | import AccessTimeTwoToneIcon from '@mui/icons-material/AccessTimeTwoTone';
30 | import NotificationsNoneTwoToneIcon from '@mui/icons-material/NotificationsNoneTwoTone';
31 |
32 | const notifications = [
33 | { avatar: avatar1, name: 'John Doe', time: 'now', message: 'New ticket Added' },
34 | { avatar: avatar2, name: 'Joseph William', time: '10 min', message: 'Purchase a new product' },
35 | { avatar: avatar3, name: 'Sara Soudein', time: '12 min', message: 'Currently Login' },
36 | { avatar: avatar4, name: 'Sepha Wilon', time: '30 min', message: 'Purchase a new product' }
37 | ];
38 |
39 | // ==============================|| NOTIFICATION ITEM ||============================== //
40 |
41 | function NotificationItem({ avatar, name, time, message }) {
42 | return (
43 |
44 |
45 |
46 |
47 |
50 | {name}
51 |
52 |
53 | {time}
54 |
55 |
56 | }
57 | secondary={{message}}
58 | />
59 |
60 | );
61 | }
62 |
63 | // ==============================|| NOTIFICATION ||============================== //
64 |
65 | export default function Notification() {
66 | const [open, setOpen] = useState(false);
67 | const [anchorEl, setAnchorEl] = useState(null);
68 |
69 | const handleClick = (event) => {
70 | setAnchorEl(event.currentTarget);
71 | setOpen((previousOpen) => !previousOpen);
72 | };
73 |
74 | const handleClickAway = () => {
75 | setOpen(false);
76 | };
77 |
78 | const canBeOpen = open && Boolean(anchorEl);
79 | const id = canBeOpen ? 'notification-popper' : undefined;
80 |
81 | return (
82 |
83 |
84 |
85 |
86 |
87 |
88 |
97 | {({ TransitionProps }) => (
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | {notifications.slice(1).map((item, index) => (
112 |
113 | ))}
114 |
115 |
116 |
117 |
118 | )}
119 |
120 |
121 |
122 | );
123 | }
124 |
125 | NotificationItem.propTypes = { avatar: PropTypes.string, name: PropTypes.string, time: PropTypes.string, message: PropTypes.string };
126 |
--------------------------------------------------------------------------------
/favicon.svg:
--------------------------------------------------------------------------------
1 |
47 |
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
47 |
--------------------------------------------------------------------------------
/src/sections/auth/AuthRegister.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect, useState } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | // material-ui
6 | import Button from '@mui/material/Button';
7 | import CardMedia from '@mui/material/CardMedia';
8 | import CircularProgress from '@mui/material/CircularProgress';
9 | import Checkbox from '@mui/material/Checkbox';
10 | import Divider from '@mui/material/Divider';
11 | import FormControl from '@mui/material/FormControl';
12 | import FormControlLabel from '@mui/material/FormControlLabel';
13 | import FormHelperText from '@mui/material/FormHelperText';
14 | import Grid from '@mui/material/Grid';
15 | import InputAdornment from '@mui/material/InputAdornment';
16 | import InputLabel from '@mui/material/InputLabel';
17 | import OutlinedInput from '@mui/material/OutlinedInput';
18 | import Stack from '@mui/material/Stack';
19 | import TextField from '@mui/material/TextField';
20 | import Typography from '@mui/material/Typography';
21 | import Box from '@mui/material/Box';
22 |
23 | // third party
24 | import { useForm } from 'react-hook-form';
25 |
26 | // project imports
27 | import { strengthColor, strengthIndicator } from 'utils/passwordStrength';
28 | import { emailSchema, firstNameSchema, lastNameSchema, passwordSchema } from 'utils/validationSchema';
29 |
30 | // assets
31 | import Visibility from '@mui/icons-material/Visibility';
32 | import VisibilityOff from '@mui/icons-material/VisibilityOff';
33 | import Google from 'assets/images/social-google.svg';
34 |
35 | // ==============================|| AUTH - REGISTER ||============================== //
36 |
37 | export default function AuthRegister({ inputSx }) {
38 | const [isPasswordVisible, setIsPasswordVisible] = useState(false);
39 | const [level, setLevel] = useState();
40 | const [checked, setChecked] = useState(true);
41 |
42 | // Initialize react-hook-form
43 | const {
44 | register,
45 | watch,
46 | formState: { errors }
47 | } = useForm();
48 |
49 | const passwordValue = watch('password');
50 |
51 | useEffect(() => {
52 | const temp = strengthIndicator(passwordValue);
53 | setLevel(strengthColor(temp));
54 | }, [passwordValue]);
55 |
56 | return (
57 | <>
58 |
67 |
68 |
69 |
70 |
81 | OR
82 |
83 |
84 |
85 |
86 |
87 | Sign up with Email address
88 |
89 |
90 |
181 | >
182 | );
183 | }
184 |
185 | AuthRegister.propTypes = { inputSx: PropTypes.any };
186 |
--------------------------------------------------------------------------------
/src/assets/images/logo-dark.svg:
--------------------------------------------------------------------------------
1 |
48 |
--------------------------------------------------------------------------------
/src/assets/images/logo.svg:
--------------------------------------------------------------------------------
1 |
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Materially Free React Material UI Dashboard Template [](https://twitter.com/intent/tweet?text=Download%20Materially%20React%20-%20The%20professional%20Material%20designed%20React%20Admin%20Dashboard%20Template%20&url=https://codedthemes.com/demos/admin-templates/materially/react/default&via=codedthemes&hashtags=reactjs,webdev,developers,javascript)
2 |
3 | [](https://opensource.org/licenses/MIT)
4 | [](https://github.com/codedthemes/materially-free-react-admin-template/)
5 | [](https://github.com/codedthemes/materially-free-react-admin-template/blob/main/LICENSE)
6 | [](https://codedthemes.com/item/materially-free-reactjs-admin-template/)
7 | [](https://discord.com/invite/p2E2WhCb6s)
8 |
9 | Materially is a free and open source React redux dashboard template made using the Material UI React component library with aim of flexibility and better customizability.
10 |
11 | ✨ Support us! If you like this theme, click the ⭐ (Top right) and let it shine
12 |
13 | 
14 |
15 | ## Table of contents
16 |
17 | - [Getting Started](#getting-started)
18 | - [Download](#download)
19 | - [Why Materially?](#why-materially)
20 | - [What's included in Premium Version?](#whats-included-in-premium-version)
21 | - [Documentation](#documentation)
22 | - [Browser support](#browser-support)
23 | - [Technology Stack](#technology-stack)
24 | - 💰[Save more with Big Bundle](#save-more-with-big-bundle)💰
25 | - [More React Dashboard Templates](#more-react-dashboard-templates)
26 | - [Issues?](#issues)
27 | - [License](#license)
28 | - [Contributor](#contributor)
29 | - [Useful Resources](#useful-resources)
30 | - [Community](#community)
31 | - [Follow us](#follow-us)
32 |
33 | ## Getting Started
34 |
35 | 11. Clone from Github
36 |
37 | ```
38 | git clone https://github.com/codedthemes/materially-free-react-admin-template.git
39 | ```
40 |
41 | 2. Install packages
42 |
43 | ```
44 | yarn
45 | ```
46 |
47 | 3. Run project
48 |
49 | ```
50 | yarn start
51 | ```
52 |
53 | ## Download
54 |
55 | - Materially Free
56 | - [Live Preview](https://codedthemes.com/demos/admin-templates/materially/react/free/)
57 | - [Download](https://github.com/codedthemes/materially-free-react-admin-template)
58 | - Materially Pro
59 | - [Live Preview](https://codedthemes.com/demos/admin-templates/materially/react/default)
60 | - [Download](https://codedthemes.com/item/materially-reactjs-admin-dashboard/)
61 |
62 | ## Why Materially?
63 |
64 | Materially offers everything needed to build an advanced dashboard application. In the initial release, we included following high-end features,
65 |
66 | - Support React 19.
67 | - Professional user interface.
68 | - Material UI React components.
69 | - Fully responsive, all modern browser supported.
70 | - Easy to use code structure
71 | - Flexible & high-Performance code
72 | - Simple documentation
73 |
74 | ## What's included in Premium Version?
75 |
76 | The [Pro version](https://codedthemes.com/demos/admin-templates/materially/react/default) of Materially react template includes features such as multiple apps, advance components, form plugins, layouts, widgets, and more.
77 |
78 | | [Materially Free](https://codedthemes.com/demos/admin-templates/materially/react/free/) | [Materially Pro](https://codedthemes.com/demos/admin-templates/materially/react/default) |
79 | | ------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------- |
80 | | **5** Demo pages | **100+** Demo pages |
81 | | - | ✓ 60+ Components |
82 | | - | ✓ Dark/Light Mode 🌓 |
83 | | - | ✓ RTL |
84 | | - | ✓ Localization |
85 | | - | ✓ [More components](https://codedthemes.com/demos/admin-templates/materially/react/default/components/accordion) |
86 | | ✓ [MIT License](https://github.com/codedthemes/materially-free-react-admin-template/blob/main/LICENSE) | ✓ [Pro License](https://codedthemes.com/item/materially-reactjs-admin-dashboard/) |
87 |
88 | ## Documentation
89 |
90 | [Materially React Documentation](https://codedthemes.gitbook.io/materially-react-material-documentation/) helps you out in all aspects from Installation to deployment.
91 |
92 | ## Browser support
93 |
94 |
95 |
96 | ## Technology Stack
97 |
98 | - React (19)
99 | - Material UI (7)
100 | - SASS with JSS Powered
101 | - Vite
102 | - Redux toolkit
103 | - React Router
104 | - Localization
105 |
106 | ## Save more with Big Bundle
107 |
108 | [](https://links.codedthemes.com/jhFBJ)
109 |
110 | ## More React Dashboard Templates
111 |
112 | | Dashboard | FREE | PRO |
113 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
114 | |
| [**Free**](https://codedthemes.com/item/berry-mui-free-react-admin-template/) | [**Pro**](https://codedthemes.com/item/berry-material-react-admin-template/) |
115 | |
| [**Free**](https://codedthemes.com/item/mantis-free-mui-admin-template/) | [**Pro**](https://codedthemes.com/item/mantis-mui-react-dashboard-template/) |
116 | |
| [**Free**](https://codedthemes.com/item/datta-able-react-free-admin-template/) | [**Pro**](https://codedthemes.com/item/datta-able-react-admin-template/) |
117 |
118 | ## Issues
119 |
120 | If you found a bug in any version, please generate a [GitHub issue](https://github.com/codedthemes/materially-free-react-admin-template/issues). We are trying our best to resolve the issue.
121 |
122 | ## License
123 |
124 | - Licensed under [MIT](https://github.com/codedthemes/materially-free-react-admin-template/blob/main/LICENSE)
125 | - Copyright © [CodedThemes](https://codedthemes.com/)
126 |
127 | ## Contributor
128 |
129 | **CodedThemes Team**
130 |
131 | - https://x.com/codedthemes
132 | - https://github.com/codedthemes
133 |
134 | **Rakesh Nakrani**
135 |
136 | - https://x.com/rakesh_nakrani
137 |
138 | **Brijesh Dobariya**
139 |
140 | - https://x.com/dobaria_brijesh
141 |
142 | ## Useful Resources
143 |
144 | - [More Admin Templates From CodedThemes](https://codedthemes.com/item/category/admin-templates/)
145 | - [Freebies From CodedThemes](https://codedthemes.com/item/category/free-templates/)
146 | - [Big Bundles](https://codedthemes.com/item/big-bundle/)
147 | - [Figma UI Kits](https://codedthemes.com/item/category/templates/figma/)
148 | - [Affiliate Program](https://codedthemes.com/affiliate/)
149 | - [Blogs](https://blog.codedthemes.com/)
150 |
151 | ## Community
152 |
153 | - 👥Follow [@codedthemes](https://x.com/codedthemes)
154 | - 🔗Join [Discord](https://discord.com/invite/p2E2WhCb6s)
155 | - 🔔Subscribe to [Codedtheme Blogs](https://blog.codedthemes.com/)
156 |
157 | ## Follow Us
158 |
159 | - [Twitter](https://twitter.com/codedthemes) 🐦
160 | - [Dribbble](https://dribbble.com/codedthemes) 🏀
161 | - [Github](https://github.com/codedthemes) 🐙
162 | - [LinkedIn](https://www.linkedin.com/company/codedthemes/) 💼
163 | - [Instagram](https://www.instagram.com/codedthemes/) 📷
164 | - [Facebook](https://www.facebook.com/codedthemes) 🟦
165 |
--------------------------------------------------------------------------------