├── .env
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── custom.md
│ └── feature_request.md
└── workflows
│ └── prod.yml
├── .gitignore
├── .prettierrc
├── .yarnrc.yml
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── eslint.config.mjs
├── favicon.svg
├── index.html
├── jsconfig.json
├── jsconfig.node.json
├── package.json
├── src
├── App.jsx
├── api
│ └── menu.js
├── assets
│ ├── images
│ │ └── users
│ │ │ ├── avatar-1.png
│ │ │ ├── avatar-2.png
│ │ │ ├── avatar-3.png
│ │ │ ├── avatar-4.png
│ │ │ ├── avatar-5.png
│ │ │ └── avatar-group.png
│ ├── style.css
│ └── third-party
│ │ ├── apex-chart.css
│ │ └── react-table.css
├── components
│ ├── @extended
│ │ ├── AnimateButton.jsx
│ │ ├── Avatar.jsx
│ │ ├── Breadcrumbs.jsx
│ │ ├── Dot.jsx
│ │ ├── IconButton.jsx
│ │ └── Transitions.jsx
│ ├── Loadable.jsx
│ ├── Loader.jsx
│ ├── MainCard.jsx
│ ├── ScrollTop.jsx
│ ├── cards
│ │ ├── AuthFooter.jsx
│ │ └── statistics
│ │ │ └── AnalyticEcommerce.jsx
│ ├── logo
│ │ ├── LogoIcon.jsx
│ │ ├── LogoMain.jsx
│ │ └── index.jsx
│ └── third-party
│ │ └── SimpleBar.jsx
├── config.js
├── contexts
│ └── README.md
├── data
│ └── README.md
├── hooks
│ └── README.md
├── index.jsx
├── layout
│ ├── Auth
│ │ └── index.jsx
│ └── Dashboard
│ │ ├── Drawer
│ │ ├── DrawerContent
│ │ │ ├── NavCard.jsx
│ │ │ ├── Navigation
│ │ │ │ ├── NavGroup.jsx
│ │ │ │ ├── NavItem.jsx
│ │ │ │ └── index.jsx
│ │ │ └── index.jsx
│ │ ├── DrawerHeader
│ │ │ ├── DrawerHeaderStyled.js
│ │ │ └── index.jsx
│ │ ├── MiniDrawerStyled.js
│ │ └── index.jsx
│ │ ├── Footer.jsx
│ │ ├── Header
│ │ ├── AppBarStyled.jsx
│ │ ├── HeaderContent
│ │ │ ├── MobileSection.jsx
│ │ │ ├── Notification.jsx
│ │ │ ├── Profile
│ │ │ │ ├── ProfileTab.jsx
│ │ │ │ ├── SettingTab.jsx
│ │ │ │ └── index.jsx
│ │ │ ├── Search.jsx
│ │ │ └── index.jsx
│ │ └── index.jsx
│ │ └── index.jsx
├── menu-items
│ ├── dashboard.jsx
│ ├── index.jsx
│ ├── page.jsx
│ ├── support.jsx
│ └── utilities.jsx
├── pages
│ ├── auth
│ │ ├── Login.jsx
│ │ └── Register.jsx
│ ├── component-overview
│ │ ├── color.jsx
│ │ ├── shadows.jsx
│ │ └── typography.jsx
│ ├── dashboard
│ │ └── default.jsx
│ └── extra-pages
│ │ └── sample-page.jsx
├── reportWebVitals.js
├── routes
│ ├── LoginRoutes.jsx
│ ├── MainRoutes.jsx
│ └── index.jsx
├── sections
│ ├── auth
│ │ ├── AuthBackground.jsx
│ │ ├── AuthCard.jsx
│ │ ├── AuthLogin.jsx
│ │ ├── AuthRegister.jsx
│ │ └── AuthWrapper.jsx
│ └── dashboard
│ │ ├── SalesChart.jsx
│ │ └── default
│ │ ├── IncomeAreaChart.jsx
│ │ ├── MonthlyBarChart.jsx
│ │ ├── OrdersTable.jsx
│ │ ├── ReportAreaChart.jsx
│ │ ├── SaleReportCard.jsx
│ │ └── UniqueVisitorCard.jsx
├── themes
│ ├── index.jsx
│ ├── overrides
│ │ ├── Badge.js
│ │ ├── Button.js
│ │ ├── ButtonBase.js
│ │ ├── CardContent.js
│ │ ├── Checkbox.jsx
│ │ ├── Chip.js
│ │ ├── Drawer.js
│ │ ├── FormHelperText.js
│ │ ├── IconButton.js
│ │ ├── InputLabel.js
│ │ ├── LinearProgress.js
│ │ ├── Link.js
│ │ ├── ListItemButton.jsx
│ │ ├── ListItemIcon.jsx
│ │ ├── OutlinedInput.js
│ │ ├── Tab.js
│ │ ├── TableBody.js
│ │ ├── TableCell.js
│ │ ├── TableHead.js
│ │ ├── TableRow.js
│ │ ├── Tabs.js
│ │ ├── Tooltip.js
│ │ ├── Typography.js
│ │ └── index.js
│ ├── palette.js
│ ├── shadows.jsx
│ ├── theme
│ │ └── index.js
│ └── typography.js
├── utils
│ ├── getColors.js
│ ├── getShadow.js
│ ├── password-strength.js
│ └── password-validation.js
└── vite-env.d.js
├── vite.config.mjs
└── yarn.lock
/.env:
--------------------------------------------------------------------------------
1 | VITE_APP_VERSION = v1.5.0
2 | GENERATE_SOURCEMAP = false
3 |
4 | ## Public URL
5 | PUBLIC_URL = https://mantisdashboard.io
6 | VITE_APP_BASE_NAME = /free
7 |
8 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.github/workflows/prod.yml:
--------------------------------------------------------------------------------
1 | name: Prod deploy
2 |
3 | # Controls when the action will run.
4 | on:
5 | # Triggers the workflow on push or pull request events but only for the master branch
6 | push:
7 | branches:
8 | - master
9 | pull_request:
10 | types:
11 | - closed
12 | branches:
13 | - master
14 |
15 | jobs:
16 | if_merged:
17 | if: github.event.pull_request.merged == true
18 | name: 🎉 Deploy
19 | runs-on: ubuntu-latest
20 |
21 | steps:
22 | - name: 🚚 Get latest code
23 | uses: actions/checkout@v4
24 |
25 | - name: Use Node.js 20
26 | uses: actions/setup-node@v4
27 | with:
28 | node-version: '20'
29 |
30 | - name: 🔨 Build Project
31 | run: |
32 | corepack enable
33 | yarn set version 4.6.0
34 | yarn
35 | yarn build
36 |
37 | - name: 📂 Deploy to Server
38 | uses: easingthemes/ssh-deploy@v4
39 | env:
40 | SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
41 | # ARGS: "-rltgoDzvO --delete"
42 | SOURCE: 'dist/'
43 | REMOTE_HOST: 192.34.62.123
44 | REMOTE_USER: mantis
45 | TARGET: public_html/free
46 | EXCLUDE: '/build/, /node_modules/'
47 |
--------------------------------------------------------------------------------
/.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 | build
40 | dist
41 |
42 | # Dependency directories
43 | node_modules/
44 | jspm_packages/
45 |
46 | # TypeScript v1 declaration files
47 | typings/
48 |
49 | # TypeScript cache
50 | *.tsbuildinfo
51 |
52 | # Optional npm cache directory
53 | .npm
54 |
55 | # Optional eslint cache
56 | .eslintcache
57 |
58 | # Microbundle cache
59 | .rpt2_cache/
60 | .rts2_cache_cjs/
61 | .rts2_cache_es/
62 | .rts2_cache_umd/
63 |
64 | # Optional REPL history
65 | .node_repl_history
66 |
67 | # Output of 'npm pack'
68 | *.tgz
69 |
70 | # Yarn Integrity file
71 | .yarn-integrity
72 | .yarn
73 |
74 | # dotenv environment variables file
75 | # .env
76 | .env.test
77 |
78 | # parcel-bundler cache (https://parceljs.org/)
79 | .cache
80 |
81 | # Next.js build output
82 | .next
83 |
84 | # Nuxt.js build / generate output
85 | .nuxt
86 | dist
87 |
88 | # Gatsby files
89 | .cache/
90 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
91 | # https://nextjs.org/blog/next-9-1#public-directory-support
92 | # public
93 |
94 | # vuepress build output
95 | .vuepress/dist
96 |
97 | # Serverless directories
98 | .serverless/
99 |
100 | # FuseBox cache
101 | .fusebox/
102 |
103 | # DynamoDB Local files
104 | .dynamodb/
105 |
106 | # TernJS port file
107 | .tern-port
108 |
109 | # wincompare file
110 | .bak
111 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "bracketSpacing": true,
3 | "printWidth": 140,
4 | "singleQuote": true,
5 | "trailingComma": "none",
6 | "tabWidth": 2,
7 | "useTabs": false
8 | }
9 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/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 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 CodedThemes
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { fixupConfigRules } from '@eslint/compat';
2 | import prettier from 'eslint-plugin-prettier';
3 | import react from 'eslint-plugin-react';
4 | import reactHooks from 'eslint-plugin-react-hooks';
5 | import jsxA11y from 'eslint-plugin-jsx-a11y';
6 | import js from '@eslint/js';
7 | import path from 'node:path';
8 | import { fileURLToPath } from 'node:url';
9 | import { FlatCompat } from '@eslint/eslintrc';
10 |
11 | const __filename = fileURLToPath(import.meta.url);
12 | const __dirname = path.dirname(__filename);
13 | const compat = new FlatCompat({
14 | baseDirectory: __dirname,
15 | recommendedConfig: js.configs.recommended,
16 | allConfig: js.configs.all
17 | });
18 |
19 | export default [
20 | ...fixupConfigRules(compat.extends('prettier')),
21 |
22 | {
23 | plugins: {
24 | prettier,
25 | react,
26 | 'react-hooks': reactHooks,
27 | 'jsx-a11y': jsxA11y
28 | },
29 |
30 | languageOptions: {
31 | ecmaVersion: 2020,
32 | sourceType: 'module',
33 | parserOptions: {
34 | ecmaFeatures: {
35 | jsx: true // ✅ Enable JSX parsing
36 | }
37 | }
38 | },
39 |
40 | settings: {
41 | react: {
42 | version: 'detect' // ✅ Detect the installed React version
43 | }
44 | },
45 |
46 | rules: {
47 | 'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
48 | 'react/react-in-jsx-scope': 'off',
49 | 'react/prop-types': 'off',
50 | 'react/jsx-props-no-spreading': 'off',
51 | 'react-hooks/rules-of-hooks': 'error',
52 | 'react-hooks/exhaustive-deps': 'warn',
53 | 'jsx-a11y/label-has-associated-control': 'off',
54 | 'jsx-a11y/no-autofocus': 'off',
55 |
56 | 'prettier/prettier': [
57 | 'warn',
58 | {
59 | bracketSpacing: true,
60 | printWidth: 140,
61 | singleQuote: true,
62 | trailingComma: 'none',
63 | tabWidth: 2,
64 | useTabs: false
65 | }
66 | ]
67 | }
68 | },
69 | {
70 | ignores: ['node_modules/**'],
71 | files: ['src/**/*.{js,jsx}']
72 | }
73 | ];
74 |
--------------------------------------------------------------------------------
/favicon.svg:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Mantis React Free Admin Dashboard
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "baseUrl": "src"
19 | },
20 | "exclude": ["node_modules"],
21 | "include": ["src", "**/*.js", "**/*.jsx", "src/**/*"],
22 | "references": [{ "path": "./jsconfig.node.json" }]
23 | }
24 |
--------------------------------------------------------------------------------
/jsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.mjs"]
9 | }
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mantis-material-free-react",
3 | "version": "1.5.0",
4 | "homepage": "https://mantisdashboard.io/free",
5 | "author": {
6 | "name": "CodedThemes",
7 | "email": "codedthemes@gmail.com",
8 | "url": "https://codedthemes.com/"
9 | },
10 | "scripts": {
11 | "start": "vite",
12 | "build": "vite build",
13 | "build-stage": "env-cmd -f .env.qa vite build",
14 | "preview": "vite preview",
15 | "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
16 | "lint:fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\"",
17 | "prettier": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
18 | "knip": "knip"
19 | },
20 | "dependencies": {
21 | "@ant-design/colors": "8.0.0",
22 | "@ant-design/icons": "6.0.0",
23 | "@emotion/cache": "11.14.0",
24 | "@emotion/react": "11.14.0",
25 | "@emotion/styled": "11.14.0",
26 | "@fontsource/inter": "5.2.5",
27 | "@fontsource/poppins": "5.2.5",
28 | "@fontsource/public-sans": "5.2.5",
29 | "@fontsource/roboto": "5.2.5",
30 | "@mui/base": "5.0.0-beta.70",
31 | "@mui/lab": "7.0.0-beta.10",
32 | "@mui/material": "7.0.2",
33 | "@mui/system": "7.0.2",
34 | "@mui/x-charts": "8.1.0",
35 | "@vitejs/plugin-react": "4.4.1",
36 | "formik": "2.4.6",
37 | "framer-motion": "12.8.2",
38 | "lodash-es": "4.17.21",
39 | "react": "19.1.0",
40 | "react-device-detect": "2.2.3",
41 | "react-dom": "19.1.0",
42 | "react-number-format": "5.4.4",
43 | "react-router": "7.5.1",
44 | "react-router-dom": "7.5.1",
45 | "simplebar-react": "3.3.0",
46 | "swr": "2.3.3",
47 | "vite": "6.3.1",
48 | "vite-jsconfig-paths": "2.0.1",
49 | "web-vitals": "4.2.4",
50 | "yup": "1.6.1"
51 | },
52 | "eslintConfig": {
53 | "extends": [
54 | "react-app",
55 | "react-app/jest"
56 | ]
57 | },
58 | "browserslist": {
59 | "production": [
60 | ">0.2%",
61 | "not dead",
62 | "not op_mini all"
63 | ],
64 | "development": [
65 | "last 1 chrome version",
66 | "last 1 firefox version",
67 | "last 1 safari version"
68 | ]
69 | },
70 | "devDependencies": {
71 | "@eslint/compat": "1.2.8",
72 | "@eslint/eslintrc": "3.3.1",
73 | "@eslint/js": "9.25.1",
74 | "eslint": "9.25.1",
75 | "eslint-config-prettier": "10.1.2",
76 | "eslint-plugin-jsx-a11y": "6.10.2",
77 | "eslint-plugin-prettier": "5.2.6",
78 | "eslint-plugin-react": "7.37.4",
79 | "eslint-plugin-react-hooks": "5.2.0",
80 | "immutable": "4.3.7",
81 | "knip": "5.45.0",
82 | "prettier": "3.5.3",
83 | "prettier-eslint-cli": "8.0.1"
84 | },
85 | "packageManager": "yarn@4.9.1"
86 | }
87 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { RouterProvider } from 'react-router-dom';
2 |
3 | // project imports
4 | import router from 'routes';
5 | import ThemeCustomization from 'themes';
6 |
7 | import ScrollTop from 'components/ScrollTop';
8 |
9 | // ==============================|| APP - THEME, ROUTER, LOCAL ||============================== //
10 |
11 | export default function App() {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/src/api/menu.js:
--------------------------------------------------------------------------------
1 | import useSWR, { mutate } from 'swr';
2 | import { useMemo } from 'react';
3 |
4 | const initialState = {
5 | isDashboardDrawerOpened: false
6 | };
7 |
8 | const endpoints = {
9 | key: 'api/menu',
10 | master: 'master',
11 | dashboard: '/dashboard' // server URL
12 | };
13 |
14 | export function useGetMenuMaster() {
15 | const { data, isLoading } = useSWR(endpoints.key + endpoints.master, () => initialState, {
16 | revalidateIfStale: false,
17 | revalidateOnFocus: false,
18 | revalidateOnReconnect: false
19 | });
20 |
21 | const memoizedValue = useMemo(
22 | () => ({
23 | menuMaster: data,
24 | menuMasterLoading: isLoading
25 | }),
26 | [data, isLoading]
27 | );
28 |
29 | return memoizedValue;
30 | }
31 |
32 | export function handlerDrawerOpen(isDashboardDrawerOpened) {
33 | // to update local state based on key
34 |
35 | mutate(
36 | endpoints.key + endpoints.master,
37 | (currentMenuMaster) => {
38 | return { ...currentMenuMaster, isDashboardDrawerOpened };
39 | },
40 | false
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/mantis-free-react-admin-template/d5312a2899cfa159aefd384b4357aaecaba4c4fe/src/assets/images/users/avatar-1.png
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/mantis-free-react-admin-template/d5312a2899cfa159aefd384b4357aaecaba4c4fe/src/assets/images/users/avatar-2.png
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/mantis-free-react-admin-template/d5312a2899cfa159aefd384b4357aaecaba4c4fe/src/assets/images/users/avatar-3.png
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/mantis-free-react-admin-template/d5312a2899cfa159aefd384b4357aaecaba4c4fe/src/assets/images/users/avatar-4.png
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/mantis-free-react-admin-template/d5312a2899cfa159aefd384b4357aaecaba4c4fe/src/assets/images/users/avatar-5.png
--------------------------------------------------------------------------------
/src/assets/images/users/avatar-group.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codedthemes/mantis-free-react-admin-template/d5312a2899cfa159aefd384b4357aaecaba4c4fe/src/assets/images/users/avatar-group.png
--------------------------------------------------------------------------------
/src/assets/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | -webkit-tap-highlight-color: transparent;
3 | }
4 |
--------------------------------------------------------------------------------
/src/assets/third-party/apex-chart.css:
--------------------------------------------------------------------------------
1 | .apexcharts-legend-series {
2 | gap: 8px;
3 | }
4 |
5 | .apexcharts-tooltip-series-group.apexcharts-active,
6 | .apexcharts-tooltip-series-group:last-child {
7 | padding-bottom: 0 !important;
8 | }
9 |
--------------------------------------------------------------------------------
/src/assets/third-party/react-table.css:
--------------------------------------------------------------------------------
1 | .cursor-pointer {
2 | cursor: pointer;
3 | }
4 |
5 | .prevent-select {
6 | -webkit-user-select: none; /* Safari */
7 | -ms-user-select: none; /* IE 10 and IE 11 */
8 | user-select: none; /* Standard syntax */
9 | }
10 |
11 | .sticky-header {
12 | margin: 0;
13 | position: sticky;
14 | top: -1px;
15 | z-index: 1;
16 | }
17 |
18 | .resizer {
19 | position: absolute;
20 | right: 0;
21 | top: 0;
22 | height: 100%;
23 | width: 5px;
24 | cursor: col-resize;
25 | user-select: none;
26 | touch-action: none;
27 | }
28 |
29 | .resizer.isResizing {
30 | opacity: 1;
31 | }
32 |
33 | .MuiTableContainer-root {
34 | border-radius: 0px !important;
35 | }
36 |
--------------------------------------------------------------------------------
/src/components/@extended/AnimateButton.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // third-party
4 | import { motion, useCycle } from 'framer-motion';
5 |
6 | export default function AnimateButton({ children, type = 'scale', direction = 'right', offset = 10, scale = { hover: 1.05, tap: 0.954 } }) {
7 | let offset1;
8 | let offset2;
9 | switch (direction) {
10 | case 'up':
11 | case 'left':
12 | offset1 = offset;
13 | offset2 = 0;
14 | break;
15 | case 'right':
16 | case 'down':
17 | default:
18 | offset1 = 0;
19 | offset2 = offset;
20 | break;
21 | }
22 |
23 | const [x, cycleX] = useCycle(offset1, offset2);
24 | const [y, cycleY] = useCycle(offset1, offset2);
25 |
26 | switch (type) {
27 | case 'rotate':
28 | return (
29 |
38 | {children}
39 |
40 | );
41 | case 'slide':
42 | if (direction === 'up' || direction === 'down') {
43 | return (
44 | cycleY()} onHoverStart={() => cycleY()}>
45 | {children}
46 |
47 | );
48 | }
49 | return (
50 | cycleX()} onHoverStart={() => cycleX()}>
51 | {children}
52 |
53 | );
54 |
55 | case 'scale':
56 | default:
57 | if (typeof scale === 'number') {
58 | scale = {
59 | hover: scale,
60 | tap: scale
61 | };
62 | }
63 | return (
64 |
65 | {children}
66 |
67 | );
68 | }
69 | }
70 |
71 | AnimateButton.propTypes = {
72 | children: PropTypes.node,
73 | type: PropTypes.oneOf(['slide', 'scale', 'rotate']),
74 | direction: PropTypes.oneOf(['up', 'down', 'left', 'right']),
75 | offset: PropTypes.number,
76 | scale: PropTypes.object
77 | };
78 |
--------------------------------------------------------------------------------
/src/components/@extended/Avatar.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import { styled } from '@mui/material/styles';
5 | import MuiAvatar from '@mui/material/Avatar';
6 |
7 | // project imports
8 | import getColors from 'utils/getColors';
9 |
10 | function getColorStyle({ theme, color, type }) {
11 | const colors = getColors(theme, color);
12 | const { lighter, light, main, contrastText } = colors;
13 |
14 | switch (type) {
15 | case 'filled':
16 | return {
17 | color: contrastText,
18 | background: main
19 | };
20 | case 'outlined':
21 | return {
22 | color: main,
23 | border: '1px solid',
24 | borderColor: main,
25 | background: 'transparent'
26 | };
27 | case 'combined':
28 | return {
29 | color: main,
30 | border: '1px solid',
31 | borderColor: light,
32 | background: lighter
33 | };
34 | default:
35 | return {
36 | color: main,
37 | background: lighter
38 | };
39 | }
40 | }
41 |
42 | // ==============================|| AVATAR - SIZE STYLE ||============================== //
43 |
44 | function getSizeStyle(size) {
45 | switch (size) {
46 | case 'badge':
47 | return {
48 | border: '2px solid',
49 | fontSize: '0.675rem',
50 | width: 20,
51 | height: 20
52 | };
53 | case 'xs':
54 | return {
55 | fontSize: '0.75rem',
56 | width: 24,
57 | height: 24
58 | };
59 | case 'sm':
60 | return {
61 | fontSize: '0.875rem',
62 | width: 32,
63 | height: 32
64 | };
65 | case 'lg':
66 | return {
67 | fontSize: '1.2rem',
68 | width: 52,
69 | height: 52
70 | };
71 | case 'xl':
72 | return {
73 | fontSize: '1.5rem',
74 | width: 64,
75 | height: 64
76 | };
77 | case 'md':
78 | default:
79 | return {
80 | fontSize: '1rem',
81 | width: 40,
82 | height: 40
83 | };
84 | }
85 | }
86 |
87 | const AvatarStyle = styled(MuiAvatar, { shouldForwardProp: (prop) => prop !== 'color' && prop !== 'type' && prop !== 'size' })(
88 | ({ theme, size, color, type }) => ({
89 | ...getSizeStyle(size),
90 | ...getColorStyle({ theme, color, type }),
91 | variants: [
92 | {
93 | props: { size: 'badge' },
94 | style: {
95 | borderColor: theme.palette.background.default
96 | }
97 | }
98 | ]
99 | })
100 | );
101 |
102 | export default function Avatar({ children, color = 'primary', type, size = 'md', ...others }) {
103 | return (
104 |
105 | {children}
106 |
107 | );
108 | }
109 |
110 | getColorStyle.propTypes = { theme: PropTypes.any, color: PropTypes.any, type: PropTypes.any };
111 |
112 | Avatar.propTypes = {
113 | children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
114 | color: PropTypes.string,
115 | type: PropTypes.any,
116 | size: PropTypes.string,
117 | others: PropTypes.any
118 | };
119 |
--------------------------------------------------------------------------------
/src/components/@extended/Dot.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | // material-ui
3 | import { useTheme } from '@mui/material/styles';
4 | import Box from '@mui/material/Box';
5 |
6 | // project imports
7 | import getColors from 'utils/getColors';
8 |
9 | export default function Dot({ color, size, variant, sx }) {
10 | const theme = useTheme();
11 | const colors = getColors(theme, color || 'primary');
12 | const { main } = colors;
13 |
14 | return (
15 |
24 | );
25 | }
26 |
27 | Dot.propTypes = { color: PropTypes.any, size: PropTypes.number, variant: PropTypes.string, sx: PropTypes.any };
28 |
--------------------------------------------------------------------------------
/src/components/@extended/IconButton.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import MuiIconButton from '@mui/material/IconButton';
5 | import { alpha, styled } from '@mui/material/styles';
6 |
7 | // project imports
8 | import getColors from 'utils/getColors';
9 | import getShadow from 'utils/getShadow';
10 |
11 | function getColorStyle({ variant, theme, color }) {
12 | const colors = getColors(theme, color);
13 | const { lighter, light, dark, main, contrastText } = colors;
14 |
15 | const buttonShadow = `${color}Button`;
16 | const shadows = getShadow(theme, buttonShadow);
17 |
18 | const commonShadow = {
19 | '&::after': {
20 | boxShadow: `0 0 6px 6px ${alpha(main, 0.9)}`
21 | },
22 | '&:active::after': {
23 | boxShadow: `0 0 0 0 ${alpha(main, 0.9)}`
24 | },
25 | '&:focus-visible': {
26 | outline: `2px solid ${dark}`,
27 | outlineOffset: 2
28 | }
29 | };
30 |
31 | switch (variant) {
32 | case 'contained':
33 | return {
34 | color: contrastText,
35 | background: main,
36 | '&:hover': {
37 | background: dark
38 | },
39 | ...commonShadow
40 | };
41 | case 'light':
42 | return {
43 | color: main,
44 | background: lighter,
45 | '&:hover': {
46 | background: alpha(light, 0.5)
47 | },
48 | ...commonShadow
49 | };
50 | case 'shadow':
51 | return {
52 | boxShadow: shadows,
53 | color: contrastText,
54 | background: main,
55 | '&:hover': {
56 | boxShadow: 'none',
57 | background: dark
58 | },
59 | ...commonShadow
60 | };
61 | case 'outlined':
62 | return {
63 | '&:hover': {
64 | background: 'transparent',
65 | color: dark,
66 | borderColor: dark
67 | },
68 | ...commonShadow
69 | };
70 | case 'dashed':
71 | return {
72 | background: lighter,
73 | '&:hover': {
74 | color: dark,
75 | borderColor: dark
76 | },
77 | ...commonShadow
78 | };
79 | case 'text':
80 | default:
81 | return {
82 | '&:hover': {
83 | color: dark,
84 | background: color === 'secondary' ? alpha(light, 0.1) : lighter
85 | },
86 | ...commonShadow
87 | };
88 | }
89 | }
90 |
91 | const IconButtonStyle = styled(MuiIconButton, { shouldForwardProp: (prop) => prop !== 'variant' && prop !== 'shape' })(
92 | ({ theme, color, variant }) => ({
93 | position: 'relative',
94 | '::after': {
95 | content: '""',
96 | display: 'block',
97 | position: 'absolute',
98 | left: 0,
99 | top: 0,
100 | width: '100%',
101 | height: '100%',
102 | borderRadius: 4,
103 | opacity: 0,
104 | transition: 'all 0.5s'
105 | },
106 |
107 | ':active::after': {
108 | position: 'absolute',
109 | borderRadius: 4,
110 | left: 0,
111 | top: 0,
112 | opacity: 1,
113 | transition: '0s'
114 | },
115 |
116 | ...getColorStyle({ variant, theme, color }),
117 |
118 | variants: [
119 | {
120 | props: { shape: 'rounded' },
121 | style: {
122 | borderRadius: '50%',
123 | '::after': { borderRadius: '50%' },
124 | ':active::after': { borderRadius: '50%' }
125 | }
126 | },
127 | {
128 | props: { variant: 'outlined' },
129 | style: {
130 | border: '1px solid',
131 | borderColor: 'inherit'
132 | }
133 | },
134 | {
135 | props: { variant: 'dashed' },
136 | style: {
137 | border: '1px dashed',
138 | borderColor: 'inherit'
139 | }
140 | },
141 | {
142 | props: ({ variant }) => variant !== 'text',
143 | style: {
144 | '&.Mui-disabled': {
145 | background: theme.palette.grey[200],
146 | '&:hover': {
147 | background: theme.palette.grey[200],
148 | color: theme.palette.grey[300],
149 | borderColor: 'inherit'
150 | }
151 | }
152 | }
153 | }
154 | ]
155 | })
156 | );
157 |
158 | function IconButton({ variant = 'text', shape = 'square', children, color = 'primary', ref, ...others }) {
159 | return (
160 |
161 | {children}
162 |
163 | );
164 | }
165 |
166 | IconButton.displayName = 'IconButton';
167 |
168 | export default IconButton;
169 |
170 | getColorStyle.propTypes = { variant: PropTypes.any, theme: PropTypes.any, color: PropTypes.any };
171 |
172 | IconButton.propTypes = {
173 | variant: PropTypes.string,
174 | shape: PropTypes.string,
175 | children: PropTypes.node,
176 | color: PropTypes.string,
177 | ref: PropTypes.any,
178 | others: PropTypes.any
179 | };
180 |
--------------------------------------------------------------------------------
/src/components/@extended/Transitions.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import Collapse from '@mui/material/Collapse';
5 | import Fade from '@mui/material/Fade';
6 | import Grow from '@mui/material/Grow';
7 | import Slide from '@mui/material/Slide';
8 | import Zoom from '@mui/material/Zoom';
9 | import Box from '@mui/material/Box';
10 |
11 | export default function Transitions({ children, position = 'top-left', type = 'grow', direction = 'up', ref, ...others }) {
12 | let positionSX = {
13 | transformOrigin: '0 0 0'
14 | };
15 |
16 | switch (position) {
17 | case 'top-right':
18 | positionSX = {
19 | transformOrigin: 'top right'
20 | };
21 | break;
22 | case 'top':
23 | positionSX = {
24 | transformOrigin: 'top'
25 | };
26 | break;
27 | case 'bottom-left':
28 | positionSX = {
29 | transformOrigin: 'bottom left'
30 | };
31 | break;
32 | case 'bottom-right':
33 | positionSX = {
34 | transformOrigin: 'bottom right'
35 | };
36 | break;
37 | case 'bottom':
38 | positionSX = {
39 | transformOrigin: 'bottom'
40 | };
41 | break;
42 | case 'top-left':
43 | default:
44 | positionSX = {
45 | transformOrigin: '0 0 0'
46 | };
47 | break;
48 | }
49 |
50 | return (
51 |
52 | {type === 'grow' && (
53 |
61 | {children}
62 |
63 | )}
64 |
65 | {type === 'collapse' && (
66 |
67 | {children}
68 |
69 | )}
70 |
71 | {type === 'fade' && (
72 |
80 | {children}
81 |
82 | )}
83 |
84 | {type === 'slide' && (
85 |
94 | {children}
95 |
96 | )}
97 |
98 | {type === 'zoom' && (
99 |
100 | {children}
101 |
102 | )}
103 |
104 | );
105 | }
106 |
107 | export function PopupTransition({ ref, ...props }) {
108 | return ;
109 | }
110 |
111 | Transitions.propTypes = {
112 | children: PropTypes.node,
113 | position: PropTypes.string,
114 | type: PropTypes.string,
115 | ref: PropTypes.any,
116 | direction: PropTypes.oneOf(['up', 'right', 'left', 'down']),
117 | others: PropTypes.any
118 | };
119 |
120 | PopupTransition.propTypes = { ref: PropTypes.any, props: PropTypes.any };
121 |
--------------------------------------------------------------------------------
/src/components/Loadable.jsx:
--------------------------------------------------------------------------------
1 | import { Suspense } from 'react';
2 |
3 | // project imports
4 | import Loader from './Loader';
5 |
6 | // ==============================|| LOADABLE - LAZY LOADING ||============================== //
7 |
8 | const Loadable = (Component) => (props) => {
9 | return (
10 | }>
11 |
12 |
13 | );
14 | };
15 |
16 | export default Loadable;
17 |
--------------------------------------------------------------------------------
/src/components/Loader.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import LinearProgress from '@mui/material/LinearProgress';
3 | import Box from '@mui/material/Box';
4 |
5 | // ==============================|| Loader ||============================== //
6 |
7 | export default function Loader() {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/MainCard.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | // material-ui
4 | import Card from '@mui/material/Card';
5 | import CardContent from '@mui/material/CardContent';
6 | import CardHeader from '@mui/material/CardHeader';
7 | import Divider from '@mui/material/Divider';
8 |
9 | // header style
10 | const headerSX = {
11 | p: 2.5,
12 | '& .MuiCardHeader-action': { m: '0px auto', alignSelf: 'center' }
13 | };
14 |
15 | export default function MainCard({
16 | border = true,
17 | boxShadow,
18 | children,
19 | subheader,
20 | content = true,
21 | contentSX = {},
22 | darkTitle,
23 | divider = true,
24 | elevation,
25 | secondary,
26 | shadow,
27 | sx = {},
28 | title,
29 | modal = false,
30 | ref,
31 | ...others
32 | }) {
33 | return (
34 | ({
38 | position: 'relative',
39 | border: border ? '1px solid' : 'none',
40 | borderRadius: 1,
41 | borderColor: 'grey.A800',
42 | boxShadow: boxShadow && !border ? shadow || theme.customShadows.z1 : 'inherit',
43 | ':hover': {
44 | boxShadow: boxShadow ? shadow || theme.customShadows.z1 : 'inherit'
45 | },
46 | ...(modal && {
47 | position: 'absolute',
48 | top: '50%',
49 | left: '50%',
50 | transform: 'translate(-50%, -50%)',
51 | width: { xs: `calc(100% - 50px)`, sm: 'auto' },
52 | maxWidth: 768,
53 | '& .MuiCardContent-root': { overflowY: 'auto', minHeight: 'auto', maxHeight: `calc(100vh - 200px)` }
54 | })
55 | }),
56 | sx
57 | ]}
58 | ref={ref}
59 | {...others}
60 | >
61 | {/* card header and action */}
62 | {!darkTitle && title && (
63 |
64 | )}
65 |
66 | {/* content & header divider */}
67 | {title && divider && }
68 |
69 | {/* card content */}
70 | {content && {children}}
71 | {!content && children}
72 |
73 | );
74 | }
75 |
76 | MainCard.propTypes = {
77 | border: PropTypes.bool,
78 | boxShadow: PropTypes.bool,
79 | children: PropTypes.node,
80 | subheader: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
81 | content: PropTypes.bool,
82 | contentSX: PropTypes.object,
83 | darkTitle: PropTypes.bool,
84 | divider: PropTypes.bool,
85 | elevation: PropTypes.number,
86 | secondary: PropTypes.any,
87 | shadow: PropTypes.string,
88 | sx: PropTypes.object,
89 | title: PropTypes.oneOfType([PropTypes.node, PropTypes.string]),
90 | modal: PropTypes.bool,
91 | ref: PropTypes.object,
92 | others: PropTypes.any
93 | };
94 |
--------------------------------------------------------------------------------
/src/components/ScrollTop.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import { useEffect } from 'react';
3 |
4 | // ==============================|| NAVIGATION - SCROLL TO TOP ||============================== //
5 |
6 | export default function ScrollTop({ children }) {
7 | useEffect(() => {
8 | window.scrollTo({
9 | top: 0,
10 | left: 0,
11 | behavior: 'smooth'
12 | });
13 | }, []);
14 |
15 | return children || null;
16 | }
17 |
18 | ScrollTop.propTypes = { children: PropTypes.oneOfType([PropTypes.any, PropTypes.node]) };
19 |
--------------------------------------------------------------------------------
/src/components/cards/AuthFooter.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import Container from '@mui/material/Container';
3 | import Link from '@mui/material/Link';
4 | import Typography from '@mui/material/Typography';
5 | import Stack from '@mui/material/Stack';
6 |
7 | // ==============================|| FOOTER - AUTHENTICATION ||============================== //
8 |
9 | export default function AuthFooter() {
10 | return (
11 |
12 |
16 |
17 | © Made with love by Team{' '}
18 |
19 | CodedThemes
20 |
21 |
22 |
23 |
24 |
32 | Terms and Conditions
33 |
34 |
42 | Privacy Policy
43 |
44 |
45 |
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/src/components/cards/statistics/AnalyticEcommerce.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | // material-ui
3 | import Chip from '@mui/material/Chip';
4 | import Grid from '@mui/material/Grid';
5 | import Stack from '@mui/material/Stack';
6 | import Typography from '@mui/material/Typography';
7 | import Box from '@mui/material/Box';
8 |
9 | // project imports
10 | import MainCard from 'components/MainCard';
11 |
12 | // assets
13 | import RiseOutlined from '@ant-design/icons/RiseOutlined';
14 | import FallOutlined from '@ant-design/icons/FallOutlined';
15 |
16 | const iconSX = { fontSize: '0.75rem', color: 'inherit', marginLeft: 0, marginRight: 0 };
17 |
18 | export default function AnalyticEcommerce({ color = 'primary', title, count, percentage, isLoss, extra }) {
19 | return (
20 |
21 |
22 |
23 | {title}
24 |
25 |
26 |
27 |
28 | {count}
29 |
30 |
31 | {percentage && (
32 |
33 | : }
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 |
58 | AnalyticEcommerce.propTypes = {
59 | color: PropTypes.string,
60 | title: PropTypes.string,
61 | count: PropTypes.string,
62 | percentage: PropTypes.number,
63 | isLoss: PropTypes.bool,
64 | extra: PropTypes.string
65 | };
66 |
--------------------------------------------------------------------------------
/src/components/logo/LogoIcon.jsx:
--------------------------------------------------------------------------------
1 | // material-ui
2 | import { useTheme } from '@mui/material/styles';
3 |
4 | /**
5 | * if you want to use image instead of