├── .env ├── .eslintrc ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── .gitignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── jsconfig.json ├── package.json ├── public ├── favicon.svg └── index.html ├── src ├── App.js ├── App.test.js ├── assets │ ├── images │ │ ├── auth │ │ │ └── AuthBackground.js │ │ ├── icons │ │ │ ├── facebook.svg │ │ │ ├── google.svg │ │ │ └── twitter.svg │ │ └── users │ │ │ ├── avatar-1.png │ │ │ ├── avatar-2.png │ │ │ ├── avatar-3.png │ │ │ ├── avatar-4.png │ │ │ └── avatar-group.png │ └── third-party │ │ └── apex-chart.css ├── components │ ├── @extended │ │ ├── AnimateButton.js │ │ ├── Breadcrumbs.js │ │ ├── Dot.js │ │ └── Transitions.js │ ├── Loadable.js │ ├── Loader.js │ ├── Logo │ │ ├── Logo.js │ │ └── index.js │ ├── MainCard.js │ ├── ScrollTop.js │ ├── cards │ │ ├── AuthFooter.js │ │ └── statistics │ │ │ └── AnalyticEcommerce.js │ └── third-party │ │ ├── Highlighter.js │ │ └── SimpleBar.js ├── config.js ├── index.js ├── layout │ ├── MainLayout │ │ ├── Drawer │ │ │ ├── DrawerContent │ │ │ │ ├── NavCard.js │ │ │ │ ├── Navigation │ │ │ │ │ ├── NavGroup.js │ │ │ │ │ ├── NavItem.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── DrawerHeader │ │ │ │ ├── DrawerHeaderStyled.js │ │ │ │ └── index.js │ │ │ ├── MiniDrawerStyled.js │ │ │ └── index.js │ │ ├── Header │ │ │ ├── AppBarStyled.js │ │ │ ├── HeaderContent │ │ │ │ ├── MobileSection.js │ │ │ │ ├── Notification.js │ │ │ │ ├── Profile │ │ │ │ │ ├── ProfileTab.js │ │ │ │ │ ├── SettingTab.js │ │ │ │ │ └── index.js │ │ │ │ ├── Search.js │ │ │ │ └── index.js │ │ │ └── index.js │ │ └── index.js │ └── MinimalLayout │ │ └── index.js ├── menu-items │ ├── dashboard.js │ ├── index.js │ ├── pages.js │ ├── support.js │ └── utilities.js ├── pages │ ├── authentication │ │ ├── AuthCard.js │ │ ├── AuthWrapper.js │ │ ├── Login.js │ │ ├── Register.js │ │ └── auth-forms │ │ │ ├── AuthLogin.js │ │ │ ├── AuthRegister.js │ │ │ └── FirebaseSocial.js │ ├── components-overview │ │ ├── AntIcons.js │ │ ├── Color.js │ │ ├── ComponentSkeleton.js │ │ ├── Shadow.js │ │ └── Typography.js │ ├── dashboard │ │ ├── IncomeAreaChart.js │ │ ├── MonthlyBarChart.js │ │ ├── OrdersTable.js │ │ ├── ReportAreaChart.js │ │ ├── SalesColumnChart.js │ │ └── index.js │ └── extra-pages │ │ └── SamplePage.js ├── react-app-env.d.js ├── reportWebVitals.js ├── routes │ ├── LoginRoutes.js │ ├── MainRoutes.js │ └── index.js ├── setupTests.js ├── store │ ├── index.js │ └── reducers │ │ ├── actions.js │ │ ├── index.js │ │ └── menu.js ├── themes │ ├── index.js │ ├── overrides │ │ ├── Badge.js │ │ ├── Button.js │ │ ├── CardContent.js │ │ ├── Checkbox.js │ │ ├── Chip.js │ │ ├── IconButton.js │ │ ├── InputLabel.js │ │ ├── LinearProgress.js │ │ ├── Link.js │ │ ├── ListItemIcon.js │ │ ├── OutlinedInput.js │ │ ├── Tab.js │ │ ├── TableCell.js │ │ ├── Tabs.js │ │ ├── Typography.js │ │ └── index.js │ ├── palette.js │ ├── shadows.js │ ├── theme │ │ └── index.js │ └── typography.js └── utils │ ├── SyntaxHighlight.js │ └── password-strength.js └── yarn.lock /.env: -------------------------------------------------------------------------------- 1 | REACT_APP_VERSION = v1.2.0 2 | GENERATE_SOURCEMAP = false 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "browser": true, 5 | "es2021": true 6 | }, 7 | "extends": [ 8 | "prettier", 9 | "plugin:react/jsx-runtime", 10 | "plugin:jsx-a11y/recommended", 11 | "plugin:react-hooks/recommended", 12 | "eslint:recommended", 13 | "plugin:react/recommended" 14 | ], 15 | "settings": { 16 | "react": { 17 | "createClass": "createReactClass", // Regex for Component Factory to use, 18 | // default to "createReactClass" 19 | "pragma": "React", // Pragma to use, default to "React" 20 | "fragment": "Fragment", // Fragment to use (may be a property of ), default to "Fragment" 21 | "version": "detect", // React version. "detect" automatically picks the version you have installed. 22 | // You can also use `16.0`, `16.3`, etc, if you want to override the detected value. 23 | // It will default to "latest" and warn if missing, and to "detect" in the future 24 | "flowVersion": "0.53" // Flow version 25 | }, 26 | "import/resolver": { 27 | "node": { 28 | "moduleDirectory": ["node_modules", "src/"] 29 | } 30 | } 31 | }, 32 | "parser": "@babel/eslint-parser", 33 | "parserOptions": { 34 | "ecmaFeatures": { 35 | "experimentalObjectRestSpread": true, 36 | "impliedStrict": true, 37 | "jsx": true 38 | }, 39 | "ecmaVersion": 12 40 | }, 41 | "plugins": ["prettier", "react", "react-hooks"], 42 | "rules": { 43 | "react/jsx-uses-react": "error", 44 | "react/jsx-uses-vars": "error", 45 | "react/react-in-jsx-scope": "off", 46 | "no-undef": "off", 47 | "react/display-name": "off", 48 | "react/jsx-filename-extension": "off", 49 | "no-param-reassign": "off", 50 | "react/prop-types": 1, 51 | "react/require-default-props": "off", 52 | "react/no-array-index-key": "off", 53 | "react/jsx-props-no-spreading": "off", 54 | "react/forbid-prop-types": "off", 55 | "import/order": "off", 56 | "import/no-cycle": "off", 57 | "no-console": "off", 58 | "jsx-a11y/anchor-is-valid": "off", 59 | "prefer-destructuring": "off", 60 | "no-shadow": "off", 61 | "import/no-named-as-default": "off", 62 | "import/no-extraneous-dependencies": "off", 63 | "jsx-a11y/no-autofocus": "off", 64 | "no-restricted-imports": [ 65 | "error", 66 | { 67 | "patterns": ["@mui/*/*/*", "!@mui/material/test-utils/*"] 68 | } 69 | ], 70 | "no-unused-vars": [ 71 | "error", 72 | { 73 | "ignoreRestSiblings": false 74 | } 75 | ], 76 | "prettier/prettier": [ 77 | "warn", 78 | { 79 | "bracketSpacing": true, 80 | "printWidth": 140, 81 | "singleQuote": true, 82 | "trailingComma": "none", 83 | "tabWidth": 2, 84 | "useTabs": false, 85 | "endOfLine": "auto" 86 | } 87 | ] 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | 28 | - OS: [e.g. iOS] 29 | - Browser [e.g. chrome, safari] 30 | - Version [e.g. 22] 31 | 32 | **Smartphone (please complete the following information):** 33 | 34 | - Device: [e.g. iPhone6] 35 | - OS: [e.g. iOS8.1] 36 | - Browser [e.g. stock browser, safari] 37 | - Version [e.g. 22] 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | # .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # Backup file 107 | *.bak 108 | 109 | #output 110 | build 111 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "printWidth": 140, 4 | "singleQuote": true, 5 | "trailingComma": "none", 6 | "tabWidth": 2, 7 | "useTabs": false 8 | } 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | codedthemes@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | [homepage]: https://www.contributor-covenant.org 122 | 123 | For answers to common questions about this code of conduct, see the FAQ at 124 | https://www.contributor-covenant.org/faq. Translations are available at 125 | https://www.contributor-covenant.org/translations. 126 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 BlitzSprinter 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mantis Free React Material UI Dashboard Template [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Download%20Mantis%20React%20-%20The%20professional%20Material%20designed%20React%20Admin%20Dashboard%20Template%20&url=https://mantisdashboard.io&via=codedthemes&hashtags=reactjs,webdev,developers,javascript) 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | [![Price](https://img.shields.io/badge/price-FREE-0098f7.svg)](https://github.com/azuresphere7/Mantis-Admin-Template/blob/main/LICENSE) 5 | [![GitHub package version](https://img.shields.io/github/package-json/v/azuresphere7/Mantis-Admin-Template)](https://github.com/azuresphere7/Mantis-Admin-Template/) 6 | 7 | Mantis 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. 8 | 9 | ### Name Derived From Nature 10 | 11 | Mantis Logo is inspired from the insect name - 'Mantises' as they have triangular heads with flexible Necks. Also, the name is derived from two popular UI frameworks, Material UI and Ant Design (M-Ant-is). 12 | 13 | Mantis has Ant Design principal on top of the MAterial UI React component library. 14 | 15 | :star: :star: :star: Support us by giving star (Top right of this page) if you like the theme :star: :star: :star: 16 | 17 | ![mantis-free-react-dashboard-template.jpg](https://mantisdashboard.io/adv-banner-images/og-social-v1.1.0.png) 18 | 19 | The [Pro version](https://mantisdashboard.io) of Mantis react template includes features such as TypeScript, apps, authentication methods (i.e. JWT, Auth0, Firebase), advance components, form plugins, layouts, widgets, and more. 20 | 21 | | [Mantis Free](https://mantisdashboard.io/free) | [Mantis Pro](https://mantisdashboard.io) | 22 | | ---------------------------------------------- | :------------------------------------------------------------------------------- | 23 | | **7** Demo pages | **85+** Demo pages | 24 | | - | ✓ Multi-language | 25 | | - | ✓ Dark/Light Mode 🌓 | 26 | | - | ✓ TypeScript version | 27 | | - | ✓ Design files (Figma) | 28 | | - | ✓ Multiple color options | 29 | | - | ✓ RTL | 30 | | - | ✓ JWT, Firebase, Auth0, AWS authentication | 31 | | - | ✓ [More components](https://mantisdashboard.io/components-overview/autocomplete) | 32 | | ✓ MIT License | ✓ [Pro License](https://mui.com/store/license/) | 33 | 34 | ## Why Mantis? 35 | 36 | Mantis offers everything needed to build an advanced dashboard application. In the initial release, we included following high-end features, 37 | 38 | - Support React18. 39 | - Professional user interface. 40 | - Material UI React components. 41 | - Fully responsive, all modern browser supported. 42 | - Easy to use code structure 43 | - Flexible & high-Performance code 44 | - Simple documentation 45 | 46 | ## Free Mantis React version 47 | 48 | #### Preview 49 | 50 | - [Demo](https://mantisdashboard.io/free) 51 | 52 | #### Download 53 | 54 | - [Download from GitHub](https://github.com/azuresphere7/Mantis-Admin-Template) 55 | 56 | ## Mantis Pro version 57 | 58 | #### Preview 59 | 60 | - [Demo](https://mantisdashboard.io) 61 | 62 | #### Purchase 63 | 64 | - [Buy now](https://mui.com/store/items/mantis-react-admin-dashboard-template/) 65 | 66 | ## Table of contents 67 | 68 | - [Getting started](#getting-started) 69 | - [Documentation](#documentation) 70 | - [Technology stack](#technology-stack) 71 | - [Author](#author) 72 | - [Issues?](#issues) 73 | - [License](#license) 74 | - [More Free React Templates](#more-free-react-material-admin-dashboard-templates) 75 | - [More Pro React Templates](#more-premium-react-material-admin-dashboard-templates) 76 | - [Follow us](#follow-us) 77 | 78 | ## Getting Started 79 | 80 | 1. Clone from Github 81 | 82 | ``` 83 | git clone https://github.com/azuresphere7/Mantis-Admin-Template.git 84 | ``` 85 | 86 | 2. Install packages 87 | 88 | ``` 89 | yarn 90 | ``` 91 | 92 | 3. Run project 93 | 94 | ``` 95 | yarn start 96 | ``` 97 | 98 | ## Documentation 99 | 100 | [Mantis documentation](https://codedthemes.gitbook.io/mantis/) helps you out in all aspects from Installation to deployment. 101 | 102 | ## Technology stack 103 | 104 | - [Material UI V5](https://mui.com/core/) 105 | - Built with React Hooks API. 106 | - Redux & React context API for state management. 107 | - Redux toolkit. 108 | - React Router for navigation routing. 109 | - Support for react-script. 110 | - Code splitting. 111 | - CSS-in-JS. 112 | 113 | ## Author 114 | 115 | Mantis is managed by team [CodedThemes](https://codedthemes.com). 116 | 117 | ## Issues 118 | 119 | Please generate a [GitHub issue](https://github.com/azuresphere7/Mantis-Admin-Template/issues) if you found a bug in any version. We are try our best to resolve the issue. 120 | 121 | ## License 122 | 123 | - Licensed under [MIT](https://github.com/codedthemes/datta-able-bootstrap-dashboard/blob/master/LICENSE) 124 | 125 | ## More Free React Material Admin Dashboard Templates 126 | 127 | - [Free Materially](https://codedthemes.com/item/materially-free-reactjs-admin-template/) 128 | - [Free Berry](https://mui.com/store/items/berry-react-material-admin-free/) 129 | 130 | ## More premium React Material Admin Dashboard Templates 131 | 132 | - [Materially](https://codedthemes.com/item/materially-reactjs-admin-dashboard/) 133 | - [Berry](https://mui.com/store/items/berry-react-material-admin/) 134 | 135 | ## Follow us 136 | 137 | - Website [https://mantisdashboard.io](https://mantisdashboard.io) 138 | - Blog [https://blog.mantisdashboard.io](https://blog.mantisdashboard.io) 139 | - CodedThemes [https://codedthemes.com](https://codedthemes.com) 140 | - Dribbble [https://dribbble.com/codedthemes](https://dribbble.com/codedthemes) 141 | - Facebook [https://www.facebook.com/codedthemes](https://www.facebook.com/codedthemes) 142 | - Twitter [https://twitter.com/codedthemes](https://twitter.com/codedthemes) 143 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "baseUrl": "src" 6 | }, 7 | "include": ["src/**/*"], 8 | "exclude": ["node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mantis-free-react-admin-template", 3 | "version": "1.2.0", 4 | "private": true, 5 | "homepage": "https://mantisdashboard.io/free", 6 | "dependencies": { 7 | "@ant-design/colors": "^7.0.2", 8 | "@ant-design/icons": "^5.2.6", 9 | "@emotion/cache": "^11.11.0", 10 | "@emotion/react": "^11.11.3", 11 | "@emotion/styled": "^11.11.0", 12 | "@mui/lab": "^5.0.0-alpha.162", 13 | "@mui/material": "^5.15.6", 14 | "@reduxjs/toolkit": "^2.1.0", 15 | "@testing-library/jest-dom": "^6.4.0", 16 | "@testing-library/react": "^14.2.0", 17 | "@testing-library/user-event": "^14.5.2", 18 | "apexcharts": "^3.45.2", 19 | "formik": "^2.4.5", 20 | "framer-motion": "^11.0.3", 21 | "history": "^5.3.0", 22 | "lodash": "^4.17.21", 23 | "prop-types": "^15.8.1", 24 | "react": "^18.2.0", 25 | "react-apexcharts": "^1.4.1", 26 | "react-copy-to-clipboard": "^5.1.0", 27 | "react-device-detect": "^2.2.3", 28 | "react-dom": "^18.2.0", 29 | "react-draggable": "^4.4.6", 30 | "react-element-to-jsx-string": "^15.0.0", 31 | "react-number-format": "^5.3.1", 32 | "react-perfect-scrollbar": "^1.5.8", 33 | "react-redux": "^9.1.0", 34 | "react-router": "^6.21.3", 35 | "react-router-dom": "^6.21.3", 36 | "react-scripts": "^5.0.1", 37 | "react-syntax-highlighter": "^15.5.0", 38 | "react-window": "^1.8.10", 39 | "redux": "^5.0.1", 40 | "simplebar": "^5.3.8", 41 | "simplebar-react": "^2.4.1", 42 | "typescript": "4.8.3", 43 | "web-vitals": "^3.5.2", 44 | "yup": "^1.3.3" 45 | }, 46 | "scripts": { 47 | "start": "react-scripts start", 48 | "build": "react-scripts build", 49 | "test": "react-scripts test", 50 | "eject": "react-scripts eject" 51 | }, 52 | "eslintConfig": { 53 | "extends": [ 54 | "react-app", 55 | "react-app/jest" 56 | ] 57 | }, 58 | "babel": { 59 | "presets": [ 60 | "@babel/preset-react" 61 | ] 62 | }, 63 | "browserslist": { 64 | "production": [ 65 | ">0.2%", 66 | "not dead", 67 | "not op_mini all" 68 | ], 69 | "development": [ 70 | "last 1 chrome version", 71 | "last 1 firefox version", 72 | "last 1 safari version" 73 | ] 74 | }, 75 | "devDependencies": { 76 | "@babel/core": "^7.23.9", 77 | "@babel/eslint-parser": "^7.23.9", 78 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 79 | "eslint": "^8.56.0", 80 | "eslint-config-prettier": "^9.1.0", 81 | "eslint-config-react-app": "^7.0.1", 82 | "eslint-plugin-flowtype": "^8.0.3", 83 | "eslint-plugin-import": "^2.29.1", 84 | "eslint-plugin-jsx-a11y": "^6.8.0", 85 | "eslint-plugin-prettier": "^5.1.3", 86 | "eslint-plugin-react": "^7.33.2", 87 | "eslint-plugin-react-hooks": "^4.6.0", 88 | "prettier": "^3.2.4" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 51 | Mantis React Dashboard | Open Source Admin Template 52 | 53 | 57 | 58 | 59 | 60 |
61 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | // project import 2 | import Routes from 'routes'; 3 | import ThemeCustomization from 'themes'; 4 | import ScrollTop from 'components/ScrollTop'; 5 | 6 | // ==============================|| APP - THEME, ROUTER, LOCAL ||============================== // 7 | 8 | const App = () => ( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/assets/images/auth/AuthBackground.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { useTheme } from '@mui/material/styles'; 3 | import { Box } from '@mui/material'; 4 | 5 | // ==============================|| AUTH BLUR BACK SVG ||============================== // 6 | 7 | const AuthBackground = () => { 8 | const theme = useTheme(); 9 | return ( 10 | 11 | 12 | 16 | 21 | 26 | 27 | 28 | ); 29 | }; 30 | 31 | export default AuthBackground; 32 | -------------------------------------------------------------------------------- /src/assets/images/icons/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/icons/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/images/icons/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/users/avatar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azurespheredev/Mantis-React-Admin/c427aafab9e880504623353d2084aae0c28ca23d/src/assets/images/users/avatar-1.png -------------------------------------------------------------------------------- /src/assets/images/users/avatar-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azurespheredev/Mantis-React-Admin/c427aafab9e880504623353d2084aae0c28ca23d/src/assets/images/users/avatar-2.png -------------------------------------------------------------------------------- /src/assets/images/users/avatar-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azurespheredev/Mantis-React-Admin/c427aafab9e880504623353d2084aae0c28ca23d/src/assets/images/users/avatar-3.png -------------------------------------------------------------------------------- /src/assets/images/users/avatar-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azurespheredev/Mantis-React-Admin/c427aafab9e880504623353d2084aae0c28ca23d/src/assets/images/users/avatar-4.png -------------------------------------------------------------------------------- /src/assets/images/users/avatar-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azurespheredev/Mantis-React-Admin/c427aafab9e880504623353d2084aae0c28ca23d/src/assets/images/users/avatar-group.png -------------------------------------------------------------------------------- /src/assets/third-party/apex-chart.css: -------------------------------------------------------------------------------- 1 | .apexcharts-legend-series .apexcharts-legend-marker { 2 | left: -4px !important; 3 | top: 2px !important; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/@extended/AnimateButton.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // third-party 4 | import { motion } from 'framer-motion'; 5 | 6 | // ==============================|| ANIMATION BUTTON ||============================== // 7 | 8 | export default function AnimateButton({ children, type }) { 9 | switch (type) { 10 | case 'rotate': // only available in paid version 11 | case 'slide': // only available in paid version 12 | case 'scale': // only available in paid version 13 | default: 14 | return ( 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | } 21 | 22 | AnimateButton.propTypes = { 23 | children: PropTypes.node, 24 | type: PropTypes.oneOf(['slide', 'scale', 'rotate']) 25 | }; 26 | 27 | AnimateButton.defaultProps = { 28 | type: 'scale' 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/@extended/Breadcrumbs.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useEffect, useState } from 'react'; 3 | import { Link, useLocation } from 'react-router-dom'; 4 | 5 | // material-ui 6 | import MuiBreadcrumbs from '@mui/material/Breadcrumbs'; 7 | import { Grid, Typography } from '@mui/material'; 8 | 9 | // project imports 10 | import MainCard from '../MainCard'; 11 | 12 | // ==============================|| BREADCRUMBS ||============================== // 13 | 14 | const Breadcrumbs = ({ navigation, title, ...others }) => { 15 | const location = useLocation(); 16 | const [main, setMain] = useState(); 17 | const [item, setItem] = useState(); 18 | 19 | // set active item state 20 | const getCollapse = (menu) => { 21 | if (menu.children) { 22 | menu.children.filter((collapse) => { 23 | if (collapse.type && collapse.type === 'collapse') { 24 | getCollapse(collapse); 25 | } else if (collapse.type && collapse.type === 'item') { 26 | if (location.pathname === collapse.url) { 27 | setMain(menu); 28 | setItem(collapse); 29 | } 30 | } 31 | return false; 32 | }); 33 | } 34 | }; 35 | 36 | useEffect(() => { 37 | navigation?.items?.map((menu) => { 38 | if (menu.type && menu.type === 'group') { 39 | getCollapse(menu); 40 | } 41 | return false; 42 | }); 43 | }); 44 | 45 | // only used for component demo breadcrumbs 46 | if (location.pathname === '/breadcrumbs') { 47 | location.pathname = '/dashboard/analytics'; 48 | } 49 | 50 | let mainContent; 51 | let itemContent; 52 | let breadcrumbContent = ; 53 | let itemTitle = ''; 54 | 55 | // collapse item 56 | if (main && main.type === 'collapse') { 57 | mainContent = ( 58 | 59 | {main.title} 60 | 61 | ); 62 | } 63 | 64 | // items 65 | if (item && item.type === 'item') { 66 | itemTitle = item.title; 67 | itemContent = ( 68 | 69 | {itemTitle} 70 | 71 | ); 72 | 73 | // main 74 | if (item.breadcrumbs !== false) { 75 | breadcrumbContent = ( 76 | 77 | 78 | 79 | 80 | 81 | Home 82 | 83 | {mainContent} 84 | {itemContent} 85 | 86 | 87 | {title && ( 88 | 89 | {item.title} 90 | 91 | )} 92 | 93 | 94 | ); 95 | } 96 | } 97 | 98 | return breadcrumbContent; 99 | }; 100 | 101 | Breadcrumbs.propTypes = { 102 | navigation: PropTypes.object, 103 | title: PropTypes.bool 104 | }; 105 | 106 | export default Breadcrumbs; 107 | -------------------------------------------------------------------------------- /src/components/@extended/Dot.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { Box } from '@mui/material'; 6 | 7 | const Dot = ({ color, size }) => { 8 | const theme = useTheme(); 9 | let main; 10 | switch (color) { 11 | case 'secondary': 12 | main = theme.palette.secondary.main; 13 | break; 14 | case 'error': 15 | main = theme.palette.error.main; 16 | break; 17 | case 'warning': 18 | main = theme.palette.warning.main; 19 | break; 20 | case 'info': 21 | main = theme.palette.info.main; 22 | break; 23 | case 'success': 24 | main = theme.palette.success.main; 25 | break; 26 | case 'primary': 27 | default: 28 | main = theme.palette.primary.main; 29 | } 30 | 31 | return ( 32 | 40 | ); 41 | }; 42 | 43 | Dot.propTypes = { 44 | color: PropTypes.string, 45 | size: PropTypes.number 46 | }; 47 | 48 | export default Dot; 49 | -------------------------------------------------------------------------------- /src/components/@extended/Transitions.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { forwardRef } from 'react'; 3 | 4 | // material-ui 5 | import { Fade, Box, Grow } from '@mui/material'; 6 | 7 | // ==============================|| TRANSITIONS ||============================== // 8 | 9 | const Transitions = forwardRef(({ children, position, type, ...others }, ref) => { 10 | let positionSX = { 11 | transformOrigin: '0 0 0' 12 | }; 13 | 14 | switch (position) { 15 | case 'top-right': 16 | case 'top': 17 | case 'bottom-left': 18 | case 'bottom-right': 19 | case 'bottom': 20 | case 'top-left': 21 | default: 22 | positionSX = { 23 | transformOrigin: '0 0 0' 24 | }; 25 | break; 26 | } 27 | 28 | return ( 29 | 30 | {type === 'grow' && ( 31 | 32 | {children} 33 | 34 | )} 35 | {type === 'fade' && ( 36 | 44 | {children} 45 | 46 | )} 47 | 48 | ); 49 | }); 50 | 51 | Transitions.propTypes = { 52 | children: PropTypes.node, 53 | type: PropTypes.oneOf(['grow', 'fade', 'collapse', 'slide', 'zoom']), 54 | position: PropTypes.oneOf(['top-left', 'top-right', 'top', 'bottom-left', 'bottom-right', 'bottom']) 55 | }; 56 | 57 | Transitions.defaultProps = { 58 | type: 'grow', 59 | position: 'top-left' 60 | }; 61 | 62 | export default Transitions; 63 | -------------------------------------------------------------------------------- /src/components/Loadable.js: -------------------------------------------------------------------------------- 1 | import { Suspense } from 'react'; 2 | 3 | // project import 4 | import Loader from './Loader'; 5 | 6 | // ==============================|| LOADABLE - LAZY LOADING ||============================== // 7 | 8 | const Loadable = (Component) => (props) => ( 9 | }> 10 | 11 | 12 | ); 13 | 14 | export default Loadable; 15 | -------------------------------------------------------------------------------- /src/components/Loader.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { styled } from '@mui/material/styles'; 3 | import LinearProgress from '@mui/material/LinearProgress'; 4 | 5 | // loader style 6 | const LoaderWrapper = styled('div')(({ theme }) => ({ 7 | position: 'fixed', 8 | top: 0, 9 | left: 0, 10 | zIndex: 2001, 11 | width: '100%', 12 | '& > * + *': { 13 | marginTop: theme.spacing(2) 14 | } 15 | })); 16 | 17 | // ==============================|| Loader ||============================== // 18 | 19 | const Loader = () => ( 20 | 21 | 22 | 23 | ); 24 | 25 | export default Loader; 26 | -------------------------------------------------------------------------------- /src/components/Logo/Logo.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { useTheme } from '@mui/material/styles'; 3 | 4 | /** 5 | * if you want to use image instead of uncomment following. 6 | * 7 | * import logoDark from 'assets/images/logo-dark.svg'; 8 | * import logo from 'assets/images/logo.svg'; 9 | * 10 | */ 11 | 12 | // ==============================|| LOGO SVG ||============================== // 13 | 14 | const Logo = () => { 15 | const theme = useTheme(); 16 | 17 | return ( 18 | /** 19 | * if you want to use image instead of svg uncomment following, and comment out element. 20 | * 21 | * Mantis 22 | * 23 | */ 24 | <> 25 | 26 | 30 | 34 | 38 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ); 60 | }; 61 | 62 | export default Logo; 63 | -------------------------------------------------------------------------------- /src/components/Logo/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | // material-ui 5 | import { ButtonBase } from '@mui/material'; 6 | import { useDispatch, useSelector } from 'react-redux'; 7 | 8 | // project import 9 | import Logo from './Logo'; 10 | import config from 'config'; 11 | import { activeItem } from 'store/reducers/menu'; 12 | 13 | // ==============================|| MAIN LOGO ||============================== // 14 | 15 | const LogoSection = ({ sx, to }) => { 16 | const { defaultId } = useSelector((state) => state.menu); 17 | const dispatch = useDispatch(); 18 | return ( 19 | dispatch(activeItem({ openItem: [defaultId] }))} 23 | to={!to ? config.defaultPath : to} 24 | sx={sx} 25 | > 26 | 27 | 28 | ); 29 | }; 30 | 31 | LogoSection.propTypes = { 32 | sx: PropTypes.object, 33 | to: PropTypes.string 34 | }; 35 | 36 | export default LogoSection; 37 | -------------------------------------------------------------------------------- /src/components/MainCard.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { forwardRef } from 'react'; 3 | 4 | // material-ui 5 | import { useTheme } from '@mui/material/styles'; 6 | import { Card, CardContent, CardHeader, Divider, Typography } from '@mui/material'; 7 | 8 | // project import 9 | import Highlighter from './third-party/Highlighter'; 10 | 11 | // header style 12 | const headerSX = { 13 | p: 2.5, 14 | '& .MuiCardHeader-action': { m: '0px auto', alignSelf: 'center' } 15 | }; 16 | 17 | // ==============================|| CUSTOM - MAIN CARD ||============================== // 18 | 19 | const MainCard = forwardRef( 20 | ( 21 | { 22 | border = true, 23 | boxShadow, 24 | children, 25 | content = true, 26 | contentSX = {}, 27 | darkTitle, 28 | elevation, 29 | secondary, 30 | shadow, 31 | sx = {}, 32 | title, 33 | codeHighlight, 34 | ...others 35 | }, 36 | ref 37 | ) => { 38 | const theme = useTheme(); 39 | boxShadow = theme.palette.mode === 'dark' ? boxShadow || true : boxShadow; 40 | 41 | return ( 42 | 63 | {/* card header and action */} 64 | {!darkTitle && title && ( 65 | 66 | )} 67 | {darkTitle && title && {title}} action={secondary} />} 68 | 69 | {/* card content */} 70 | {content && {children}} 71 | {!content && children} 72 | 73 | {/* card footer - clipboard & highlighter */} 74 | {codeHighlight && ( 75 | <> 76 | 77 | 78 | {children} 79 | 80 | 81 | )} 82 | 83 | ); 84 | } 85 | ); 86 | 87 | MainCard.propTypes = { 88 | border: PropTypes.bool, 89 | boxShadow: PropTypes.bool, 90 | contentSX: PropTypes.object, 91 | darkTitle: PropTypes.bool, 92 | divider: PropTypes.bool, 93 | elevation: PropTypes.number, 94 | secondary: PropTypes.node, 95 | shadow: PropTypes.string, 96 | sx: PropTypes.object, 97 | title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), 98 | codeHighlight: PropTypes.bool, 99 | content: PropTypes.bool, 100 | children: PropTypes.node 101 | }; 102 | 103 | export default MainCard; 104 | -------------------------------------------------------------------------------- /src/components/ScrollTop.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useEffect } from 'react'; 3 | import { useLocation } from 'react-router-dom'; 4 | 5 | // ==============================|| NAVIGATION - SCROLL TO TOP ||============================== // 6 | 7 | const ScrollTop = ({ children }) => { 8 | const location = useLocation(); 9 | const { pathname } = location; 10 | 11 | useEffect(() => { 12 | window.scrollTo({ 13 | top: 0, 14 | left: 0, 15 | behavior: 'smooth' 16 | }); 17 | }, [pathname]); 18 | 19 | return children || null; 20 | }; 21 | 22 | ScrollTop.propTypes = { 23 | children: PropTypes.node 24 | }; 25 | 26 | export default ScrollTop; 27 | -------------------------------------------------------------------------------- /src/components/cards/AuthFooter.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { useMediaQuery, Container, Link, Typography, Stack } from '@mui/material'; 3 | 4 | // ==============================|| FOOTER - AUTHENTICATION ||============================== // 5 | 6 | const AuthFooter = () => { 7 | const matchDownSM = useMediaQuery((theme) => theme.breakpoints.down('sm')); 8 | 9 | return ( 10 | 11 | 17 | 18 | © Mantis React Dashboard Template By  19 | 20 | CodedThemes 21 | 22 | 23 | 24 | 25 | 33 | MUI Templates 34 | 35 | 43 | Privacy Policy 44 | 45 | 53 | Support 54 | 55 | 56 | 57 | 58 | ); 59 | }; 60 | 61 | export default AuthFooter; 62 | -------------------------------------------------------------------------------- /src/components/cards/statistics/AnalyticEcommerce.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { Box, Chip, Grid, Stack, Typography } from '@mui/material'; 5 | 6 | // project import 7 | import MainCard from 'components/MainCard'; 8 | 9 | // assets 10 | import { RiseOutlined, FallOutlined } from '@ant-design/icons'; 11 | 12 | // ==============================|| STATISTICS - ECOMMERCE CARD ||============================== // 13 | 14 | const AnalyticEcommerce = ({ color, title, count, percentage, isLoss, extra }) => ( 15 | 16 | 17 | 18 | {title} 19 | 20 | 21 | 22 | 23 | {count} 24 | 25 | 26 | {percentage && ( 27 | 28 | 33 | {!isLoss && } 34 | {isLoss && } 35 | 36 | } 37 | label={`${percentage}%`} 38 | sx={{ ml: 1.25, pl: 1 }} 39 | size="small" 40 | /> 41 | 42 | )} 43 | 44 | 45 | 46 | 47 | You made an extra{' '} 48 | 49 | {extra} 50 | {' '} 51 | this year 52 | 53 | 54 | 55 | ); 56 | 57 | AnalyticEcommerce.propTypes = { 58 | color: PropTypes.string, 59 | title: PropTypes.string, 60 | count: PropTypes.string, 61 | percentage: PropTypes.number, 62 | isLoss: PropTypes.bool, 63 | extra: PropTypes.oneOfType([PropTypes.node, PropTypes.string]) 64 | }; 65 | 66 | AnalyticEcommerce.defaultProps = { 67 | color: 'primary' 68 | }; 69 | 70 | export default AnalyticEcommerce; 71 | -------------------------------------------------------------------------------- /src/components/third-party/Highlighter.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useState } from 'react'; 3 | 4 | // material-ui 5 | import { Box, CardActions, Collapse, Divider, IconButton, Tooltip } from '@mui/material'; 6 | 7 | // third-party 8 | import { CopyToClipboard } from 'react-copy-to-clipboard'; 9 | import reactElementToJSXString from 'react-element-to-jsx-string'; 10 | 11 | // project import 12 | import SyntaxHighlight from 'utils/SyntaxHighlight'; 13 | 14 | // assets 15 | import { CodeOutlined, CopyOutlined } from '@ant-design/icons'; 16 | 17 | // ==============================|| CLIPBOARD & HIGHLIGHTER ||============================== // 18 | 19 | const Highlighter = ({ children }) => { 20 | const [highlight, setHighlight] = useState(false); 21 | 22 | return ( 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | setHighlight(!highlight)} 40 | > 41 | 42 | 43 | 44 | 45 | 46 | 47 | {highlight && ( 48 | 49 | {reactElementToJSXString(children, { 50 | showFunctions: true, 51 | showDefaultProps: false, 52 | maxInlineAttributesLineLength: 100 53 | })} 54 | 55 | )} 56 | 57 | 58 | ); 59 | }; 60 | 61 | Highlighter.propTypes = { 62 | children: PropTypes.node 63 | }; 64 | 65 | export default Highlighter; 66 | -------------------------------------------------------------------------------- /src/components/third-party/SimpleBar.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { alpha, styled } from '@mui/material/styles'; 5 | import { Box } from '@mui/material'; 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 | backgroundColor: alpha(theme.palette.grey[500], 0.48) 24 | }, 25 | '&.simplebar-visible:before': { 26 | opacity: 1 27 | } 28 | }, 29 | '& .simplebar-track.simplebar-vertical': { 30 | width: 10 31 | }, 32 | '& .simplebar-track.simplebar-horizontal .simplebar-scrollbar': { 33 | height: 6 34 | }, 35 | '& .simplebar-mask': { 36 | zIndex: 'inherit' 37 | } 38 | })); 39 | 40 | // ==============================|| SIMPLE SCROLL BAR ||============================== // 41 | 42 | export default function SimpleBarScroll({ children, sx, ...other }) { 43 | return ( 44 | <> 45 | 46 | 47 | {children} 48 | 49 | 50 | 51 | 52 | {children} 53 | 54 | 55 | 56 | ); 57 | } 58 | 59 | SimpleBarScroll.propTypes = { 60 | children: PropTypes.node, 61 | sx: PropTypes.object 62 | }; 63 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | // ==============================|| THEME CONFIG ||============================== // 2 | 3 | const config = { 4 | defaultPath: '/dashboard/default', 5 | fontFamily: `'Public Sans', sans-serif`, 6 | i18n: 'en', 7 | miniDrawer: false, 8 | container: true, 9 | mode: 'light', 10 | presetColor: 'default', 11 | themeDirection: 'ltr' 12 | }; 13 | 14 | export default config; 15 | export const drawerWidth = 260; 16 | 17 | export const twitterColor = '#1DA1F2'; 18 | export const facebookColor = '#3b5998'; 19 | export const linkedInColor = '#0e76a8'; 20 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import { BrowserRouter } from 'react-router-dom'; 4 | 5 | // scroll bar 6 | import 'simplebar/src/simplebar.css'; 7 | 8 | // third-party 9 | import { Provider as ReduxProvider } from 'react-redux'; 10 | 11 | // apex-chart 12 | import 'assets/third-party/apex-chart.css'; 13 | 14 | // project import 15 | import App from './App'; 16 | import { store } from 'store'; 17 | import reportWebVitals from './reportWebVitals'; 18 | 19 | // ==============================|| MAIN - REACT DOM RENDER ||============================== // 20 | 21 | const container = document.getElementById('root'); 22 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 23 | root.render( 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | 33 | // If you want to start measuring performance in your app, pass a function 34 | // to log results (for example: reportWebVitals(console.log)) 35 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 36 | reportWebVitals(); 37 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerContent/NavCard.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { Button, CardMedia, Link, Stack, Typography } from '@mui/material'; 3 | 4 | // project import 5 | import MainCard from 'components/MainCard'; 6 | 7 | // assets 8 | import avatar from 'assets/images/users/avatar-group.png'; 9 | import AnimateButton from 'components/@extended/AnimateButton'; 10 | 11 | // ==============================|| DRAWER CONTENT - NAVIGATION CARD ||============================== // 12 | 13 | const NavCard = () => ( 14 | 15 | 16 | 17 | 18 | Mantis Pro 19 | 20 | Checkout pro features 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | ); 31 | 32 | export default NavCard; 33 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavGroup.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useSelector } from 'react-redux'; 3 | 4 | // material-ui 5 | import { Box, List, Typography } from '@mui/material'; 6 | 7 | // project import 8 | import NavItem from './NavItem'; 9 | 10 | // ==============================|| NAVIGATION - LIST GROUP ||============================== // 11 | 12 | const NavGroup = ({ item }) => { 13 | const menu = useSelector((state) => state.menu); 14 | const { drawerOpen } = menu; 15 | 16 | const navCollapse = item.children?.map((menuItem) => { 17 | switch (menuItem.type) { 18 | case 'collapse': 19 | return ( 20 | 21 | collapse - only available in paid version 22 | 23 | ); 24 | case 'item': 25 | return ; 26 | default: 27 | return ( 28 | 29 | Fix - Group Collapse or Items 30 | 31 | ); 32 | } 33 | }); 34 | 35 | return ( 36 | 41 | 42 | {item.title} 43 | 44 | {/* only available in paid version */} 45 | 46 | ) 47 | } 48 | sx={{ mb: drawerOpen ? 1.5 : 0, py: 0, zIndex: 0 }} 49 | > 50 | {navCollapse} 51 | 52 | ); 53 | }; 54 | 55 | NavGroup.propTypes = { 56 | item: PropTypes.object 57 | }; 58 | 59 | export default NavGroup; 60 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerContent/Navigation/NavItem.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { forwardRef, useEffect } from 'react'; 3 | import { Link, useLocation } from 'react-router-dom'; 4 | import { useDispatch, useSelector } from 'react-redux'; 5 | 6 | // material-ui 7 | import { useTheme } from '@mui/material/styles'; 8 | import { Avatar, Chip, ListItemButton, ListItemIcon, ListItemText, Typography } from '@mui/material'; 9 | 10 | // project import 11 | import { activeItem } from 'store/reducers/menu'; 12 | 13 | // ==============================|| NAVIGATION - LIST ITEM ||============================== // 14 | 15 | const NavItem = ({ item, level }) => { 16 | const theme = useTheme(); 17 | const dispatch = useDispatch(); 18 | const { pathname } = useLocation(); 19 | 20 | const { drawerOpen, openItem } = useSelector((state) => state.menu); 21 | 22 | let itemTarget = '_self'; 23 | if (item.target) { 24 | itemTarget = '_blank'; 25 | } 26 | 27 | let listItemProps = { component: forwardRef((props, ref) => ) }; 28 | if (item?.external) { 29 | listItemProps = { component: 'a', href: item.url, target: itemTarget }; 30 | } 31 | 32 | const itemHandler = (id) => { 33 | dispatch(activeItem({ openItem: [id] })); 34 | }; 35 | 36 | const Icon = item.icon; 37 | const itemIcon = item.icon ? : false; 38 | 39 | const isSelected = openItem.findIndex((id) => id === item.id) > -1; 40 | // active menu item on page load 41 | useEffect(() => { 42 | if (pathname.includes(item.url)) { 43 | dispatch(activeItem({ openItem: [item.id] })); 44 | } 45 | // eslint-disable-next-line 46 | }, [pathname]); 47 | 48 | const textColor = 'text.primary'; 49 | const iconSelectedColor = 'primary.main'; 50 | 51 | return ( 52 | itemHandler(item.id)} 56 | selected={isSelected} 57 | sx={{ 58 | zIndex: 1201, 59 | pl: drawerOpen ? `${level * 28}px` : 1.5, 60 | py: !drawerOpen && level === 1 ? 1.25 : 1, 61 | ...(drawerOpen && { 62 | '&:hover': { 63 | bgcolor: 'primary.lighter' 64 | }, 65 | '&.Mui-selected': { 66 | bgcolor: 'primary.lighter', 67 | borderRight: `2px solid ${theme.palette.primary.main}`, 68 | color: iconSelectedColor, 69 | '&:hover': { 70 | color: iconSelectedColor, 71 | bgcolor: 'primary.lighter' 72 | } 73 | } 74 | }), 75 | ...(!drawerOpen && { 76 | '&:hover': { 77 | bgcolor: 'transparent' 78 | }, 79 | '&.Mui-selected': { 80 | '&:hover': { 81 | bgcolor: 'transparent' 82 | }, 83 | bgcolor: 'transparent' 84 | } 85 | }) 86 | }} 87 | > 88 | {itemIcon && ( 89 | 112 | {itemIcon} 113 | 114 | )} 115 | {(drawerOpen || (!drawerOpen && level !== 1)) && ( 116 | 119 | {item.title} 120 | 121 | } 122 | /> 123 | )} 124 | {(drawerOpen || (!drawerOpen && level !== 1)) && item.chip && ( 125 | {item.chip.avatar}} 131 | /> 132 | )} 133 | 134 | ); 135 | }; 136 | 137 | NavItem.propTypes = { 138 | item: PropTypes.object, 139 | level: PropTypes.number 140 | }; 141 | 142 | export default NavItem; 143 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerContent/Navigation/index.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { Box, Typography } from '@mui/material'; 3 | 4 | // project import 5 | import NavGroup from './NavGroup'; 6 | import menuItem from 'menu-items'; 7 | 8 | // ==============================|| DRAWER CONTENT - NAVIGATION ||============================== // 9 | 10 | const Navigation = () => { 11 | const navGroups = menuItem.items.map((item) => { 12 | switch (item.type) { 13 | case 'group': 14 | return ; 15 | default: 16 | return ( 17 | 18 | Fix - Navigation Group 19 | 20 | ); 21 | } 22 | }); 23 | 24 | return {navGroups}; 25 | }; 26 | 27 | export default Navigation; 28 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerContent/index.js: -------------------------------------------------------------------------------- 1 | // project import 2 | import NavCard from './NavCard'; 3 | import Navigation from './Navigation'; 4 | import SimpleBar from 'components/third-party/SimpleBar'; 5 | 6 | // ==============================|| DRAWER CONTENT ||============================== // 7 | 8 | const DrawerContent = () => ( 9 | 17 | 18 | 19 | 20 | ); 21 | 22 | export default DrawerContent; 23 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerHeader/DrawerHeaderStyled.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { styled } from '@mui/material/styles'; 3 | import { Box } from '@mui/material'; 4 | 5 | // ==============================|| DRAWER HEADER - STYLED ||============================== // 6 | 7 | const DrawerHeaderStyled = styled(Box, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({ 8 | ...theme.mixins.toolbar, 9 | display: 'flex', 10 | alignItems: 'center', 11 | justifyContent: open ? 'flex-start' : 'center', 12 | paddingLeft: theme.spacing(open ? 3 : 0) 13 | })); 14 | 15 | export default DrawerHeaderStyled; 16 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/DrawerHeader/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { Stack, Chip } from '@mui/material'; 6 | 7 | // project import 8 | import DrawerHeaderStyled from './DrawerHeaderStyled'; 9 | import Logo from 'components/Logo'; 10 | 11 | // ==============================|| DRAWER HEADER ||============================== // 12 | 13 | const DrawerHeader = ({ open }) => { 14 | const theme = useTheme(); 15 | 16 | return ( 17 | // only available in paid version 18 | 19 | 20 | 21 | 30 | 31 | 32 | ); 33 | }; 34 | 35 | DrawerHeader.propTypes = { 36 | open: PropTypes.bool 37 | }; 38 | 39 | export default DrawerHeader; 40 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/MiniDrawerStyled.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { styled } from '@mui/material/styles'; 3 | import Drawer from '@mui/material/Drawer'; 4 | 5 | // project import 6 | import { drawerWidth } from 'config'; 7 | 8 | const openedMixin = (theme) => ({ 9 | width: drawerWidth, 10 | borderRight: `1px solid ${theme.palette.divider}`, 11 | transition: theme.transitions.create('width', { 12 | easing: theme.transitions.easing.sharp, 13 | duration: theme.transitions.duration.enteringScreen 14 | }), 15 | overflowX: 'hidden', 16 | boxShadow: 'none' 17 | }); 18 | 19 | const closedMixin = (theme) => ({ 20 | transition: theme.transitions.create('width', { 21 | easing: theme.transitions.easing.sharp, 22 | duration: theme.transitions.duration.leavingScreen 23 | }), 24 | overflowX: 'hidden', 25 | width: 0, 26 | borderRight: 'none', 27 | boxShadow: theme.customShadows.z1 28 | }); 29 | 30 | // ==============================|| DRAWER - MINI STYLED ||============================== // 31 | 32 | const MiniDrawerStyled = styled(Drawer, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({ 33 | width: drawerWidth, 34 | flexShrink: 0, 35 | whiteSpace: 'nowrap', 36 | boxSizing: 'border-box', 37 | ...(open && { 38 | ...openedMixin(theme), 39 | '& .MuiDrawer-paper': openedMixin(theme) 40 | }), 41 | ...(!open && { 42 | ...closedMixin(theme), 43 | '& .MuiDrawer-paper': closedMixin(theme) 44 | }) 45 | })); 46 | 47 | export default MiniDrawerStyled; 48 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Drawer/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useMemo } from 'react'; 3 | 4 | // material-ui 5 | import { useTheme } from '@mui/material/styles'; 6 | import { Box, Drawer, useMediaQuery } from '@mui/material'; 7 | 8 | // project import 9 | import DrawerHeader from './DrawerHeader'; 10 | import DrawerContent from './DrawerContent'; 11 | import MiniDrawerStyled from './MiniDrawerStyled'; 12 | import { drawerWidth } from 'config'; 13 | 14 | // ==============================|| MAIN LAYOUT - DRAWER ||============================== // 15 | 16 | const MainDrawer = ({ open, handleDrawerToggle, window }) => { 17 | const theme = useTheme(); 18 | const matchDownMD = useMediaQuery(theme.breakpoints.down('lg')); 19 | 20 | // responsive drawer container 21 | const container = window !== undefined ? () => window().document.body : undefined; 22 | 23 | // header content 24 | const drawerContent = useMemo(() => , []); 25 | const drawerHeader = useMemo(() => , [open]); 26 | 27 | return ( 28 | 29 | {!matchDownMD ? ( 30 | 31 | {drawerHeader} 32 | {drawerContent} 33 | 34 | ) : ( 35 | 52 | {open && drawerHeader} 53 | {open && drawerContent} 54 | 55 | )} 56 | 57 | ); 58 | }; 59 | 60 | MainDrawer.propTypes = { 61 | open: PropTypes.bool, 62 | handleDrawerToggle: PropTypes.func, 63 | window: PropTypes.object 64 | }; 65 | 66 | export default MainDrawer; 67 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/AppBarStyled.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { styled } from '@mui/material/styles'; 3 | import AppBar from '@mui/material/AppBar'; 4 | 5 | // project import 6 | import { drawerWidth } from 'config'; 7 | 8 | // ==============================|| HEADER - APP BAR STYLED ||============================== // 9 | 10 | const AppBarStyled = styled(AppBar, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({ 11 | zIndex: theme.zIndex.drawer + 1, 12 | transition: theme.transitions.create(['width', 'margin'], { 13 | easing: theme.transitions.easing.sharp, 14 | duration: theme.transitions.duration.leavingScreen 15 | }), 16 | ...(open && { 17 | marginLeft: drawerWidth, 18 | width: `calc(100% - ${drawerWidth}px)`, 19 | transition: theme.transitions.create(['width', 'margin'], { 20 | easing: theme.transitions.easing.sharp, 21 | duration: theme.transitions.duration.enteringScreen 22 | }) 23 | }) 24 | })); 25 | 26 | export default AppBarStyled; 27 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/MobileSection.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { AppBar, Box, ClickAwayListener, IconButton, Paper, Popper, Toolbar } from '@mui/material'; 6 | 7 | // project import 8 | import Search from './Search'; 9 | import Profile from './Profile'; 10 | import Transitions from 'components/@extended/Transitions'; 11 | 12 | // assets 13 | import { MoreOutlined } from '@ant-design/icons'; 14 | 15 | // ==============================|| HEADER CONTENT - MOBILE ||============================== // 16 | 17 | const MobileSection = () => { 18 | const theme = useTheme(); 19 | 20 | const [open, setOpen] = useState(false); 21 | const anchorRef = useRef(null); 22 | 23 | const handleToggle = () => { 24 | setOpen((prevOpen) => !prevOpen); 25 | }; 26 | 27 | const handleClose = (event) => { 28 | if (anchorRef.current && anchorRef.current.contains(event.target)) { 29 | return; 30 | } 31 | 32 | setOpen(false); 33 | }; 34 | 35 | const prevOpen = useRef(open); 36 | useEffect(() => { 37 | if (prevOpen.current === true && open === false) { 38 | anchorRef.current.focus(); 39 | } 40 | 41 | prevOpen.current = open; 42 | }, [open]); 43 | 44 | return ( 45 | <> 46 | 47 | 59 | 60 | 61 | 62 | 83 | {({ TransitionProps }) => ( 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | )} 97 | 98 | 99 | ); 100 | }; 101 | 102 | export default MobileSection; 103 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/Notification.js: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from 'react'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { 6 | Avatar, 7 | Badge, 8 | Box, 9 | ClickAwayListener, 10 | Divider, 11 | IconButton, 12 | List, 13 | ListItemButton, 14 | ListItemAvatar, 15 | ListItemText, 16 | ListItemSecondaryAction, 17 | Paper, 18 | Popper, 19 | Typography, 20 | useMediaQuery 21 | } from '@mui/material'; 22 | 23 | // project import 24 | import MainCard from 'components/MainCard'; 25 | import Transitions from 'components/@extended/Transitions'; 26 | 27 | // assets 28 | import { BellOutlined, CloseOutlined, GiftOutlined, MessageOutlined, SettingOutlined } from '@ant-design/icons'; 29 | 30 | // sx styles 31 | const avatarSX = { 32 | width: 36, 33 | height: 36, 34 | fontSize: '1rem' 35 | }; 36 | 37 | const actionSX = { 38 | mt: '6px', 39 | ml: 1, 40 | top: 'auto', 41 | right: 'auto', 42 | alignSelf: 'flex-start', 43 | 44 | transform: 'none' 45 | }; 46 | 47 | // ==============================|| HEADER CONTENT - NOTIFICATION ||============================== // 48 | 49 | const Notification = () => { 50 | const theme = useTheme(); 51 | const matchesXs = useMediaQuery(theme.breakpoints.down('md')); 52 | 53 | const anchorRef = useRef(null); 54 | const [open, setOpen] = useState(false); 55 | const handleToggle = () => { 56 | setOpen((prevOpen) => !prevOpen); 57 | }; 58 | 59 | const handleClose = (event) => { 60 | if (anchorRef.current && anchorRef.current.contains(event.target)) { 61 | return; 62 | } 63 | setOpen(false); 64 | }; 65 | 66 | const iconBackColorOpen = 'grey.300'; 67 | const iconBackColor = 'grey.100'; 68 | 69 | return ( 70 | 71 | 81 | 82 | 83 | 84 | 85 | 103 | {({ TransitionProps }) => ( 104 | 105 | 116 | 117 | 124 | 125 | 126 | } 127 | > 128 | 139 | 140 | 141 | 147 | 148 | 149 | 150 | 153 | It's{' '} 154 | 155 | Cristina danny's 156 | {' '} 157 | birthday today. 158 | 159 | } 160 | secondary="2 min ago" 161 | /> 162 | 163 | 164 | 3:00 AM 165 | 166 | 167 | 168 | 169 | 170 | 171 | 177 | 178 | 179 | 180 | 183 | 184 | Aida Burg 185 | {' '} 186 | commented your post. 187 | 188 | } 189 | secondary="5 August" 190 | /> 191 | 192 | 193 | 6:00 PM 194 | 195 | 196 | 197 | 198 | 199 | 200 | 206 | 207 | 208 | 209 | 212 | Your Profile is Complete   213 | 214 | 60% 215 | {' '} 216 | 217 | } 218 | secondary="7 hours ago" 219 | /> 220 | 221 | 222 | 2:45 PM 223 | 224 | 225 | 226 | 227 | 228 | 229 | 235 | C 236 | 237 | 238 | 241 | 242 | Cristina Danny 243 | {' '} 244 | invited to join{' '} 245 | 246 | Meeting. 247 | 248 | 249 | } 250 | secondary="Daily scrum meeting time" 251 | /> 252 | 253 | 254 | 9:10 PM 255 | 256 | 257 | 258 | 259 | 260 | 263 | View All 264 | 265 | } 266 | /> 267 | 268 | 269 | 270 | 271 | 272 | 273 | )} 274 | 275 | 276 | ); 277 | }; 278 | 279 | export default Notification; 280 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/Profile/ProfileTab.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useState } from 'react'; 3 | 4 | // material-ui 5 | import { useTheme } from '@mui/material/styles'; 6 | import { List, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; 7 | 8 | // assets 9 | import { EditOutlined, ProfileOutlined, LogoutOutlined, UserOutlined, WalletOutlined } from '@ant-design/icons'; 10 | 11 | // ==============================|| HEADER PROFILE - PROFILE TAB ||============================== // 12 | 13 | const ProfileTab = ({ handleLogout }) => { 14 | const theme = useTheme(); 15 | 16 | const [selectedIndex, setSelectedIndex] = useState(0); 17 | const handleListItemClick = (event, index) => { 18 | setSelectedIndex(index); 19 | }; 20 | 21 | return ( 22 | 23 | handleListItemClick(event, 0)}> 24 | 25 | 26 | 27 | 28 | 29 | handleListItemClick(event, 1)}> 30 | 31 | 32 | 33 | 34 | 35 | 36 | handleListItemClick(event, 3)}> 37 | 38 | 39 | 40 | 41 | 42 | handleListItemClick(event, 4)}> 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ); 56 | }; 57 | 58 | ProfileTab.propTypes = { 59 | handleLogout: PropTypes.func 60 | }; 61 | 62 | export default ProfileTab; 63 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/Profile/SettingTab.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { List, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; 6 | 7 | // assets 8 | import { CommentOutlined, LockOutlined, QuestionCircleOutlined, UserOutlined, UnorderedListOutlined } from '@ant-design/icons'; 9 | 10 | // ==============================|| HEADER PROFILE - SETTING TAB ||============================== // 11 | 12 | const SettingTab = () => { 13 | const theme = useTheme(); 14 | 15 | const [selectedIndex, setSelectedIndex] = useState(0); 16 | const handleListItemClick = (event, index) => { 17 | setSelectedIndex(index); 18 | }; 19 | 20 | return ( 21 | 22 | handleListItemClick(event, 0)}> 23 | 24 | 25 | 26 | 27 | 28 | handleListItemClick(event, 1)}> 29 | 30 | 31 | 32 | 33 | 34 | handleListItemClick(event, 2)}> 35 | 36 | 37 | 38 | 39 | 40 | handleListItemClick(event, 3)}> 41 | 42 | 43 | 44 | 45 | 46 | handleListItemClick(event, 4)}> 47 | 48 | 49 | 50 | 51 | 52 | 53 | ); 54 | }; 55 | 56 | export default SettingTab; 57 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/Profile/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useRef, useState } from 'react'; 3 | 4 | // material-ui 5 | import { useTheme } from '@mui/material/styles'; 6 | import { 7 | Avatar, 8 | Box, 9 | ButtonBase, 10 | CardContent, 11 | ClickAwayListener, 12 | Grid, 13 | IconButton, 14 | Paper, 15 | Popper, 16 | Stack, 17 | Tab, 18 | Tabs, 19 | Typography 20 | } from '@mui/material'; 21 | 22 | // project import 23 | import MainCard from 'components/MainCard'; 24 | import Transitions from 'components/@extended/Transitions'; 25 | import ProfileTab from './ProfileTab'; 26 | import SettingTab from './SettingTab'; 27 | 28 | // assets 29 | import avatar1 from 'assets/images/users/avatar-1.png'; 30 | import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; 31 | 32 | // tab panel wrapper 33 | function TabPanel({ children, value, index, ...other }) { 34 | return ( 35 | 38 | ); 39 | } 40 | 41 | TabPanel.propTypes = { 42 | children: PropTypes.node, 43 | index: PropTypes.any.isRequired, 44 | value: PropTypes.any.isRequired 45 | }; 46 | 47 | function a11yProps(index) { 48 | return { 49 | id: `profile-tab-${index}`, 50 | 'aria-controls': `profile-tabpanel-${index}` 51 | }; 52 | } 53 | 54 | // ==============================|| HEADER CONTENT - PROFILE ||============================== // 55 | 56 | const Profile = () => { 57 | const theme = useTheme(); 58 | 59 | const handleLogout = async () => { 60 | // logout 61 | }; 62 | 63 | const anchorRef = useRef(null); 64 | const [open, setOpen] = useState(false); 65 | const handleToggle = () => { 66 | setOpen((prevOpen) => !prevOpen); 67 | }; 68 | 69 | const handleClose = (event) => { 70 | if (anchorRef.current && anchorRef.current.contains(event.target)) { 71 | return; 72 | } 73 | setOpen(false); 74 | }; 75 | 76 | const [value, setValue] = useState(0); 77 | 78 | const handleChange = (event, newValue) => { 79 | setValue(newValue); 80 | }; 81 | 82 | const iconBackColorOpen = 'grey.300'; 83 | 84 | return ( 85 | 86 | 99 | 100 | 101 | John Doe 102 | 103 | 104 | 122 | {({ TransitionProps }) => ( 123 | 124 | {open && ( 125 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | John Doe 145 | 146 | UI/UX Designer 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | {open && ( 159 | <> 160 | 161 | 162 | } 171 | label="Profile" 172 | {...a11yProps(0)} 173 | /> 174 | } 183 | label="Setting" 184 | {...a11yProps(1)} 185 | /> 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | )} 196 | 197 | 198 | 199 | )} 200 | 201 | )} 202 | 203 | 204 | ); 205 | }; 206 | 207 | export default Profile; 208 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/Search.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { Box, FormControl, InputAdornment, OutlinedInput } from '@mui/material'; 3 | 4 | // assets 5 | import { SearchOutlined } from '@ant-design/icons'; 6 | 7 | // ==============================|| HEADER CONTENT - SEARCH ||============================== // 8 | 9 | const Search = () => ( 10 | 11 | 12 | 17 | 18 | 19 | } 20 | aria-describedby="header-search-text" 21 | inputProps={{ 22 | 'aria-label': 'weight' 23 | }} 24 | placeholder="Ctrl + K" 25 | /> 26 | 27 | 28 | ); 29 | 30 | export default Search; 31 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/HeaderContent/index.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { Box, IconButton, Link, useMediaQuery } from '@mui/material'; 3 | import { GithubOutlined } from '@ant-design/icons'; 4 | 5 | // project import 6 | import Search from './Search'; 7 | import Profile from './Profile'; 8 | import Notification from './Notification'; 9 | import MobileSection from './MobileSection'; 10 | 11 | // ==============================|| HEADER - CONTENT ||============================== // 12 | 13 | const HeaderContent = () => { 14 | const matchesXs = useMediaQuery((theme) => theme.breakpoints.down('md')); 15 | 16 | return ( 17 | <> 18 | {!matchesXs && } 19 | {matchesXs && } 20 | 21 | 30 | 31 | 32 | 33 | 34 | {!matchesXs && } 35 | {matchesXs && } 36 | 37 | ); 38 | }; 39 | 40 | export default HeaderContent; 41 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Header/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { AppBar, IconButton, Toolbar, useMediaQuery } from '@mui/material'; 6 | 7 | // project import 8 | import AppBarStyled from './AppBarStyled'; 9 | import HeaderContent from './HeaderContent'; 10 | 11 | // assets 12 | import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; 13 | 14 | // ==============================|| MAIN LAYOUT - HEADER ||============================== // 15 | 16 | const Header = ({ open, handleDrawerToggle }) => { 17 | const theme = useTheme(); 18 | const matchDownMD = useMediaQuery(theme.breakpoints.down('lg')); 19 | 20 | const iconBackColor = 'grey.100'; 21 | const iconBackColorOpen = 'grey.200'; 22 | 23 | // common header 24 | const mainHeader = ( 25 | 26 | 34 | {!open ? : } 35 | 36 | 37 | 38 | ); 39 | 40 | // app-bar params 41 | const appBar = { 42 | position: 'fixed', 43 | color: 'inherit', 44 | elevation: 0, 45 | sx: { 46 | borderBottom: `1px solid ${theme.palette.divider}` 47 | // boxShadow: theme.customShadows.z1 48 | } 49 | }; 50 | 51 | return ( 52 | <> 53 | {!matchDownMD ? ( 54 | 55 | {mainHeader} 56 | 57 | ) : ( 58 | {mainHeader} 59 | )} 60 | 61 | ); 62 | }; 63 | 64 | Header.propTypes = { 65 | open: PropTypes.bool, 66 | handleDrawerToggle: PropTypes.func 67 | }; 68 | 69 | export default Header; 70 | -------------------------------------------------------------------------------- /src/layout/MainLayout/index.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { Outlet } from 'react-router-dom'; 3 | import { useDispatch, useSelector } from 'react-redux'; 4 | 5 | // material-ui 6 | import { useTheme } from '@mui/material/styles'; 7 | import { Box, Toolbar, useMediaQuery } from '@mui/material'; 8 | 9 | // project import 10 | import Drawer from './Drawer'; 11 | import Header from './Header'; 12 | import navigation from 'menu-items'; 13 | import Breadcrumbs from 'components/@extended/Breadcrumbs'; 14 | 15 | // types 16 | import { openDrawer } from 'store/reducers/menu'; 17 | 18 | // ==============================|| MAIN LAYOUT ||============================== // 19 | 20 | const MainLayout = () => { 21 | const theme = useTheme(); 22 | const matchDownLG = useMediaQuery(theme.breakpoints.down('lg')); 23 | const dispatch = useDispatch(); 24 | 25 | const { drawerOpen } = useSelector((state) => state.menu); 26 | 27 | // drawer toggler 28 | const [open, setOpen] = useState(drawerOpen); 29 | const handleDrawerToggle = () => { 30 | setOpen(!open); 31 | dispatch(openDrawer({ drawerOpen: !open })); 32 | }; 33 | 34 | // set media wise responsive drawer 35 | useEffect(() => { 36 | setOpen(!matchDownLG); 37 | dispatch(openDrawer({ drawerOpen: !matchDownLG })); 38 | 39 | // eslint-disable-next-line react-hooks/exhaustive-deps 40 | }, [matchDownLG]); 41 | 42 | useEffect(() => { 43 | if (open !== drawerOpen) setOpen(drawerOpen); 44 | // eslint-disable-next-line react-hooks/exhaustive-deps 45 | }, [drawerOpen]); 46 | 47 | return ( 48 | 49 |
50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ); 58 | }; 59 | 60 | export default MainLayout; 61 | -------------------------------------------------------------------------------- /src/layout/MinimalLayout/index.js: -------------------------------------------------------------------------------- 1 | import { Outlet } from 'react-router-dom'; 2 | 3 | // ==============================|| MINIMAL LAYOUT ||============================== // 4 | 5 | const MinimalLayout = () => ( 6 | <> 7 | 8 | 9 | ); 10 | 11 | export default MinimalLayout; 12 | -------------------------------------------------------------------------------- /src/menu-items/dashboard.js: -------------------------------------------------------------------------------- 1 | // assets 2 | import { DashboardOutlined } from '@ant-design/icons'; 3 | 4 | // icons 5 | const icons = { 6 | DashboardOutlined 7 | }; 8 | 9 | // ==============================|| MENU ITEMS - DASHBOARD ||============================== // 10 | 11 | const dashboard = { 12 | id: 'group-dashboard', 13 | title: 'Navigation', 14 | type: 'group', 15 | children: [ 16 | { 17 | id: 'dashboard', 18 | title: 'Dashboard', 19 | type: 'item', 20 | url: '/dashboard/default', 21 | icon: icons.DashboardOutlined, 22 | breadcrumbs: false 23 | } 24 | ] 25 | }; 26 | 27 | export default dashboard; 28 | -------------------------------------------------------------------------------- /src/menu-items/index.js: -------------------------------------------------------------------------------- 1 | // project import 2 | import pages from './pages'; 3 | import dashboard from './dashboard'; 4 | import utilities from './utilities'; 5 | import support from './support'; 6 | 7 | // ==============================|| MENU ITEMS ||============================== // 8 | 9 | const menuItems = { 10 | items: [dashboard, pages, utilities, support] 11 | }; 12 | 13 | export default menuItems; 14 | -------------------------------------------------------------------------------- /src/menu-items/pages.js: -------------------------------------------------------------------------------- 1 | // assets 2 | import { LoginOutlined, ProfileOutlined } from '@ant-design/icons'; 3 | 4 | // icons 5 | const icons = { 6 | LoginOutlined, 7 | ProfileOutlined 8 | }; 9 | 10 | // ==============================|| MENU ITEMS - EXTRA PAGES ||============================== // 11 | 12 | const pages = { 13 | id: 'authentication', 14 | title: 'Authentication', 15 | type: 'group', 16 | children: [ 17 | { 18 | id: 'login1', 19 | title: 'Login', 20 | type: 'item', 21 | url: '/login', 22 | icon: icons.LoginOutlined, 23 | target: true 24 | }, 25 | { 26 | id: 'register1', 27 | title: 'Register', 28 | type: 'item', 29 | url: '/register', 30 | icon: icons.ProfileOutlined, 31 | target: true 32 | } 33 | ] 34 | }; 35 | 36 | export default pages; 37 | -------------------------------------------------------------------------------- /src/menu-items/support.js: -------------------------------------------------------------------------------- 1 | // assets 2 | import { ChromeOutlined, QuestionOutlined } from '@ant-design/icons'; 3 | 4 | // icons 5 | const icons = { 6 | ChromeOutlined, 7 | QuestionOutlined 8 | }; 9 | 10 | // ==============================|| MENU ITEMS - SAMPLE PAGE & DOCUMENTATION ||============================== // 11 | 12 | const support = { 13 | id: 'support', 14 | title: 'Support', 15 | type: 'group', 16 | children: [ 17 | { 18 | id: 'sample-page', 19 | title: 'Sample Page', 20 | type: 'item', 21 | url: '/sample-page', 22 | icon: icons.ChromeOutlined 23 | }, 24 | { 25 | id: 'documentation', 26 | title: 'Documentation', 27 | type: 'item', 28 | url: 'https://codedthemes.gitbook.io/mantis/', 29 | icon: icons.QuestionOutlined, 30 | external: true, 31 | target: true 32 | } 33 | ] 34 | }; 35 | 36 | export default support; 37 | -------------------------------------------------------------------------------- /src/menu-items/utilities.js: -------------------------------------------------------------------------------- 1 | // assets 2 | import { 3 | AppstoreAddOutlined, 4 | AntDesignOutlined, 5 | BarcodeOutlined, 6 | BgColorsOutlined, 7 | FontSizeOutlined, 8 | LoadingOutlined 9 | } from '@ant-design/icons'; 10 | 11 | // icons 12 | const icons = { 13 | FontSizeOutlined, 14 | BgColorsOutlined, 15 | BarcodeOutlined, 16 | AntDesignOutlined, 17 | LoadingOutlined, 18 | AppstoreAddOutlined 19 | }; 20 | 21 | // ==============================|| MENU ITEMS - UTILITIES ||============================== // 22 | 23 | const utilities = { 24 | id: 'utilities', 25 | title: 'Utilities', 26 | type: 'group', 27 | children: [ 28 | { 29 | id: 'util-typography', 30 | title: 'Typography', 31 | type: 'item', 32 | url: '/typography', 33 | icon: icons.FontSizeOutlined 34 | }, 35 | { 36 | id: 'util-color', 37 | title: 'Color', 38 | type: 'item', 39 | url: '/color', 40 | icon: icons.BgColorsOutlined 41 | }, 42 | { 43 | id: 'util-shadow', 44 | title: 'Shadow', 45 | type: 'item', 46 | url: '/shadow', 47 | icon: icons.BarcodeOutlined 48 | }, 49 | { 50 | id: 'ant-icons', 51 | title: 'Ant Icons', 52 | type: 'item', 53 | url: '/icons/ant', 54 | icon: icons.AntDesignOutlined, 55 | breadcrumbs: false 56 | } 57 | ] 58 | }; 59 | 60 | export default utilities; 61 | -------------------------------------------------------------------------------- /src/pages/authentication/AuthCard.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { Box } from '@mui/material'; 5 | 6 | // project import 7 | import MainCard from 'components/MainCard'; 8 | 9 | // ==============================|| AUTHENTICATION - CARD WRAPPER ||============================== // 10 | 11 | const AuthCard = ({ children, ...other }) => ( 12 | *': { 17 | flexGrow: 1, 18 | flexBasis: '50%' 19 | } 20 | }} 21 | content={false} 22 | {...other} 23 | border={false} 24 | boxShadow 25 | > 26 | {children} 27 | 28 | ); 29 | 30 | AuthCard.propTypes = { 31 | children: PropTypes.node 32 | }; 33 | 34 | export default AuthCard; 35 | -------------------------------------------------------------------------------- /src/pages/authentication/AuthWrapper.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { Box, Grid } from '@mui/material'; 5 | 6 | // project import 7 | import AuthCard from './AuthCard'; 8 | import Logo from 'components/Logo'; 9 | import AuthFooter from 'components/cards/AuthFooter'; 10 | 11 | // assets 12 | import AuthBackground from 'assets/images/auth/AuthBackground'; 13 | 14 | // ==============================|| AUTHENTICATION - WRAPPER ||============================== // 15 | 16 | const AuthWrapper = ({ children }) => ( 17 | 18 | 19 | 27 | 28 | 29 | 30 | 31 | 39 | 40 | {children} 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ); 50 | 51 | AuthWrapper.propTypes = { 52 | children: PropTypes.node 53 | }; 54 | 55 | export default AuthWrapper; 56 | -------------------------------------------------------------------------------- /src/pages/authentication/Login.js: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | 3 | // material-ui 4 | import { Grid, Stack, Typography } from '@mui/material'; 5 | 6 | // project import 7 | import AuthLogin from './auth-forms/AuthLogin'; 8 | import AuthWrapper from './AuthWrapper'; 9 | 10 | // ================================|| LOGIN ||================================ // 11 | 12 | const Login = () => ( 13 | 14 | 15 | 16 | 17 | Login 18 | 19 | Don't have an account? 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ); 29 | 30 | export default Login; 31 | -------------------------------------------------------------------------------- /src/pages/authentication/Register.js: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | 3 | // material-ui 4 | import { Grid, Stack, Typography } from '@mui/material'; 5 | 6 | // project import 7 | import FirebaseRegister from './auth-forms/AuthRegister'; 8 | import AuthWrapper from './AuthWrapper'; 9 | 10 | // ================================|| REGISTER ||================================ // 11 | 12 | const Register = () => ( 13 | 14 | 15 | 16 | 17 | Sign up 18 | 19 | Already have an account? 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ); 29 | 30 | export default Register; 31 | -------------------------------------------------------------------------------- /src/pages/authentication/auth-forms/AuthLogin.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link as RouterLink } from 'react-router-dom'; 3 | 4 | // material-ui 5 | import { 6 | Button, 7 | Checkbox, 8 | Divider, 9 | FormControlLabel, 10 | FormHelperText, 11 | Grid, 12 | Link, 13 | IconButton, 14 | InputAdornment, 15 | InputLabel, 16 | OutlinedInput, 17 | Stack, 18 | Typography 19 | } from '@mui/material'; 20 | 21 | // third party 22 | import * as Yup from 'yup'; 23 | import { Formik } from 'formik'; 24 | 25 | // project import 26 | import FirebaseSocial from './FirebaseSocial'; 27 | import AnimateButton from 'components/@extended/AnimateButton'; 28 | 29 | // assets 30 | import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; 31 | 32 | // ============================|| FIREBASE - LOGIN ||============================ // 33 | 34 | const AuthLogin = () => { 35 | const [checked, setChecked] = React.useState(false); 36 | 37 | const [showPassword, setShowPassword] = React.useState(false); 38 | const handleClickShowPassword = () => { 39 | setShowPassword(!showPassword); 40 | }; 41 | 42 | const handleMouseDownPassword = (event) => { 43 | event.preventDefault(); 44 | }; 45 | 46 | return ( 47 | <> 48 | { 59 | try { 60 | setStatus({ success: false }); 61 | setSubmitting(false); 62 | } catch (err) { 63 | setStatus({ success: false }); 64 | setErrors({ submit: err.message }); 65 | setSubmitting(false); 66 | } 67 | }} 68 | > 69 | {({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => ( 70 |
71 | 72 | 73 | 74 | Email Address 75 | 86 | {touched.email && errors.email && ( 87 | 88 | {errors.email} 89 | 90 | )} 91 | 92 | 93 | 94 | 95 | Password 96 | 107 | 114 | {showPassword ? : } 115 | 116 | 117 | } 118 | placeholder="Enter password" 119 | /> 120 | {touched.password && errors.password && ( 121 | 122 | {errors.password} 123 | 124 | )} 125 | 126 | 127 | 128 | 129 | 130 | setChecked(event.target.checked)} 135 | name="checked" 136 | color="primary" 137 | size="small" 138 | /> 139 | } 140 | label={Keep me sign in} 141 | /> 142 | 143 | Forgot Password? 144 | 145 | 146 | 147 | {errors.submit && ( 148 | 149 | {errors.submit} 150 | 151 | )} 152 | 153 | 154 | 157 | 158 | 159 | 160 | 161 | Login with 162 | 163 | 164 | 165 | 166 | 167 | 168 |
169 | )} 170 |
171 | 172 | ); 173 | }; 174 | 175 | export default AuthLogin; 176 | -------------------------------------------------------------------------------- /src/pages/authentication/auth-forms/AuthRegister.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { Link as RouterLink } from 'react-router-dom'; 3 | 4 | // material-ui 5 | import { 6 | Box, 7 | Button, 8 | Divider, 9 | FormControl, 10 | FormHelperText, 11 | Grid, 12 | Link, 13 | IconButton, 14 | InputAdornment, 15 | InputLabel, 16 | OutlinedInput, 17 | Stack, 18 | Typography 19 | } from '@mui/material'; 20 | 21 | // third party 22 | import * as Yup from 'yup'; 23 | import { Formik } from 'formik'; 24 | 25 | // project import 26 | import FirebaseSocial from './FirebaseSocial'; 27 | import AnimateButton from 'components/@extended/AnimateButton'; 28 | import { strengthColor, strengthIndicator } from 'utils/password-strength'; 29 | 30 | // assets 31 | import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; 32 | 33 | // ============================|| FIREBASE - REGISTER ||============================ // 34 | 35 | const AuthRegister = () => { 36 | const [level, setLevel] = useState(); 37 | const [showPassword, setShowPassword] = useState(false); 38 | const handleClickShowPassword = () => { 39 | setShowPassword(!showPassword); 40 | }; 41 | 42 | const handleMouseDownPassword = (event) => { 43 | event.preventDefault(); 44 | }; 45 | 46 | const changePassword = (value) => { 47 | const temp = strengthIndicator(value); 48 | setLevel(strengthColor(temp)); 49 | }; 50 | 51 | useEffect(() => { 52 | changePassword(''); 53 | }, []); 54 | 55 | return ( 56 | <> 57 | { 73 | try { 74 | setStatus({ success: false }); 75 | setSubmitting(false); 76 | } catch (err) { 77 | console.error(err); 78 | setStatus({ success: false }); 79 | setErrors({ submit: err.message }); 80 | setSubmitting(false); 81 | } 82 | }} 83 | > 84 | {({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => ( 85 |
86 | 87 | 88 | 89 | First Name* 90 | 101 | {touched.firstname && errors.firstname && ( 102 | 103 | {errors.firstname} 104 | 105 | )} 106 | 107 | 108 | 109 | 110 | Last Name* 111 | 123 | {touched.lastname && errors.lastname && ( 124 | 125 | {errors.lastname} 126 | 127 | )} 128 | 129 | 130 | 131 | 132 | Company 133 | 144 | {touched.company && errors.company && ( 145 | 146 | {errors.company} 147 | 148 | )} 149 | 150 | 151 | 152 | 153 | Email Address* 154 | 166 | {touched.email && errors.email && ( 167 | 168 | {errors.email} 169 | 170 | )} 171 | 172 | 173 | 174 | 175 | Password 176 | { 185 | handleChange(e); 186 | changePassword(e.target.value); 187 | }} 188 | endAdornment={ 189 | 190 | 197 | {showPassword ? : } 198 | 199 | 200 | } 201 | placeholder="******" 202 | inputProps={{}} 203 | /> 204 | {touched.password && errors.password && ( 205 | 206 | {errors.password} 207 | 208 | )} 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | {level?.label} 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | By Signing up, you agree to our   226 | 227 | Terms of Service 228 | 229 |   and   230 | 231 | Privacy Policy 232 | 233 | 234 | 235 | {errors.submit && ( 236 | 237 | {errors.submit} 238 | 239 | )} 240 | 241 | 242 | 245 | 246 | 247 | 248 | 249 | Sign up with 250 | 251 | 252 | 253 | 254 | 255 | 256 |
257 | )} 258 |
259 | 260 | ); 261 | }; 262 | 263 | export default AuthRegister; 264 | -------------------------------------------------------------------------------- /src/pages/authentication/auth-forms/FirebaseSocial.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { useTheme } from '@mui/material/styles'; 3 | import { useMediaQuery, Button, Stack } from '@mui/material'; 4 | 5 | // assets 6 | import Google from 'assets/images/icons/google.svg'; 7 | import Twitter from 'assets/images/icons/twitter.svg'; 8 | import Facebook from 'assets/images/icons/facebook.svg'; 9 | 10 | // ==============================|| FIREBASE - SOCIAL BUTTON ||============================== // 11 | 12 | const FirebaseSocial = () => { 13 | const theme = useTheme(); 14 | const matchDownSM = useMediaQuery(theme.breakpoints.down('sm')); 15 | 16 | const googleHandler = async () => { 17 | // login || singup 18 | }; 19 | 20 | const twitterHandler = async () => { 21 | // login || singup 22 | }; 23 | 24 | const facebookHandler = async () => { 25 | // login || singup 26 | }; 27 | 28 | return ( 29 | 35 | 44 | 53 | 62 | 63 | ); 64 | }; 65 | 66 | export default FirebaseSocial; 67 | -------------------------------------------------------------------------------- /src/pages/components-overview/AntIcons.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { styled } from '@mui/material/styles'; 3 | 4 | // project import 5 | import ComponentSkeleton from './ComponentSkeleton'; 6 | import MainCard from 'components/MainCard'; 7 | 8 | // styles 9 | const IFrameWrapper = styled('iframe')(() => ({ 10 | height: 'calc(100vh - 210px)', 11 | border: 'none' 12 | })); 13 | 14 | // ============================|| ANT ICONS ||============================ // 15 | 16 | const AntIcons = () => ( 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | 24 | export default AntIcons; 25 | -------------------------------------------------------------------------------- /src/pages/components-overview/Color.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { Box, Card, Grid, Stack, Typography } from '@mui/material'; 5 | 6 | // project import 7 | import MainCard from 'components/MainCard'; 8 | import ComponentSkeleton from './ComponentSkeleton'; 9 | 10 | // ===============================|| COLOR BOX ||=============================== // 11 | 12 | function ColorBox({ bgcolor, title, data, dark, main }) { 13 | return ( 14 | <> 15 | 16 | 27 | {title && ( 28 | 29 | 30 | {data && ( 31 | 32 | {data.label} 33 | {data.color} 34 | 35 | )} 36 | 37 | 38 | 39 | {title} 40 | 41 | 42 | 43 | )} 44 | 45 | 46 | 47 | ); 48 | } 49 | 50 | ColorBox.propTypes = { 51 | bgcolor: PropTypes.string, 52 | title: PropTypes.string, 53 | data: PropTypes.object.isRequired, 54 | dark: PropTypes.bool, 55 | main: PropTypes.bool 56 | }; 57 | 58 | // ===============================|| COMPONENT - COLOR ||=============================== // 59 | 60 | const ComponentColor = () => ( 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | ); 140 | 141 | export default ComponentColor; 142 | -------------------------------------------------------------------------------- /src/pages/components-overview/ComponentSkeleton.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useEffect, useState } from 'react'; 3 | 4 | // material-ui 5 | import { Grid, Skeleton, Stack } from '@mui/material'; 6 | 7 | // project import 8 | import MainCard from 'components/MainCard'; 9 | 10 | // ===============================|| COMPONENT - SKELETON ||=============================== // 11 | 12 | const ComponentSkeleton = ({ children }) => { 13 | const [isLoading, setLoading] = useState(true); 14 | useEffect(() => { 15 | setLoading(false); 16 | }, []); 17 | 18 | const skeletonCard = ( 19 | } 21 | secondary={} 22 | > 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ); 31 | 32 | return ( 33 | <> 34 | {isLoading && ( 35 | 36 | 37 | {skeletonCard} 38 | 39 | 40 | {skeletonCard} 41 | 42 | 43 | {skeletonCard} 44 | 45 | 46 | {skeletonCard} 47 | 48 | 49 | )} 50 | {!isLoading && children} 51 | 52 | ); 53 | }; 54 | 55 | ComponentSkeleton.propTypes = { 56 | children: PropTypes.node 57 | }; 58 | 59 | export default ComponentSkeleton; 60 | -------------------------------------------------------------------------------- /src/pages/components-overview/Shadow.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | import { Grid, Stack, Typography } from '@mui/material'; 6 | 7 | // project import 8 | import MainCard from 'components/MainCard'; 9 | import ComponentSkeleton from './ComponentSkeleton'; 10 | 11 | // ===============================|| SHADOW BOX ||=============================== // 12 | 13 | function ShadowBox({ shadow }) { 14 | return ( 15 | 16 | 17 | boxShadow 18 | {shadow} 19 | 20 | 21 | ); 22 | } 23 | 24 | ShadowBox.propTypes = { 25 | shadow: PropTypes.string.isRequired 26 | }; 27 | 28 | // ===============================|| CUSTOM - SHADOW BOX ||=============================== // 29 | 30 | function CustomShadowBox({ shadow, label, color, bgcolor }) { 31 | return ( 32 | 33 | 34 | 35 | {label} 36 | 37 | 38 | 39 | ); 40 | } 41 | 42 | CustomShadowBox.propTypes = { 43 | shadow: PropTypes.string.isRequired, 44 | color: PropTypes.string.isRequired, 45 | label: PropTypes.string.isRequired, 46 | bgcolor: PropTypes.string 47 | }; 48 | 49 | // ============================|| COMPONENT - SHADOW ||============================ // 50 | 51 | const ComponentShadow = () => { 52 | const theme = useTheme(); 53 | 54 | return ( 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | ); 150 | }; 151 | 152 | export default ComponentShadow; 153 | -------------------------------------------------------------------------------- /src/pages/dashboard/IncomeAreaChart.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useState, useEffect } from 'react'; 3 | 4 | // material-ui 5 | import { useTheme } from '@mui/material/styles'; 6 | 7 | // third-party 8 | import ReactApexChart from 'react-apexcharts'; 9 | 10 | // chart options 11 | const areaChartOptions = { 12 | chart: { 13 | height: 450, 14 | type: 'area', 15 | toolbar: { 16 | show: false 17 | } 18 | }, 19 | dataLabels: { 20 | enabled: false 21 | }, 22 | stroke: { 23 | curve: 'smooth', 24 | width: 2 25 | }, 26 | grid: { 27 | strokeDashArray: 0 28 | } 29 | }; 30 | 31 | // ==============================|| INCOME AREA CHART ||============================== // 32 | 33 | const IncomeAreaChart = ({ slot }) => { 34 | const theme = useTheme(); 35 | 36 | const { primary, secondary } = theme.palette.text; 37 | const line = theme.palette.divider; 38 | 39 | const [options, setOptions] = useState(areaChartOptions); 40 | 41 | useEffect(() => { 42 | setOptions((prevState) => ({ 43 | ...prevState, 44 | colors: [theme.palette.primary.main, theme.palette.primary[700]], 45 | xaxis: { 46 | categories: 47 | slot === 'month' 48 | ? ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 49 | : ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 50 | labels: { 51 | style: { 52 | colors: [ 53 | secondary, 54 | secondary, 55 | secondary, 56 | secondary, 57 | secondary, 58 | secondary, 59 | secondary, 60 | secondary, 61 | secondary, 62 | secondary, 63 | secondary, 64 | secondary 65 | ] 66 | } 67 | }, 68 | axisBorder: { 69 | show: true, 70 | color: line 71 | }, 72 | tickAmount: slot === 'month' ? 11 : 7 73 | }, 74 | yaxis: { 75 | labels: { 76 | style: { 77 | colors: [secondary] 78 | } 79 | } 80 | }, 81 | grid: { 82 | borderColor: line 83 | }, 84 | tooltip: { 85 | theme: 'light' 86 | } 87 | })); 88 | }, [primary, secondary, line, theme, slot]); 89 | 90 | const [series, setSeries] = useState([ 91 | { 92 | name: 'Page Views', 93 | data: [0, 86, 28, 115, 48, 210, 136] 94 | }, 95 | { 96 | name: 'Sessions', 97 | data: [0, 43, 14, 56, 24, 105, 68] 98 | } 99 | ]); 100 | 101 | useEffect(() => { 102 | setSeries([ 103 | { 104 | name: 'Page Views', 105 | data: slot === 'month' ? [76, 85, 101, 98, 87, 105, 91, 114, 94, 86, 115, 35] : [31, 40, 28, 51, 42, 109, 100] 106 | }, 107 | { 108 | name: 'Sessions', 109 | data: slot === 'month' ? [110, 60, 150, 35, 60, 36, 26, 45, 65, 52, 53, 41] : [11, 32, 45, 32, 34, 52, 41] 110 | } 111 | ]); 112 | }, [slot]); 113 | 114 | return ; 115 | }; 116 | 117 | IncomeAreaChart.propTypes = { 118 | slot: PropTypes.string 119 | }; 120 | 121 | export default IncomeAreaChart; 122 | -------------------------------------------------------------------------------- /src/pages/dashboard/MonthlyBarChart.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | 6 | // third-party 7 | import ReactApexChart from 'react-apexcharts'; 8 | 9 | // chart options 10 | const barChartOptions = { 11 | chart: { 12 | type: 'bar', 13 | height: 365, 14 | toolbar: { 15 | show: false 16 | } 17 | }, 18 | plotOptions: { 19 | bar: { 20 | columnWidth: '45%', 21 | borderRadius: 4 22 | } 23 | }, 24 | dataLabels: { 25 | enabled: false 26 | }, 27 | xaxis: { 28 | categories: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'], 29 | axisBorder: { 30 | show: false 31 | }, 32 | axisTicks: { 33 | show: false 34 | } 35 | }, 36 | yaxis: { 37 | show: false 38 | }, 39 | grid: { 40 | show: false 41 | } 42 | }; 43 | 44 | // ==============================|| MONTHLY BAR CHART ||============================== // 45 | 46 | const MonthlyBarChart = () => { 47 | const theme = useTheme(); 48 | 49 | const { primary, secondary } = theme.palette.text; 50 | const info = theme.palette.info.light; 51 | 52 | const [series] = useState([ 53 | { 54 | data: [80, 95, 70, 42, 65, 55, 78] 55 | } 56 | ]); 57 | 58 | const [options, setOptions] = useState(barChartOptions); 59 | 60 | useEffect(() => { 61 | setOptions((prevState) => ({ 62 | ...prevState, 63 | colors: [info], 64 | xaxis: { 65 | labels: { 66 | style: { 67 | colors: [secondary, secondary, secondary, secondary, secondary, secondary, secondary] 68 | } 69 | } 70 | }, 71 | tooltip: { 72 | theme: 'light' 73 | } 74 | })); 75 | // eslint-disable-next-line react-hooks/exhaustive-deps 76 | }, [primary, info, secondary]); 77 | 78 | return ( 79 |
80 | 81 |
82 | ); 83 | }; 84 | 85 | export default MonthlyBarChart; 86 | -------------------------------------------------------------------------------- /src/pages/dashboard/OrdersTable.js: -------------------------------------------------------------------------------- 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 { Box, Link, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; 7 | 8 | // third-party 9 | import { NumericFormat } from 'react-number-format'; 10 | 11 | // project import 12 | import Dot from 'components/@extended/Dot'; 13 | 14 | function createData(trackingNo, name, fat, carbs, protein) { 15 | return { trackingNo, name, fat, carbs, protein }; 16 | } 17 | 18 | const rows = [ 19 | createData(84564564, 'Camera Lens', 40, 2, 40570), 20 | createData(98764564, 'Laptop', 300, 0, 180139), 21 | createData(98756325, 'Mobile', 355, 1, 90989), 22 | createData(98652366, 'Handset', 50, 1, 10239), 23 | createData(13286564, 'Computer Accessories', 100, 1, 83348), 24 | createData(86739658, 'TV', 99, 0, 410780), 25 | createData(13256498, 'Keyboard', 125, 2, 70999), 26 | createData(98753263, 'Mouse', 89, 2, 10570), 27 | createData(98753275, 'Desktop', 185, 1, 98063), 28 | createData(98753291, 'Chair', 100, 0, 14001) 29 | ]; 30 | 31 | function descendingComparator(a, b, orderBy) { 32 | if (b[orderBy] < a[orderBy]) { 33 | return -1; 34 | } 35 | if (b[orderBy] > a[orderBy]) { 36 | return 1; 37 | } 38 | return 0; 39 | } 40 | 41 | function getComparator(order, orderBy) { 42 | return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); 43 | } 44 | 45 | function stableSort(array, comparator) { 46 | const stabilizedThis = array.map((el, index) => [el, index]); 47 | stabilizedThis.sort((a, b) => { 48 | const order = comparator(a[0], b[0]); 49 | if (order !== 0) { 50 | return order; 51 | } 52 | return a[1] - b[1]; 53 | }); 54 | return stabilizedThis.map((el) => el[0]); 55 | } 56 | 57 | // ==============================|| ORDER TABLE - HEADER CELL ||============================== // 58 | 59 | const headCells = [ 60 | { 61 | id: 'trackingNo', 62 | align: 'left', 63 | disablePadding: false, 64 | label: 'Tracking No.' 65 | }, 66 | { 67 | id: 'name', 68 | align: 'left', 69 | disablePadding: true, 70 | label: 'Product Name' 71 | }, 72 | { 73 | id: 'fat', 74 | align: 'right', 75 | disablePadding: false, 76 | label: 'Total Order' 77 | }, 78 | { 79 | id: 'carbs', 80 | align: 'left', 81 | disablePadding: false, 82 | 83 | label: 'Status' 84 | }, 85 | { 86 | id: 'protein', 87 | align: 'right', 88 | disablePadding: false, 89 | label: 'Total Amount' 90 | } 91 | ]; 92 | 93 | // ==============================|| ORDER TABLE - HEADER ||============================== // 94 | 95 | function OrderTableHead({ order, orderBy }) { 96 | return ( 97 | 98 | 99 | {headCells.map((headCell) => ( 100 | 106 | {headCell.label} 107 | 108 | ))} 109 | 110 | 111 | ); 112 | } 113 | 114 | OrderTableHead.propTypes = { 115 | order: PropTypes.string, 116 | orderBy: PropTypes.string 117 | }; 118 | 119 | // ==============================|| ORDER TABLE - STATUS ||============================== // 120 | 121 | const OrderStatus = ({ status }) => { 122 | let color; 123 | let title; 124 | 125 | switch (status) { 126 | case 0: 127 | color = 'warning'; 128 | title = 'Pending'; 129 | break; 130 | case 1: 131 | color = 'success'; 132 | title = 'Approved'; 133 | break; 134 | case 2: 135 | color = 'error'; 136 | title = 'Rejected'; 137 | break; 138 | default: 139 | color = 'primary'; 140 | title = 'None'; 141 | } 142 | 143 | return ( 144 | 145 | 146 | {title} 147 | 148 | ); 149 | }; 150 | 151 | OrderStatus.propTypes = { 152 | status: PropTypes.number 153 | }; 154 | 155 | // ==============================|| ORDER TABLE ||============================== // 156 | 157 | export default function OrderTable() { 158 | const [order] = useState('asc'); 159 | const [orderBy] = useState('trackingNo'); 160 | const [selected] = useState([]); 161 | 162 | const isSelected = (trackingNo) => selected.indexOf(trackingNo) !== -1; 163 | 164 | return ( 165 | 166 | 176 | 187 | 188 | 189 | {stableSort(rows, getComparator(order, orderBy)).map((row, index) => { 190 | const isItemSelected = isSelected(row.trackingNo); 191 | const labelId = `enhanced-table-checkbox-${index}`; 192 | 193 | return ( 194 | 203 | 204 | 205 | {row.trackingNo} 206 | 207 | 208 | {row.name} 209 | {row.fat} 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | ); 218 | })} 219 | 220 |
221 |
222 |
223 | ); 224 | } 225 | -------------------------------------------------------------------------------- /src/pages/dashboard/ReportAreaChart.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | 6 | // third-party 7 | import ReactApexChart from 'react-apexcharts'; 8 | 9 | // chart options 10 | const areaChartOptions = { 11 | chart: { 12 | height: 340, 13 | type: 'line', 14 | toolbar: { 15 | show: false 16 | } 17 | }, 18 | dataLabels: { 19 | enabled: false 20 | }, 21 | stroke: { 22 | curve: 'smooth', 23 | width: 1.5 24 | }, 25 | grid: { 26 | strokeDashArray: 4 27 | }, 28 | xaxis: { 29 | type: 'datetime', 30 | categories: [ 31 | '2018-05-19T00:00:00.000Z', 32 | '2018-06-19T00:00:00.000Z', 33 | '2018-07-19T01:30:00.000Z', 34 | '2018-08-19T02:30:00.000Z', 35 | '2018-09-19T03:30:00.000Z', 36 | '2018-10-19T04:30:00.000Z', 37 | '2018-11-19T05:30:00.000Z', 38 | '2018-12-19T06:30:00.000Z' 39 | ], 40 | labels: { 41 | format: 'MMM' 42 | }, 43 | axisBorder: { 44 | show: false 45 | }, 46 | axisTicks: { 47 | show: false 48 | } 49 | }, 50 | yaxis: { 51 | show: false 52 | }, 53 | tooltip: { 54 | x: { 55 | format: 'MM' 56 | } 57 | } 58 | }; 59 | 60 | // ==============================|| REPORT AREA CHART ||============================== // 61 | 62 | const ReportAreaChart = () => { 63 | const theme = useTheme(); 64 | 65 | const { primary, secondary } = theme.palette.text; 66 | const line = theme.palette.divider; 67 | 68 | const [options, setOptions] = useState(areaChartOptions); 69 | 70 | useEffect(() => { 71 | setOptions((prevState) => ({ 72 | ...prevState, 73 | colors: [theme.palette.warning.main], 74 | xaxis: { 75 | labels: { 76 | style: { 77 | colors: [secondary, secondary, secondary, secondary, secondary, secondary, secondary, secondary] 78 | } 79 | } 80 | }, 81 | grid: { 82 | borderColor: line 83 | }, 84 | tooltip: { 85 | theme: 'light' 86 | }, 87 | legend: { 88 | labels: { 89 | colors: 'grey.500' 90 | } 91 | } 92 | })); 93 | }, [primary, secondary, line, theme]); 94 | 95 | const [series] = useState([ 96 | { 97 | name: 'Series 1', 98 | data: [58, 115, 28, 83, 63, 75, 35, 55] 99 | } 100 | ]); 101 | 102 | return ; 103 | }; 104 | 105 | export default ReportAreaChart; 106 | -------------------------------------------------------------------------------- /src/pages/dashboard/SalesColumnChart.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | // material-ui 4 | import { useTheme } from '@mui/material/styles'; 5 | 6 | // third-party 7 | import ReactApexChart from 'react-apexcharts'; 8 | 9 | // chart options 10 | const columnChartOptions = { 11 | chart: { 12 | type: 'bar', 13 | height: 430, 14 | toolbar: { 15 | show: false 16 | } 17 | }, 18 | plotOptions: { 19 | bar: { 20 | columnWidth: '30%', 21 | borderRadius: 4 22 | } 23 | }, 24 | dataLabels: { 25 | enabled: false 26 | }, 27 | stroke: { 28 | show: true, 29 | width: 8, 30 | colors: ['transparent'] 31 | }, 32 | xaxis: { 33 | categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'] 34 | }, 35 | yaxis: { 36 | title: { 37 | text: '$ (thousands)' 38 | } 39 | }, 40 | fill: { 41 | opacity: 1 42 | }, 43 | tooltip: { 44 | y: { 45 | formatter(val) { 46 | return `$ ${val} thousands`; 47 | } 48 | } 49 | }, 50 | legend: { 51 | show: true, 52 | fontFamily: `'Public Sans', sans-serif`, 53 | offsetX: 10, 54 | offsetY: 10, 55 | labels: { 56 | useSeriesColors: false 57 | }, 58 | markers: { 59 | width: 16, 60 | height: 16, 61 | radius: '50%', 62 | offsexX: 2, 63 | offsexY: 2 64 | }, 65 | itemMargin: { 66 | horizontal: 15, 67 | vertical: 50 68 | } 69 | }, 70 | responsive: [ 71 | { 72 | breakpoint: 600, 73 | options: { 74 | yaxis: { 75 | show: false 76 | } 77 | } 78 | } 79 | ] 80 | }; 81 | 82 | // ==============================|| SALES COLUMN CHART ||============================== // 83 | 84 | const SalesColumnChart = () => { 85 | const theme = useTheme(); 86 | 87 | const { primary, secondary } = theme.palette.text; 88 | const line = theme.palette.divider; 89 | 90 | const warning = theme.palette.warning.main; 91 | const primaryMain = theme.palette.primary.main; 92 | const successDark = theme.palette.success.dark; 93 | 94 | const [series] = useState([ 95 | { 96 | name: 'Net Profit', 97 | data: [180, 90, 135, 114, 120, 145] 98 | }, 99 | { 100 | name: 'Revenue', 101 | data: [120, 45, 78, 150, 168, 99] 102 | } 103 | ]); 104 | 105 | const [options, setOptions] = useState(columnChartOptions); 106 | 107 | useEffect(() => { 108 | setOptions((prevState) => ({ 109 | ...prevState, 110 | colors: [warning, primaryMain], 111 | xaxis: { 112 | labels: { 113 | style: { 114 | colors: [secondary, secondary, secondary, secondary, secondary, secondary] 115 | } 116 | } 117 | }, 118 | yaxis: { 119 | labels: { 120 | style: { 121 | colors: [secondary] 122 | } 123 | } 124 | }, 125 | grid: { 126 | borderColor: line 127 | }, 128 | tooltip: { 129 | theme: 'light' 130 | }, 131 | legend: { 132 | position: 'top', 133 | horizontalAlign: 'right', 134 | labels: { 135 | colors: 'grey.500' 136 | } 137 | } 138 | })); 139 | }, [primary, secondary, line, warning, primaryMain, successDark]); 140 | 141 | return ( 142 |
143 | 144 |
145 | ); 146 | }; 147 | 148 | export default SalesColumnChart; 149 | -------------------------------------------------------------------------------- /src/pages/dashboard/index.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | // material-ui 4 | import { 5 | Avatar, 6 | AvatarGroup, 7 | Box, 8 | Button, 9 | Grid, 10 | List, 11 | ListItemAvatar, 12 | ListItemButton, 13 | ListItemSecondaryAction, 14 | ListItemText, 15 | MenuItem, 16 | Stack, 17 | TextField, 18 | Typography 19 | } from '@mui/material'; 20 | 21 | // project import 22 | import OrdersTable from './OrdersTable'; 23 | import IncomeAreaChart from './IncomeAreaChart'; 24 | import MonthlyBarChart from './MonthlyBarChart'; 25 | import ReportAreaChart from './ReportAreaChart'; 26 | import SalesColumnChart from './SalesColumnChart'; 27 | import MainCard from 'components/MainCard'; 28 | import AnalyticEcommerce from 'components/cards/statistics/AnalyticEcommerce'; 29 | 30 | // assets 31 | import { GiftOutlined, MessageOutlined, SettingOutlined } from '@ant-design/icons'; 32 | import avatar1 from 'assets/images/users/avatar-1.png'; 33 | import avatar2 from 'assets/images/users/avatar-2.png'; 34 | import avatar3 from 'assets/images/users/avatar-3.png'; 35 | import avatar4 from 'assets/images/users/avatar-4.png'; 36 | 37 | // avatar style 38 | const avatarSX = { 39 | width: 36, 40 | height: 36, 41 | fontSize: '1rem' 42 | }; 43 | 44 | // action style 45 | const actionSX = { 46 | mt: 0.75, 47 | ml: 1, 48 | top: 'auto', 49 | right: 'auto', 50 | alignSelf: 'flex-start', 51 | transform: 'none' 52 | }; 53 | 54 | // sales report status 55 | const status = [ 56 | { 57 | value: 'today', 58 | label: 'Today' 59 | }, 60 | { 61 | value: 'month', 62 | label: 'This Month' 63 | }, 64 | { 65 | value: 'year', 66 | label: 'This Year' 67 | } 68 | ]; 69 | 70 | // ==============================|| DASHBOARD - DEFAULT ||============================== // 71 | 72 | const DashboardDefault = () => { 73 | const [value, setValue] = useState('today'); 74 | const [slot, setSlot] = useState('week'); 75 | 76 | return ( 77 | 78 | {/* row 1 */} 79 | 80 | Dashboard 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | {/* row 2 */} 98 | 99 | 100 | 101 | Unique Visitor 102 | 103 | 104 | 105 | 113 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | Income Overview 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | This Week Statistics 142 | 143 | $7,650 144 | 145 | 146 | 147 | 148 | 149 | 150 | {/* row 3 */} 151 | 152 | 153 | 154 | Recent Orders 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | Analytics Report 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | +45.14% 174 | 175 | 176 | 177 | 0.58% 178 | 179 | 180 | 181 | Low 182 | 183 | 184 | 185 | 186 | 187 | 188 | {/* row 4 */} 189 | 190 | 191 | 192 | Sales Report 193 | 194 | 195 | setValue(e.target.value)} 201 | sx={{ '& .MuiInputBase-input': { py: 0.5, fontSize: '0.875rem' } }} 202 | > 203 | {status.map((option) => ( 204 | 205 | {option.label} 206 | 207 | ))} 208 | 209 | 210 | 211 | 212 | 213 | 214 | Net Profit 215 | 216 | $1560 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | Transaction History 225 | 226 | 227 | 228 | 229 | 241 | 242 | 243 | 249 | 250 | 251 | 252 | Order #002434} secondary="Today, 2:00 AM" /> 253 | 254 | 255 | 256 | + $1,430 257 | 258 | 259 | 78% 260 | 261 | 262 | 263 | 264 | 265 | 266 | 272 | 273 | 274 | 275 | Order #984947} secondary="5 August, 1:45 PM" /> 276 | 277 | 278 | 279 | + $302 280 | 281 | 282 | 8% 283 | 284 | 285 | 286 | 287 | 288 | 289 | 295 | 296 | 297 | 298 | Order #988784} secondary="7 hours ago" /> 299 | 300 | 301 | 302 | + $682 303 | 304 | 305 | 16% 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | Help & Support Chat 319 | 320 | 321 | Typical replay within 5 min 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 337 | 338 | 339 | 340 | 341 | ); 342 | }; 343 | 344 | export default DashboardDefault; 345 | -------------------------------------------------------------------------------- /src/pages/extra-pages/SamplePage.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { Typography } from '@mui/material'; 3 | 4 | // project import 5 | import MainCard from 'components/MainCard'; 6 | 7 | // ==============================|| SAMPLE PAGE ||============================== // 8 | 9 | const SamplePage = () => ( 10 | 11 | 12 | Lorem ipsum dolor sit amen, consenter nipissing eli, sed do elusion tempos incident ut laborers et doolie magna alissa. Ut enif ad 13 | minim venice, quin nostrum exercitation illampu laborings nisi ut liquid ex ea commons construal. Duos aube grue dolor in reprehended 14 | in voltage veil esse colum doolie eu fujian bulla parian. Exceptive sin ocean cuspidate non president, sunk in culpa qui officiate 15 | descent molls anim id est labours. 16 | 17 | 18 | ); 19 | 20 | export default SamplePage; 21 | -------------------------------------------------------------------------------- /src/react-app-env.d.js: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/routes/LoginRoutes.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | // project import 4 | import Loadable from 'components/Loadable'; 5 | import MinimalLayout from 'layout/MinimalLayout'; 6 | 7 | // render - login 8 | const AuthLogin = Loadable(lazy(() => import('pages/authentication/Login'))); 9 | const AuthRegister = Loadable(lazy(() => import('pages/authentication/Register'))); 10 | 11 | // ==============================|| AUTH ROUTING ||============================== // 12 | 13 | const LoginRoutes = { 14 | path: '/', 15 | element: , 16 | children: [ 17 | { 18 | path: 'login', 19 | element: 20 | }, 21 | { 22 | path: 'register', 23 | element: 24 | } 25 | ] 26 | }; 27 | 28 | export default LoginRoutes; 29 | -------------------------------------------------------------------------------- /src/routes/MainRoutes.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | // project import 4 | import Loadable from 'components/Loadable'; 5 | import MainLayout from 'layout/MainLayout'; 6 | 7 | // render - dashboard 8 | const DashboardDefault = Loadable(lazy(() => import('pages/dashboard'))); 9 | 10 | // render - sample page 11 | const SamplePage = Loadable(lazy(() => import('pages/extra-pages/SamplePage'))); 12 | 13 | // render - utilities 14 | const Typography = Loadable(lazy(() => import('pages/components-overview/Typography'))); 15 | const Color = Loadable(lazy(() => import('pages/components-overview/Color'))); 16 | const Shadow = Loadable(lazy(() => import('pages/components-overview/Shadow'))); 17 | const AntIcons = Loadable(lazy(() => import('pages/components-overview/AntIcons'))); 18 | 19 | // ==============================|| MAIN ROUTING ||============================== // 20 | 21 | const MainRoutes = { 22 | path: '/', 23 | element: , 24 | children: [ 25 | { 26 | path: '/', 27 | element: 28 | }, 29 | { 30 | path: 'color', 31 | element: 32 | }, 33 | { 34 | path: 'dashboard', 35 | children: [ 36 | { 37 | path: 'default', 38 | element: 39 | } 40 | ] 41 | }, 42 | { 43 | path: 'sample-page', 44 | element: 45 | }, 46 | { 47 | path: 'shadow', 48 | element: 49 | }, 50 | { 51 | path: 'typography', 52 | element: 53 | }, 54 | { 55 | path: 'icons/ant', 56 | element: 57 | } 58 | ] 59 | }; 60 | 61 | export default MainRoutes; 62 | -------------------------------------------------------------------------------- /src/routes/index.js: -------------------------------------------------------------------------------- 1 | import { useRoutes } from 'react-router-dom'; 2 | 3 | // project import 4 | import LoginRoutes from './LoginRoutes'; 5 | import MainRoutes from './MainRoutes'; 6 | 7 | // ==============================|| ROUTING RENDER ||============================== // 8 | 9 | export default function ThemeRoutes() { 10 | return useRoutes([MainRoutes, LoginRoutes]); 11 | } 12 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | // third-party 2 | import { configureStore } from '@reduxjs/toolkit'; 3 | 4 | // project import 5 | import reducers from './reducers'; 6 | 7 | // ==============================|| REDUX TOOLKIT - MAIN STORE ||============================== // 8 | 9 | const store = configureStore({ 10 | reducer: reducers 11 | }); 12 | 13 | const { dispatch } = store; 14 | 15 | export { store, dispatch }; 16 | -------------------------------------------------------------------------------- /src/store/reducers/actions.js: -------------------------------------------------------------------------------- 1 | // action - account reducer 2 | export const LOGIN = '@auth/LOGIN'; 3 | export const LOGOUT = '@auth/LOGOUT'; 4 | export const REGISTER = '@auth/REGISTER'; 5 | -------------------------------------------------------------------------------- /src/store/reducers/index.js: -------------------------------------------------------------------------------- 1 | // third-party 2 | import { combineReducers } from 'redux'; 3 | 4 | // project import 5 | import menu from './menu'; 6 | 7 | // ==============================|| COMBINE REDUCERS ||============================== // 8 | 9 | const reducers = combineReducers({ menu }); 10 | 11 | export default reducers; 12 | -------------------------------------------------------------------------------- /src/store/reducers/menu.js: -------------------------------------------------------------------------------- 1 | // types 2 | import { createSlice } from '@reduxjs/toolkit'; 3 | 4 | // initial state 5 | const initialState = { 6 | openItem: ['dashboard'], 7 | defaultId: 'dashboard', 8 | openComponent: 'buttons', 9 | drawerOpen: false, 10 | componentDrawerOpen: true 11 | }; 12 | 13 | // ==============================|| SLICE - MENU ||============================== // 14 | 15 | const menu = createSlice({ 16 | name: 'menu', 17 | initialState, 18 | reducers: { 19 | activeItem(state, action) { 20 | state.openItem = action.payload.openItem; 21 | }, 22 | 23 | activeComponent(state, action) { 24 | state.openComponent = action.payload.openComponent; 25 | }, 26 | 27 | openDrawer(state, action) { 28 | state.drawerOpen = action.payload.drawerOpen; 29 | }, 30 | 31 | openComponentDrawer(state, action) { 32 | state.componentDrawerOpen = action.payload.componentDrawerOpen; 33 | } 34 | } 35 | }); 36 | 37 | export default menu.reducer; 38 | 39 | export const { activeItem, activeComponent, openDrawer, openComponentDrawer } = menu.actions; 40 | -------------------------------------------------------------------------------- /src/themes/index.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import { useMemo } from 'react'; 3 | 4 | // material-ui 5 | import { CssBaseline, StyledEngineProvider } from '@mui/material'; 6 | import { createTheme, ThemeProvider } from '@mui/material/styles'; 7 | 8 | // project import 9 | import Palette from './palette'; 10 | import Typography from './typography'; 11 | import CustomShadows from './shadows'; 12 | import componentsOverride from './overrides'; 13 | 14 | // ==============================|| DEFAULT THEME - MAIN ||============================== // 15 | 16 | export default function ThemeCustomization({ children }) { 17 | const theme = Palette('light', 'default'); 18 | 19 | // eslint-disable-next-line react-hooks/exhaustive-deps 20 | const themeTypography = Typography(`'Public Sans', sans-serif`); 21 | const themeCustomShadows = useMemo(() => CustomShadows(theme), [theme]); 22 | 23 | const themeOptions = useMemo( 24 | () => ({ 25 | breakpoints: { 26 | values: { 27 | xs: 0, 28 | sm: 768, 29 | md: 1024, 30 | lg: 1266, 31 | xl: 1536 32 | } 33 | }, 34 | direction: 'ltr', 35 | mixins: { 36 | toolbar: { 37 | minHeight: 60, 38 | paddingTop: 8, 39 | paddingBottom: 8 40 | } 41 | }, 42 | palette: theme.palette, 43 | customShadows: themeCustomShadows, 44 | typography: themeTypography 45 | }), 46 | [theme, themeTypography, themeCustomShadows] 47 | ); 48 | 49 | const themes = createTheme(themeOptions); 50 | themes.components = componentsOverride(themes); 51 | 52 | return ( 53 | 54 | 55 | 56 | {children} 57 | 58 | 59 | ); 60 | } 61 | 62 | ThemeCustomization.propTypes = { 63 | children: PropTypes.node 64 | }; 65 | -------------------------------------------------------------------------------- /src/themes/overrides/Badge.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - BADGE ||============================== // 2 | 3 | export default function Badge(theme) { 4 | return { 5 | MuiBadge: { 6 | styleOverrides: { 7 | standard: { 8 | minWidth: theme.spacing(2), 9 | height: theme.spacing(2), 10 | padding: theme.spacing(0.5) 11 | } 12 | } 13 | } 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/themes/overrides/Button.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - BUTTON ||============================== // 2 | 3 | export default function Button(theme) { 4 | const disabledStyle = { 5 | '&.Mui-disabled': { 6 | backgroundColor: theme.palette.grey[200] 7 | } 8 | }; 9 | 10 | return { 11 | MuiButton: { 12 | defaultProps: { 13 | disableElevation: true 14 | }, 15 | styleOverrides: { 16 | root: { 17 | fontWeight: 400 18 | }, 19 | contained: { 20 | ...disabledStyle 21 | }, 22 | outlined: { 23 | ...disabledStyle 24 | } 25 | } 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /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: 20, 9 | '&:last-child': { 10 | paddingBottom: 20 11 | } 12 | } 13 | } 14 | } 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /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.secondary[300] 9 | } 10 | } 11 | } 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/themes/overrides/Chip.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - CHIP ||============================== // 2 | 3 | export default function Chip(theme) { 4 | return { 5 | MuiChip: { 6 | styleOverrides: { 7 | root: { 8 | borderRadius: 4, 9 | '&:active': { 10 | boxShadow: 'none' 11 | } 12 | }, 13 | sizeLarge: { 14 | fontSize: '1rem', 15 | height: 40 16 | }, 17 | light: { 18 | color: theme.palette.primary.main, 19 | backgroundColor: theme.palette.primary.lighter, 20 | borderColor: theme.palette.primary.light, 21 | '&.MuiChip-lightError': { 22 | color: theme.palette.error.main, 23 | backgroundColor: theme.palette.error.lighter, 24 | borderColor: theme.palette.error.light 25 | }, 26 | '&.MuiChip-lightSuccess': { 27 | color: theme.palette.success.main, 28 | backgroundColor: theme.palette.success.lighter, 29 | borderColor: theme.palette.success.light 30 | }, 31 | '&.MuiChip-lightWarning': { 32 | color: theme.palette.warning.main, 33 | backgroundColor: theme.palette.warning.lighter, 34 | borderColor: theme.palette.warning.light 35 | } 36 | } 37 | } 38 | } 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/themes/overrides/IconButton.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - ICON BUTTON ||============================== // 2 | 3 | export default function IconButton(theme) { 4 | return { 5 | MuiIconButton: { 6 | styleOverrides: { 7 | root: { 8 | borderRadius: 4 9 | }, 10 | sizeLarge: { 11 | width: theme.spacing(5.5), 12 | height: theme.spacing(5.5), 13 | fontSize: '1.25rem' 14 | }, 15 | sizeMedium: { 16 | width: theme.spacing(4.5), 17 | height: theme.spacing(4.5), 18 | fontSize: '1rem' 19 | }, 20 | sizeSmall: { 21 | width: theme.spacing(3.75), 22 | height: theme.spacing(3.75), 23 | fontSize: '0.75rem' 24 | } 25 | } 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/themes/overrides/InputLabel.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - INPUT LABEL ||============================== // 2 | 3 | export default function InputLabel(theme) { 4 | return { 5 | MuiInputLabel: { 6 | styleOverrides: { 7 | root: { 8 | color: theme.palette.grey[600] 9 | }, 10 | outlined: { 11 | lineHeight: '0.8em', 12 | '&.MuiInputLabel-sizeSmall': { 13 | lineHeight: '1em' 14 | }, 15 | '&.MuiInputLabel-shrink': { 16 | background: theme.palette.background.paper, 17 | padding: '0 8px', 18 | marginLeft: -6, 19 | lineHeight: '1.4375em' 20 | } 21 | } 22 | } 23 | } 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /src/themes/overrides/LinearProgress.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - LINER PROGRESS ||============================== // 2 | 3 | export default function LinearProgress() { 4 | return { 5 | MuiLinearProgress: { 6 | styleOverrides: { 7 | root: { 8 | height: 6, 9 | borderRadius: 100 10 | }, 11 | bar: { 12 | borderRadius: 100 13 | } 14 | } 15 | } 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /src/themes/overrides/Link.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - LINK ||============================== // 2 | 3 | export default function Link() { 4 | return { 5 | MuiLink: { 6 | defaultProps: { 7 | underline: 'hover' 8 | } 9 | } 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /src/themes/overrides/ListItemIcon.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - LIST ITEM ICON ||============================== // 2 | 3 | export default function ListItemIcon() { 4 | return { 5 | MuiListItemIcon: { 6 | styleOverrides: { 7 | root: { 8 | minWidth: 24 9 | } 10 | } 11 | } 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/themes/overrides/OutlinedInput.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { alpha } from '@mui/material/styles'; 3 | 4 | // ==============================|| OVERRIDES - OUTLINED INPUT ||============================== // 5 | 6 | export default function OutlinedInput(theme) { 7 | return { 8 | MuiOutlinedInput: { 9 | styleOverrides: { 10 | input: { 11 | padding: '10.5px 14px 10.5px 12px' 12 | }, 13 | notchedOutline: { 14 | borderColor: theme.palette.grey[300] 15 | }, 16 | root: { 17 | '&:hover .MuiOutlinedInput-notchedOutline': { 18 | borderColor: theme.palette.primary.light 19 | }, 20 | '&.Mui-focused': { 21 | boxShadow: `0 0 0 2px ${alpha(theme.palette.primary.main, 0.2)}`, 22 | '& .MuiOutlinedInput-notchedOutline': { 23 | border: `1px solid ${theme.palette.primary.light}` 24 | } 25 | }, 26 | '&.Mui-error': { 27 | '&:hover .MuiOutlinedInput-notchedOutline': { 28 | borderColor: theme.palette.error.light 29 | }, 30 | '&.Mui-focused': { 31 | boxShadow: `0 0 0 2px ${alpha(theme.palette.error.main, 0.2)}`, 32 | '& .MuiOutlinedInput-notchedOutline': { 33 | border: `1px solid ${theme.palette.error.light}` 34 | } 35 | } 36 | } 37 | }, 38 | inputSizeSmall: { 39 | padding: '7.5px 8px 7.5px 12px' 40 | }, 41 | inputMultiline: { 42 | padding: 0 43 | } 44 | } 45 | } 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /src/themes/overrides/Tab.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - TAB ||============================== // 2 | 3 | export default function Tab(theme) { 4 | return { 5 | MuiTab: { 6 | styleOverrides: { 7 | root: { 8 | minHeight: 46, 9 | color: theme.palette.text.primary 10 | } 11 | } 12 | } 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/themes/overrides/TableCell.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - TABLE CELL ||============================== // 2 | 3 | export default function TableCell(theme) { 4 | return { 5 | MuiTableCell: { 6 | styleOverrides: { 7 | root: { 8 | fontSize: '0.875rem', 9 | padding: 12, 10 | borderColor: theme.palette.divider 11 | }, 12 | head: { 13 | fontWeight: 600, 14 | paddingTop: 20, 15 | paddingBottom: 20 16 | } 17 | } 18 | } 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /src/themes/overrides/Tabs.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - TABS ||============================== // 2 | 3 | export default function Tabs() { 4 | return { 5 | MuiTabs: { 6 | styleOverrides: { 7 | vertical: { 8 | overflow: 'visible' 9 | } 10 | } 11 | } 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/themes/overrides/Typography.js: -------------------------------------------------------------------------------- 1 | // ==============================|| OVERRIDES - TYPOGRAPHY ||============================== // 2 | 3 | export default function Typography() { 4 | return { 5 | MuiTypography: { 6 | styleOverrides: { 7 | gutterBottom: { 8 | marginBottom: 12 9 | } 10 | } 11 | } 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/themes/overrides/index.js: -------------------------------------------------------------------------------- 1 | // third-party 2 | import { merge } from 'lodash'; 3 | 4 | // project import 5 | import Badge from './Badge'; 6 | import Button from './Button'; 7 | import CardContent from './CardContent'; 8 | import Checkbox from './Checkbox'; 9 | import Chip from './Chip'; 10 | import IconButton from './IconButton'; 11 | import InputLabel from './InputLabel'; 12 | import LinearProgress from './LinearProgress'; 13 | import Link from './Link'; 14 | import ListItemIcon from './ListItemIcon'; 15 | import OutlinedInput from './OutlinedInput'; 16 | import Tab from './Tab'; 17 | import TableCell from './TableCell'; 18 | import Tabs from './Tabs'; 19 | import Typography from './Typography'; 20 | 21 | // ==============================|| OVERRIDES - MAIN ||============================== // 22 | 23 | export default function ComponentsOverrides(theme) { 24 | return merge( 25 | Button(theme), 26 | Badge(theme), 27 | CardContent(), 28 | Checkbox(theme), 29 | Chip(theme), 30 | IconButton(theme), 31 | InputLabel(theme), 32 | LinearProgress(), 33 | Link(), 34 | ListItemIcon(), 35 | OutlinedInput(theme), 36 | Tab(theme), 37 | TableCell(theme), 38 | Tabs(), 39 | Typography() 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /src/themes/palette.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { createTheme } from '@mui/material/styles'; 3 | 4 | // third-party 5 | import { presetPalettes } from '@ant-design/colors'; 6 | 7 | // project import 8 | import ThemeOption from './theme'; 9 | 10 | // ==============================|| DEFAULT THEME - PALETTE ||============================== // 11 | 12 | const Palette = (mode) => { 13 | const colors = presetPalettes; 14 | 15 | const greyPrimary = [ 16 | '#ffffff', 17 | '#fafafa', 18 | '#f5f5f5', 19 | '#f0f0f0', 20 | '#d9d9d9', 21 | '#bfbfbf', 22 | '#8c8c8c', 23 | '#595959', 24 | '#262626', 25 | '#141414', 26 | '#000000' 27 | ]; 28 | const greyAscent = ['#fafafa', '#bfbfbf', '#434343', '#1f1f1f']; 29 | const greyConstant = ['#fafafb', '#e6ebf1']; 30 | 31 | colors.grey = [...greyPrimary, ...greyAscent, ...greyConstant]; 32 | 33 | const paletteColor = ThemeOption(colors); 34 | 35 | return createTheme({ 36 | palette: { 37 | mode, 38 | common: { 39 | black: '#000', 40 | white: '#fff' 41 | }, 42 | ...paletteColor, 43 | text: { 44 | primary: paletteColor.grey[700], 45 | secondary: paletteColor.grey[500], 46 | disabled: paletteColor.grey[400] 47 | }, 48 | action: { 49 | disabled: paletteColor.grey[300] 50 | }, 51 | divider: paletteColor.grey[200], 52 | background: { 53 | paper: paletteColor.grey[0], 54 | default: paletteColor.grey.A50 55 | } 56 | } 57 | }); 58 | }; 59 | 60 | export default Palette; 61 | -------------------------------------------------------------------------------- /src/themes/shadows.js: -------------------------------------------------------------------------------- 1 | // material-ui 2 | import { alpha } from '@mui/material/styles'; 3 | 4 | // ==============================|| DEFAULT THEME - CUSTOM SHADOWS ||============================== // 5 | 6 | const CustomShadows = (theme) => ({ 7 | button: `0 2px #0000000b`, 8 | text: `0 -1px 0 rgb(0 0 0 / 12%)`, 9 | z1: `0px 2px 8px ${alpha(theme.palette.grey[900], 0.15)}` 10 | // only available in paid version 11 | }); 12 | 13 | export default CustomShadows; 14 | -------------------------------------------------------------------------------- /src/themes/theme/index.js: -------------------------------------------------------------------------------- 1 | // ==============================|| PRESET THEME - THEME SELECTOR ||============================== // 2 | 3 | const Theme = (colors) => { 4 | const { blue, red, gold, cyan, green, grey } = colors; 5 | const greyColors = { 6 | 0: grey[0], 7 | 50: grey[1], 8 | 100: grey[2], 9 | 200: grey[3], 10 | 300: grey[4], 11 | 400: grey[5], 12 | 500: grey[6], 13 | 600: grey[7], 14 | 700: grey[8], 15 | 800: grey[9], 16 | 900: grey[10], 17 | A50: grey[15], 18 | A100: grey[11], 19 | A200: grey[12], 20 | A400: grey[13], 21 | A700: grey[14], 22 | A800: grey[16] 23 | }; 24 | const contrastText = '#fff'; 25 | 26 | return { 27 | primary: { 28 | lighter: blue[0], 29 | 100: blue[1], 30 | 200: blue[2], 31 | light: blue[3], 32 | 400: blue[4], 33 | main: blue[5], 34 | dark: blue[6], 35 | 700: blue[7], 36 | darker: blue[8], 37 | 900: blue[9], 38 | contrastText 39 | }, 40 | secondary: { 41 | lighter: greyColors[100], 42 | 100: greyColors[100], 43 | 200: greyColors[200], 44 | light: greyColors[300], 45 | 400: greyColors[400], 46 | main: greyColors[500], 47 | 600: greyColors[600], 48 | dark: greyColors[700], 49 | 800: greyColors[800], 50 | darker: greyColors[900], 51 | A100: greyColors[0], 52 | A200: greyColors.A400, 53 | A300: greyColors.A700, 54 | contrastText: greyColors[0] 55 | }, 56 | error: { 57 | lighter: red[0], 58 | light: red[2], 59 | main: red[4], 60 | dark: red[7], 61 | darker: red[9], 62 | contrastText 63 | }, 64 | warning: { 65 | lighter: gold[0], 66 | light: gold[3], 67 | main: gold[5], 68 | dark: gold[7], 69 | darker: gold[9], 70 | contrastText: greyColors[100] 71 | }, 72 | info: { 73 | lighter: cyan[0], 74 | light: cyan[3], 75 | main: cyan[5], 76 | dark: cyan[7], 77 | darker: cyan[9], 78 | contrastText 79 | }, 80 | success: { 81 | lighter: green[0], 82 | light: green[3], 83 | main: green[5], 84 | dark: green[7], 85 | darker: green[9], 86 | contrastText 87 | }, 88 | grey: greyColors 89 | }; 90 | }; 91 | 92 | export default Theme; 93 | -------------------------------------------------------------------------------- /src/themes/typography.js: -------------------------------------------------------------------------------- 1 | // ==============================|| DEFAULT THEME - TYPOGRAPHY ||============================== // 2 | 3 | const Typography = (fontFamily) => ({ 4 | htmlFontSize: 16, 5 | fontFamily, 6 | fontWeightLight: 300, 7 | fontWeightRegular: 400, 8 | fontWeightMedium: 500, 9 | fontWeightBold: 600, 10 | h1: { 11 | fontWeight: 600, 12 | fontSize: '2.375rem', 13 | lineHeight: 1.21 14 | }, 15 | h2: { 16 | fontWeight: 600, 17 | fontSize: '1.875rem', 18 | lineHeight: 1.27 19 | }, 20 | h3: { 21 | fontWeight: 600, 22 | fontSize: '1.5rem', 23 | lineHeight: 1.33 24 | }, 25 | h4: { 26 | fontWeight: 600, 27 | fontSize: '1.25rem', 28 | lineHeight: 1.4 29 | }, 30 | h5: { 31 | fontWeight: 600, 32 | fontSize: '1rem', 33 | lineHeight: 1.5 34 | }, 35 | h6: { 36 | fontWeight: 400, 37 | fontSize: '0.875rem', 38 | lineHeight: 1.57 39 | }, 40 | caption: { 41 | fontWeight: 400, 42 | fontSize: '0.75rem', 43 | lineHeight: 1.66 44 | }, 45 | body1: { 46 | fontSize: '0.875rem', 47 | lineHeight: 1.57 48 | }, 49 | body2: { 50 | fontSize: '0.75rem', 51 | lineHeight: 1.66 52 | }, 53 | subtitle1: { 54 | fontSize: '0.875rem', 55 | fontWeight: 600, 56 | lineHeight: 1.57 57 | }, 58 | subtitle2: { 59 | fontSize: '0.75rem', 60 | fontWeight: 500, 61 | lineHeight: 1.66 62 | }, 63 | overline: { 64 | lineHeight: 1.66 65 | }, 66 | button: { 67 | textTransform: 'capitalize' 68 | } 69 | }); 70 | 71 | export default Typography; 72 | -------------------------------------------------------------------------------- /src/utils/SyntaxHighlight.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | // third-party 4 | import SyntaxHighlighter from 'react-syntax-highlighter'; 5 | import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; 6 | 7 | // ==============================|| CODE HIGHLIGHTER ||============================== // 8 | 9 | export default function SyntaxHighlight({ children, ...others }) { 10 | return ( 11 | 12 | {children} 13 | 14 | ); 15 | } 16 | 17 | SyntaxHighlight.propTypes = { 18 | children: PropTypes.node 19 | }; 20 | -------------------------------------------------------------------------------- /src/utils/password-strength.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 | --------------------------------------------------------------------------------