init
15
.editorconfig
Normal file
@ -0,0 +1,15 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
[*.yml]
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
58
.eslintrc.js
Normal file
@ -0,0 +1,58 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
es6: true,
|
||||
browser: true
|
||||
},
|
||||
parser: 'babel-eslint',
|
||||
extends: ['next/core-web-vitals', 'prettier'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 11,
|
||||
sourceType: 'module',
|
||||
project: './jsconfig.json',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
modules: true,
|
||||
experimentalObjectRestSpread: true
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
|
||||
'react/display-name': 'off',
|
||||
'@next/next/no-img-element': 'off',
|
||||
'react/no-unescaped-entities': 'off',
|
||||
'import/no-anonymous-default-export': 'off',
|
||||
|
||||
// add new line above comment
|
||||
'lines-around-comment': [
|
||||
'error',
|
||||
{
|
||||
beforeLineComment: true,
|
||||
beforeBlockComment: true,
|
||||
allowBlockStart: true,
|
||||
allowClassStart: true,
|
||||
allowObjectStart: true,
|
||||
allowArrayStart: true
|
||||
}
|
||||
],
|
||||
|
||||
// add new line above return
|
||||
'newline-before-return': 'error',
|
||||
|
||||
// add new line below import
|
||||
'import/newline-after-import': [
|
||||
'error',
|
||||
{
|
||||
count: 1
|
||||
}
|
||||
],
|
||||
|
||||
// add new line after each var, const, let declaration
|
||||
'padding-line-between-statements': [
|
||||
'error',
|
||||
{ blankLine: 'always', prev: ['export'], next: ['*'] },
|
||||
{ blankLine: 'always', prev: ['*'], next: ['multiline-const', 'multiline-let', 'multiline-var', 'export'] }
|
||||
]
|
||||
}
|
||||
}
|
37
.gitignore
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
17
.prettierrc.js
Normal file
@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
arrowParens: 'avoid',
|
||||
bracketSpacing: true,
|
||||
htmlWhitespaceSensitivity: 'css',
|
||||
insertPragma: false,
|
||||
bracketSameLine: false,
|
||||
jsxSingleQuote: true,
|
||||
printWidth: 120,
|
||||
proseWrap: 'preserve',
|
||||
quoteProps: 'as-needed',
|
||||
requirePragma: false,
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
tabWidth: 2,
|
||||
trailingComma: 'none',
|
||||
useTabs: false
|
||||
}
|
8
jsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
6
next-env.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
18
next.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
trailingSlash: true,
|
||||
reactStrictMode: false,
|
||||
experimental: {
|
||||
esmExternals: false,
|
||||
jsconfigPaths: true // enables it for both jsconfig.json and tsconfig.json
|
||||
},
|
||||
webpack: config => {
|
||||
config.resolve.alias = {
|
||||
...config.resolve.alias,
|
||||
apexcharts: path.resolve(__dirname, './node_modules/apexcharts-clevision')
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
}
|
6430
package-lock.json
generated
Normal file
76
package.json
Normal file
@ -0,0 +1,76 @@
|
||||
{
|
||||
"name": "materio-mui-react-nextjs-admin-template-free",
|
||||
"description": "Most Powerful & Comprehensive Free MUI React NextJS Admin Dashboard Template built for developers! 🚀",
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "ThemeSelection",
|
||||
"url": "https://themeselection.com/"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free/issues"
|
||||
},
|
||||
"private": false,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free.git"
|
||||
},
|
||||
"homepage": "https://themeselection.com/products/materio-free-mui-react-nextjs-admin-template/",
|
||||
"keywords": [
|
||||
"react",
|
||||
"javascript",
|
||||
"admin",
|
||||
"dashboard",
|
||||
"material-design",
|
||||
"nextjs",
|
||||
"material-ui",
|
||||
"admin-dashboard",
|
||||
"free",
|
||||
"mui",
|
||||
"admin-template",
|
||||
"admin-panel",
|
||||
"freebies",
|
||||
"nextjs-template",
|
||||
"react-dashboard",
|
||||
"themeselection"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"export": "next export",
|
||||
"lint": "eslint --fix \"src/**/*.{js,jsx}\"",
|
||||
"format": "prettier --write \"src/**/*.{js,jsx}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/cache": "^11.6.0",
|
||||
"@emotion/react": "^11.7.0",
|
||||
"@emotion/server": "^11.4.0",
|
||||
"@emotion/styled": "^11.6.0",
|
||||
"@mui/lab": "^5.0.0-alpha.70",
|
||||
"@mui/material": "^5.4.3",
|
||||
"@popperjs/core": "^2.11.2",
|
||||
"apexcharts-clevision": "3.28.5",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"clsx": "^1.1.1",
|
||||
"mdi-material-ui": "^7.1.0",
|
||||
"next": "12.0.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"react": "17.0.2",
|
||||
"react-apexcharts": "^1.3.9",
|
||||
"react-datepicker": "^4.5.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-perfect-scrollbar": "^1.5.8",
|
||||
"react-popper": "^2.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-next": "12.0.4",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-import-resolver-typescript": "^2.5.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"next-transpile-modules": "^9.0.0",
|
||||
"prettier": "2.5.1"
|
||||
}
|
||||
}
|
BIN
public/images/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
public/images/avatars/1.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
public/images/avatars/2.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
public/images/avatars/3.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
public/images/avatars/4.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
public/images/avatars/5.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
public/images/avatars/6.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
public/images/avatars/7.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
public/images/avatars/8.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
public/images/cards/analog-clock.jpg
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
public/images/cards/background-user.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
public/images/cards/glass-house.png
Normal file
After Width: | Height: | Size: 272 KiB |
BIN
public/images/cards/iPhone-11-pro.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
public/images/cards/logo-aviato.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
public/images/cards/logo-bitbank.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
public/images/cards/logo-zipcar.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
public/images/cards/paper-boat.png
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
public/images/cards/paypal.png
Normal file
After Width: | Height: | Size: 696 B |
BIN
public/images/cards/watch-on-hand.jpg
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
public/images/favicon.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/images/logos/american-bank.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
public/images/logos/aws.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/images/logos/citi-bank.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
public/images/logos/digital-ocean.png
Normal file
After Width: | Height: | Size: 934 B |
BIN
public/images/logos/github.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
public/images/logos/google.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
public/images/logos/gumroad.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/logos/mastercard-label.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/logos/slack.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
public/images/logos/stripe.png
Normal file
After Width: | Height: | Size: 826 B |
BIN
public/images/misc/chart.png
Normal file
After Width: | Height: | Size: 455 B |
BIN
public/images/misc/materio-pro-banner.png
Normal file
After Width: | Height: | Size: 899 KiB |
BIN
public/images/misc/paypal.png
Normal file
After Width: | Height: | Size: 785 B |
BIN
public/images/misc/triangle-dark.png
Normal file
After Width: | Height: | Size: 757 B |
BIN
public/images/misc/triangle-light.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
public/images/misc/trophy.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
public/images/misc/upgrade-banner-dark.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
public/images/misc/upgrade-banner-light.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
public/images/pages/401.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
public/images/pages/404.png
Normal file
After Width: | Height: | Size: 161 KiB |
BIN
public/images/pages/500.png
Normal file
After Width: | Height: | Size: 171 KiB |
BIN
public/images/pages/auth-v1-mask-dark.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/pages/auth-v1-mask-light.png
Normal file
After Width: | Height: | Size: 777 B |
BIN
public/images/pages/auth-v1-tree-2.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
public/images/pages/auth-v1-tree.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/pages/misc-mask-dark.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/pages/misc-mask-light.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/pages/pose-m-1.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/images/pages/tree-2.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
public/images/pages/tree-3.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
public/images/pages/tree.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
4
public/vercel.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,51 @@
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Card from '@mui/material/Card'
|
||||
import Avatar from '@mui/material/Avatar'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
// ** Icons Imports
|
||||
import DotsVertical from 'mdi-material-ui/DotsVertical'
|
||||
|
||||
const CardStatsVertical = props => {
|
||||
// ** Props
|
||||
const { title, subtitle, color, icon, stats, trend, trendNumber } = props
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Box sx={{ display: 'flex', marginBottom: 5.5, alignItems: 'flex-start', justifyContent: 'space-between' }}>
|
||||
<Avatar sx={{ boxShadow: 3, marginRight: 4, color: 'common.white', backgroundColor: `${color}.main` }}>
|
||||
{icon}
|
||||
</Avatar>
|
||||
<IconButton size='small' aria-label='settings' className='card-more-options' sx={{ color: 'text.secondary' }}>
|
||||
<DotsVertical />
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Typography sx={{ fontWeight: 600, fontSize: '0.875rem' }}>{title}</Typography>
|
||||
<Box sx={{ marginTop: 1.5, display: 'flex', flexWrap: 'wrap', marginBottom: 1.5, alignItems: 'flex-start' }}>
|
||||
<Typography variant='h6' sx={{ mr: 2 }}>
|
||||
{stats}
|
||||
</Typography>
|
||||
<Typography
|
||||
component='sup'
|
||||
variant='caption'
|
||||
sx={{ color: trend === 'positive' ? 'success.main' : 'error.main' }}
|
||||
>
|
||||
{trendNumber}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Typography variant='caption'>{subtitle}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default CardStatsVertical
|
||||
|
||||
CardStatsVertical.defaultProps = {
|
||||
color: 'primary',
|
||||
trend: 'positive'
|
||||
}
|
7
src/@core/components/react-apexcharts/index.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
// ** Next Import
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
// ! To avoid 'Window is not defined' error
|
||||
const ReactApexcharts = dynamic(() => import('react-apexcharts'), { ssr: false })
|
||||
|
||||
export default ReactApexcharts
|
39
src/@core/components/scroll-to-top/index.js
Normal file
@ -0,0 +1,39 @@
|
||||
// ** MUI Imports
|
||||
import Zoom from '@mui/material/Zoom'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import useScrollTrigger from '@mui/material/useScrollTrigger'
|
||||
|
||||
const ScrollToTopStyled = styled('div')(({ theme }) => ({
|
||||
zIndex: 11,
|
||||
position: 'fixed',
|
||||
right: theme.spacing(6),
|
||||
bottom: theme.spacing(10)
|
||||
}))
|
||||
|
||||
const ScrollToTop = props => {
|
||||
// ** Props
|
||||
const { children, className } = props
|
||||
|
||||
// ** init trigger
|
||||
const trigger = useScrollTrigger({
|
||||
threshold: 400,
|
||||
disableHysteresis: true
|
||||
})
|
||||
|
||||
const handleClick = () => {
|
||||
const anchor = document.querySelector('body')
|
||||
if (anchor) {
|
||||
anchor.scrollIntoView({ behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Zoom in={trigger}>
|
||||
<ScrollToTopStyled className={className} onClick={handleClick} role='presentation'>
|
||||
{children}
|
||||
</ScrollToTopStyled>
|
||||
</Zoom>
|
||||
)
|
||||
}
|
||||
|
||||
export default ScrollToTop
|
30
src/@core/context/settingsContext.js
Normal file
@ -0,0 +1,30 @@
|
||||
// ** React Imports
|
||||
import { createContext, useState } from 'react'
|
||||
|
||||
// ** ThemeConfig Import
|
||||
import themeConfig from 'src/configs/themeConfig'
|
||||
|
||||
const initialSettings = {
|
||||
themeColor: 'primary',
|
||||
mode: themeConfig.mode,
|
||||
contentWidth: themeConfig.contentWidth
|
||||
}
|
||||
|
||||
// ** Create Context
|
||||
export const SettingsContext = createContext({
|
||||
saveSettings: () => null,
|
||||
settings: initialSettings
|
||||
})
|
||||
|
||||
export const SettingsProvider = ({ children }) => {
|
||||
// ** State
|
||||
const [settings, setSettings] = useState({ ...initialSettings })
|
||||
|
||||
const saveSettings = updatedSettings => {
|
||||
setSettings(updatedSettings)
|
||||
}
|
||||
|
||||
return <SettingsContext.Provider value={{ settings, saveSettings }}>{children}</SettingsContext.Provider>
|
||||
}
|
||||
|
||||
export const SettingsConsumer = SettingsContext.Consumer
|
4
src/@core/hooks/useSettings.js
Normal file
@ -0,0 +1,4 @@
|
||||
import { useContext } from 'react'
|
||||
import { SettingsContext } from 'src/@core/context/settingsContext'
|
||||
|
||||
export const useSettings = () => useContext(SettingsContext)
|
37
src/@core/layouts/BlankLayout.js
Normal file
@ -0,0 +1,37 @@
|
||||
// ** MUI Imports
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Box from '@mui/material/Box'
|
||||
|
||||
// Styled component for Blank Layout component
|
||||
const BlankLayoutWrapper = styled(Box)(({ theme }) => ({
|
||||
height: '100vh',
|
||||
|
||||
// For V1 Blank layout pages
|
||||
'& .content-center': {
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: theme.spacing(5)
|
||||
},
|
||||
|
||||
// For V2 Blank layout pages
|
||||
'& .content-right': {
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
overflowX: 'hidden',
|
||||
position: 'relative'
|
||||
}
|
||||
}))
|
||||
|
||||
const BlankLayout = ({ children }) => {
|
||||
return (
|
||||
<BlankLayoutWrapper className='layout-wrapper'>
|
||||
<Box className='app-content' sx={{ minHeight: '100vh', overflowX: 'hidden', position: 'relative' }}>
|
||||
{children}
|
||||
</Box>
|
||||
</BlankLayoutWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default BlankLayout
|
109
src/@core/layouts/VerticalLayout.js
Normal file
@ -0,0 +1,109 @@
|
||||
// ** React Imports
|
||||
import { useState } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Fab from '@mui/material/Fab'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Box from '@mui/material/Box'
|
||||
|
||||
// ** Icons Imports
|
||||
import ArrowUp from 'mdi-material-ui/ArrowUp'
|
||||
|
||||
// ** Theme Config Import
|
||||
import themeConfig from 'src/configs/themeConfig'
|
||||
|
||||
// ** Components
|
||||
import AppBar from './components/vertical/appBar'
|
||||
import Navigation from './components/vertical/navigation'
|
||||
import Footer from './components/shared-components/footer'
|
||||
import ScrollToTop from 'src/@core/components/scroll-to-top'
|
||||
|
||||
// ** Styled Component
|
||||
import DatePickerWrapper from 'src/@core/styles/libs/react-datepicker'
|
||||
|
||||
const VerticalLayoutWrapper = styled('div')({
|
||||
height: '100%',
|
||||
display: 'flex'
|
||||
})
|
||||
|
||||
const MainContentWrapper = styled(Box)({
|
||||
flexGrow: 1,
|
||||
minWidth: 0,
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
flexDirection: 'column'
|
||||
})
|
||||
|
||||
const ContentWrapper = styled('main')(({ theme }) => ({
|
||||
flexGrow: 1,
|
||||
width: '100%',
|
||||
padding: theme.spacing(6),
|
||||
transition: 'padding .25s ease-in-out',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
paddingLeft: theme.spacing(4),
|
||||
paddingRight: theme.spacing(4)
|
||||
}
|
||||
}))
|
||||
|
||||
const VerticalLayout = props => {
|
||||
// ** Props
|
||||
const { settings, children, scrollToTop } = props
|
||||
|
||||
// ** Vars
|
||||
const { contentWidth } = settings
|
||||
const navWidth = themeConfig.navigationSize
|
||||
|
||||
// ** States
|
||||
const [navVisible, setNavVisible] = useState(false)
|
||||
|
||||
// ** Toggle Functions
|
||||
const toggleNavVisibility = () => setNavVisible(!navVisible)
|
||||
|
||||
return (
|
||||
<>
|
||||
<VerticalLayoutWrapper className='layout-wrapper'>
|
||||
<Navigation
|
||||
navWidth={navWidth}
|
||||
navVisible={navVisible}
|
||||
setNavVisible={setNavVisible}
|
||||
toggleNavVisibility={toggleNavVisibility}
|
||||
{...props}
|
||||
/>
|
||||
<MainContentWrapper className='layout-content-wrapper'>
|
||||
<AppBar toggleNavVisibility={toggleNavVisibility} {...props} />
|
||||
|
||||
<ContentWrapper
|
||||
className='layout-page-content'
|
||||
sx={{
|
||||
...(contentWidth === 'boxed' && {
|
||||
mx: 'auto',
|
||||
'@media (min-width:1440px)': { maxWidth: 1440 },
|
||||
'@media (min-width:1200px)': { maxWidth: '100%' }
|
||||
})
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ContentWrapper>
|
||||
|
||||
<Footer {...props} />
|
||||
|
||||
<DatePickerWrapper sx={{ zIndex: 11 }}>
|
||||
<Box id='react-datepicker-portal'></Box>
|
||||
</DatePickerWrapper>
|
||||
</MainContentWrapper>
|
||||
</VerticalLayoutWrapper>
|
||||
|
||||
{scrollToTop ? (
|
||||
scrollToTop(props)
|
||||
) : (
|
||||
<ScrollToTop className='mui-fixed'>
|
||||
<Fab color='primary' size='small' aria-label='scroll back to top'>
|
||||
<ArrowUp />
|
||||
</Fab>
|
||||
</ScrollToTop>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalLayout
|
@ -0,0 +1,30 @@
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
|
||||
// ** Icons Imports
|
||||
import WeatherNight from 'mdi-material-ui/WeatherNight'
|
||||
import WeatherSunny from 'mdi-material-ui/WeatherSunny'
|
||||
|
||||
const ModeToggler = props => {
|
||||
// ** Props
|
||||
const { settings, saveSettings } = props
|
||||
|
||||
const handleModeChange = mode => {
|
||||
saveSettings({ ...settings, mode })
|
||||
}
|
||||
|
||||
const handleModeToggle = () => {
|
||||
if (settings.mode === 'light') {
|
||||
handleModeChange('dark')
|
||||
} else {
|
||||
handleModeChange('light')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<IconButton color='inherit' aria-haspopup='true' onClick={handleModeToggle}>
|
||||
{settings.mode === 'dark' ? <WeatherSunny /> : <WeatherNight />}
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
|
||||
export default ModeToggler
|
@ -0,0 +1,217 @@
|
||||
// ** React Imports
|
||||
import { useState, Fragment } from 'react'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Chip from '@mui/material/Chip'
|
||||
import Button from '@mui/material/Button'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
import MuiMenu from '@mui/material/Menu'
|
||||
import MuiAvatar from '@mui/material/Avatar'
|
||||
import MuiMenuItem from '@mui/material/MenuItem'
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
// ** Icons Imports
|
||||
import BellOutline from 'mdi-material-ui/BellOutline'
|
||||
|
||||
// ** Third Party Components
|
||||
import PerfectScrollbarComponent from 'react-perfect-scrollbar'
|
||||
|
||||
// ** Styled Menu component
|
||||
const Menu = styled(MuiMenu)(({ theme }) => ({
|
||||
'& .MuiMenu-paper': {
|
||||
width: 380,
|
||||
overflow: 'hidden',
|
||||
marginTop: theme.spacing(4),
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
width: '100%'
|
||||
}
|
||||
},
|
||||
'& .MuiMenu-list': {
|
||||
padding: 0
|
||||
}
|
||||
}))
|
||||
|
||||
// ** Styled MenuItem component
|
||||
const MenuItem = styled(MuiMenuItem)(({ theme }) => ({
|
||||
paddingTop: theme.spacing(3),
|
||||
paddingBottom: theme.spacing(3),
|
||||
borderBottom: `1px solid ${theme.palette.divider}`
|
||||
}))
|
||||
|
||||
const styles = {
|
||||
maxHeight: 349,
|
||||
'& .MuiMenuItem-root:last-of-type': {
|
||||
border: 0
|
||||
}
|
||||
}
|
||||
|
||||
// ** Styled PerfectScrollbar component
|
||||
const PerfectScrollbar = styled(PerfectScrollbarComponent)({
|
||||
...styles
|
||||
})
|
||||
|
||||
// ** Styled Avatar component
|
||||
const Avatar = styled(MuiAvatar)({
|
||||
width: '2.375rem',
|
||||
height: '2.375rem',
|
||||
fontSize: '1.125rem'
|
||||
})
|
||||
|
||||
// ** Styled component for the title in MenuItems
|
||||
const MenuItemTitle = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
flex: '1 1 100%',
|
||||
overflow: 'hidden',
|
||||
fontSize: '0.875rem',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
marginBottom: theme.spacing(0.75)
|
||||
}))
|
||||
|
||||
// ** Styled component for the subtitle in MenuItems
|
||||
const MenuItemSubtitle = styled(Typography)({
|
||||
flex: '1 1 100%',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis'
|
||||
})
|
||||
|
||||
const NotificationDropdown = () => {
|
||||
// ** States
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
|
||||
// ** Hook
|
||||
const hidden = useMediaQuery(theme => theme.breakpoints.down('lg'))
|
||||
|
||||
const handleDropdownOpen = event => {
|
||||
setAnchorEl(event.currentTarget)
|
||||
}
|
||||
|
||||
const handleDropdownClose = () => {
|
||||
setAnchorEl(null)
|
||||
}
|
||||
|
||||
const ScrollWrapper = ({ children }) => {
|
||||
if (hidden) {
|
||||
return <Box sx={{ ...styles, overflowY: 'auto', overflowX: 'hidden' }}>{children}</Box>
|
||||
} else {
|
||||
return (
|
||||
<PerfectScrollbar options={{ wheelPropagation: false, suppressScrollX: true }}>{children}</PerfectScrollbar>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<IconButton color='inherit' aria-haspopup='true' onClick={handleDropdownOpen} aria-controls='customized-menu'>
|
||||
<BellOutline />
|
||||
</IconButton>
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleDropdownClose}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||
>
|
||||
<MenuItem disableRipple>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
|
||||
<Typography sx={{ fontWeight: 600 }}>Notifications</Typography>
|
||||
<Chip
|
||||
size='small'
|
||||
label='8 New'
|
||||
color='primary'
|
||||
sx={{ height: 20, fontSize: '0.75rem', fontWeight: 500, borderRadius: '10px' }}
|
||||
/>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<ScrollWrapper>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar alt='Flora' src='/images/avatars/4.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Congratulation Flora! 🎉</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>Won the monthly best seller badge</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
Today
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar sx={{ color: 'common.white', backgroundColor: 'primary.main' }}>VU</Avatar>
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>New user registered.</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>5 hours ago</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
Yesterday
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar alt='message' src='/images/avatars/5.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>New message received 👋🏻</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>You have 10 unread messages</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
11 Aug
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<img width={38} height={38} alt='paypal' src='/images/misc/paypal.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Paypal</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>Received Payment</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
25 May
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar alt='order' src='/images/avatars/3.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Revised Order 📦</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>New order revised from john</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
19 Mar
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDropdownClose}>
|
||||
<Box sx={{ width: '100%', display: 'flex', alignItems: 'center' }}>
|
||||
<img width={38} height={38} alt='chart' src='/images/misc/chart.png' />
|
||||
<Box sx={{ mx: 4, flex: '1 1', display: 'flex', overflow: 'hidden', flexDirection: 'column' }}>
|
||||
<MenuItemTitle>Finance report has been generated</MenuItemTitle>
|
||||
<MenuItemSubtitle variant='body2'>25 hrs ago</MenuItemSubtitle>
|
||||
</Box>
|
||||
<Typography variant='caption' sx={{ color: 'text.disabled' }}>
|
||||
27 Dec
|
||||
</Typography>
|
||||
</Box>
|
||||
</MenuItem>
|
||||
</ScrollWrapper>
|
||||
<MenuItem
|
||||
disableRipple
|
||||
sx={{ py: 3.5, borderBottom: 0, borderTop: theme => `1px solid ${theme.palette.divider}` }}
|
||||
>
|
||||
<Button fullWidth variant='contained' onClick={handleDropdownClose}>
|
||||
Read All Notifications
|
||||
</Button>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default NotificationDropdown
|
156
src/@core/layouts/components/shared-components/UserDropdown.js
Normal file
@ -0,0 +1,156 @@
|
||||
// ** React Imports
|
||||
import { useState, Fragment } from 'react'
|
||||
|
||||
// ** Next Import
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Menu from '@mui/material/Menu'
|
||||
import Badge from '@mui/material/Badge'
|
||||
import Avatar from '@mui/material/Avatar'
|
||||
import Divider from '@mui/material/Divider'
|
||||
import MenuItem from '@mui/material/MenuItem'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
// ** Icons Imports
|
||||
import CogOutline from 'mdi-material-ui/CogOutline'
|
||||
import CurrencyUsd from 'mdi-material-ui/CurrencyUsd'
|
||||
import EmailOutline from 'mdi-material-ui/EmailOutline'
|
||||
import LogoutVariant from 'mdi-material-ui/LogoutVariant'
|
||||
import AccountOutline from 'mdi-material-ui/AccountOutline'
|
||||
import MessageOutline from 'mdi-material-ui/MessageOutline'
|
||||
import HelpCircleOutline from 'mdi-material-ui/HelpCircleOutline'
|
||||
|
||||
// ** Styled Components
|
||||
const BadgeContentSpan = styled('span')(({ theme }) => ({
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: '50%',
|
||||
backgroundColor: theme.palette.success.main,
|
||||
boxShadow: `0 0 0 2px ${theme.palette.background.paper}`
|
||||
}))
|
||||
|
||||
const UserDropdown = () => {
|
||||
// ** States
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
|
||||
// ** Hooks
|
||||
const router = useRouter()
|
||||
|
||||
const handleDropdownOpen = event => {
|
||||
setAnchorEl(event.currentTarget)
|
||||
}
|
||||
|
||||
const handleDropdownClose = url => {
|
||||
if (url) {
|
||||
router.push(url)
|
||||
}
|
||||
setAnchorEl(null)
|
||||
}
|
||||
|
||||
const styles = {
|
||||
py: 2,
|
||||
px: 4,
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
color: 'text.primary',
|
||||
textDecoration: 'none',
|
||||
'& svg': {
|
||||
fontSize: '1.375rem',
|
||||
color: 'text.secondary'
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Badge
|
||||
overlap='circular'
|
||||
onClick={handleDropdownOpen}
|
||||
sx={{ ml: 2, cursor: 'pointer' }}
|
||||
badgeContent={<BadgeContentSpan />}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
>
|
||||
<Avatar
|
||||
alt='John Doe'
|
||||
onClick={handleDropdownOpen}
|
||||
sx={{ width: 40, height: 40 }}
|
||||
src='/images/avatars/1.png'
|
||||
/>
|
||||
</Badge>
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={() => handleDropdownClose()}
|
||||
sx={{ '& .MuiMenu-paper': { width: 230, marginTop: 4 } }}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||
>
|
||||
<Box sx={{ pt: 2, pb: 3, px: 4 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Badge
|
||||
overlap='circular'
|
||||
badgeContent={<BadgeContentSpan />}
|
||||
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||
>
|
||||
<Avatar alt='John Doe' src='/images/avatars/1.png' sx={{ width: '2.5rem', height: '2.5rem' }} />
|
||||
</Badge>
|
||||
<Box sx={{ display: 'flex', marginLeft: 3, alignItems: 'flex-start', flexDirection: 'column' }}>
|
||||
<Typography sx={{ fontWeight: 600 }}>John Doe</Typography>
|
||||
<Typography variant='body2' sx={{ fontSize: '0.8rem', color: 'text.disabled' }}>
|
||||
Admin
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
<Divider sx={{ mt: 0, mb: 1 }} />
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<AccountOutline sx={{ marginRight: 2 }} />
|
||||
Profile
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<EmailOutline sx={{ marginRight: 2 }} />
|
||||
Inbox
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<MessageOutline sx={{ marginRight: 2 }} />
|
||||
Chat
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<CogOutline sx={{ marginRight: 2 }} />
|
||||
Settings
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<CurrencyUsd sx={{ marginRight: 2 }} />
|
||||
Pricing
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<MenuItem sx={{ p: 0 }} onClick={() => handleDropdownClose()}>
|
||||
<Box sx={styles}>
|
||||
<HelpCircleOutline sx={{ marginRight: 2 }} />
|
||||
FAQ
|
||||
</Box>
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
<MenuItem sx={{ py: 2 }} onClick={() => handleDropdownClose('/pages/login')}>
|
||||
<LogoutVariant sx={{ marginRight: 2, fontSize: '1.375rem', color: 'text.secondary' }} />
|
||||
Logout
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default UserDropdown
|
@ -0,0 +1,52 @@
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import Link from '@mui/material/Link'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import useMediaQuery from '@mui/material/useMediaQuery'
|
||||
|
||||
const FooterContent = () => {
|
||||
// ** Var
|
||||
const hidden = useMediaQuery(theme => theme.breakpoints.down('md'))
|
||||
|
||||
return (
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<Typography sx={{ mr: 2 }}>
|
||||
{`© ${new Date().getFullYear()}, Made with `}
|
||||
<Box component='span' sx={{ color: 'error.main' }}>
|
||||
❤️
|
||||
</Box>
|
||||
{` by `}
|
||||
<Link target='_blank' href='https://themeselection.com/'>
|
||||
ThemeSelection
|
||||
</Link>
|
||||
</Typography>
|
||||
{hidden ? null : (
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', '& :not(:last-child)': { mr: 4 } }}>
|
||||
<Link
|
||||
target='_blank'
|
||||
href='https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free/blob/main/LICENSE'
|
||||
>
|
||||
MIT License
|
||||
</Link>
|
||||
<Link target='_blank' href='https://themeselection.com/'>
|
||||
More Themes
|
||||
</Link>
|
||||
<Link
|
||||
target='_blank'
|
||||
href='https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free/blob/main/README.md'
|
||||
>
|
||||
Documentation
|
||||
</Link>
|
||||
<Link
|
||||
target='_blank'
|
||||
href='https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free/issues'
|
||||
>
|
||||
Support
|
||||
</Link>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default FooterContent
|
@ -0,0 +1,45 @@
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { useTheme } from '@mui/material/styles'
|
||||
|
||||
// ** Footer Content Component
|
||||
import FooterContent from './FooterContent'
|
||||
|
||||
const Footer = props => {
|
||||
// ** Props
|
||||
const { settings, footerContent: userFooterContent } = props
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
// ** Vars
|
||||
const { contentWidth } = settings
|
||||
|
||||
return (
|
||||
<Box
|
||||
component='footer'
|
||||
className='layout-footer'
|
||||
sx={{
|
||||
zIndex: 10,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
className='footer-content-container'
|
||||
sx={{
|
||||
width: '100%',
|
||||
borderTopLeftRadius: 14,
|
||||
borderTopRightRadius: 14,
|
||||
padding: theme.spacing(4, 6),
|
||||
...(contentWidth === 'boxed' && { '@media (min-width:1440px)': { maxWidth: 1440 } })
|
||||
}}
|
||||
>
|
||||
{userFooterContent ? userFooterContent(props) : <FooterContent />}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
56
src/@core/layouts/components/vertical/appBar/index.js
Normal file
@ -0,0 +1,56 @@
|
||||
// ** MUI Imports
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import MuiAppBar from '@mui/material/AppBar'
|
||||
import MuiToolbar from '@mui/material/Toolbar'
|
||||
|
||||
const AppBar = styled(MuiAppBar)(({ theme }) => ({
|
||||
transition: 'none',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: theme.spacing(0, 6),
|
||||
backgroundColor: 'transparent',
|
||||
color: theme.palette.text.primary,
|
||||
minHeight: theme.mixins.toolbar.minHeight,
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
paddingLeft: theme.spacing(4),
|
||||
paddingRight: theme.spacing(4)
|
||||
}
|
||||
}))
|
||||
|
||||
const Toolbar = styled(MuiToolbar)(({ theme }) => ({
|
||||
width: '100%',
|
||||
borderBottomLeftRadius: 10,
|
||||
borderBottomRightRadius: 10,
|
||||
padding: `${theme.spacing(0)} !important`,
|
||||
minHeight: `${theme.mixins.toolbar.minHeight}px !important`,
|
||||
transition:
|
||||
'padding .25s ease-in-out, box-shadow .25s ease-in-out, backdrop-filter .25s ease-in-out, background-color .25s ease-in-out'
|
||||
}))
|
||||
|
||||
const LayoutAppBar = props => {
|
||||
// ** Props
|
||||
const { settings, verticalAppBarContent: userVerticalAppBarContent } = props
|
||||
|
||||
// ** Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
// ** Vars
|
||||
const { contentWidth } = settings
|
||||
|
||||
return (
|
||||
<AppBar elevation={0} color='default' className='layout-navbar' position='static'>
|
||||
<Toolbar
|
||||
className='navbar-content-container'
|
||||
sx={{
|
||||
...(contentWidth === 'boxed' && {
|
||||
'@media (min-width:1440px)': { maxWidth: `calc(1440px - ${theme.spacing(6)} * 2)` }
|
||||
})
|
||||
}}
|
||||
>
|
||||
{(userVerticalAppBarContent && userVerticalAppBarContent(props)) || null}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
)
|
||||
}
|
||||
|
||||
export default LayoutAppBar
|
66
src/@core/layouts/components/vertical/navigation/Drawer.js
Normal file
@ -0,0 +1,66 @@
|
||||
// ** MUI Imports
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import MuiSwipeableDrawer from '@mui/material/SwipeableDrawer'
|
||||
|
||||
const SwipeableDrawer = styled(MuiSwipeableDrawer)({
|
||||
overflowX: 'hidden',
|
||||
transition: 'width .25s ease-in-out',
|
||||
'& ul': {
|
||||
listStyle: 'none'
|
||||
},
|
||||
'& .MuiListItem-gutters': {
|
||||
paddingLeft: 4,
|
||||
paddingRight: 4
|
||||
},
|
||||
'& .MuiDrawer-paper': {
|
||||
left: 'unset',
|
||||
right: 'unset',
|
||||
overflowX: 'hidden',
|
||||
transition: 'width .25s ease-in-out, box-shadow .25s ease-in-out'
|
||||
}
|
||||
})
|
||||
|
||||
const Drawer = props => {
|
||||
// ** Props
|
||||
const { hidden, children, navWidth, navVisible, setNavVisible } = props
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
// Drawer Props for Mobile & Tablet screens
|
||||
const MobileDrawerProps = {
|
||||
open: navVisible,
|
||||
onOpen: () => setNavVisible(true),
|
||||
onClose: () => setNavVisible(false),
|
||||
ModalProps: {
|
||||
keepMounted: true // Better open performance on mobile.
|
||||
}
|
||||
}
|
||||
|
||||
// Drawer Props for Desktop screens
|
||||
const DesktopDrawerProps = {
|
||||
open: true,
|
||||
onOpen: () => null,
|
||||
onClose: () => null
|
||||
}
|
||||
|
||||
return (
|
||||
<SwipeableDrawer
|
||||
className='layout-vertical-nav'
|
||||
variant={hidden ? 'temporary' : 'permanent'}
|
||||
{...(hidden ? { ...MobileDrawerProps } : { ...DesktopDrawerProps })}
|
||||
PaperProps={{ sx: { width: navWidth } }}
|
||||
sx={{
|
||||
width: navWidth,
|
||||
'& .MuiDrawer-paper': {
|
||||
borderRight: 0,
|
||||
backgroundColor: theme.palette.background.default
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</SwipeableDrawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Drawer
|
@ -0,0 +1,119 @@
|
||||
// ** Next Import
|
||||
import Link from 'next/link'
|
||||
|
||||
// ** MUI Imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
|
||||
// ** Configs
|
||||
import themeConfig from 'src/configs/themeConfig'
|
||||
|
||||
// ** Styled Components
|
||||
const MenuHeaderWrapper = styled(Box)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingRight: theme.spacing(4.5),
|
||||
transition: 'padding .25s ease-in-out',
|
||||
minHeight: theme.mixins.toolbar.minHeight
|
||||
}))
|
||||
|
||||
const HeaderTitle = styled(Typography)(({ theme }) => ({
|
||||
fontWeight: 600,
|
||||
lineHeight: 'normal',
|
||||
textTransform: 'uppercase',
|
||||
color: theme.palette.text.primary,
|
||||
transition: 'opacity .25s ease-in-out, margin .25s ease-in-out'
|
||||
}))
|
||||
|
||||
const StyledLink = styled('a')({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
textDecoration: 'none'
|
||||
})
|
||||
|
||||
const VerticalNavHeader = props => {
|
||||
// ** Props
|
||||
const { verticalNavMenuBranding: userVerticalNavMenuBranding } = props
|
||||
|
||||
// ** Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<MenuHeaderWrapper className='nav-header' sx={{ pl: 6 }}>
|
||||
{userVerticalNavMenuBranding ? (
|
||||
userVerticalNavMenuBranding(props)
|
||||
) : (
|
||||
<Link href='/' passHref>
|
||||
<StyledLink>
|
||||
<svg
|
||||
width={30}
|
||||
height={25}
|
||||
version='1.1'
|
||||
viewBox='0 0 30 23'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
>
|
||||
<g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'>
|
||||
<g id='Artboard' transform='translate(-95.000000, -51.000000)'>
|
||||
<g id='logo' transform='translate(95.000000, 50.000000)'>
|
||||
<path
|
||||
id='Combined-Shape'
|
||||
fill={theme.palette.primary.main}
|
||||
d='M30,21.3918362 C30,21.7535219 29.9019196,22.1084381 29.7162004,22.4188007 C29.1490236,23.366632 27.9208668,23.6752135 26.9730355,23.1080366 L26.9730355,23.1080366 L23.714971,21.1584295 C23.1114106,20.7972624 22.7419355,20.1455972 22.7419355,19.4422291 L22.7419355,19.4422291 L22.741,12.7425689 L15,17.1774194 L7.258,12.7425689 L7.25806452,19.4422291 C7.25806452,20.1455972 6.88858935,20.7972624 6.28502902,21.1584295 L3.0269645,23.1080366 C2.07913318,23.6752135 0.850976404,23.366632 0.283799571,22.4188007 C0.0980803893,22.1084381 2.0190442e-15,21.7535219 0,21.3918362 L0,3.58469444 L0.00548573643,3.43543209 L0.00548573643,3.43543209 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 L15,9.19354839 L26.9548759,1.86636639 C27.2693965,1.67359571 27.6311047,1.5715689 28,1.5715689 C29.1045695,1.5715689 30,2.4669994 30,3.5715689 L30,3.5715689 Z'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='0 8.58870968 7.25806452 12.7505183 7.25806452 16.8305646'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='0 8.58870968 7.25806452 12.6445567 7.25806452 15.1370162'
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='22.7419355 8.58870968 30 12.7417372 30 16.9537453'
|
||||
transform='translate(26.370968, 12.771227) scale(-1, 1) translate(-26.370968, -12.771227) '
|
||||
/>
|
||||
<polygon
|
||||
id='Rectangle'
|
||||
opacity='0.077704'
|
||||
fill={theme.palette.common.black}
|
||||
points='22.7419355 8.58870968 30 12.6409734 30 15.2601969'
|
||||
transform='translate(26.370968, 11.924453) scale(-1, 1) translate(-26.370968, -11.924453) '
|
||||
/>
|
||||
<path
|
||||
id='Rectangle'
|
||||
fillOpacity='0.15'
|
||||
fill={theme.palette.common.white}
|
||||
d='M3.04512412,1.86636639 L15,9.19354839 L15,9.19354839 L15,17.1774194 L0,8.58649679 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 Z'
|
||||
/>
|
||||
<path
|
||||
id='Rectangle'
|
||||
fillOpacity='0.35'
|
||||
fill={theme.palette.common.white}
|
||||
transform='translate(22.500000, 8.588710) scale(-1, 1) translate(-22.500000, -8.588710) '
|
||||
d='M18.0451241,1.86636639 L30,9.19354839 L30,9.19354839 L30,17.1774194 L15,8.58649679 L15,3.5715689 C15,2.4669994 15.8954305,1.5715689 17,1.5715689 C17.3688953,1.5715689 17.7306035,1.67359571 18.0451241,1.86636639 Z'
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<HeaderTitle variant='h6' sx={{ ml: 3 }}>
|
||||
{themeConfig.templateName}
|
||||
</HeaderTitle>
|
||||
</StyledLink>
|
||||
</Link>
|
||||
)}
|
||||
</MenuHeaderWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalNavHeader
|
@ -0,0 +1,24 @@
|
||||
// ** Custom Menu Components
|
||||
import VerticalNavLink from './VerticalNavLink'
|
||||
import VerticalNavSectionTitle from './VerticalNavSectionTitle'
|
||||
|
||||
const resolveNavItemComponent = item => {
|
||||
if (item.sectionTitle) return VerticalNavSectionTitle
|
||||
|
||||
return VerticalNavLink
|
||||
}
|
||||
|
||||
const VerticalNavItems = props => {
|
||||
// ** Props
|
||||
const { verticalNavItems } = props
|
||||
|
||||
const RenderMenuItems = verticalNavItems?.map((item, index) => {
|
||||
const TagName = resolveNavItemComponent(item)
|
||||
|
||||
return <TagName {...props} key={index} item={item} />
|
||||
})
|
||||
|
||||
return <>{RenderMenuItems}</>
|
||||
}
|
||||
|
||||
export default VerticalNavItems
|
@ -0,0 +1,119 @@
|
||||
// ** Next Imports
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
// ** MUI Imports
|
||||
import Chip from '@mui/material/Chip'
|
||||
import ListItem from '@mui/material/ListItem'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Box from '@mui/material/Box'
|
||||
import ListItemIcon from '@mui/material/ListItemIcon'
|
||||
import ListItemButton from '@mui/material/ListItemButton'
|
||||
|
||||
// ** Configs Import
|
||||
import themeConfig from 'src/configs/themeConfig'
|
||||
|
||||
// ** Custom Components Imports
|
||||
import UserIcon from 'src/layouts/components/UserIcon'
|
||||
|
||||
// ** Utils
|
||||
import { handleURLQueries } from 'src/@core/layouts/utils'
|
||||
|
||||
// ** Styled Components
|
||||
const MenuNavLink = styled(ListItemButton)(({ theme }) => ({
|
||||
width: '100%',
|
||||
borderTopRightRadius: 100,
|
||||
borderBottomRightRadius: 100,
|
||||
color: theme.palette.text.primary,
|
||||
padding: theme.spacing(2.25, 3.5),
|
||||
transition: 'opacity .25s ease-in-out',
|
||||
'&.active, &.active:hover': {
|
||||
boxShadow: theme.shadows[3],
|
||||
backgroundImage: `linear-gradient(98deg, ${theme.palette.customColors.primaryGradient}, ${theme.palette.primary.main} 94%)`
|
||||
},
|
||||
'&.active .MuiTypography-root, &.active .MuiSvgIcon-root': {
|
||||
color: `${theme.palette.common.white} !important`
|
||||
}
|
||||
}))
|
||||
|
||||
const MenuItemTextMetaWrapper = styled(Box)({
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
transition: 'opacity .25s ease-in-out',
|
||||
...(themeConfig.menuTextTruncate && { overflow: 'hidden' })
|
||||
})
|
||||
|
||||
const VerticalNavLink = ({ item, navVisible, toggleNavVisibility }) => {
|
||||
// ** Hooks
|
||||
const router = useRouter()
|
||||
const IconTag = item.icon
|
||||
|
||||
const isNavLinkActive = () => {
|
||||
if (router.pathname === item.path || handleURLQueries(router, item.path)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
disablePadding
|
||||
className='nav-link'
|
||||
disabled={item.disabled || false}
|
||||
sx={{ mt: 1.5, px: '0 !important' }}
|
||||
>
|
||||
<Link passHref href={item.path === undefined ? '/' : `${item.path}`}>
|
||||
<MenuNavLink
|
||||
component={'a'}
|
||||
className={isNavLinkActive() ? 'active' : ''}
|
||||
{...(item.openInNewTab ? { target: '_blank' } : null)}
|
||||
onClick={e => {
|
||||
if (item.path === undefined) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
if (navVisible) {
|
||||
toggleNavVisibility()
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
pl: 5.5,
|
||||
...(item.disabled ? { pointerEvents: 'none' } : { cursor: 'pointer' })
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
mr: 2.5,
|
||||
color: 'text.primary',
|
||||
transition: 'margin .25s ease-in-out'
|
||||
}}
|
||||
>
|
||||
<UserIcon icon={IconTag} />
|
||||
</ListItemIcon>
|
||||
|
||||
<MenuItemTextMetaWrapper>
|
||||
<Typography {...(themeConfig.menuTextTruncate && { noWrap: true })}>{item.title}</Typography>
|
||||
{item.badgeContent ? (
|
||||
<Chip
|
||||
label={item.badgeContent}
|
||||
color={item.badgeColor || 'primary'}
|
||||
sx={{
|
||||
height: 20,
|
||||
fontWeight: 500,
|
||||
marginLeft: 1.25,
|
||||
'& .MuiChip-label': { px: 1.5, textTransform: 'capitalize' }
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</MenuItemTextMetaWrapper>
|
||||
</MenuNavLink>
|
||||
</Link>
|
||||
</ListItem>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalNavLink
|
@ -0,0 +1,63 @@
|
||||
// ** MUI Imports
|
||||
import Divider from '@mui/material/Divider'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import MuiListSubheader from '@mui/material/ListSubheader'
|
||||
|
||||
// ** Styled Components
|
||||
const ListSubheader = styled(props => <MuiListSubheader component='li' {...props} />)(({ theme }) => ({
|
||||
lineHeight: 1,
|
||||
display: 'flex',
|
||||
position: 'relative',
|
||||
marginTop: theme.spacing(7),
|
||||
marginBottom: theme.spacing(2),
|
||||
backgroundColor: 'transparent',
|
||||
transition: 'padding-left .25s ease-in-out'
|
||||
}))
|
||||
|
||||
const TypographyHeaderText = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '0.75rem',
|
||||
lineHeight: 'normal',
|
||||
letterSpacing: '0.21px',
|
||||
textTransform: 'uppercase',
|
||||
color: theme.palette.text.disabled,
|
||||
fontWeight: theme.typography.fontWeightMedium
|
||||
}))
|
||||
|
||||
const VerticalNavSectionTitle = props => {
|
||||
// ** Props
|
||||
const { item } = props
|
||||
|
||||
// ** Hook
|
||||
const theme = useTheme()
|
||||
|
||||
return (
|
||||
<ListSubheader
|
||||
className='nav-section-title'
|
||||
sx={{
|
||||
px: 0,
|
||||
py: 1.75,
|
||||
color: theme.palette.text.disabled,
|
||||
'& .MuiDivider-root:before, & .MuiDivider-root:after, & hr': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.12)`
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Divider
|
||||
textAlign='left'
|
||||
sx={{
|
||||
m: 0,
|
||||
width: '100%',
|
||||
lineHeight: 'normal',
|
||||
textTransform: 'uppercase',
|
||||
'&:before, &:after': { top: 7, transform: 'none' },
|
||||
'& .MuiDivider-wrapper': { px: 2.5, fontSize: '0.75rem', letterSpacing: '0.21px' }
|
||||
}}
|
||||
>
|
||||
<TypographyHeaderText noWrap>{item.sectionTitle}</TypographyHeaderText>
|
||||
</Divider>
|
||||
</ListSubheader>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalNavSectionTitle
|
131
src/@core/layouts/components/vertical/navigation/index.js
Normal file
@ -0,0 +1,131 @@
|
||||
// ** React Import
|
||||
import { useRef, useState } from 'react'
|
||||
|
||||
// ** MUI Import
|
||||
import List from '@mui/material/List'
|
||||
import Box from '@mui/material/Box'
|
||||
import { styled, useTheme } from '@mui/material/styles'
|
||||
|
||||
// ** Third Party Components
|
||||
import PerfectScrollbar from 'react-perfect-scrollbar'
|
||||
|
||||
// ** Component Imports
|
||||
import Drawer from './Drawer'
|
||||
import VerticalNavItems from './VerticalNavItems'
|
||||
import VerticalNavHeader from './VerticalNavHeader'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from 'src/@core/utils/hex-to-rgba'
|
||||
|
||||
const StyledBoxForShadow = styled(Box)({
|
||||
top: 50,
|
||||
left: -8,
|
||||
zIndex: 2,
|
||||
height: 75,
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
pointerEvents: 'none',
|
||||
width: 'calc(100% + 15px)',
|
||||
'&.d-block': {
|
||||
display: 'block'
|
||||
}
|
||||
})
|
||||
|
||||
const Navigation = props => {
|
||||
// ** Props
|
||||
const {
|
||||
hidden,
|
||||
afterVerticalNavMenuContent,
|
||||
beforeVerticalNavMenuContent,
|
||||
verticalNavMenuContent: userVerticalNavMenuContent
|
||||
} = props
|
||||
|
||||
// ** States
|
||||
const [groupActive, setGroupActive] = useState([])
|
||||
const [currentActiveGroup, setCurrentActiveGroup] = useState([])
|
||||
|
||||
// ** Ref
|
||||
const shadowRef = useRef(null)
|
||||
|
||||
// ** Hooks
|
||||
const theme = useTheme()
|
||||
|
||||
// ** Fixes Navigation InfiniteScroll
|
||||
const handleInfiniteScroll = ref => {
|
||||
if (ref) {
|
||||
// @ts-ignore
|
||||
ref._getBoundingClientRect = ref.getBoundingClientRect
|
||||
ref.getBoundingClientRect = () => {
|
||||
// @ts-ignore
|
||||
const original = ref._getBoundingClientRect()
|
||||
|
||||
return { ...original, height: Math.floor(original.height) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ** Scroll Menu
|
||||
const scrollMenu = container => {
|
||||
container = hidden ? container.target : container
|
||||
if (shadowRef && container.scrollTop > 0) {
|
||||
// @ts-ignore
|
||||
if (!shadowRef.current.classList.contains('d-block')) {
|
||||
// @ts-ignore
|
||||
shadowRef.current.classList.add('d-block')
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
shadowRef.current.classList.remove('d-block')
|
||||
}
|
||||
}
|
||||
const ScrollWrapper = hidden ? Box : PerfectScrollbar
|
||||
|
||||
return (
|
||||
<Drawer {...props}>
|
||||
<VerticalNavHeader {...props} />
|
||||
<StyledBoxForShadow
|
||||
ref={shadowRef}
|
||||
sx={{
|
||||
background: `linear-gradient(${theme.palette.background.default} 40%,${hexToRGBA(
|
||||
theme.palette.background.default,
|
||||
0.1
|
||||
)} 95%,${hexToRGBA(theme.palette.background.default, 0.05)})`
|
||||
}}
|
||||
/>
|
||||
<Box sx={{ height: '100%', position: 'relative', overflow: 'hidden' }}>
|
||||
<ScrollWrapper
|
||||
{...(hidden
|
||||
? {
|
||||
onScroll: container => scrollMenu(container),
|
||||
sx: { height: '100%', overflowY: 'auto', overflowX: 'hidden' }
|
||||
}
|
||||
: {
|
||||
options: { wheelPropagation: false },
|
||||
onScrollY: container => scrollMenu(container),
|
||||
containerRef: ref => handleInfiniteScroll(ref)
|
||||
})}
|
||||
>
|
||||
{beforeVerticalNavMenuContent ? beforeVerticalNavMenuContent(props) : null}
|
||||
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
|
||||
{userVerticalNavMenuContent ? (
|
||||
userVerticalNavMenuContent(props)
|
||||
) : (
|
||||
<List className='nav-items' sx={{ transition: 'padding .25s ease', pr: 4.5 }}>
|
||||
<VerticalNavItems
|
||||
groupActive={groupActive}
|
||||
setGroupActive={setGroupActive}
|
||||
currentActiveGroup={currentActiveGroup}
|
||||
setCurrentActiveGroup={setCurrentActiveGroup}
|
||||
{...props}
|
||||
/>
|
||||
</List>
|
||||
)}
|
||||
</Box>
|
||||
</ScrollWrapper>
|
||||
</Box>
|
||||
{afterVerticalNavMenuContent ? afterVerticalNavMenuContent(props) : null}
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navigation
|
16
src/@core/layouts/utils.js
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Check for URL queries as well for matching
|
||||
* Current URL & Item Path
|
||||
*
|
||||
* @param item
|
||||
* @param activeItem
|
||||
*/
|
||||
export const handleURLQueries = (router, path) => {
|
||||
if (Object.keys(router.query).length && path) {
|
||||
const arr = Object.keys(router.query)
|
||||
|
||||
return router.asPath.includes(path) && router.asPath.includes(router.query[arr[0]]) && path !== '/'
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
103
src/@core/styles/libs/react-apexcharts/index.js
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// ** MUI imports
|
||||
import { styled } from '@mui/material/styles'
|
||||
|
||||
const ApexChartWrapper = styled('div')(({ theme }) => ({
|
||||
'& .apexcharts-canvas': {
|
||||
"& line[stroke='transparent']": {
|
||||
display: 'none'
|
||||
},
|
||||
'& .apexcharts-xaxis > line, & .apexcharts-yaxis > line': {
|
||||
stroke: theme.palette.divider
|
||||
},
|
||||
'& .apexcharts-xaxis-tick, & .apexcharts-yaxis-tick': {
|
||||
stroke: theme.palette.divider
|
||||
},
|
||||
'& .apexcharts-tooltip': {
|
||||
boxShadow: theme.shadows[3],
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.background.paper,
|
||||
'& .apexcharts-tooltip-title': {
|
||||
fontWeight: 600,
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.background.paper
|
||||
},
|
||||
'&.apexcharts-theme-dark': {
|
||||
'& .apexcharts-tooltip-text-label, & .apexcharts-tooltip-text-value': {
|
||||
color: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
'& .bar-chart': {
|
||||
padding: theme.spacing(2, 2.5)
|
||||
}
|
||||
},
|
||||
'& .apexcharts-xaxistooltip': {
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& .apexcharts-xaxistooltip-text': {
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'&:after': {
|
||||
borderBottomColor: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default
|
||||
},
|
||||
'&:before': {
|
||||
borderBottomColor: theme.palette.divider
|
||||
}
|
||||
},
|
||||
'& .apexcharts-yaxistooltip': {
|
||||
borderColor: theme.palette.divider,
|
||||
background: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& .apexcharts-yaxistooltip-text': {
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'&:after': {
|
||||
borderLeftColor: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default
|
||||
},
|
||||
'&:before': {
|
||||
borderLeftColor: theme.palette.divider
|
||||
}
|
||||
},
|
||||
'& .apexcharts-text, & .apexcharts-tooltip-text, & .apexcharts-datalabel-label, & .apexcharts-datalabel': {
|
||||
filter: 'none',
|
||||
fontWeight: 400,
|
||||
fill: theme.palette.text.primary,
|
||||
fontFamily: `${theme.typography.fontFamily} !important`
|
||||
},
|
||||
'& .apexcharts-pie-label': {
|
||||
filter: 'none',
|
||||
fill: theme.palette.common.white
|
||||
},
|
||||
'& .apexcharts-pie': {
|
||||
'& .apexcharts-datalabel-label, .apexcharts-datalabel-value': {
|
||||
fontSize: '1.5rem'
|
||||
}
|
||||
},
|
||||
'& .apexcharts-marker': {
|
||||
boxShadow: 'none'
|
||||
},
|
||||
'& .apexcharts-legend-series': {
|
||||
margin: `${theme.spacing(0.75, 2)} !important`,
|
||||
'& .apexcharts-legend-text': {
|
||||
marginLeft: theme.spacing(0.75),
|
||||
color: `${theme.palette.text.primary} !important`
|
||||
}
|
||||
},
|
||||
'& .apexcharts-xcrosshairs, & .apexcharts-ycrosshairs, & .apexcharts-gridline': {
|
||||
stroke: theme.palette.divider
|
||||
},
|
||||
'& .apexcharts-heatmap-rect': {
|
||||
stroke: theme.palette.mode === 'light' ? theme.palette.background.paper : theme.palette.background.default
|
||||
},
|
||||
'& .apexcharts-radialbar > g > g:first-of-type .apexcharts-radialbar-area': {
|
||||
stroke: theme.palette.background.default
|
||||
},
|
||||
'& .apexcharts-radar-series polygon': {
|
||||
stroke: theme.palette.divider,
|
||||
fill: theme.palette.background.paper
|
||||
},
|
||||
'& .apexcharts-radar-series line': {
|
||||
stroke: theme.palette.divider
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
export default ApexChartWrapper
|
358
src/@core/styles/libs/react-datepicker/index.js
vendored
Normal file
@ -0,0 +1,358 @@
|
||||
// ** MUI imports
|
||||
import { styled } from '@mui/material/styles'
|
||||
import Box from '@mui/material/Box'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from 'src/@core/utils/hex-to-rgba'
|
||||
|
||||
const DatePickerWrapper = styled(Box)(({ theme }) => {
|
||||
return {
|
||||
'& .react-datepicker-popper': {
|
||||
zIndex: 5
|
||||
},
|
||||
'& .react-datepicker-wrapper': {
|
||||
width: '100%'
|
||||
},
|
||||
'& .react-datepicker': {
|
||||
border: 'none',
|
||||
boxShadow: theme.shadows[7],
|
||||
padding: theme.spacing(2, 0),
|
||||
color: theme.palette.text.primary,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
fontFamily: theme.typography.fontFamily,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
'& .react-datepicker__header': {
|
||||
padding: 0,
|
||||
border: 'none',
|
||||
fontWeight: 'normal',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
'& .react-datepicker__day-name': {
|
||||
margin: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker-year-header': {
|
||||
lineHeight: 2.1,
|
||||
marginBottom: '0.5rem',
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'& .react-datepicker__triangle': {
|
||||
display: 'none'
|
||||
},
|
||||
'& > .react-datepicker__navigation': {
|
||||
top: theme.spacing(3),
|
||||
'&.react-datepicker__navigation--previous': {
|
||||
border: 'none',
|
||||
backgroundImage: `${"url('data:image/svg+xml,%3Csvg xmlns=\\'http://www.w3.org/2000/svg\\' style=\\'width:24px;height:24px\\' viewBox=\\'0 0 24 24\\'%3E%3Cpath fill=\\'currentColor\\' d=\\'M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z\\' /%3E%3C/svg%3E')"
|
||||
.replace('currentColor', theme.palette.text.secondary)
|
||||
.replace('#', '%23')}`,
|
||||
height: '24px',
|
||||
width: '24px',
|
||||
'& .react-datepicker__navigation-icon': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__navigation--next': {
|
||||
border: 'none',
|
||||
backgroundImage: `${"url('data:image/svg+xml,%3Csvg xmlns=\\'http://www.w3.org/2000/svg\\' style=\\'width:24px;height:24px\\' viewBox=\\'0 0 24 24\\'%3E%3Cpath fill=\\'currentColor\\' d=\\'M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z\\' /%3E%3C/svg%3E')"
|
||||
.replace('currentColor', theme.palette.text.secondary)
|
||||
.replace('#', '%23')}`,
|
||||
height: '24px',
|
||||
width: '24px',
|
||||
'& .react-datepicker__navigation-icon': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__navigation--next--with-time': {
|
||||
right: '122px'
|
||||
},
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__current-month': {
|
||||
lineHeight: 2.1,
|
||||
fontSize: '1rem',
|
||||
fontWeight: 'normal',
|
||||
letterSpacing: '0.15px',
|
||||
marginBottom: theme.spacing(2),
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'& .react-datepicker__day-name': {
|
||||
lineHeight: 1.5,
|
||||
width: '2.25rem',
|
||||
fontSize: '0.75rem',
|
||||
letterSpacing: '0.4px',
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
'& .react-datepicker__day': {
|
||||
margin: 0,
|
||||
width: '2.25rem',
|
||||
lineHeight: 2.75,
|
||||
height: '2.25rem',
|
||||
borderRadius: '50%',
|
||||
color: theme.palette.text.primary,
|
||||
'&.react-datepicker__day--selected, &.react-datepicker__day--keyboard-selected': {
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'&.react-datepicker__day--in-range, &.react-datepicker__day--in-selecting-range': {
|
||||
borderRadius: 0,
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: `${hexToRGBA(theme.palette.primary.main, 0.06)} !important`,
|
||||
'&:empty': {
|
||||
backgroundColor: 'transparent !important'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__day--selected.react-datepicker__day--in-selecting-range.react-datepicker__day--selecting-range-start, &.react-datepicker__day--selected.react-datepicker__day--range-start.react-datepicker__day--in-range, &.react-datepicker__day--range-start':
|
||||
{
|
||||
borderTopLeftRadius: '50%',
|
||||
borderBottomLeftRadius: '50%',
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'&.react-datepicker__day--range-end': {
|
||||
borderTopRightRadius: '50%',
|
||||
borderBottomRightRadius: '50%',
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
},
|
||||
'&.react-datepicker__day--outside-month': {
|
||||
height: 'auto'
|
||||
},
|
||||
'&.react-datepicker__day--outside-month, &.react-datepicker__day--disabled:not(.react-datepicker__day--selected)':
|
||||
{
|
||||
color: theme.palette.text.disabled,
|
||||
'&:hover': {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
},
|
||||
'&.react-datepicker__day--highlighted, &.react-datepicker__day--highlighted:hover': {
|
||||
color: theme.palette.success.main,
|
||||
backgroundColor: hexToRGBA(theme.palette.success.main, 0.12)
|
||||
},
|
||||
'&.react-datepicker__day--today': {
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__header__dropdown': {
|
||||
'& .react-datepicker__month-dropdown-container:not(:last-child)': {
|
||||
marginRight: theme.spacing(8)
|
||||
},
|
||||
'& .react-datepicker__month-dropdown-container, & .react-datepicker__year-dropdown-container': {
|
||||
marginBottom: theme.spacing(4)
|
||||
},
|
||||
'& .react-datepicker__month-read-view--selected-month, & .react-datepicker__year-read-view--selected-year': {
|
||||
fontSize: '0.875rem',
|
||||
marginRight: theme.spacing(1),
|
||||
color: theme.palette.text.primary
|
||||
},
|
||||
'& .react-datepicker__month-read-view:hover .react-datepicker__month-read-view--down-arrow, & .react-datepicker__year-read-view:hover .react-datepicker__year-read-view--down-arrow':
|
||||
{
|
||||
borderTopColor: theme.palette.text.secondary,
|
||||
borderRightColor: theme.palette.text.secondary
|
||||
},
|
||||
'& .react-datepicker__month-read-view--down-arrow, & .react-datepicker__year-read-view--down-arrow': {
|
||||
top: 4,
|
||||
borderTopColor: theme.palette.text.disabled,
|
||||
borderRightColor: theme.palette.text.disabled
|
||||
},
|
||||
'& .react-datepicker__month-dropdown, & .react-datepicker__year-dropdown': {
|
||||
paddingTop: theme.spacing(1.5),
|
||||
paddingBottom: theme.spacing(1.5),
|
||||
borderColor: theme.palette.divider,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
boxShadow: theme.palette.mode === 'light' ? theme.shadows[8] : theme.shadows[9]
|
||||
},
|
||||
'& .react-datepicker__month-option, & .react-datepicker__year-option': {
|
||||
paddingTop: theme.spacing(0.5),
|
||||
paddingBottom: theme.spacing(0.5),
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.action.hover
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__month-option.react-datepicker__month-option--selected_month': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.08),
|
||||
'&:hover': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.12)
|
||||
},
|
||||
'& .react-datepicker__month-option--selected': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__year-option.react-datepicker__year-option--selected_year': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.08),
|
||||
'&:hover': {
|
||||
backgroundColor: hexToRGBA(theme.palette.primary.main, 0.12)
|
||||
},
|
||||
'& .react-datepicker__year-option--selected': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__year-option': {
|
||||
// TODO: Remove some of the following styles for arrow in Year dropdown when react-datepicker give arrows in Year dropdown
|
||||
'& .react-datepicker__navigation--years-upcoming': {
|
||||
width: 9,
|
||||
height: 9,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '3px 3px 0 0',
|
||||
transform: 'rotate(-45deg)',
|
||||
borderTopColor: theme.palette.text.disabled,
|
||||
borderRightColor: theme.palette.text.disabled,
|
||||
margin: `${theme.spacing(2.75)} auto ${theme.spacing(0)}`
|
||||
},
|
||||
'&:hover .react-datepicker__navigation--years-upcoming': {
|
||||
borderTopColor: theme.palette.text.secondary,
|
||||
borderRightColor: theme.palette.text.secondary
|
||||
},
|
||||
'& .react-datepicker__navigation--years-previous': {
|
||||
width: 9,
|
||||
height: 9,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '0 0 3px 3px',
|
||||
transform: 'rotate(-45deg)',
|
||||
borderLeftColor: theme.palette.text.disabled,
|
||||
borderBottomColor: theme.palette.text.disabled,
|
||||
margin: `${theme.spacing(0)} auto ${theme.spacing(2.75)}`
|
||||
},
|
||||
'&:hover .react-datepicker__navigation--years-previous': {
|
||||
borderLeftColor: theme.palette.text.secondary,
|
||||
borderBottomColor: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__month': {
|
||||
marginTop: theme.spacing(3)
|
||||
},
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
'& .react-datepicker__month': {
|
||||
marginLeft: 0,
|
||||
marginRight: 0,
|
||||
marginBottom: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__month, & .react-datepicker__year': {
|
||||
'& .react-datepicker__month-text, & .react-datepicker__year-text, & .react-datepicker__quarter-text': {
|
||||
height: '2rem',
|
||||
alignItems: 'center',
|
||||
display: 'inline-flex',
|
||||
justifyContent: 'center',
|
||||
'&:hover': {
|
||||
borderRadius: theme.shape.borderRadius
|
||||
},
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__quarter--selected, & .react-datepicker__year-text--selected, & .react-datepicker__month--selected, & .react-datepicker__quarter-text--keyboard-selected, & .react-datepicker__month-text--keyboard-selected, & .react-datepicker__year-text--keyboard-selected':
|
||||
{
|
||||
color: theme.palette.common.white,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
},
|
||||
'& .react-datepicker__week-number': {
|
||||
fontWeight: 600,
|
||||
color: theme.palette.text.primary
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__year-wrapper': {
|
||||
maxWidth: 205,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
'& .react-datepicker__input-time-container': {
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
},
|
||||
'& .react-datepicker__today-button': {
|
||||
borderRadius: '1rem',
|
||||
margin: '0 1rem 0.3rem',
|
||||
color: theme.palette.common.white,
|
||||
backgroundColor: theme.palette.primary.main
|
||||
},
|
||||
|
||||
// ** Time Picker
|
||||
'& .react-datepicker__time-container': {
|
||||
borderLeftColor: theme.palette.divider
|
||||
},
|
||||
'&.react-datepicker--time-only, & .react-datepicker__time-container': {
|
||||
width: '7rem',
|
||||
padding: theme.spacing(1.2, 0),
|
||||
'& .react-datepicker-time__header': {
|
||||
marginBottom: theme.spacing(3),
|
||||
color: theme.palette.text.primary,
|
||||
fontSize: theme.typography.body2.fontSize
|
||||
},
|
||||
'& .react-datepicker__time': {
|
||||
background: theme.palette.background.paper,
|
||||
'& .react-datepicker__time-box .react-datepicker__time-list-item--disabled': {
|
||||
color: theme.palette.text.disabled
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__time-list-item': {
|
||||
lineHeight: 1.75,
|
||||
height: 'auto !important',
|
||||
marginLeft: theme.spacing(3.2),
|
||||
marginRight: theme.spacing(1.2),
|
||||
color: theme.palette.text.primary,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
'&:focus, &:active': {
|
||||
outline: 0
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: `${theme.palette.action.hover} !important`
|
||||
},
|
||||
'&.react-datepicker__time-list-item--selected': {
|
||||
color: `${theme.palette.common.white} !important`,
|
||||
backgroundColor: `${theme.palette.primary.main} !important`
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__time-box': {
|
||||
width: '100%'
|
||||
},
|
||||
'& .react-datepicker__time-list': {
|
||||
'&::-webkit-scrollbar': {
|
||||
width: 8
|
||||
},
|
||||
|
||||
/* Track */
|
||||
'&::-webkit-scrollbar-track': {
|
||||
background: theme.palette.background.paper
|
||||
},
|
||||
|
||||
/* Handle */
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
background: '#aaa',
|
||||
borderRadius: '10px'
|
||||
},
|
||||
|
||||
/* Handle on hover */
|
||||
'&::-webkit-scrollbar-thumb:hover': {
|
||||
background: '#999'
|
||||
}
|
||||
}
|
||||
},
|
||||
'&.react-datepicker--time-only .react-datepicker__time-container': {
|
||||
width: 'calc(7rem - 2px)'
|
||||
},
|
||||
'& .react-datepicker__day:hover, & .react-datepicker__month-text:hover, & .react-datepicker__quarter-text:hover, & .react-datepicker__year-text:hover':
|
||||
{
|
||||
backgroundColor: theme.palette.action.hover
|
||||
}
|
||||
},
|
||||
'& .react-datepicker__close-icon': {
|
||||
paddingRight: theme.spacing(4),
|
||||
'&:after': {
|
||||
width: 'unset',
|
||||
height: 'unset',
|
||||
fontSize: '1.5rem',
|
||||
color: theme.palette.text.primary,
|
||||
backgroundColor: 'transparent !important'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default DatePickerWrapper
|
49
src/@core/theme/ThemeComponent.js
Normal file
@ -0,0 +1,49 @@
|
||||
// ** MUI Imports
|
||||
import CssBaseline from '@mui/material/CssBaseline'
|
||||
import GlobalStyles from '@mui/material/GlobalStyles'
|
||||
import { ThemeProvider, createTheme, responsiveFontSizes } from '@mui/material/styles'
|
||||
|
||||
// ** Theme Config
|
||||
import themeConfig from 'src/configs/themeConfig'
|
||||
|
||||
// ** Theme Override Imports
|
||||
import overrides from './overrides'
|
||||
import typography from './typography'
|
||||
|
||||
// ** Theme
|
||||
import themeOptions from './ThemeOptions'
|
||||
|
||||
// ** Global Styles
|
||||
import GlobalStyling from './globalStyles'
|
||||
|
||||
const ThemeComponent = props => {
|
||||
// ** Props
|
||||
const { settings, children } = props
|
||||
|
||||
// ** Merged ThemeOptions of Core and User
|
||||
const coreThemeConfig = themeOptions(settings)
|
||||
|
||||
// ** Pass ThemeOptions to CreateTheme Function to create partial theme without component overrides
|
||||
let theme = createTheme(coreThemeConfig)
|
||||
|
||||
// ** Continue theme creation and pass merged component overrides to CreateTheme function
|
||||
theme = createTheme(theme, {
|
||||
components: { ...overrides(theme) },
|
||||
typography: { ...typography(theme) }
|
||||
})
|
||||
|
||||
// ** Set responsive font sizes to true
|
||||
if (themeConfig.responsiveFontSizes) {
|
||||
theme = responsiveFontSizes(theme)
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<GlobalStyles styles={() => GlobalStyling(theme)} />
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default ThemeComponent
|
54
src/@core/theme/ThemeOptions.js
Normal file
@ -0,0 +1,54 @@
|
||||
// ** MUI Theme Provider
|
||||
import { deepmerge } from '@mui/utils'
|
||||
|
||||
// ** Theme Override Imports
|
||||
import palette from './palette'
|
||||
import spacing from './spacing'
|
||||
import shadows from './shadows'
|
||||
import breakpoints from './breakpoints'
|
||||
|
||||
const themeOptions = settings => {
|
||||
// ** Vars
|
||||
const { mode, themeColor } = settings
|
||||
|
||||
const themeConfig = {
|
||||
palette: palette(mode, themeColor),
|
||||
typography: {
|
||||
fontFamily: [
|
||||
'Inter',
|
||||
'sans-serif',
|
||||
'-apple-system',
|
||||
'BlinkMacSystemFont',
|
||||
'"Segoe UI"',
|
||||
'Roboto',
|
||||
'"Helvetica Neue"',
|
||||
'Arial',
|
||||
'sans-serif',
|
||||
'"Apple Color Emoji"',
|
||||
'"Segoe UI Emoji"',
|
||||
'"Segoe UI Symbol"'
|
||||
].join(',')
|
||||
},
|
||||
shadows: shadows(mode),
|
||||
...spacing,
|
||||
breakpoints: breakpoints(),
|
||||
shape: {
|
||||
borderRadius: 6
|
||||
},
|
||||
mixins: {
|
||||
toolbar: {
|
||||
minHeight: 64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deepmerge(themeConfig, {
|
||||
palette: {
|
||||
primary: {
|
||||
...themeConfig.palette[themeColor]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default themeOptions
|
11
src/@core/theme/breakpoints/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
const breakpoints = () => ({
|
||||
values: {
|
||||
xs: 0,
|
||||
sm: 600,
|
||||
md: 900,
|
||||
lg: 1200,
|
||||
xl: 1536
|
||||
}
|
||||
})
|
||||
|
||||
export default breakpoints
|
43
src/@core/theme/globalStyles.js
Normal file
@ -0,0 +1,43 @@
|
||||
const GlobalStyles = theme => {
|
||||
return {
|
||||
'.ps__rail-y': {
|
||||
zIndex: 1,
|
||||
right: '0 !important',
|
||||
left: 'auto !important',
|
||||
'&:hover, &:focus, &.ps--clicking': {
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#E4E5EB !important' : '#423D5D !important'
|
||||
},
|
||||
'& .ps__thumb-y': {
|
||||
right: '3px !important',
|
||||
left: 'auto !important',
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#C2C4D1 !important' : '#504B6D !important'
|
||||
},
|
||||
'.layout-vertical-nav &': {
|
||||
'& .ps__thumb-y': {
|
||||
width: 4,
|
||||
backgroundColor: theme.palette.mode === 'light' ? '#C2C4D1 !important' : '#504B6D !important'
|
||||
},
|
||||
'&:hover, &:focus, &.ps--clicking': {
|
||||
backgroundColor: 'transparent !important',
|
||||
'& .ps__thumb-y': {
|
||||
width: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'#nprogress': {
|
||||
pointerEvents: 'none',
|
||||
'& .bar': {
|
||||
left: 0,
|
||||
top: 0,
|
||||
height: 3,
|
||||
width: '100%',
|
||||
zIndex: 2000,
|
||||
position: 'fixed',
|
||||
backgroundColor: theme.palette.primary.main
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GlobalStyles
|
46
src/@core/theme/overrides/accordion.js
Normal file
@ -0,0 +1,46 @@
|
||||
const Accordion = theme => {
|
||||
return {
|
||||
MuiAccordion: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&.Mui-disabled': {
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.12)`
|
||||
},
|
||||
'&.Mui-expanded': {
|
||||
boxShadow: theme.shadows[3]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAccordionSummary: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: `0 ${theme.spacing(5)}`,
|
||||
'& + .MuiCollapse-root': {
|
||||
'& .MuiAccordionDetails-root:first-child': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
content: {
|
||||
margin: `${theme.spacing(2.5)} 0`
|
||||
},
|
||||
expandIconWrapper: {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAccordionDetails: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiAccordionDetails-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Accordion
|
110
src/@core/theme/overrides/alerts.js
Normal file
@ -0,0 +1,110 @@
|
||||
import { lighten, darken } from '@mui/material/styles'
|
||||
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from 'src/@core/utils/hex-to-rgba'
|
||||
|
||||
const Alert = theme => {
|
||||
const getColor = theme.palette.mode === 'light' ? darken : lighten
|
||||
|
||||
return {
|
||||
MuiAlert: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 5,
|
||||
'& .MuiAlertTitle-root': {
|
||||
marginBottom: theme.spacing(1.6)
|
||||
},
|
||||
'& a': {
|
||||
color: 'inherit',
|
||||
fontWeight: 500
|
||||
}
|
||||
},
|
||||
standardSuccess: {
|
||||
color: getColor(theme.palette.success.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.success.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
}
|
||||
},
|
||||
standardInfo: {
|
||||
color: getColor(theme.palette.info.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.info.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
}
|
||||
},
|
||||
standardWarning: {
|
||||
color: getColor(theme.palette.warning.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.warning.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
}
|
||||
},
|
||||
standardError: {
|
||||
color: getColor(theme.palette.error.main, 0.12),
|
||||
backgroundColor: hexToRGBA(theme.palette.error.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedSuccess: {
|
||||
borderColor: theme.palette.success.main,
|
||||
color: getColor(theme.palette.success.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.success.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedInfo: {
|
||||
borderColor: theme.palette.info.main,
|
||||
color: getColor(theme.palette.info.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.info.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedWarning: {
|
||||
borderColor: theme.palette.warning.main,
|
||||
color: getColor(theme.palette.warning.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.warning.main, 0.12)
|
||||
}
|
||||
},
|
||||
outlinedError: {
|
||||
borderColor: theme.palette.error.main,
|
||||
color: getColor(theme.palette.error.main, 0.12),
|
||||
'& .MuiAlertTitle-root': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
},
|
||||
'& .MuiAlert-icon': {
|
||||
color: getColor(theme.palette.error.main, 0.12)
|
||||
}
|
||||
},
|
||||
filled: {
|
||||
fontWeight: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Alert
|
27
src/@core/theme/overrides/avatars.js
Normal file
@ -0,0 +1,27 @@
|
||||
const Avatar = theme => {
|
||||
return {
|
||||
MuiAvatar: {
|
||||
styleOverrides: {
|
||||
colorDefault: {
|
||||
color: theme.palette.text.secondary,
|
||||
backgroundColor: theme.palette.mode === 'light' ? theme.palette.grey[200] : theme.palette.grey[700]
|
||||
},
|
||||
rounded: {
|
||||
borderRadius: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAvatarGroup: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
justifyContent: 'flex-end',
|
||||
'.MuiCard-root & .MuiAvatar-root': {
|
||||
borderColor: theme.palette.background.paper
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Avatar
|
22
src/@core/theme/overrides/backdrop.js
Normal file
@ -0,0 +1,22 @@
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from 'src/@core/utils/hex-to-rgba'
|
||||
|
||||
const Backdrop = theme => {
|
||||
return {
|
||||
MuiBackdrop: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light'
|
||||
? `rgba(${theme.palette.customColors.main}, 0.7)`
|
||||
: hexToRGBA(theme.palette.background.default, 0.7)
|
||||
},
|
||||
invisible: {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Backdrop
|
50
src/@core/theme/overrides/button.js
Normal file
@ -0,0 +1,50 @@
|
||||
// ** Theme Config Imports
|
||||
import themeConfig from 'src/configs/themeConfig'
|
||||
|
||||
const Button = theme => {
|
||||
return {
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontWeight: 500,
|
||||
borderRadius: 5,
|
||||
lineHeight: 1.71,
|
||||
letterSpacing: '0.3px',
|
||||
padding: `${theme.spacing(1.875, 3)}`
|
||||
},
|
||||
contained: {
|
||||
boxShadow: theme.shadows[3],
|
||||
padding: `${theme.spacing(1.875, 5.5)}`
|
||||
},
|
||||
outlined: {
|
||||
padding: `${theme.spacing(1.625, 5.25)}`
|
||||
},
|
||||
sizeSmall: {
|
||||
padding: `${theme.spacing(1, 2.25)}`,
|
||||
'&.MuiButton-contained': {
|
||||
padding: `${theme.spacing(1, 3.5)}`
|
||||
},
|
||||
'&.MuiButton-outlined': {
|
||||
padding: `${theme.spacing(0.75, 3.25)}`
|
||||
}
|
||||
},
|
||||
sizeLarge: {
|
||||
padding: `${theme.spacing(2.125, 5.5)}`,
|
||||
'&.MuiButton-contained': {
|
||||
padding: `${theme.spacing(2.125, 6.5)}`
|
||||
},
|
||||
'&.MuiButton-outlined': {
|
||||
padding: `${theme.spacing(1.875, 6.25)}`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiButtonBase: {
|
||||
defaultProps: {
|
||||
disableRipple: themeConfig.disableRipple
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Button
|
83
src/@core/theme/overrides/card.js
Normal file
@ -0,0 +1,83 @@
|
||||
const Card = theme => {
|
||||
return {
|
||||
MuiCard: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
boxShadow: theme.shadows[6],
|
||||
'& .card-more-options': {
|
||||
marginTop: theme.spacing(-1),
|
||||
marginRight: theme.spacing(-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCardHeader: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiCardContent-root, & + .MuiCollapse-root .MuiCardContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'& .MuiCardHeader-subheader': {
|
||||
fontSize: '0.875rem'
|
||||
}
|
||||
},
|
||||
title: {
|
||||
lineHeight: 1,
|
||||
fontWeight: 500,
|
||||
fontSize: '1.25rem',
|
||||
letterSpacing: '0.0125em'
|
||||
},
|
||||
action: {
|
||||
marginTop: 0,
|
||||
marginRight: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCardContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiCardContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'&:last-of-type': {
|
||||
paddingBottom: theme.spacing(5)
|
||||
},
|
||||
'& + .MuiCardActions-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCardActions: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'&.card-action-dense': {
|
||||
padding: theme.spacing(0, 2.5, 2.5),
|
||||
'.MuiCard-root .MuiCardMedia-root + &': {
|
||||
paddingTop: theme.spacing(2.5)
|
||||
},
|
||||
'.MuiCard-root &:first-of-type': {
|
||||
paddingTop: theme.spacing(5),
|
||||
paddingBottom: theme.spacing(5),
|
||||
'& + .MuiCardContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'& + .MuiCardHeader-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .MuiButton-text': {
|
||||
paddingLeft: theme.spacing(2.5),
|
||||
paddingRight: theme.spacing(2.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Card
|
19
src/@core/theme/overrides/chip.js
Normal file
@ -0,0 +1,19 @@
|
||||
const Chip = theme => {
|
||||
return {
|
||||
MuiChip: {
|
||||
styleOverrides: {
|
||||
outlined: {
|
||||
'&.MuiChip-colorDefault': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
}
|
||||
},
|
||||
deleteIcon: {
|
||||
width: 18,
|
||||
height: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Chip
|
61
src/@core/theme/overrides/dateTimePicker.js
Normal file
@ -0,0 +1,61 @@
|
||||
const DateTimePicker = theme => {
|
||||
return {
|
||||
MuiCalendarPicker: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& [role="presentation"]': {
|
||||
fontWeight: 400,
|
||||
'& .PrivatePickersFadeTransitionGroup-root + .PrivatePickersFadeTransitionGroup-root > div': {
|
||||
marginRight: 0
|
||||
},
|
||||
'& .MuiIconButton-sizeSmall': {
|
||||
padding: theme.spacing(0.5)
|
||||
},
|
||||
'& + div .MuiIconButton-root:not(.Mui-disabled)': {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
},
|
||||
'& .PrivatePickersSlideTransition-root': {
|
||||
minHeight: 240
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiPickersDay: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontSize: '0.875rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiClockPicker: {
|
||||
styleOverrides: {
|
||||
arrowSwitcher: {
|
||||
'& .MuiIconButton-root:not(.Mui-disabled)': {
|
||||
color: theme.palette.text.secondary
|
||||
},
|
||||
'& + div': {
|
||||
'& > div': {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& ~ .MuiIconButton-root span.MuiTypography-caption': {
|
||||
color: 'inherit'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiMonthPicker: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& > .MuiTypography-root.Mui-selected': {
|
||||
fontSize: '1rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DateTimePicker
|
104
src/@core/theme/overrides/dialog.js
Normal file
@ -0,0 +1,104 @@
|
||||
// ** Util Import
|
||||
import { hexToRGBA } from 'src/@core/utils/hex-to-rgba'
|
||||
|
||||
const Dialog = theme => {
|
||||
return {
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
boxShadow: theme.shadows[6],
|
||||
'&:not(.MuiDialog-paperFullScreen)': {
|
||||
'@media (max-width:599px)': {
|
||||
margin: theme.spacing(4),
|
||||
width: `calc(100% - ${theme.spacing(8)})`,
|
||||
maxWidth: `calc(100% - ${theme.spacing(8)}) !important`
|
||||
}
|
||||
},
|
||||
'& > .MuiList-root': {
|
||||
paddingLeft: theme.spacing(1),
|
||||
paddingRight: theme.spacing(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiDialogTitle: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5)
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiDialogContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiDialogContent-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
'& + .MuiDialogActions-root': {
|
||||
paddingTop: 0
|
||||
},
|
||||
|
||||
// Styling for Mobile Date Picker starts
|
||||
'& .PrivatePickersToolbar-root': {
|
||||
padding: theme.spacing(4, 5),
|
||||
color: theme.palette.primary.contrastText,
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
'& .MuiTypography-root': {
|
||||
color: theme.palette.primary.contrastText
|
||||
},
|
||||
'& span.MuiTypography-overline': {
|
||||
fontSize: '1rem',
|
||||
lineHeight: '24px',
|
||||
letterSpacing: '0.15px'
|
||||
},
|
||||
'& ~ div[class^="css-"] > div[class^="css-"]': {
|
||||
marginTop: theme.spacing(6),
|
||||
marginBottom: theme.spacing(6),
|
||||
'& > div[class^="css-"]': {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.background.default,
|
||||
'& ~ .MuiIconButton-root span.MuiTypography-caption': {
|
||||
color: 'inherit'
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .PrivateTimePickerToolbar-hourMinuteLabel': {
|
||||
alignItems: 'center',
|
||||
'& > .MuiButton-root span.MuiTypography-root': {
|
||||
fontWeight: 300,
|
||||
lineHeight: '72px',
|
||||
fontSize: '3.75rem',
|
||||
letterSpacing: '-0.5px'
|
||||
},
|
||||
'& > .MuiTypography-root': {
|
||||
color: hexToRGBA(theme.palette.primary.contrastText, 0.54),
|
||||
'& + .MuiButton-root > span.MuiTypography-root': {
|
||||
color: hexToRGBA(theme.palette.primary.contrastText, 0.54)
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .PrivateTimePickerToolbar-ampmSelection span.MuiTypography-root:not(.Mui-selected)': {
|
||||
color: hexToRGBA(theme.palette.primary.contrastText, 0.54)
|
||||
}
|
||||
}
|
||||
|
||||
// Styling for Mobile Date Picker ends
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiDialogActions: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: theme.spacing(5),
|
||||
'&.dialog-actions-dense': {
|
||||
padding: theme.spacing(2.5),
|
||||
paddingTop: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Dialog
|
13
src/@core/theme/overrides/divider.js
Normal file
@ -0,0 +1,13 @@
|
||||
const Divider = theme => {
|
||||
return {
|
||||
MuiDivider: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
margin: `${theme.spacing(2)} 0`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Divider
|
85
src/@core/theme/overrides/index.js
Normal file
@ -0,0 +1,85 @@
|
||||
// ** Overrides Imports
|
||||
import MuiCard from './card'
|
||||
import MuiChip from './chip'
|
||||
import MuiLink from './link'
|
||||
import MuiList from './list'
|
||||
import MuiMenu from './menu'
|
||||
import MuiTabs from './tabs'
|
||||
import MuiInput from './input'
|
||||
import MuiPaper from './paper'
|
||||
import MuiTable from './table'
|
||||
import MuiAlerts from './alerts'
|
||||
import MuiButton from './button'
|
||||
import MuiDialog from './dialog'
|
||||
import MuiRating from './rating'
|
||||
import MuiSelect from './select'
|
||||
import MuiAvatar from './avatars'
|
||||
import MuiDivider from './divider'
|
||||
import MuiPopover from './popover'
|
||||
import MuiTooltip from './tooltip'
|
||||
import MuiBackdrop from './backdrop'
|
||||
import MuiSnackbar from './snackbar'
|
||||
import MuiSwitches from './switches'
|
||||
import MuiTimeline from './timeline'
|
||||
import MuiAccordion from './accordion'
|
||||
import MuiPagination from './pagination'
|
||||
import MuiTypography from './typography'
|
||||
import MuiToggleButton from './toggleButton'
|
||||
import MuiDateTimePicker from './dateTimePicker'
|
||||
|
||||
const Overrides = theme => {
|
||||
const chip = MuiChip(theme)
|
||||
const list = MuiList(theme)
|
||||
const menu = MuiMenu(theme)
|
||||
const tabs = MuiTabs(theme)
|
||||
const cards = MuiCard(theme)
|
||||
const input = MuiInput(theme)
|
||||
const tables = MuiTable(theme)
|
||||
const alerts = MuiAlerts(theme)
|
||||
const button = MuiButton(theme)
|
||||
const rating = MuiRating(theme)
|
||||
const avatars = MuiAvatar(theme)
|
||||
const divider = MuiDivider(theme)
|
||||
const dialog = MuiDialog(theme)
|
||||
const popover = MuiPopover(theme)
|
||||
const tooltip = MuiTooltip(theme)
|
||||
const backdrop = MuiBackdrop(theme)
|
||||
const snackbar = MuiSnackbar(theme)
|
||||
const switches = MuiSwitches(theme)
|
||||
const timeline = MuiTimeline(theme)
|
||||
const accordion = MuiAccordion(theme)
|
||||
const pagination = MuiPagination(theme)
|
||||
const dateTimePicker = MuiDateTimePicker(theme)
|
||||
|
||||
return Object.assign(
|
||||
chip,
|
||||
list,
|
||||
menu,
|
||||
tabs,
|
||||
cards,
|
||||
input,
|
||||
alerts,
|
||||
button,
|
||||
dialog,
|
||||
rating,
|
||||
tables,
|
||||
avatars,
|
||||
divider,
|
||||
MuiLink,
|
||||
popover,
|
||||
tooltip,
|
||||
backdrop,
|
||||
MuiPaper,
|
||||
snackbar,
|
||||
switches,
|
||||
timeline,
|
||||
accordion,
|
||||
MuiSelect,
|
||||
pagination,
|
||||
MuiTypography,
|
||||
dateTimePicker,
|
||||
MuiToggleButton
|
||||
)
|
||||
}
|
||||
|
||||
export default Overrides
|
62
src/@core/theme/overrides/input.js
Normal file
@ -0,0 +1,62 @@
|
||||
const input = theme => {
|
||||
return {
|
||||
MuiInputLabel: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: theme.palette.text.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
'&:hover:not(.Mui-disabled):before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.32)`
|
||||
},
|
||||
'&.Mui-disabled:before': {
|
||||
borderBottom: `1px solid ${theme.palette.text.disabled}`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiFilledInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.04)`,
|
||||
'&:hover:not(.Mui-disabled)': {
|
||||
backgroundColor: `rgba(${theme.palette.customColors.main}, 0.08)`
|
||||
},
|
||||
'&:before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
'&:hover:not(.Mui-disabled):before': {
|
||||
borderBottom: `1px solid rgba(${theme.palette.customColors.main}, 0.32)`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:hover:not(.Mui-focused) .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.32)`
|
||||
},
|
||||
'&:hover.Mui-error .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: theme.palette.error.main
|
||||
},
|
||||
'& .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: `rgba(${theme.palette.customColors.main}, 0.22)`
|
||||
},
|
||||
'&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: theme.palette.text.disabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default input
|
9
src/@core/theme/overrides/link.js
Normal file
@ -0,0 +1,9 @@
|
||||
export default {
|
||||
MuiLink: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
textDecoration: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|