add front-urban
This commit is contained in:
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
BACKEND_URL=http://localhost:3001
|
||||
NEXT_PUBLIC_BACKEND_URL=http://localhost:3001
|
||||
NEXT_PUBLIC_API_URL=http://localhost:3001
|
||||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||
NEXT_PUBLIC_MIN_AUTH=30
|
||||
REACT_EDITOR=code
|
||||
@@ -0,0 +1,128 @@
|
||||
module.exports = {
|
||||
extends: ['next/core-web-vitals', 'plugin:@typescript-eslint/recommended', 'plugin:import/recommended', 'prettier'],
|
||||
rules: {
|
||||
'jsx-a11y/alt-text': 'off',
|
||||
'react/display-name': 'off',
|
||||
'react/no-children-prop': 'off',
|
||||
'@next/next/no-img-element': 'off',
|
||||
'@next/next/no-page-custom-font': 'off',
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'lines-around-comment': [
|
||||
'error',
|
||||
{
|
||||
beforeBlockComment: true,
|
||||
beforeLineComment: true,
|
||||
allowBlockStart: true,
|
||||
allowObjectStart: true,
|
||||
allowArrayStart: true
|
||||
}
|
||||
],
|
||||
'padding-line-between-statements': [
|
||||
'error',
|
||||
{
|
||||
blankLine: 'any',
|
||||
prev: 'export',
|
||||
next: 'export'
|
||||
},
|
||||
{
|
||||
blankLine: 'always',
|
||||
prev: ['const', 'let', 'var'],
|
||||
next: '*'
|
||||
},
|
||||
{
|
||||
blankLine: 'any',
|
||||
prev: ['const', 'let', 'var'],
|
||||
next: ['const', 'let', 'var']
|
||||
},
|
||||
{
|
||||
blankLine: 'always',
|
||||
prev: '*',
|
||||
next: ['function', 'multiline-const', 'multiline-block-like']
|
||||
},
|
||||
{
|
||||
blankLine: 'always',
|
||||
prev: ['function', 'multiline-const', 'multiline-block-like'],
|
||||
next: '*'
|
||||
}
|
||||
],
|
||||
'newline-before-return': 'error',
|
||||
'import/newline-after-import': [
|
||||
'error',
|
||||
{
|
||||
count: 1
|
||||
}
|
||||
],
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
groups: ['builtin', 'external', ['internal', 'parent', 'sibling', 'index'], ['object', 'unknown']],
|
||||
pathGroups: [
|
||||
{
|
||||
pattern: 'react',
|
||||
group: 'external',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: 'next/**',
|
||||
group: 'external',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: '~/**',
|
||||
group: 'external',
|
||||
position: 'before'
|
||||
},
|
||||
{
|
||||
pattern: '@/**',
|
||||
group: 'internal'
|
||||
}
|
||||
],
|
||||
pathGroupsExcludedImportTypes: ['react', 'type'],
|
||||
'newlines-between': 'always-and-inside-groups'
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/ban-types': [
|
||||
'error',
|
||||
{
|
||||
extendDefaults: true,
|
||||
types: {
|
||||
Function: 'Use a specific function type instead',
|
||||
Object: 'Use object instead',
|
||||
Boolean: 'Use boolean instead',
|
||||
Number: 'Use number instead',
|
||||
String: 'Use string instead',
|
||||
Symbol: 'Use symbol instead',
|
||||
any: false,
|
||||
'{}': false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
},
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts', '.tsx']
|
||||
},
|
||||
'import/resolver': {
|
||||
node: {},
|
||||
typescript: {
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.tsx', 'src/iconify-bundle/*'],
|
||||
rules: {
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-var-requires': 'off'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# 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*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
.env
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# icon generated file
|
||||
src/assets/iconify-icons/generated-icons.js
|
||||
src/assets/iconify-icons/generated-icons.css
|
||||
@@ -0,0 +1,2 @@
|
||||
auto-install-peers=true
|
||||
shamefully-hoist=true
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"plugins": [
|
||||
"stylelint-use-logical-spec"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"customSyntax": "postcss-styled-syntax",
|
||||
"files": [
|
||||
"**/*.{js,ts,jsx,tsx}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"liberty/use-logical-spec": "always"
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
{
|
||||
// JavaScript Snippets
|
||||
"exportDefault": {
|
||||
"prefix": "exp",
|
||||
"body": [
|
||||
"export default ${1:moduleName}",
|
||||
""
|
||||
]
|
||||
},
|
||||
"exportDestructing": {
|
||||
"prefix": "exd",
|
||||
"body": [
|
||||
"export { ${2:destructuredModule} } from '${1:module}'",
|
||||
""
|
||||
]
|
||||
},
|
||||
"exportAs": {
|
||||
"prefix": "exa",
|
||||
"body": [
|
||||
"export { ${2:originalName} as ${3:aliasName}} from '${1:module}'",
|
||||
""
|
||||
]
|
||||
},
|
||||
"exportDefaultFunction": {
|
||||
"prefix": "edf",
|
||||
"body": [
|
||||
"export default (${1:params}) => {",
|
||||
" $0",
|
||||
"}",
|
||||
""
|
||||
]
|
||||
},
|
||||
"exportDefaultNamedFunction": {
|
||||
"prefix": "ednf",
|
||||
"body": [
|
||||
"export default function ${1:functionName}(${2:params}) {",
|
||||
" $0",
|
||||
"}",
|
||||
""
|
||||
]
|
||||
},
|
||||
// React Snippets
|
||||
"reactArrowFunctionExportComponent": {
|
||||
"prefix": "rafce",
|
||||
"body": [
|
||||
"const ${1:ComponentName} = () => {",
|
||||
" return (",
|
||||
" $0",
|
||||
" )",
|
||||
"}",
|
||||
"",
|
||||
"export default ${1:ComponentName}",
|
||||
""
|
||||
]
|
||||
},
|
||||
"reactArrowFunctionComponent": {
|
||||
"prefix": "rafc",
|
||||
"body": [
|
||||
"const ${1:ComponentName} = () => {",
|
||||
" return (",
|
||||
" $0",
|
||||
" )",
|
||||
"}",
|
||||
""
|
||||
]
|
||||
},
|
||||
"reactUseState": {
|
||||
"prefix": "useState",
|
||||
"body": [
|
||||
"const [${1:state}, set${1/(.*)/${1:/capitalize}/}] = useState(${2:initialState})"
|
||||
]
|
||||
},
|
||||
"reactUseEffect": {
|
||||
"prefix": "useEffect",
|
||||
"body": [
|
||||
"useEffect(() => {",
|
||||
" $0",
|
||||
"}, [])"
|
||||
]
|
||||
},
|
||||
// Type Snippets
|
||||
"exportType": {
|
||||
"prefix": "exptp",
|
||||
"body": [
|
||||
"export type ${1:Props} = {",
|
||||
" ${2:name}: ${3:string}",
|
||||
"}",
|
||||
""
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"prefix": "tp",
|
||||
"body": [
|
||||
"type ${1:Props} = {",
|
||||
" ${2:name}: ${3:string}",
|
||||
"}",
|
||||
""
|
||||
]
|
||||
},
|
||||
// Next Snippets
|
||||
"nextImport": {
|
||||
"prefix": "impn",
|
||||
"body": [
|
||||
"// Next Import",
|
||||
"import ${2:second} from '${1:first}'",
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"formulahendry.auto-close-tag",
|
||||
"steoates.autoimport",
|
||||
"mgmcdermott.vscode-language-babel",
|
||||
"aaron-bond.better-comments",
|
||||
"MohammadBaqer.better-folding",
|
||||
"pustelto.bracketeer",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"naumovs.color-highlight",
|
||||
"mikestead.dotenv",
|
||||
"EditorConfig.EditorConfig",
|
||||
"usernamehw.errorlens",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"eamodio.gitlens",
|
||||
"antfu.iconify",
|
||||
"xabikos.JavaScriptSnippets",
|
||||
"christian-kohler.npm-intellisense",
|
||||
"christian-kohler.path-intellisense",
|
||||
"esbenp.prettier-vscode",
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"jasonnutter.search-node-modules",
|
||||
"stylelint.vscode-stylelint",
|
||||
"styled-components.vscode-styled-components"
|
||||
]
|
||||
}
|
||||
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
// JS
|
||||
"javascript.updateImportsOnFileMove.enabled": "always",
|
||||
// JSON
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
},
|
||||
// VSCode Editor
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never",
|
||||
"source.fixAll.stylelint": "explicit"
|
||||
},
|
||||
// Extension: Git
|
||||
"git.rebaseWhenSync": true,
|
||||
"git.autofetch": true,
|
||||
"git.enableSmartCommit": true,
|
||||
// Extension: Prettier
|
||||
"prettier.requireConfig": true,
|
||||
// Extension: ESLint
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"typescript",
|
||||
"javascriptreact",
|
||||
"typescriptreact"
|
||||
],
|
||||
"eslint.format.enable": true,
|
||||
// Stylelint
|
||||
"css.validate": false,
|
||||
"less.validate": false,
|
||||
"scss.validate": false,
|
||||
"stylelint.enable": true,
|
||||
"stylelint.validate": [
|
||||
"css",
|
||||
"scss",
|
||||
"typescript",
|
||||
"typescriptreact"
|
||||
],
|
||||
"markdown.extension.toc.updateOnSave": false,
|
||||
"files.insertFinalNewline": true,
|
||||
"editor.linkedEditing": true,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"cSpell.words": [
|
||||
"iconify"
|
||||
],
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
FROM node:22.9-alpine AS base
|
||||
WORKDIR /app
|
||||
|
||||
FROM base AS deps
|
||||
RUN apk add --no-cache libc6-compat
|
||||
COPY package.json package-lock.json ./
|
||||
# Instalar dependencias (lockfile desactualizado). Luego podrás volver a npm ci cuando esté sincronizado.
|
||||
ENV npm_config_ignore_scripts=true
|
||||
RUN npm install --legacy-peer-deps
|
||||
ENV npm_config_ignore_scripts=false
|
||||
|
||||
FROM deps AS builder
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
COPY next.config.mjs ./next.config.mjs
|
||||
COPY tsconfig.json ./tsconfig.json
|
||||
COPY postcss.config.mjs ./postcss.config.mjs
|
||||
COPY tailwind.config.ts ./tailwind.config.ts
|
||||
COPY public ./public
|
||||
COPY src ./src
|
||||
COPY .env* ./
|
||||
|
||||
ENV NEXT_PUBLIC_BACKEND_URL=https://backend.cl-danzas.valentin-romero.online
|
||||
ENV NEXT_PUBLIC_API_URL=https://backend.cl-danzas.valentin-romero.online
|
||||
ENV NEXT_PUBLIC_APP_URL=https://frontend.cl-danzas.valentin-romero.online
|
||||
ENV NEXT_PUBLIC_MIN_AUTH=30
|
||||
ENV NEXT_PUBLIC_DOCS_URL=https://demos.themeselection.com/materio-mui-nextjs-admin-template/documentation
|
||||
ENV NEXT_PUBLIC_PRO_URL=https://demos.themeselection.com/materio-mui-nextjs-admin-template/demo-1
|
||||
ENV NEXT_PUBLIC_REPO_NAME=materio-mui-nextjs-admin-template-free
|
||||
ENV NEXT_PUBLIC_WHATSAPP_NUMBER=3434067735
|
||||
ENV REACT_EDITOR=code
|
||||
ENV BACKEND_URL=http://urban_backend:3001
|
||||
# Generate icons (was postinstall) then build Next.js with output tracing
|
||||
RUN npm run build:icons && npm run build
|
||||
|
||||
FROM builder AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
# Use non-root user
|
||||
RUN addgroup -g 1001 -S nodejs && adduser -S -u 1001 nodejs
|
||||
|
||||
# Copy only necessary runtime files
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
|
||||
ENV PORT=3000
|
||||
EXPOSE 3000
|
||||
USER nodejs
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
@@ -0,0 +1,10 @@
|
||||
node_modules
|
||||
.next
|
||||
.env*
|
||||
.git
|
||||
.gitignore
|
||||
Dockerfile*
|
||||
docker-compose*
|
||||
**/*.log
|
||||
coverage
|
||||
pnpm-lock.yaml
|
||||
@@ -0,0 +1 @@
|
||||
REACT_EDITOR=code
|
||||
@@ -0,0 +1,9 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'standalone',
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
Generated
+10491
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "next-app-test",
|
||||
"version": "0.1.0",
|
||||
"license": "Commercial",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"lint:fix": "next lint --fix",
|
||||
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
|
||||
"build:icons": "tsx src/assets/iconify-icons/bundle-icons-css.ts",
|
||||
"postinstall": "npm run build:icons"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@mui/icons-material": "^5.14.0",
|
||||
"@mui/lab": "5.0.0-alpha.170",
|
||||
"@mui/material": "^5.15.19",
|
||||
"@mui/material-nextjs": "^5.15.11",
|
||||
"axios": "^1.10.0",
|
||||
"classnames": "^2.5.1",
|
||||
"dayjs": "^1.11.14",
|
||||
"material-react-table": "^2.13.2",
|
||||
"next": "^14.2.3",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.3.8",
|
||||
"react-perfect-scrollbar": "^1.5.8",
|
||||
"react-apexcharts": "^1.8.0",
|
||||
"apexcharts": "^4.0.0",
|
||||
"@mui/x-date-pickers": "^6.20.0",
|
||||
"react-use": "^17.5.0",
|
||||
"recharts": "^3.5.0",
|
||||
"server-only": "^0.0.1",
|
||||
"swr": "^2.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.2.218",
|
||||
"@iconify/tools": "^4.0.4",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"@iconify/utils": "^2.1.24",
|
||||
"@types/node": "^20.14.2",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-dropzone": "^4.2.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.13.0",
|
||||
"@typescript-eslint/parser": "^7.13.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "^14.2.3",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss-styled-syntax": "^0.6.4",
|
||||
"prettier": "^3.3.2",
|
||||
"stylelint": "^16.6.1",
|
||||
"stylelint-use-logical-spec": "^5.0.1",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"tailwindcss-logical": "^3.0.1",
|
||||
"tsx": "^4.15.2",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"resolutions": {
|
||||
"rimraf": "^5.0.7"
|
||||
},
|
||||
"overrides": {
|
||||
"react": "^18.3.1",
|
||||
"rimraf": "^5.0.7"
|
||||
}
|
||||
}
|
||||
Generated
+5895
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
'tailwindcss/nesting': {},
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
||||
|
||||
export default config
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
||||
|
After Width: | Height: | Size: 629 B |
@@ -0,0 +1,51 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import { forwardRef } from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import MuiAvatar from '@mui/material/Avatar'
|
||||
import { lighten, styled } from '@mui/material/styles'
|
||||
import type { AvatarProps } from '@mui/material/Avatar'
|
||||
|
||||
// Type Imports
|
||||
import type { ThemeColor } from '@core/types'
|
||||
|
||||
export type CustomAvatarProps = AvatarProps & {
|
||||
color?: ThemeColor
|
||||
skin?: 'filled' | 'light' | 'light-static'
|
||||
size?: number
|
||||
}
|
||||
|
||||
const Avatar = styled(MuiAvatar)<CustomAvatarProps>(({ skin, color, size, theme }) => {
|
||||
return {
|
||||
...(color &&
|
||||
skin === 'light' && {
|
||||
backgroundColor: `var(--mui-palette-${color}-lightOpacity)`,
|
||||
color: `var(--mui-palette-${color}-main)`
|
||||
}),
|
||||
...(color &&
|
||||
skin === 'light-static' && {
|
||||
backgroundColor: lighten(theme.palette[color as ThemeColor].main, 0.84),
|
||||
color: `var(--mui-palette-${color}-main)`
|
||||
}),
|
||||
...(color &&
|
||||
skin === 'filled' && {
|
||||
backgroundColor: `var(--mui-palette-${color}-main)`,
|
||||
color: `var(--mui-palette-${color}-contrastText)`
|
||||
}),
|
||||
...(size && {
|
||||
height: size,
|
||||
width: size
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const CustomAvatar = forwardRef<HTMLDivElement, CustomAvatarProps>((props: CustomAvatarProps, ref) => {
|
||||
// Props
|
||||
const { color, skin = 'filled', ...rest } = props
|
||||
|
||||
return <Avatar color={color} skin={skin} ref={ref} {...rest} />
|
||||
})
|
||||
|
||||
export default CustomAvatar
|
||||
@@ -0,0 +1,75 @@
|
||||
'use client'
|
||||
|
||||
import MuiButton from '@mui/material/Button'
|
||||
import { styled } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const CustomIconButton = styled(MuiButton)(({ color, size, theme, variant }) => {
|
||||
return {
|
||||
minInlineSize: 0,
|
||||
...(size === 'small'
|
||||
? {
|
||||
fontSize: '20px',
|
||||
padding: theme.spacing(variant === 'outlined' ? 1 : 1.25),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
: {
|
||||
...(size === 'large'
|
||||
? {
|
||||
fontSize: '24px',
|
||||
padding: theme.spacing(variant === 'outlined' ? 2 : 2.25),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
: {
|
||||
fontSize: '22px',
|
||||
padding: theme.spacing(variant === 'outlined' ? 1.5 : 1.75),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
})
|
||||
}),
|
||||
...(!color && {
|
||||
color: 'var(--mui-palette-action-active)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
}
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
},
|
||||
...(variant === 'outlined' && {
|
||||
border: 'none !important',
|
||||
...(size === 'small'
|
||||
? {
|
||||
padding: theme.spacing(1.5)
|
||||
}
|
||||
: {
|
||||
...(size === 'large'
|
||||
? {
|
||||
padding: theme.spacing(2.25)
|
||||
}
|
||||
: {
|
||||
padding: theme.spacing(1.75)
|
||||
})
|
||||
})
|
||||
}),
|
||||
...(variant === 'contained' && {
|
||||
boxShadow: 'none !important',
|
||||
backgroundColor: 'transparent'
|
||||
})
|
||||
})
|
||||
}
|
||||
}) as typeof MuiButton
|
||||
|
||||
export default CustomIconButton
|
||||
@@ -0,0 +1,135 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import { useRef, useState } from 'react'
|
||||
import type { ReactElement, ReactNode, SyntheticEvent } from 'react'
|
||||
|
||||
// Next Imports
|
||||
import Link from 'next/link'
|
||||
|
||||
// MUI Imports
|
||||
import Tooltip from '@mui/material/Tooltip'
|
||||
import Box from '@mui/material/Box'
|
||||
import Popper from '@mui/material/Popper'
|
||||
import MenuItem from '@mui/material/MenuItem'
|
||||
import MenuList from '@mui/material/MenuList'
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener'
|
||||
import Fade from '@mui/material/Fade'
|
||||
import Paper from '@mui/material/Paper'
|
||||
import IconButton from '@mui/material/IconButton'
|
||||
import Divider from '@mui/material/Divider'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Type Imports
|
||||
import type { OptionsMenuType, OptionType, OptionMenuItemType } from './types'
|
||||
|
||||
const IconButtonWrapper = (props: Pick<OptionsMenuType, 'tooltipProps'> & { children: ReactElement }) => {
|
||||
// Props
|
||||
const { tooltipProps, children } = props
|
||||
|
||||
return tooltipProps?.title ? <Tooltip {...tooltipProps}>{children}</Tooltip> : children
|
||||
}
|
||||
|
||||
const MenuItemWrapper = ({ children, option }: { children: ReactNode; option: OptionMenuItemType }) => {
|
||||
if (option.href) {
|
||||
return (
|
||||
<Box component={Link} href={option.href} {...option.linkProps}>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
} else {
|
||||
return <>{children}</>
|
||||
}
|
||||
}
|
||||
|
||||
const OptionMenu = (props: OptionsMenuType) => {
|
||||
// Props
|
||||
const { tooltipProps, icon, iconClassName, options, leftAlignMenu, iconButtonProps } = props
|
||||
|
||||
// States
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
// Refs
|
||||
const anchorRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
const handleToggle = () => {
|
||||
setOpen(prevOpen => !prevOpen)
|
||||
}
|
||||
|
||||
const handleClose = (event: Event | SyntheticEvent) => {
|
||||
if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) {
|
||||
return
|
||||
}
|
||||
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButtonWrapper tooltipProps={tooltipProps}>
|
||||
<IconButton ref={anchorRef} size='small' onClick={handleToggle} {...iconButtonProps}>
|
||||
{typeof icon === 'string' ? (
|
||||
<i className={classnames(icon, iconClassName)} />
|
||||
) : (icon as ReactNode) ? (
|
||||
icon
|
||||
) : (
|
||||
<i className={classnames('ri-more-2-line', iconClassName)} />
|
||||
)}
|
||||
</IconButton>
|
||||
</IconButtonWrapper>
|
||||
<Popper
|
||||
open={open}
|
||||
anchorEl={anchorRef.current}
|
||||
placement={leftAlignMenu ? 'bottom-start' : 'bottom-end'}
|
||||
transition
|
||||
disablePortal
|
||||
sx={{ zIndex: 1 }}
|
||||
>
|
||||
{({ TransitionProps }) => (
|
||||
<Fade {...TransitionProps}>
|
||||
<Paper className='shadow-lg'>
|
||||
<ClickAwayListener onClickAway={handleClose}>
|
||||
<MenuList autoFocusItem={open}>
|
||||
{options.map((option: OptionType, index: number) => {
|
||||
if (typeof option === 'string') {
|
||||
return (
|
||||
<MenuItem key={index} onClick={handleClose}>
|
||||
{option}
|
||||
</MenuItem>
|
||||
)
|
||||
} else if ('divider' in option) {
|
||||
return option.divider && <Divider key={index} {...option.dividerProps} />
|
||||
} else {
|
||||
return (
|
||||
<MenuItem
|
||||
key={index}
|
||||
{...option.menuItemProps}
|
||||
{...(option.href && { className: 'p-0' })}
|
||||
onClick={e => {
|
||||
handleClose(e)
|
||||
option.menuItemProps && option.menuItemProps.onClick
|
||||
? option.menuItemProps.onClick(e)
|
||||
: null
|
||||
}}
|
||||
>
|
||||
<MenuItemWrapper option={option}>
|
||||
{(typeof option.icon === 'string' ? <i className={option.icon} /> : option.icon) || null}
|
||||
{option.text}
|
||||
</MenuItemWrapper>
|
||||
</MenuItem>
|
||||
)
|
||||
}
|
||||
})}
|
||||
</MenuList>
|
||||
</ClickAwayListener>
|
||||
</Paper>
|
||||
</Fade>
|
||||
)}
|
||||
</Popper>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default OptionMenu
|
||||
@@ -0,0 +1,42 @@
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
// Next Imports
|
||||
import type { LinkProps } from 'next/link'
|
||||
|
||||
// MUI Imports
|
||||
import type { IconButtonProps } from '@mui/material/IconButton'
|
||||
import type { MenuItemProps } from '@mui/material/MenuItem'
|
||||
import type { DividerProps } from '@mui/material/Divider'
|
||||
import type { BoxProps } from '@mui/material/Box'
|
||||
import type { TooltipProps } from '@mui/material/Tooltip'
|
||||
|
||||
export type OptionDividerType = {
|
||||
divider: boolean
|
||||
dividerProps?: DividerProps
|
||||
href?: never
|
||||
icon?: never
|
||||
text?: never
|
||||
linkProps?: never
|
||||
menuItemProps?: never
|
||||
}
|
||||
export type OptionMenuItemType = {
|
||||
text: ReactNode
|
||||
icon?: ReactNode
|
||||
linkProps?: BoxProps
|
||||
href?: LinkProps['href']
|
||||
menuItemProps?: MenuItemProps
|
||||
divider?: never
|
||||
dividerProps?: never
|
||||
}
|
||||
|
||||
export type OptionType = string | OptionDividerType | OptionMenuItemType
|
||||
|
||||
export type OptionsMenuType = {
|
||||
tooltipProps?: Omit<TooltipProps, 'children'>
|
||||
icon?: ReactNode
|
||||
iconClassName?: string
|
||||
options: OptionType[]
|
||||
leftAlignMenu?: boolean
|
||||
iconButtonProps?: IconButtonProps
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
import { createContext, useMemo, useState } from 'react'
|
||||
|
||||
// Type Imports
|
||||
import type { Mode } from '@core/types'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
// Hook Imports
|
||||
import { useObjectCookie } from '@core/hooks/useObjectCookie'
|
||||
|
||||
// Settings type
|
||||
export type Settings = {
|
||||
mode?: Mode
|
||||
}
|
||||
|
||||
// UpdateSettingsOptions type
|
||||
type UpdateSettingsOptions = {
|
||||
updateCookie?: boolean
|
||||
}
|
||||
|
||||
// SettingsContextProps type
|
||||
type SettingsContextProps = {
|
||||
settings: Settings
|
||||
updateSettings: (settings: Partial<Settings>, options?: UpdateSettingsOptions) => void
|
||||
isSettingsChanged: boolean
|
||||
resetSettings: () => void
|
||||
updatePageSettings: (settings: Partial<Settings>) => () => void
|
||||
}
|
||||
|
||||
type Props = {
|
||||
children: ReactNode
|
||||
settingsCookie: Settings | null
|
||||
mode?: Mode
|
||||
}
|
||||
|
||||
// Initial Settings Context
|
||||
export const SettingsContext = createContext<SettingsContextProps | null>(null)
|
||||
|
||||
// Settings Provider
|
||||
export const SettingsProvider = (props: Props) => {
|
||||
// Initial Settings
|
||||
const initialSettings: Settings = {
|
||||
mode: themeConfig.mode
|
||||
}
|
||||
|
||||
const updatedInitialSettings = {
|
||||
...initialSettings,
|
||||
mode: props.mode || themeConfig.mode
|
||||
}
|
||||
|
||||
// Cookies
|
||||
const [settingsCookie, updateSettingsCookie] = useObjectCookie<Settings>(
|
||||
themeConfig.settingsCookieName,
|
||||
JSON.stringify(props.settingsCookie) !== '{}' ? props.settingsCookie : updatedInitialSettings
|
||||
)
|
||||
|
||||
// State
|
||||
const [_settingsState, _updateSettingsState] = useState<Settings>(
|
||||
JSON.stringify(settingsCookie) !== '{}' ? settingsCookie : updatedInitialSettings
|
||||
)
|
||||
|
||||
const updateSettings = (settings: Partial<Settings>, options?: UpdateSettingsOptions) => {
|
||||
const { updateCookie = true } = options || {}
|
||||
|
||||
_updateSettingsState(prev => {
|
||||
const newSettings = { ...prev, ...settings }
|
||||
|
||||
// Update cookie if needed
|
||||
if (updateCookie) updateSettingsCookie(newSettings)
|
||||
|
||||
return newSettings
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the settings for page with the provided settings object.
|
||||
* Updated settings won't be saved to cookie hence will be reverted once navigating away from the page.
|
||||
*
|
||||
* @param settings - The partial settings object containing the properties to update.
|
||||
* @returns A function to reset the page settings.
|
||||
*
|
||||
* @example
|
||||
* useEffect(() => {
|
||||
* return updatePageSettings({ theme: 'dark' });
|
||||
* }, []);
|
||||
*/
|
||||
const updatePageSettings = (settings: Partial<Settings>): (() => void) => {
|
||||
updateSettings(settings, { updateCookie: false })
|
||||
|
||||
// Returns a function to reset the page settings
|
||||
return () => updateSettings(settingsCookie, { updateCookie: false })
|
||||
}
|
||||
|
||||
const resetSettings = () => {
|
||||
updateSettings(initialSettings)
|
||||
}
|
||||
|
||||
const isSettingsChanged = useMemo(
|
||||
() => JSON.stringify(initialSettings) !== JSON.stringify(_settingsState),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[_settingsState]
|
||||
)
|
||||
|
||||
return (
|
||||
<SettingsContext.Provider
|
||||
value={{
|
||||
settings: _settingsState,
|
||||
updateSettings,
|
||||
isSettingsChanged,
|
||||
resetSettings,
|
||||
updatePageSettings
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</SettingsContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export const downloadInvoicePdf = async (invoiceId: string) => {
|
||||
const response = await apiClient.get(
|
||||
`/invoices/download/${invoiceId}`,
|
||||
{ responseType: 'blob' }
|
||||
);
|
||||
|
||||
const blob = new Blob([response.data], { type: 'application/pdf' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `factura-${invoiceId}.pdf`;
|
||||
a.click();
|
||||
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
// src/@core/hooks/useAccessLogs.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
|
||||
export type AccessLog = {
|
||||
id: string;
|
||||
userId: string;
|
||||
direction: 'INGRESS' | 'EGRESS';
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
export type ResponseAccessLogs = {
|
||||
userId: string;
|
||||
name: string;
|
||||
accessLogs: AccessLog[];
|
||||
};
|
||||
|
||||
export function useAccessLogs(userId?: string, date?: string, enabled: boolean = true) {
|
||||
const { token } = useUserAuth();
|
||||
const [data, setData] = useState<ResponseAccessLogs | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(
|
||||
async (signal?: AbortSignal) => {
|
||||
if (!enabled || !userId || !date) return;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const res = await apiClient.get<ResponseAccessLogs>('/attendance', {
|
||||
params: { userId, date },
|
||||
signal,
|
||||
});
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError') return;
|
||||
setError(e?.response?.data?.message ?? 'No se pudieron cargar los registros de acceso.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[enabled, userId, date, token]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const ctrl = new AbortController();
|
||||
fetchData(ctrl.signal);
|
||||
return () => ctrl.abort();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refresh: fetchData };
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// src/@core/hooks/useAttendeesSnapshot.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
|
||||
export type ResponseAttendeesSnapshot = {
|
||||
dateRange: { start: string; end: string };
|
||||
instructors: { id: string; name: string }[];
|
||||
assistants: { id: string; name: string }[];
|
||||
attendance: { id: string; name: string }[];
|
||||
};
|
||||
|
||||
export function useAttendeesSnapshot(snapshotId?: string, enabled: boolean = true) {
|
||||
const { token } = useUserAuth();
|
||||
const [data, setData] = useState<ResponseAttendeesSnapshot | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(
|
||||
async (signal?: AbortSignal) => {
|
||||
if (!enabled || !snapshotId) return;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const res = await apiClient.get<ResponseAttendeesSnapshot>(
|
||||
`/sessions/${snapshotId}/attendees`,
|
||||
{ signal }
|
||||
);
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError') return;
|
||||
setError(e?.response?.data?.message ?? 'No se pudieron cargar los asistentes.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[enabled, snapshotId, token]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const ctrl = new AbortController();
|
||||
fetchData(ctrl.signal);
|
||||
return () => ctrl.abort();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refresh: fetchData };
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// useClases.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { Clase } from '@/views/clases/DetailClaseDialog';
|
||||
|
||||
type Options = {
|
||||
/** Lanza el fetch al montar el hook (default: true) */
|
||||
auto?: boolean;
|
||||
/** Filtro de estado: 'all', 'active', 'inactive' */
|
||||
status?: 'all' | 'active' | 'inactive';
|
||||
};
|
||||
|
||||
type UseClasesResult = {
|
||||
data: Clase[];
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
/** Vuelve a pedir la lista */
|
||||
refresh: () => Promise<void>;
|
||||
/** Setea manualmente el array (útil para optimist updates) */
|
||||
setData: React.Dispatch<React.SetStateAction<Clase[]>>;
|
||||
};
|
||||
|
||||
export function useClases(opts: Options = {}): UseClasesResult {
|
||||
const { auto = true, status = 'all' } = opts;
|
||||
|
||||
const [data, setData] = useState<Clase[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
// guardamos una referencia al abortController para cancelar en unmount
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// cancelar request previa si hubiera
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
const params = status && status !== 'all' ? { status } : undefined;
|
||||
const res = await apiClient.get<Clase[]>('/sessions', { params, signal: ac.signal });
|
||||
setData(res.data ?? []);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
console.error('Error al obtener clases:', e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => {
|
||||
// cancelar si el componente se desmonta
|
||||
abortRef.current?.abort();
|
||||
};
|
||||
}, [auto, refresh]);
|
||||
|
||||
return { data, loading, error, refresh, setData };
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// useDashboard.ts
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import apiClient from '@/lib/apiClient'
|
||||
import { useUserAuth } from '@/app/context/UserAuth'
|
||||
|
||||
export type DashboardUser = {
|
||||
message: string
|
||||
accessLog: { currentAccess: string; lastAccess: string }
|
||||
cardDetails: { sessions: number; users: number; assistants: number; revenue: number }
|
||||
sessions: { id: string; description: string; instructors: string; startDate: string }[]
|
||||
}
|
||||
|
||||
type Options = {
|
||||
auto?: boolean
|
||||
}
|
||||
|
||||
type UseDashboardResult = {
|
||||
data: DashboardUser | null
|
||||
loading: boolean
|
||||
error: unknown
|
||||
refresh: () => Promise<void>
|
||||
}
|
||||
|
||||
export function useDashboard(opts: Options = {}): UseDashboardResult {
|
||||
const { token } = useUserAuth()
|
||||
const { auto = true } = opts
|
||||
|
||||
const [data, setData] = useState<DashboardUser | null>(null)
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [error, setError] = useState<unknown>(null)
|
||||
|
||||
const abortRef = useRef<AbortController | null>(null)
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
// si no hay token aún, no pidas nada ni cambies loading
|
||||
if (!token) return
|
||||
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
abortRef.current?.abort()
|
||||
const ac = new AbortController()
|
||||
abortRef.current = ac
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<DashboardUser>('/dashboard', { signal: ac.signal })
|
||||
setData(res.data ?? null)
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return
|
||||
setError(e)
|
||||
console.error('Error al obtener dashboard:', e)
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false)
|
||||
}
|
||||
}, [token]) // ← incluye token!
|
||||
|
||||
useEffect(() => {
|
||||
if (auto && token) refresh() // ← solo cuando haya token
|
||||
return () => abortRef.current?.abort()
|
||||
}, [auto, token, refresh]) // ← depende de token también
|
||||
|
||||
return { data, loading, error, refresh }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// React Imports
|
||||
import { useMemo } from 'react'
|
||||
|
||||
// Third-party imports
|
||||
import { useColorScheme } from '@mui/material'
|
||||
|
||||
// Type imports
|
||||
import type { Mode } from '@core/types'
|
||||
|
||||
export const useImageVariant = (mode: Mode, imgLight: string, imgDark: string): string => {
|
||||
// Hooks
|
||||
const { mode: muiMode } = useColorScheme()
|
||||
|
||||
return useMemo(() => {
|
||||
const isServer = typeof window === 'undefined'
|
||||
|
||||
const currentMode = (() => {
|
||||
if (isServer) return mode
|
||||
|
||||
return muiMode
|
||||
})()
|
||||
|
||||
const isDarkMode = currentMode === 'dark'
|
||||
|
||||
return isDarkMode ? imgDark : imgLight
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [mode, muiMode])
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// src/@core/hooks/useInstructors.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
import type { Instructor } from '@/app/modules/users/dto/instructor.dto';
|
||||
|
||||
type UseInstructorsResult = {
|
||||
data: Instructor[];
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para obtener la lista de instructores.
|
||||
* - Lee el token del contexto.
|
||||
* - Maneja estados data/loading/error.
|
||||
* - Cancela la request al desmontar.
|
||||
*/
|
||||
export function useInstructors(enabled: boolean = true): UseInstructorsResult {
|
||||
const { token } = useUserAuth();
|
||||
|
||||
const [data, setData] = useState<Instructor[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fetchData = useCallback(
|
||||
async (signal?: AbortSignal) => {
|
||||
if (!token) {
|
||||
setData([]);
|
||||
setLoading(false);
|
||||
setError(null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const res = await apiClient.get<Instructor[]>('/users/instructor', { signal });
|
||||
|
||||
setData(res.data ?? []);
|
||||
} catch (err: any) {
|
||||
if (err?.name !== 'CanceledError') {
|
||||
const msg =
|
||||
err?.response?.data?.message ||
|
||||
err?.message ||
|
||||
'Error al obtener instructores.';
|
||||
setError(msg);
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[token]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
const ctrl = new AbortController();
|
||||
fetchData(ctrl.signal);
|
||||
return () => ctrl.abort();
|
||||
}, [enabled, fetchData]);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
await fetchData();
|
||||
}, [fetchData]);
|
||||
|
||||
return { data, loading, error, refresh };
|
||||
}
|
||||
|
||||
export default useInstructors;
|
||||
@@ -0,0 +1,68 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
export type InvoiceStatus = 'PENDING' | 'PAID' | 'FAILED' | 'CANCELED';
|
||||
|
||||
export type InvoiceWithDescription = {
|
||||
id: string;
|
||||
subscriptionId: string;
|
||||
base64Invoice: string | null;
|
||||
linkPayment: string | null;
|
||||
status: InvoiceStatus | string;
|
||||
amount: number;
|
||||
createdAt: string | Date;
|
||||
updatedAt: string | Date;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type UseInvoicesOptions = {
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
export type UseInvoicesResult = {
|
||||
data: InvoiceWithDescription[];
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
refresh: () => Promise<void>;
|
||||
setData: React.Dispatch<React.SetStateAction<InvoiceWithDescription[]>>;
|
||||
};
|
||||
|
||||
export function useInvoices(
|
||||
userId: string,
|
||||
opts: UseInvoicesOptions = {}
|
||||
): UseInvoicesResult {
|
||||
const { auto = true } = opts;
|
||||
|
||||
const [data, setData] = useState<InvoiceWithDescription[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!userId) return;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<InvoiceWithDescription[] | null>(`/invoices/${encodeURIComponent(userId)}`, { signal: ac.signal });
|
||||
setData((res.data ?? []) as InvoiceWithDescription[]);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, [userId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => abortRef.current?.abort();
|
||||
}, [auto, refresh, userId]);
|
||||
|
||||
return { data, loading, error, refresh, setData };
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// React Imports
|
||||
import { useMemo } from 'react'
|
||||
|
||||
// Third-party Imports
|
||||
import { useCookie } from 'react-use'
|
||||
|
||||
export const useObjectCookie = <T>(key: string, fallback?: T | null): [T, (newVal: T) => void] => {
|
||||
// Hooks
|
||||
const [valStr, updateCookie] = useCookie(key)
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const value = useMemo<T>(() => (valStr ? JSON.parse(valStr) : fallback), [valStr])
|
||||
|
||||
const updateValue = (newVal: T) => {
|
||||
updateCookie(JSON.stringify(newVal))
|
||||
}
|
||||
|
||||
return [value, updateValue]
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export type ProfilePictureResponse = {
|
||||
profilePicture: string | null;
|
||||
updatedAt: string | null;
|
||||
};
|
||||
|
||||
export type UseProfilePictureOptions = {
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
export type UseProfilePictureResult = {
|
||||
profilePicture: string | null;
|
||||
updatedAt: string | null;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para obtener la foto de perfil de un usuario
|
||||
*
|
||||
* @param userId - ID del usuario
|
||||
* @param options - Opciones de configuración
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { profilePicture, loading, error, refresh } = useProfilePicture('user-123', { auto: true });
|
||||
*
|
||||
* return (
|
||||
* <img src={profilePicture || '/default-avatar.png'} alt="Profile" />
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export function useProfilePicture(
|
||||
userId: string,
|
||||
options: UseProfilePictureOptions = {}
|
||||
): UseProfilePictureResult {
|
||||
const { auto = true } = options;
|
||||
|
||||
const [profilePicture, setProfilePicture] = useState<string | null>(null);
|
||||
const [updatedAt, setUpdatedAt] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!userId) return;
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<ProfilePictureResponse>(`/users/${encodeURIComponent(userId)}/profile-picture`);
|
||||
|
||||
setProfilePicture(res.data.profilePicture);
|
||||
setUpdatedAt(res.data.updatedAt);
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
setProfilePicture(null);
|
||||
setUpdatedAt(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [userId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto && userId) {
|
||||
refresh();
|
||||
}
|
||||
}, [auto, userId, refresh]);
|
||||
|
||||
return {
|
||||
profilePicture,
|
||||
updatedAt,
|
||||
loading,
|
||||
error,
|
||||
refresh,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// useSessionInvoicesByMonth.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export type InvoiceStatus = 'PENDING' | 'PAID' | 'CANCELED';
|
||||
|
||||
export type AssistantInvoice = {
|
||||
id: string;
|
||||
name: string;
|
||||
hasInvoice: boolean;
|
||||
invoiceStatus: InvoiceStatus | null;
|
||||
invoiceId: string | null;
|
||||
amount: number | null;
|
||||
};
|
||||
|
||||
export type SessionInvoicesByMonth = {
|
||||
sessionId: string;
|
||||
sessionCustomId: string;
|
||||
sessionDescription: string;
|
||||
sessionType: string;
|
||||
month: string;
|
||||
year: string;
|
||||
assistants: AssistantInvoice[];
|
||||
};
|
||||
|
||||
type Options = {
|
||||
sessionId: string;
|
||||
month: string; // "01" a "12"
|
||||
year: string; // "YYYY"
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
type UseSessionInvoicesByMonthResult = {
|
||||
data: SessionInvoicesByMonth | null;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
refresh: () => Promise<void>;
|
||||
};
|
||||
|
||||
export function useSessionInvoicesByMonth(
|
||||
opts: Options
|
||||
): UseSessionInvoicesByMonthResult {
|
||||
const { sessionId, month, year, auto = true } = opts;
|
||||
|
||||
const [data, setData] = useState<SessionInvoicesByMonth | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!sessionId || !month || !year) {
|
||||
setData(null);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// Cancelar request previa si hubiera
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<SessionInvoicesByMonth>(
|
||||
`/sessions/${sessionId}/invoices-by-month`,
|
||||
{ params: { month, year }, signal: ac.signal }
|
||||
);
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
console.error('Error al obtener facturas por mes:', e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, [sessionId, month, year]);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => {
|
||||
abortRef.current?.abort();
|
||||
};
|
||||
}, [auto, refresh]);
|
||||
|
||||
return { data, loading, error, refresh };
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// useSessionParticipants.ts
|
||||
'use client';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
export type Participant = { id: string; name: string; customId?: string };
|
||||
|
||||
export function useSessionParticipants(token: string, sessionId: string, auto = true) {
|
||||
const [selected, setSelected] = useState<Participant[]>([]);
|
||||
const [available, setAvailable] = useState<Participant[]>([]);
|
||||
const [loading, setLoading] = useState(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true); setError(null);
|
||||
try {
|
||||
const { data } = await apiClient.get(`/sessions/${sessionId}/participants`);
|
||||
setSelected(data.selected);
|
||||
setAvailable(data.available);
|
||||
} catch (e) { setError(e); } finally { setLoading(false); }
|
||||
}, [sessionId]);
|
||||
|
||||
const save = useCallback(async () => {
|
||||
await apiClient.put(`/sessions/${sessionId}/participants`, {
|
||||
userIds: selected.map(s => s.id),
|
||||
});
|
||||
}, [sessionId, selected]);
|
||||
|
||||
useEffect(() => { if (auto) refresh(); }, [auto, refresh]);
|
||||
|
||||
// helpers UI
|
||||
const add = (p: Participant) => {
|
||||
setAvailable(prev => prev.filter(x => x.id !== p.id));
|
||||
setSelected(prev => [...prev, p]);
|
||||
};
|
||||
const remove = (p: Participant) => {
|
||||
setSelected(prev => prev.filter(x => x.id !== p.id));
|
||||
setAvailable(prev => [...prev, p]);
|
||||
};
|
||||
|
||||
return { selected, available, setSelected, setAvailable, loading, error, refresh, save, add, remove };
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// React Imports
|
||||
import { useContext } from 'react'
|
||||
|
||||
// Context Imports
|
||||
import { SettingsContext } from '@core/contexts/settingsContext'
|
||||
|
||||
export const useSettings = () => {
|
||||
// Hooks
|
||||
const context = useContext(SettingsContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useSettingsContext must be used within a SettingsProvider')
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
'use client';
|
||||
import type { SystemConfig, UpdateSystemConfigDto } from '@/@core/types/system-config';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export type UseSystemConfigOptions = {};
|
||||
|
||||
export type UseSystemConfigResult = {
|
||||
data: SystemConfig | null;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
fetchConfig: () => Promise<void>;
|
||||
updateConfig: (dto: UpdateSystemConfigDto) => Promise<void>;
|
||||
reloadConfig: () => Promise<void>;
|
||||
updating: boolean;
|
||||
reloading: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para gestionar la configuración del sistema
|
||||
*/
|
||||
export function useSystemConfig(
|
||||
options: UseSystemConfigOptions = {}
|
||||
): UseSystemConfigResult {
|
||||
|
||||
const [data, setData] = useState<SystemConfig | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [updating, setUpdating] = useState<boolean>(false);
|
||||
const [reloading, setReloading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
// Obtener configuración actual
|
||||
const fetchConfig = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<SystemConfig>('/system-config');
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
console.log('Error fetching system config:', e);
|
||||
setError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Actualizar configuración
|
||||
const updateConfig = useCallback(
|
||||
async (dto: UpdateSystemConfigDto) => {
|
||||
setUpdating(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.patch<SystemConfig>('/system-config', dto);
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setUpdating(false);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
// Recargar configuración desde BD
|
||||
const reloadConfig = useCallback(async () => {
|
||||
setReloading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const res = await apiClient.get<SystemConfig>('/system-config/reload');
|
||||
setData(res.data);
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setReloading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
fetchConfig,
|
||||
updateConfig,
|
||||
reloadConfig,
|
||||
updating,
|
||||
reloading,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const useToggleUserActive = () => {
|
||||
const { token } = useUserAuth();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const toggleActive = async (userId: string, isActive: boolean) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
<<<<<<< Updated upstream
|
||||
const deleted = isActive ? null : new Date().toISOString();
|
||||
const response = await apiClient.put(`/users/${userId}/active`, { deleted });
|
||||
console.log('✅ User active status updated successfully:', response.data);
|
||||
=======
|
||||
const url = `${process.env.NEXT_PUBLIC_BACKEND_URL ?? ''}/users/${userId}/active`;
|
||||
const deleted = isActive ? null : new Date().toISOString();
|
||||
const response = await axios.put(
|
||||
url,
|
||||
{ deleted },
|
||||
{ headers: { Authorization: `Bearer ${token}` } }
|
||||
);
|
||||
>>>>>>> Stashed changes
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error('❌ Error al cambiar estado del usuario', err);
|
||||
setError('No se pudo cambiar el estado del usuario');
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return { toggleActive, loading, error };
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useCallback } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import type { InvoiceStatus } from './useInvoices';
|
||||
|
||||
export type UpdateInvoiceStatusParams = {
|
||||
userId: string;
|
||||
invoiceId: string;
|
||||
status: InvoiceStatus;
|
||||
};
|
||||
|
||||
export type UpdateInvoiceStatusOptions = {
|
||||
onSuccess?: () => void | Promise<void>;
|
||||
onError?: (error: any) => void;
|
||||
};
|
||||
|
||||
export type UpdateInvoiceStatusResult = {
|
||||
mutate: (params: UpdateInvoiceStatusParams) => Promise<void>;
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
isSuccess: boolean;
|
||||
reset: () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook para actualizar el estado de una factura
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { mutate, loading, error, isSuccess } = useUpdateInvoiceStatus({
|
||||
* onSuccess: () => {
|
||||
* toast.success('Factura actualizada');
|
||||
* refetchInvoices();
|
||||
* },
|
||||
* onError: (error) => {
|
||||
* toast.error('Error al actualizar factura');
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // Usar la mutación
|
||||
* await mutate({
|
||||
* userId: 'user-123',
|
||||
* invoiceId: 'invoice-456',
|
||||
* status: 'PAID'
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function useUpdateInvoiceStatus(
|
||||
options: UpdateInvoiceStatusOptions = {}
|
||||
): UpdateInvoiceStatusResult {
|
||||
const { onSuccess, onError } = options;
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
const [isSuccess, setIsSuccess] = useState<boolean>(false);
|
||||
|
||||
const mutate = useCallback(
|
||||
async ({ userId, invoiceId, status }: UpdateInvoiceStatusParams) => {
|
||||
if (!userId || !invoiceId || !status) {
|
||||
const validationError = new Error('userId, invoiceId y status son requeridos');
|
||||
setError(validationError);
|
||||
onError?.(validationError);
|
||||
throw validationError;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setIsSuccess(false);
|
||||
|
||||
try {
|
||||
await apiClient.put(
|
||||
`/invoices/${encodeURIComponent(userId)}/${encodeURIComponent(invoiceId)}`,
|
||||
{ status }
|
||||
);
|
||||
|
||||
setIsSuccess(true);
|
||||
|
||||
// Ejecutar callback de éxito
|
||||
await onSuccess?.();
|
||||
} catch (e: any) {
|
||||
setError(e);
|
||||
setIsSuccess(false);
|
||||
onError?.(e);
|
||||
throw e;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[onSuccess, onError]
|
||||
);
|
||||
|
||||
const reset = useCallback(() => {
|
||||
setLoading(false);
|
||||
setError(null);
|
||||
setIsSuccess(false);
|
||||
}, []);
|
||||
|
||||
return { mutate, loading, error, isSuccess, reset };
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// useUsuarios.ts
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { Usuario } from '@/views/usuarios/usuarios.dto';
|
||||
|
||||
type Options = {
|
||||
/** Lanza el fetch al montar el hook (default: true) */
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
type UseUsuariosResult = {
|
||||
data: Usuario[];
|
||||
loading: boolean;
|
||||
error: unknown;
|
||||
/** Vuelve a pedir la lista */
|
||||
refresh: () => Promise<void>;
|
||||
/** Setea manualmente el array (útil para optimist updates) */
|
||||
setData: React.Dispatch<React.SetStateAction<Usuario[]>>;
|
||||
};
|
||||
|
||||
export function useUsuarios(opts: Options = {}): UseUsuariosResult {
|
||||
const { auto = true } = opts;
|
||||
|
||||
const [data, setData] = useState<Usuario[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(auto);
|
||||
const [error, setError] = useState<unknown>(null);
|
||||
|
||||
// guardamos una referencia al abortController para cancelar en unmount
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
// cancelar request previa si hubiera
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const ac = new AbortController();
|
||||
abortRef.current = ac;
|
||||
|
||||
try {
|
||||
<<<<<<< Updated upstream
|
||||
const res = await apiClient.get<Usuario[]>('/users', { signal: ac.signal });
|
||||
=======
|
||||
if (!token) throw new Error('Token no encontrado');
|
||||
|
||||
// Asegurar que baseUrl no esté vacío
|
||||
const backendUrl = baseUrl
|
||||
const url = `${backendUrl}/users`;
|
||||
|
||||
|
||||
const res = await axios.get<Usuario[]>(url, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
signal: ac.signal, // axios v1 soporta AbortController
|
||||
});
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
setData(res.data ?? []);
|
||||
} catch (e: any) {
|
||||
if (e?.name === 'CanceledError' || e?.message === 'canceled') return;
|
||||
setError(e);
|
||||
console.error('Error al obtener usuarios:', e);
|
||||
} finally {
|
||||
if (!ac.signal.aborted) setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (auto) refresh();
|
||||
return () => {
|
||||
// cancelar si el componente se desmonta
|
||||
abortRef.current?.abort();
|
||||
};
|
||||
}, [auto, refresh]);
|
||||
|
||||
return { data, loading, error, refresh, setData };
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// hooks/useWhatsappStatus.ts
|
||||
'use client';
|
||||
import useSWR from 'swr';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
|
||||
const WHATSAPP_STATUS_PATH = '/whatsapp/status';
|
||||
|
||||
const fetcher = async (path: string) => {
|
||||
const res = await apiClient.get(path);
|
||||
return res.data; // { status, phone, qr }
|
||||
};
|
||||
|
||||
export type UseWhatsappStatusOptions = {};
|
||||
|
||||
export function useWhatsappStatus(_options: UseWhatsappStatusOptions = {}) {
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
WHATSAPP_STATUS_PATH,
|
||||
fetcher,
|
||||
{
|
||||
// más frecuencia si NO hay sesión; más relajado si ya está conectada
|
||||
refreshInterval: (data) =>
|
||||
data?.status === 'Correcto' ? 30_000 : 3_000,
|
||||
revalidateOnFocus: false,
|
||||
shouldRetryOnError: true,
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
status: data?.status ?? 'Sin session',
|
||||
phone: data?.phone ?? 'No disponible',
|
||||
qr: data?.qr ?? null,
|
||||
loading: isLoading,
|
||||
error,
|
||||
refresh: () => mutate(), // botón "Actualizar"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// MUI imports
|
||||
import Box from '@mui/material/Box'
|
||||
import { styled } from '@mui/material/styles'
|
||||
import type { BoxProps } from '@mui/material/Box'
|
||||
|
||||
const StepperWrapper = styled(Box)<BoxProps>(({ theme }) => {
|
||||
return {
|
||||
[theme.breakpoints.down('md')]: {
|
||||
'& .MuiStepper-horizontal:not(.MuiStepper-alternativeLabel)': {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start'
|
||||
}
|
||||
},
|
||||
'& .MuiStep-root': {
|
||||
'& .MuiStepLabel-iconContainer:empty': {
|
||||
display: 'none'
|
||||
},
|
||||
'& .step-label': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
'& .step-number': {
|
||||
...theme.typography.h4,
|
||||
marginRight: theme.spacing(2)
|
||||
},
|
||||
'&:not(:has(.step-subtitle)) .step-number': {
|
||||
...theme.typography.h6
|
||||
},
|
||||
'& .step-title': {
|
||||
...theme.typography.body1,
|
||||
letterSpacing: 0.15,
|
||||
fontWeight: 500
|
||||
},
|
||||
'& .step-subtitle': {
|
||||
...theme.typography.body2,
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'& .MuiStepLabel-root.Mui-disabled': {
|
||||
'& .step-number': {
|
||||
color: 'var(--mui-palette-text-disabled)'
|
||||
}
|
||||
},
|
||||
'& .Mui-error': {
|
||||
'& .MuiStepLabel-labelContainer, & .step-number, & .step-title, & .step-subtitle': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .MuiStepConnector-root': {
|
||||
'& .MuiStepConnector-line': {
|
||||
borderBlockStartWidth: 3,
|
||||
borderRadius: 3
|
||||
},
|
||||
'&.Mui-active, &.Mui-completed': {
|
||||
'& .MuiStepConnector-line': {
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled .MuiStepConnector-line': {
|
||||
borderColor: 'var(--mui-palette-primary-lightOpacity)'
|
||||
}
|
||||
},
|
||||
'& .MuiStepper-alternativeLabel': {
|
||||
'& .MuiStepConnector-root': {
|
||||
top: 9
|
||||
},
|
||||
'& .MuiStepLabel-labelContainer': {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column'
|
||||
}
|
||||
},
|
||||
'& .MuiStepper-vertical': {
|
||||
'& .MuiStep-root': {
|
||||
'& .step-label': {
|
||||
justifyContent: 'flex-start'
|
||||
},
|
||||
'& .MuiStepContent-root': {
|
||||
borderInlineStartWidth: 3,
|
||||
marginLeft: theme.spacing(2.25),
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'& .button-wrapper': {
|
||||
marginTop: theme.spacing(4)
|
||||
},
|
||||
'&.active + .MuiStepConnector-root .MuiStepConnector-line': {
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
'& .MuiStepConnector-root': {
|
||||
marginLeft: theme.spacing(2.25),
|
||||
'& .MuiStepConnector-line': {
|
||||
borderBlockStartWidth: 0,
|
||||
borderInlineStartWidth: 3,
|
||||
borderRadius: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default StepperWrapper
|
||||
@@ -0,0 +1,92 @@
|
||||
.table {
|
||||
inline-size: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.875rem;
|
||||
white-space: nowrap;
|
||||
|
||||
[align='right'] > * {
|
||||
text-align: end;
|
||||
}
|
||||
[align='center'] > * {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
thead {
|
||||
text-transform: uppercase;
|
||||
color: var(--mui-palette-text-primary);
|
||||
|
||||
th {
|
||||
font-weight: 500;
|
||||
font-size: 0.8125rem;
|
||||
letter-spacing: 0.2px;
|
||||
line-height: 1.8462;
|
||||
text-align: start;
|
||||
block-size: 56px;
|
||||
background-color: var(--mui-palette-customColors-tableHeaderBg);
|
||||
&:not(:first-of-type):not(:last-of-type) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
&:first-of-type {
|
||||
&:not(:has(input[type='checkbox'])) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1.25rem 1rem;
|
||||
}
|
||||
&:has(input[type='checkbox']) {
|
||||
padding-inline-start: 0.6875rem;
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
color: var(--mui-palette-text-secondary);
|
||||
|
||||
th,
|
||||
td {
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.4667;
|
||||
block-size: 50px;
|
||||
&:not(:first-of-type):not(:last-of-type) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
&:first-of-type {
|
||||
&:not(:has(input[type='checkbox'])) {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1.25rem 1rem;
|
||||
}
|
||||
&:has(input[type='checkbox']) {
|
||||
padding-inline-start: 0.6875rem;
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
padding-block: 0.5rem;
|
||||
padding-inline: 1rem 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
tr:not(:last-child) {
|
||||
border-block-end: 1px solid var(--border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cellWithInput input {
|
||||
inline-size: 100%;
|
||||
background-color: transparent;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
border-radius: var(--mui-shape-customBorderRadius-sm);
|
||||
padding-block: 6px;
|
||||
padding-inline: 10px;
|
||||
margin-inline: -10px;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1px solid var(--mui-palette-primary-main);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// MUI Imports
|
||||
import { lighten } from '@mui/material/styles'
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { MenuItemStyles } from '@menu/types'
|
||||
|
||||
// Util Imports
|
||||
import { menuClasses } from '@menu/utils/menuClasses'
|
||||
|
||||
const menuItemStyles = (theme: Theme): MenuItemStyles => {
|
||||
return {
|
||||
root: {
|
||||
marginBlockStart: theme.spacing(1.5),
|
||||
[`&.${menuClasses.subMenuRoot}.${menuClasses.open} > .${menuClasses.button}, &.${menuClasses.subMenuRoot} > .${menuClasses.button}.${menuClasses.active}`]:
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-action-selected) !important'
|
||||
},
|
||||
[`&.${menuClasses.disabled} > .${menuClasses.button}`]: {
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
[`& .${menuClasses.icon}`]: {
|
||||
color: 'inherit'
|
||||
}
|
||||
},
|
||||
[`&:not(.${menuClasses.subMenuRoot}) > .${menuClasses.button}.${menuClasses.active}`]: {
|
||||
color: 'var(--mui-palette-primary-contrastText)',
|
||||
background:
|
||||
theme.direction === 'ltr'
|
||||
? `linear-gradient(270deg, var(--mui-palette-primary-main), ${lighten(
|
||||
theme.palette.primary.main,
|
||||
0.5
|
||||
)} 100%)`
|
||||
: `linear-gradient(270deg, ${lighten(
|
||||
theme.palette.primary.main,
|
||||
0.5
|
||||
)}, var(--mui-palette-primary-main) 100%)`,
|
||||
[`& .${menuClasses.icon}`]: {
|
||||
color: 'inherit'
|
||||
}
|
||||
}
|
||||
},
|
||||
button: ({ active }) => ({
|
||||
paddingBlock: theme.spacing(2),
|
||||
'&:has(.MuiChip-root)': {
|
||||
paddingBlock: theme.spacing(1.75)
|
||||
},
|
||||
paddingInlineStart: theme.spacing(5.5),
|
||||
paddingInlineEnd: theme.spacing(3.5),
|
||||
borderStartEndRadius: 50,
|
||||
borderEndEndRadius: 50,
|
||||
...(!active && {
|
||||
'&:hover, &:focus-visible': {
|
||||
backgroundColor: 'var(--mui-palette-action-hover)'
|
||||
},
|
||||
'&[aria-expanded="true"]': {
|
||||
backgroundColor: 'var(--mui-palette-action-selected)'
|
||||
}
|
||||
})
|
||||
}),
|
||||
icon: ({ level }) => ({
|
||||
...(level === 0 && {
|
||||
fontSize: '1.375rem',
|
||||
marginInlineEnd: theme.spacing(2)
|
||||
}),
|
||||
...(level > 0 && {
|
||||
fontSize: '0.75rem',
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
marginInlineEnd: theme.spacing(3.5)
|
||||
}),
|
||||
...(level === 1 && {
|
||||
marginInlineStart: theme.spacing(1.5)
|
||||
}),
|
||||
...(level > 1 && {
|
||||
marginInlineStart: theme.spacing(1.5 + 2.5 * (level - 1))
|
||||
}),
|
||||
'& > i, & > svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}),
|
||||
prefix: {
|
||||
marginInlineEnd: theme.spacing(2)
|
||||
},
|
||||
suffix: {
|
||||
marginInlineStart: theme.spacing(2)
|
||||
},
|
||||
subMenuExpandIcon: {
|
||||
fontSize: '1.375rem',
|
||||
marginInlineStart: theme.spacing(2),
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
},
|
||||
subMenuContent: {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default menuItemStyles
|
||||
@@ -0,0 +1,42 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { MenuProps } from '@menu/vertical-menu'
|
||||
|
||||
// Util Imports
|
||||
import { menuClasses } from '@menu/utils/menuClasses'
|
||||
|
||||
const menuSectionStyles = (theme: Theme): MenuProps['menuSectionStyles'] => {
|
||||
return {
|
||||
root: {
|
||||
marginBlockStart: theme.spacing(7),
|
||||
[`& .${menuClasses.menuSectionContent}`]: {
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
paddingInline: '0 !important',
|
||||
paddingBlock: `${theme.spacing(1.75)} !important`,
|
||||
gap: theme.spacing(2.5),
|
||||
|
||||
'&:before': {
|
||||
content: '""',
|
||||
blockSize: 1,
|
||||
inlineSize: '0.875rem',
|
||||
backgroundColor: 'var(--mui-palette-divider)'
|
||||
},
|
||||
'&:after': {
|
||||
content: '""',
|
||||
blockSize: 1,
|
||||
flexGrow: 1,
|
||||
backgroundColor: 'var(--mui-palette-divider)'
|
||||
}
|
||||
},
|
||||
[`& .${menuClasses.menuSectionLabel}`]: {
|
||||
flexGrow: 0,
|
||||
fontSize: '13px',
|
||||
lineHeight: 1.38462
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default menuSectionStyles
|
||||
@@ -0,0 +1,35 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Util Imports
|
||||
import { menuClasses, verticalNavClasses } from '@menu/utils/menuClasses'
|
||||
|
||||
const navigationCustomStyles = (theme: Theme) => {
|
||||
return {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
zIndex: 'var(--drawer-z-index) !important',
|
||||
[`& .${verticalNavClasses.bgColorContainer}`]: {
|
||||
backgroundColor: 'var(--mui-palette-background-default)'
|
||||
},
|
||||
[`& .${verticalNavClasses.header}`]: {
|
||||
paddingBlock: theme.spacing(5),
|
||||
paddingInline: theme.spacing(5.5, 4)
|
||||
},
|
||||
[`& .${verticalNavClasses.container}`]: {
|
||||
transition: 'none',
|
||||
borderColor: 'transparent',
|
||||
[`& .${verticalNavClasses.toggled}`]: {
|
||||
boxShadow: 'var(--mui-customShadows-lg)'
|
||||
}
|
||||
},
|
||||
[`& .${menuClasses.root}`]: {
|
||||
paddingBlockEnd: theme.spacing(2),
|
||||
paddingInlineEnd: theme.spacing(4)
|
||||
},
|
||||
[`& .${verticalNavClasses.backdrop}`]: {
|
||||
backgroundColor: 'var(--backdrop-color)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default navigationCustomStyles
|
||||
@@ -0,0 +1,77 @@
|
||||
// React Imports
|
||||
import type { SVGAttributes } from 'react'
|
||||
|
||||
const Logo = (props: SVGAttributes<SVGElement>) => {
|
||||
return (
|
||||
<svg width='1.2658em' height='1em' viewBox='0 0 100 79' fill='none' xmlns='http://www.w3.org/2000/svg' {...props}>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M4.92008 0.501904L22.662 11.4573C23.614 12.0451 24.1936 13.0844 24.1936 14.2036V64.2521C24.1936 65.3871 23.5976 66.4387 22.6241 67.0214L4.8822 77.6429C3.35344 78.5581 1.37254 78.0602 0.457741 76.5307C0.158194 76.0299 0 75.4572 0 74.8736V3.24818C0 1.46582 1.44424 0.0209274 3.22581 0.0209274C3.82422 0.0209274 4.41085 0.18746 4.92008 0.501904Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M0 26.1063L24.1936 39.9852V53.5915L0 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M0 26.1063L24.1936 39.6319V47.9438L0 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M95.084 0.489601L77.3421 11.4083C76.3878 11.9956 75.8064 13.0362 75.8064 14.1571V64.2526C75.8064 65.3875 76.4024 66.4391 77.3759 67.0219L95.1178 77.6433C96.6466 78.5585 98.6275 78.0606 99.5423 76.5312C99.8418 76.0303 100 75.4576 100 74.874V3.23842C100 1.45605 98.5558 0.0111618 96.7742 0.0111618C96.1774 0.0111618 95.5923 0.176782 95.084 0.489601Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M100 26.1063L75.8064 39.956V54.0023L100 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
opacity='0.077704'
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M100 26.1063L75.8064 39.6199V48.3546L100 26.1063Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M4.91149 0.475694L50 28.123V54.7479L0 26.0986V3.22726C0 1.44489 1.44424 0 3.22581 0C3.8208 0 4.4042 0.164633 4.91149 0.475694Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M4.91149 0.475694L50 28.123V54.7479L0 26.0986V3.22726C0 1.44489 1.44424 0 3.22581 0C3.8208 0 4.4042 0.164633 4.91149 0.475694Z'
|
||||
fill='white'
|
||||
fillOpacity='0.15'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M95.0885 0.475694L50 28.123V54.7479L100 26.0986V3.22726C100 1.44489 98.5558 0 96.7742 0C96.1792 0 95.5958 0.164633 95.0885 0.475694Z'
|
||||
fill='currentColor'
|
||||
/>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M95.0885 0.475694L50 28.123V54.7479L100 26.0986V3.22726C100 1.44489 98.5558 0 96.7742 0C96.1792 0 95.5958 0.164633 95.0885 0.475694Z'
|
||||
fill='white'
|
||||
fillOpacity='0.3'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default Logo
|
||||
@@ -0,0 +1,74 @@
|
||||
import plugin from 'tailwindcss/plugin'
|
||||
|
||||
module.exports = plugin(function () {}, {
|
||||
theme: {
|
||||
borderColor: ({ theme }) => ({
|
||||
...theme('colors'),
|
||||
DEFAULT: 'var(--border-color, currentColor)'
|
||||
}),
|
||||
borderRadius: {
|
||||
none: '0px',
|
||||
xs: 'var(--mui-shape-customBorderRadius-xs)',
|
||||
sm: 'var(--mui-shape-customBorderRadius-sm)',
|
||||
DEFAULT: '0.375rem',
|
||||
md: 'var(--mui-shape-customBorderRadius-md)',
|
||||
lg: 'var(--mui-shape-customBorderRadius-lg)',
|
||||
xl: 'var(--mui-shape-customBorderRadius-xl)',
|
||||
'2xl': '0.75rem',
|
||||
'3xl': '1rem',
|
||||
'4xl': '1.5rem',
|
||||
full: '9999px'
|
||||
},
|
||||
screens: {
|
||||
sm: '600px',
|
||||
md: '900px',
|
||||
lg: '1200px',
|
||||
xl: '1536px',
|
||||
'2xl': '1920px'
|
||||
},
|
||||
extend: {
|
||||
boxShadow: {
|
||||
xs: 'var(--mui-customShadows-xs)',
|
||||
sm: 'var(--mui-customShadows-sm)',
|
||||
DEFAULT: 'var(--mui-customShadows-md)',
|
||||
md: 'var(--mui-customShadows-md)',
|
||||
lg: 'var(--mui-customShadows-lg)',
|
||||
xl: 'var(--mui-customShadows-xl)'
|
||||
},
|
||||
colors: {
|
||||
primary: 'var(--primary-color)',
|
||||
primaryLight: 'var(--mui-palette-primary-lightOpacity)',
|
||||
primaryLighter: 'var(--mui-palette-primary-lighterOpacity)',
|
||||
secondary: 'var(--mui-palette-secondary-main)',
|
||||
error: 'var(--mui-palette-error-main)',
|
||||
errorLight: 'var(--mui-palette-error-lightOpacity)',
|
||||
errorLighter: 'var(--mui-palette-error-lighterOpacity)',
|
||||
warning: 'var(--mui-palette-warning-main)',
|
||||
info: 'var(--mui-palette-info-main)',
|
||||
success: 'var(--mui-palette-success-main)',
|
||||
textPrimary: 'var(--mui-palette-text-primary)',
|
||||
textSecondary: 'var(--mui-palette-text-secondary)',
|
||||
textDisabled: 'var(--mui-palette-text-disabled)',
|
||||
actionActive: 'var(--mui-palette-action-active)',
|
||||
actionHover: 'var(--mui-palette-action-hover)',
|
||||
actionSelected: 'var(--mui-palette-action-selected)',
|
||||
actionFocus: 'var(--mui-palette-action-focus)',
|
||||
backgroundPaper: 'var(--mui-palette-background-paper)',
|
||||
backgroundDefault: 'var(--mui-palette-background-default)',
|
||||
track: 'var(--mui-palette-customColors-trackBg)',
|
||||
backdrop: 'var(--backdrop-color)',
|
||||
facebook: '#497ce2',
|
||||
twitter: '#1da1f2',
|
||||
github: '#272727',
|
||||
googlePlus: '#db4437'
|
||||
},
|
||||
zIndex: {
|
||||
header: 'var(--header-z-index)',
|
||||
footer: 'var(--footer-z-index)',
|
||||
customizer: 'var(--customizer-z-index)',
|
||||
search: 'var(--search-z-index)',
|
||||
drawer: 'var(--drawer-z-index)'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,329 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const colorSchemes = (): Theme['colorSchemes'] => {
|
||||
const skin = 'default' as string
|
||||
|
||||
return {
|
||||
light: {
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#8C57FF',
|
||||
light: '#A379FF',
|
||||
dark: '#7E4EE6',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.38)'
|
||||
},
|
||||
secondary: {
|
||||
main: '#8A8D93',
|
||||
light: '#A1A4A9',
|
||||
dark: '#7C7F84',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.38)'
|
||||
},
|
||||
error: {
|
||||
main: '#FF4C51',
|
||||
light: '#FF7074',
|
||||
dark: '#E64449',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.38)'
|
||||
},
|
||||
warning: {
|
||||
main: '#FFB400',
|
||||
light: '#FFC333',
|
||||
dark: '#E6A200',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.38)'
|
||||
},
|
||||
info: {
|
||||
main: '#16B1FF',
|
||||
light: '#45C1FF',
|
||||
dark: '#149FE6',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.38)'
|
||||
},
|
||||
success: {
|
||||
main: '#56CA00',
|
||||
light: '#78D533',
|
||||
dark: '#4DB600',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.38)'
|
||||
},
|
||||
text: {
|
||||
primary: `rgb(var(--mui-mainColorChannels-light) / 0.9)`,
|
||||
secondary: `rgb(var(--mui-mainColorChannels-light) / 0.7)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-light) / 0.4)`,
|
||||
primaryChannel: 'var(--mui-mainColorChannels-light)',
|
||||
secondaryChannel: 'var(--mui-mainColorChannels-light)'
|
||||
},
|
||||
divider: `rgb(var(--mui-mainColorChannels-light) / 0.12)`,
|
||||
dividerChannel: 'var(--mui-mainColorChannels-light)',
|
||||
background: {
|
||||
default: skin === 'bordered' ? '#FFFFFF' : '#F4F5FA',
|
||||
paper: '#FFFFFF'
|
||||
},
|
||||
action: {
|
||||
active: `rgb(var(--mui-mainColorChannels-light) / 0.6)`,
|
||||
hover: `rgb(var(--mui-mainColorChannels-light) / 0.04)`,
|
||||
selected: `rgb(var(--mui-mainColorChannels-light) / 0.08)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-light) / 0.3)`,
|
||||
disabledBackground: `rgb(var(--mui-mainColorChannels-light) / 0.12)`,
|
||||
focus: `rgb(var(--mui-mainColorChannels-light) / 0.1)`,
|
||||
focusOpacity: 0.1,
|
||||
activeChannel: 'var(--mui-mainColorChannels-light)',
|
||||
selectedChannel: 'var(--mui-mainColorChannels-light)'
|
||||
},
|
||||
Alert: {
|
||||
errorColor: 'var(--mui-palette-error-main)',
|
||||
warningColor: 'var(--mui-palette-warning-main)',
|
||||
infoColor: 'var(--mui-palette-info-main)',
|
||||
successColor: 'var(--mui-palette-success-main)',
|
||||
errorStandardBg: 'var(--mui-palette-error-lightOpacity)',
|
||||
warningStandardBg: 'var(--mui-palette-warning-lightOpacity)',
|
||||
infoStandardBg: 'var(--mui-palette-info-lightOpacity)',
|
||||
successStandardBg: 'var(--mui-palette-success-lightOpacity)',
|
||||
errorFilledColor: 'var(--mui-palette-error-contrastText)',
|
||||
warningFilledColor: 'var(--mui-palette-warning-contrastText)',
|
||||
infoFilledColor: 'var(--mui-palette-info-contrastText)',
|
||||
successFilledColor: 'var(--mui-palette-success-contrastText)',
|
||||
errorFilledBg: 'var(--mui-palette-error-main)',
|
||||
warningFilledBg: 'var(--mui-palette-warning-main)',
|
||||
infoFilledBg: 'var(--mui-palette-info-main)',
|
||||
successFilledBg: 'var(--mui-palette-success-main)'
|
||||
},
|
||||
Avatar: {
|
||||
defaultBg: '#F0EFF0'
|
||||
},
|
||||
Chip: {
|
||||
defaultBorder: 'var(--mui-palette-divider)'
|
||||
},
|
||||
FilledInput: {
|
||||
bg: `rgb(var(--mui-mainColorChannels-light) / 0.06)`,
|
||||
hoverBg: `rgb(var(--mui-mainColorChannels-light) / 0.08)`,
|
||||
disabledBg: `rgb(var(--mui-mainColorChannels-light) / 0.06)`
|
||||
},
|
||||
LinearProgress: {
|
||||
primaryBg: 'var(--mui-palette-primary-mainOpacity)',
|
||||
secondaryBg: 'var(--mui-palette-secondary-mainOpacity)',
|
||||
errorBg: 'var(--mui-palette-error-mainOpacity)',
|
||||
warningBg: 'var(--mui-palette-warning-mainOpacity)',
|
||||
infoBg: 'var(--mui-palette-info-mainOpacity)',
|
||||
successBg: 'var(--mui-palette-success-mainOpacity)'
|
||||
},
|
||||
SnackbarContent: {
|
||||
bg: '#1A0E33',
|
||||
color: 'var(--mui-palette-background-paper)'
|
||||
},
|
||||
Switch: {
|
||||
defaultColor: 'var(--mui-palette-common-white)',
|
||||
defaultDisabledColor: 'var(--mui-palette-common-white)',
|
||||
primaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
secondaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
errorDisabledColor: 'var(--mui-palette-common-white)',
|
||||
warningDisabledColor: 'var(--mui-palette-common-white)',
|
||||
infoDisabledColor: 'var(--mui-palette-common-white)',
|
||||
successDisabledColor: 'var(--mui-palette-common-white)'
|
||||
},
|
||||
Tooltip: {
|
||||
bg: '#1A0E33'
|
||||
},
|
||||
TableCell: {
|
||||
border: 'var(--mui-palette-divider)'
|
||||
},
|
||||
customColors: {
|
||||
bodyBg: '#F4F5FA',
|
||||
chatBg: '#F7F6FA',
|
||||
greyLightBg: '#FAFAFA',
|
||||
inputBorder: `rgb(var(--mui-mainColorChannels-light) / 0.22)`,
|
||||
tableHeaderBg: '#F6F7FB',
|
||||
tooltipText: '#FFFFFF',
|
||||
trackBg: '#F0F2F8'
|
||||
}
|
||||
}
|
||||
},
|
||||
dark: {
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#8C57FF',
|
||||
light: '#A379FF',
|
||||
dark: '#7E4EE6',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.38)'
|
||||
},
|
||||
secondary: {
|
||||
main: '#8A8D93',
|
||||
light: '#A1A4A9',
|
||||
dark: '#7C7F84',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.38)'
|
||||
},
|
||||
error: {
|
||||
main: '#FF4C51',
|
||||
light: '#FF7074',
|
||||
dark: '#E64449',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.38)'
|
||||
},
|
||||
warning: {
|
||||
main: '#FFB400',
|
||||
light: '#FFC333',
|
||||
dark: '#E6A200',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.38)'
|
||||
},
|
||||
info: {
|
||||
main: '#16B1FF',
|
||||
light: '#45C1FF',
|
||||
dark: '#149FE6',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.38)'
|
||||
},
|
||||
success: {
|
||||
main: '#56CA00',
|
||||
light: '#78D533',
|
||||
dark: '#4DB600',
|
||||
contrastText: '#fff',
|
||||
lighterOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.08)',
|
||||
lightOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.16)',
|
||||
mainOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.24)',
|
||||
darkOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.32)',
|
||||
darkerOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.38)'
|
||||
},
|
||||
text: {
|
||||
primary: `rgb(var(--mui-mainColorChannels-dark) / 0.9)`,
|
||||
secondary: `rgb(var(--mui-mainColorChannels-dark) / 0.7)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-dark) / 0.4)`,
|
||||
primaryChannel: 'var(--mui-mainColorChannels-dark)',
|
||||
secondaryChannel: 'var(--mui-mainColorChannels-dark)'
|
||||
},
|
||||
divider: `rgb(var(--mui-mainColorChannels-dark) / 0.12)`,
|
||||
dividerChannel: 'var(--mui-mainColorChannels-dark)',
|
||||
background: {
|
||||
default: skin === 'bordered' ? '#312D4B' : '#28243D',
|
||||
paper: '#312D4B'
|
||||
},
|
||||
action: {
|
||||
active: `rgb(var(--mui-mainColorChannels-dark) / 0.6)`,
|
||||
hover: `rgb(var(--mui-mainColorChannels-dark) / 0.04)`,
|
||||
selected: `rgb(var(--mui-mainColorChannels-dark) / 0.08)`,
|
||||
disabled: `rgb(var(--mui-mainColorChannels-dark) / 0.3)`,
|
||||
disabledBackground: `rgb(var(--mui-mainColorChannels-dark) / 0.12)`,
|
||||
focus: `rgb(var(--mui-mainColorChannels-dark) / 0.1)`,
|
||||
focusOpacity: 0.1,
|
||||
activeChannel: 'var(--mui-mainColorChannels-dark)',
|
||||
selectedChannel: 'var(--mui-mainColorChannels-dark)'
|
||||
},
|
||||
Alert: {
|
||||
errorColor: 'var(--mui-palette-error-main)',
|
||||
warningColor: 'var(--mui-palette-warning-main)',
|
||||
infoColor: 'var(--mui-palette-info-main)',
|
||||
successColor: 'var(--mui-palette-success-main)',
|
||||
errorStandardBg: 'var(--mui-palette-error-lightOpacity)',
|
||||
warningStandardBg: 'var(--mui-palette-warning-lightOpacity)',
|
||||
infoStandardBg: 'var(--mui-palette-info-lightOpacity)',
|
||||
successStandardBg: 'var(--mui-palette-success-lightOpacity)',
|
||||
errorFilledColor: 'var(--mui-palette-error-contrastText)',
|
||||
warningFilledColor: 'var(--mui-palette-warning-contrastText)',
|
||||
infoFilledColor: 'var(--mui-palette-info-contrastText)',
|
||||
successFilledColor: 'var(--mui-palette-success-contrastText)',
|
||||
errorFilledBg: 'var(--mui-palette-error-main)',
|
||||
warningFilledBg: 'var(--mui-palette-warning-main)',
|
||||
infoFilledBg: 'var(--mui-palette-info-main)',
|
||||
successFilledBg: 'var(--mui-palette-success-main)'
|
||||
},
|
||||
Avatar: {
|
||||
defaultBg: '#3F3B59'
|
||||
},
|
||||
Chip: {
|
||||
defaultBorder: 'var(--mui-palette-divider)'
|
||||
},
|
||||
FilledInput: {
|
||||
bg: `rgb(var(--mui-mainColorChannels-dark) / 0.06)`,
|
||||
hoverBg: `rgb(var(--mui-mainColorChannels-dark) / 0.08)`,
|
||||
disabledBg: `rgb(var(--mui-mainColorChannels-dark) / 0.06)`
|
||||
},
|
||||
LinearProgress: {
|
||||
primaryBg: 'var(--mui-palette-primary-mainOpacity)',
|
||||
secondaryBg: 'var(--mui-palette-secondary-mainOpacity)',
|
||||
errorBg: 'var(--mui-palette-error-mainOpacity)',
|
||||
warningBg: 'var(--mui-palette-warning-mainOpacity)',
|
||||
infoBg: 'var(--mui-palette-info-mainOpacity)',
|
||||
successBg: 'var(--mui-palette-success-mainOpacity)'
|
||||
},
|
||||
SnackbarContent: {
|
||||
bg: '#F7F4FF',
|
||||
color: 'var(--mui-palette-background-paper)'
|
||||
},
|
||||
Switch: {
|
||||
defaultColor: 'var(--mui-palette-common-white)',
|
||||
defaultDisabledColor: 'var(--mui-palette-common-white)',
|
||||
primaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
secondaryDisabledColor: 'var(--mui-palette-common-white)',
|
||||
errorDisabledColor: 'var(--mui-palette-common-white)',
|
||||
warningDisabledColor: 'var(--mui-palette-common-white)',
|
||||
infoDisabledColor: 'var(--mui-palette-common-white)',
|
||||
successDisabledColor: 'var(--mui-palette-common-white)'
|
||||
},
|
||||
Tooltip: {
|
||||
bg: '#F7F4FF'
|
||||
},
|
||||
TableCell: {
|
||||
border: 'var(--mui-palette-divider)'
|
||||
},
|
||||
customColors: {
|
||||
bodyBg: '#28243D',
|
||||
chatBg: '#373452',
|
||||
greyLightBg: '#373350',
|
||||
inputBorder: `rgb(var(--mui-mainColorChannels-dark) / 0.22)`,
|
||||
tableHeaderBg: '#3D3759',
|
||||
tooltipText: '#312D4B',
|
||||
trackBg: '#474360'
|
||||
}
|
||||
}
|
||||
}
|
||||
} as Theme['colorSchemes']
|
||||
}
|
||||
|
||||
export default colorSchemes
|
||||
@@ -0,0 +1,17 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
const customShadows = (mode: SystemMode): Theme['customShadows'] => {
|
||||
return {
|
||||
xs: `0px 2px 4px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.16 : 0.2})`,
|
||||
sm: `0px 3px 6px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.18 : 0.22})`,
|
||||
md: `0px 4px 10px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.2 : 0.24})`,
|
||||
lg: `0px 6px 16px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.22 : 0.26})`,
|
||||
xl: `0px 8px 28px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.24 : 0.28})`
|
||||
}
|
||||
}
|
||||
|
||||
export default customShadows
|
||||
@@ -0,0 +1,48 @@
|
||||
// Next Imports
|
||||
import { Inter } from 'next/font/google'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
// Theme Options Imports
|
||||
import overrides from './overrides'
|
||||
import colorSchemes from './colorSchemes'
|
||||
import spacing from './spacing'
|
||||
import shadows from './shadows'
|
||||
import customShadows from './customShadows'
|
||||
import typography from './typography'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'], weight: ['300', '400', '500', '600', '700', '800', '900'] })
|
||||
|
||||
const theme = (mode: SystemMode, direction: Theme['direction']): Theme => {
|
||||
return {
|
||||
direction,
|
||||
components: overrides(),
|
||||
colorSchemes: colorSchemes(),
|
||||
...spacing,
|
||||
shape: {
|
||||
borderRadius: 6,
|
||||
customBorderRadius: {
|
||||
xs: 2,
|
||||
sm: 4,
|
||||
md: 6,
|
||||
lg: 8,
|
||||
xl: 10
|
||||
}
|
||||
},
|
||||
shadows: shadows(mode),
|
||||
typography: typography(inter.style.fontFamily),
|
||||
customShadows: customShadows(mode),
|
||||
mainColorChannels: {
|
||||
light: '46 38 61',
|
||||
dark: '231 227 252',
|
||||
lightShadow: '46 38 61',
|
||||
darkShadow: '19 17 32'
|
||||
}
|
||||
} as Theme
|
||||
}
|
||||
|
||||
export default theme
|
||||
@@ -0,0 +1,90 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const accordion = (skin: Skin): Theme['components'] => ({
|
||||
MuiAccordion: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
variant: 'outlined'
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
transition: theme.transitions.create(['margin', 'border-radius', 'box-shadow']),
|
||||
...(skin !== 'bordered'
|
||||
? {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
: {
|
||||
'&:not(.Mui-expanded) + &:not(.Mui-expanded)': {
|
||||
borderBlockStart: 0
|
||||
},
|
||||
'&:not(.Mui-expanded):has(+ &:not(.Mui-expanded))': {
|
||||
borderBlockEnd: 0
|
||||
}
|
||||
}),
|
||||
'&:not(.Mui-expanded):has(+ .Mui-expanded)': {
|
||||
borderBottomLeftRadius: 'var(--mui-shape-borderRadius)',
|
||||
borderBottomRightRadius: 'var(--mui-shape-borderRadius)'
|
||||
},
|
||||
'&.Mui-expanded': {
|
||||
borderRadius: 'var(--mui-shape-borderRadius)',
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-md)'
|
||||
}),
|
||||
margin: theme.spacing(2, 0),
|
||||
'& + .MuiAccordion-root': {
|
||||
borderTopLeftRadius: 'var(--mui-shape-borderRadius)',
|
||||
borderTopRightRadius: 'var(--mui-shape-borderRadius)',
|
||||
'&:before': {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiAccordionSummary: {
|
||||
defaultProps: {
|
||||
expandIcon: <i className='ri-arrow-down-s-line' />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(3, 5),
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'&.Mui-expanded': {
|
||||
minHeight: 48
|
||||
},
|
||||
'& .MuiTypography-root': {
|
||||
color: 'inherit',
|
||||
fontWeight: theme.typography.fontWeightMedium
|
||||
}
|
||||
}),
|
||||
content: {
|
||||
margin: '0 !important'
|
||||
},
|
||||
expandIconWrapper: {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
fontSize: '1.25rem',
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiAccordionDetails: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(0, 5, 5),
|
||||
'& .MuiTypography-root': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default accordion
|
||||
@@ -0,0 +1,179 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const alerts: Theme['components'] = {
|
||||
MuiAlert: {
|
||||
defaultProps: {
|
||||
iconMapping: {
|
||||
error: <i className='ri-error-warning-line' />,
|
||||
warning: <i className='ri-alert-line' />,
|
||||
info: <i className='ri-information-line' />,
|
||||
success: <i className='ri-checkbox-circle-line' />
|
||||
}
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(4),
|
||||
gap: theme.spacing(4),
|
||||
...theme.typography.body1,
|
||||
'&:not(:has(.MuiAlertTitle-root))': {
|
||||
'& .MuiAlert-icon + .MuiAlert-message': {
|
||||
alignSelf: 'center'
|
||||
}
|
||||
}
|
||||
}),
|
||||
icon: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
minWidth: 30,
|
||||
height: 30,
|
||||
borderRadius: 'var(--mui-shape-borderRadius)',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
'& i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
},
|
||||
message: {
|
||||
padding: 0
|
||||
},
|
||||
action: {
|
||||
padding: 0,
|
||||
marginRight: 0
|
||||
}
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'standard', severity: 'error' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-error-main)',
|
||||
color: 'var(--mui-palette-error-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'standard', severity: 'warning' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-warning-main)',
|
||||
color: 'var(--mui-palette-warning-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'standard', severity: 'info' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-info-main)',
|
||||
color: 'var(--mui-palette-info-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'standard', severity: 'success' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-success-main)',
|
||||
color: 'var(--mui-palette-success-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'error' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-error-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-error-mainOpacity)',
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'warning' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-warning-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-warning-mainOpacity)',
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'info' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-info-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-info-mainOpacity)',
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', severity: 'success' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-success-main)',
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-success-mainOpacity)',
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'error' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-error-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'warning' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'info' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-info-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', severity: 'success' },
|
||||
style: {
|
||||
'& .MuiAlert-icon': {
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
color: 'var(--mui-palette-success-main)',
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
MuiAlertTitle: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
...theme.typography.h5,
|
||||
marginTop: 0,
|
||||
marginBottom: theme.spacing(1),
|
||||
color: 'inherit'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default alerts
|
||||
@@ -0,0 +1,76 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const autocomplete = (skin: Skin): Theme['components'] => ({
|
||||
MuiAutocomplete: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
slotProps: {
|
||||
paper: {
|
||||
variant: 'outlined'
|
||||
}
|
||||
}
|
||||
}),
|
||||
ChipProps: {
|
||||
size: 'small'
|
||||
},
|
||||
popupIcon: <i className='ri-arrow-down-s-line' />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiButtonBase-root.Mui-disabled i, & .MuiButtonBase-root.Mui-disabled svg': {
|
||||
color: 'var(--mui-palette-action-disabled)'
|
||||
},
|
||||
'& .MuiOutlinedInput-input': {
|
||||
height: '1.4375em'
|
||||
}
|
||||
},
|
||||
input: {
|
||||
'& + .MuiAutocomplete-endAdornment': {
|
||||
right: '1rem',
|
||||
'& i, & svg': {
|
||||
fontSize: '1.5rem',
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
},
|
||||
'& .MuiAutocomplete-clearIndicator': {
|
||||
padding: 2
|
||||
}
|
||||
},
|
||||
'&.MuiInputBase-inputSizeSmall + .MuiAutocomplete-endAdornment': {
|
||||
'& i, & svg': {
|
||||
fontSize: '1.375rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
paper: {
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-lg)',
|
||||
marginBlockStart: '0.125rem'
|
||||
})
|
||||
},
|
||||
listbox: ({ theme }) => ({
|
||||
'& .MuiAutocomplete-option': {
|
||||
padding: theme.spacing(2, 5),
|
||||
'&[aria-selected="true"]': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'&.Mui-focused, &.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
}
|
||||
}
|
||||
},
|
||||
'& .MuiAutocomplete-option.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-action-hover)'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default autocomplete
|
||||
@@ -0,0 +1,38 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const avatar: Theme['components'] = {
|
||||
MuiAvatarGroup: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
justifyContent: 'flex-end',
|
||||
'& .MuiAvatar-root': {
|
||||
borderColor: 'var(--mui-palette-background-paper)'
|
||||
},
|
||||
'&.pull-up .MuiAvatar-root': {
|
||||
cursor: 'pointer',
|
||||
transition: theme.transitions.create(['box-shadow', 'transform'], {
|
||||
easing: 'ease',
|
||||
duration: theme.transitions.duration.shorter
|
||||
}),
|
||||
'&:hover': {
|
||||
zIndex: 2,
|
||||
boxShadow: 'var(--mui-customShadows-md)',
|
||||
transform: 'translateY(-5px)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiAvatar: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
fontSize: theme.typography.body1.fontSize,
|
||||
lineHeight: 1.2
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default avatar
|
||||
@@ -0,0 +1,16 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const backdrop: Theme['components'] = {
|
||||
MuiBackdrop: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(.MuiBackdrop-invisible)': {
|
||||
backgroundColor: 'var(--backdrop-color)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default backdrop
|
||||
@@ -0,0 +1,19 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const badges: Theme['components'] = {
|
||||
MuiBadge: {
|
||||
styleOverrides: {
|
||||
standard: ({ theme }) => ({
|
||||
height: 22,
|
||||
minWidth: 22,
|
||||
borderRadius: 20,
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
lineHeight: 1.07,
|
||||
padding: theme.spacing(1, 2)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default badges
|
||||
@@ -0,0 +1,29 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const breadcrumbs: Theme['components'] = {
|
||||
MuiBreadcrumbs: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& svg, & i': {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
'& a': {
|
||||
textDecoration: 'none',
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
}
|
||||
},
|
||||
li: ({ theme }) => ({
|
||||
lineHeight: theme.typography.body1.lineHeight,
|
||||
'& > *:not(a)': {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default breadcrumbs
|
||||
@@ -0,0 +1,73 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const buttonGroup: Theme['components'] = {
|
||||
MuiButtonGroup: {
|
||||
defaultProps: {
|
||||
disableRipple: themeConfig.disableRipple
|
||||
},
|
||||
styleOverrides: {
|
||||
contained: ({ ownerState }) => ({
|
||||
boxShadow: 'var(--mui-customShadows-xs)',
|
||||
...(ownerState.disabled && {
|
||||
boxShadow: 'none'
|
||||
})
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'text', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'error' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'warning' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'info' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'success' },
|
||||
style: {
|
||||
'& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': {
|
||||
borderColor: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default buttonGroup
|
||||
@@ -0,0 +1,377 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const iconStyles = (size?: string) => ({
|
||||
'& > *:nth-of-type(1)': {
|
||||
...(size === 'small'
|
||||
? {
|
||||
fontSize: '14px'
|
||||
}
|
||||
: {
|
||||
...(size === 'medium'
|
||||
? {
|
||||
fontSize: '16px'
|
||||
}
|
||||
: {
|
||||
fontSize: '20px'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const button: Theme['components'] = {
|
||||
MuiButtonBase: {
|
||||
defaultProps: {
|
||||
disableRipple: themeConfig.disableRipple
|
||||
}
|
||||
},
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
...(ownerState.variant === 'text'
|
||||
? {
|
||||
...(ownerState.size === 'small' && {
|
||||
padding: theme.spacing(2, 2.5)
|
||||
}),
|
||||
...(ownerState.size === 'medium' && {
|
||||
padding: theme.spacing(2, 3.5)
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
padding: theme.spacing(2, 4.5)
|
||||
})
|
||||
}
|
||||
: {
|
||||
...(ownerState.variant === 'outlined'
|
||||
? {
|
||||
...(ownerState.size === 'small' && {
|
||||
padding: theme.spacing(1.75, 3.25)
|
||||
}),
|
||||
...(ownerState.size === 'medium' && {
|
||||
padding: theme.spacing(1.75, 4.25)
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
padding: theme.spacing(1.75, 5.25)
|
||||
})
|
||||
}
|
||||
: {
|
||||
...(ownerState.size === 'small' && {
|
||||
padding: theme.spacing(2, 3.5)
|
||||
}),
|
||||
...(ownerState.size === 'medium' && {
|
||||
padding: theme.spacing(2, 4.5)
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
padding: theme.spacing(2, 5.5)
|
||||
})
|
||||
})
|
||||
})
|
||||
}),
|
||||
contained: ({ ownerState }) => ({
|
||||
boxShadow: 'var(--mui-customShadows-xs)',
|
||||
...(!ownerState.disabled && {
|
||||
'&:hover, &.Mui-focusVisible': {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
'&:active': {
|
||||
boxShadow: 'none'
|
||||
}
|
||||
})
|
||||
}),
|
||||
sizeSmall: ({ theme }) => ({
|
||||
lineHeight: 1.38462,
|
||||
fontSize: theme.typography.body2.fontSize,
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
}),
|
||||
sizeLarge: {
|
||||
fontSize: '1.0625rem',
|
||||
lineHeight: 1.529412,
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
},
|
||||
startIcon: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
marginInlineEnd: theme.spacing(1.5)
|
||||
}
|
||||
: {
|
||||
...(ownerState.size === 'medium'
|
||||
? {
|
||||
marginInlineEnd: theme.spacing(2)
|
||||
}
|
||||
: {
|
||||
marginInlineEnd: theme.spacing(2.5)
|
||||
})
|
||||
}),
|
||||
...iconStyles(ownerState.size)
|
||||
}),
|
||||
endIcon: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
marginInlineStart: theme.spacing(1.5)
|
||||
}
|
||||
: {
|
||||
...(ownerState.size === 'medium'
|
||||
? {
|
||||
marginInlineStart: theme.spacing(2)
|
||||
}
|
||||
: {
|
||||
marginInlineStart: theme.spacing(2.5)
|
||||
})
|
||||
}),
|
||||
...iconStyles(ownerState.size)
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'text', color: 'primary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-primary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'secondary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'error' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-error-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'warning' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-warning-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'info' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-info-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'success' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-success-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'primary' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-primary-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-primary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
borderColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'secondary' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-secondary-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
borderColor: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'error' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-error-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-error-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-main)',
|
||||
borderColor: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'warning' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-warning-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-warning-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
borderColor: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'info' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-info-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-info-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-main)',
|
||||
borderColor: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'success' },
|
||||
style: {
|
||||
borderColor: 'var(--mui-palette-success-main)',
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))':
|
||||
{
|
||||
backgroundColor: 'var(--mui-palette-success-lighterOpacity)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-main)',
|
||||
borderColor: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'primary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-primary-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'secondary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'error' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-error-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'warning' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-warning-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'info' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-info-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'contained', color: 'success' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-success-dark)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-contrastText)',
|
||||
backgroundColor: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default button
|
||||
@@ -0,0 +1,91 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const card = (skin: Skin): Theme['components'] => {
|
||||
return {
|
||||
MuiCard: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
variant: 'outlined'
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
...(ownerState.variant !== 'outlined' && {
|
||||
boxShadow: 'var(--mui-customShadows-md)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiCardHeader: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiCardContent-root, & + .MuiCardActions-root': {
|
||||
paddingBlockStart: 0
|
||||
},
|
||||
'& + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child':
|
||||
{
|
||||
paddingBlockStart: 0
|
||||
}
|
||||
}),
|
||||
subheader: ({ theme }) => ({
|
||||
...theme.typography.subtitle1,
|
||||
color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)'
|
||||
}),
|
||||
action: ({ theme }) => ({
|
||||
...theme.typography.body1,
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
marginBlock: 0,
|
||||
marginInlineEnd: 0,
|
||||
'& .MuiIconButton-root': {
|
||||
color: 'inherit'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiCardContent: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
'&:last-child': {
|
||||
paddingBlockEnd: theme.spacing(5)
|
||||
},
|
||||
'& + .MuiCardHeader-root, & + .MuiCardContent-root, & + .MuiCardActions-root': {
|
||||
paddingBlockStart: 0
|
||||
},
|
||||
'& + .MuiCollapse-root .MuiCardHeader-root:first-child, & + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child':
|
||||
{
|
||||
paddingBlockStart: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiCardActions: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'&:where(.card-actions-dense)': {
|
||||
padding: theme.spacing(2.5),
|
||||
'& .MuiButton-text': {
|
||||
paddingInline: theme.spacing(2.5)
|
||||
}
|
||||
},
|
||||
'& + .MuiCardHeader-root, & + .MuiCardContent-root, & + .MuiCardActions-root': {
|
||||
paddingBlockStart: 0
|
||||
},
|
||||
'& + .MuiCollapse-root .MuiCardHeader-root:first-child, & + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child':
|
||||
{
|
||||
paddingBlockStart: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default card
|
||||
@@ -0,0 +1,94 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const Icon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path
|
||||
d='M8 4h8a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4V8a4 4 0 0 1 4-4Z'
|
||||
stroke='var(--mui-palette-text-secondary)'
|
||||
strokeWidth='2'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const IndeterminateIcon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M3 8a5 5 0 0 1 5-5h8a5 5 0 0 1 5 5v8a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8Z' fill='currentColor' />
|
||||
<path d='M8.5 11.5h7v1h-7v-1Z' fill='var(--mui-palette-common-white)' />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const CheckedIcon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M3 8a5 5 0 0 1 5-5h8a5 5 0 0 1 5 5v8a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8Z' fill='currentColor' />
|
||||
<path
|
||||
d='m11 13.586 4.596-4.597.707.707L11 15l-3.182-3.182.707-.707L11 13.586Z'
|
||||
fill='var(--mui-palette-common-white)'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const checkbox: Theme['components'] = {
|
||||
MuiCheckbox: {
|
||||
defaultProps: {
|
||||
icon: <Icon />,
|
||||
indeterminateIcon: <IndeterminateIcon />,
|
||||
checkedIcon: <CheckedIcon />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
padding: theme.spacing(1),
|
||||
'& svg': {
|
||||
fontSize: '1.25rem'
|
||||
}
|
||||
}
|
||||
: {
|
||||
padding: theme.spacing(1.5),
|
||||
'& svg': {
|
||||
fontSize: '1.5rem'
|
||||
}
|
||||
}),
|
||||
'&.Mui-checked:not(.Mui-disabled) svg': {
|
||||
filter: 'drop-shadow(var(--mui-customShadows-xs))'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
'&:not(.Mui-checked)': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorPrimary': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorSecondary': {
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorError': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorWarning': {
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorInfo': {
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiCheckbox-colorSuccess': {
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default checkbox
|
||||
@@ -0,0 +1,190 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const chip: Theme['components'] = {
|
||||
MuiChip: {
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'tonal', color: 'primary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-primary-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'secondary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-secondary-lightOpacity)',
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'error' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-error-lightOpacity)',
|
||||
color: 'var(--mui-palette-error-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-error-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-error-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-error-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'warning' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-warning-lightOpacity)',
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-warning-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-warning-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-warning-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'info' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-info-lightOpacity)',
|
||||
color: 'var(--mui-palette-info-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-info-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-info-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-info-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'success' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-success-lightOpacity)',
|
||||
color: 'var(--mui-palette-success-main)',
|
||||
'&.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-success-mainOpacity)'
|
||||
},
|
||||
'& .MuiChip-deleteIcon': {
|
||||
color: 'rgb(var(--mui-palette-success-mainChannel) / 0.7)',
|
||||
'&:hover': {
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
},
|
||||
'&.MuiChip-clickable:hover': {
|
||||
backgroundColor: 'var(--mui-palette-success-main)',
|
||||
color: 'var(--mui-palette-common-white)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
styleOverrides: {
|
||||
root: ({ ownerState, theme }) => ({
|
||||
...theme.typography.body2,
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
|
||||
'& .MuiChip-deleteIcon': {
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
fontSize: '1rem',
|
||||
marginInlineEnd: theme.spacing(1),
|
||||
marginInlineStart: theme.spacing(-2)
|
||||
}
|
||||
: {
|
||||
fontSize: '1.25rem',
|
||||
marginInlineEnd: theme.spacing(2),
|
||||
marginInlineStart: theme.spacing(-3)
|
||||
})
|
||||
},
|
||||
'& .MuiChip-avatar, & .MuiChip-icon': {
|
||||
'& i, & svg': {
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
fontSize: 13
|
||||
}
|
||||
: {
|
||||
fontSize: 15
|
||||
})
|
||||
},
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
height: 16,
|
||||
width: 16,
|
||||
marginInlineStart: theme.spacing(1),
|
||||
marginInlineEnd: theme.spacing(-2)
|
||||
}
|
||||
: {
|
||||
height: 20,
|
||||
width: 20,
|
||||
marginInlineStart: theme.spacing(2),
|
||||
marginInlineEnd: theme.spacing(-3)
|
||||
})
|
||||
}
|
||||
}),
|
||||
label: ({ ownerState, theme }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
paddingInline: theme.spacing(3)
|
||||
}
|
||||
: {
|
||||
paddingInline: theme.spacing(4)
|
||||
})
|
||||
}),
|
||||
iconMedium: {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
iconSmall: {
|
||||
fontSize: '1rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default chip
|
||||
@@ -0,0 +1,67 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const dialog = (skin: Skin): Theme['components'] => ({
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: ({ theme }) => ({
|
||||
...(skin !== 'bordered'
|
||||
? {
|
||||
boxShadow: 'var(--mui-customShadows-xl)'
|
||||
}
|
||||
: {
|
||||
boxShadow: 'none'
|
||||
}),
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
'&:not(.MuiDialog-paperFullScreen)': {
|
||||
margin: theme.spacing(6)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiDialogTitle: {
|
||||
defaultProps: {
|
||||
variant: 'h5'
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiDialogActions-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiDialogContent: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& + .MuiDialogContent-root, & + .MuiDialogActions-root': {
|
||||
paddingTop: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiDialogActions: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(5),
|
||||
'& .MuiButtonBase-root:not(:first-of-type)': {
|
||||
marginInlineStart: theme.spacing(4)
|
||||
},
|
||||
'&:where(.dialog-actions-dense)': {
|
||||
padding: theme.spacing(2.5),
|
||||
'& .MuiButton-text': {
|
||||
paddingInline: theme.spacing(2.5)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default dialog
|
||||
@@ -0,0 +1,26 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const drawer = (skin: Skin): Theme['components'] => ({
|
||||
MuiDrawer: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
PaperProps: {
|
||||
elevation: 0
|
||||
}
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-lg)'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default drawer
|
||||
@@ -0,0 +1,68 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const fab: Theme['components'] = {
|
||||
MuiFab: {
|
||||
variants: [
|
||||
{
|
||||
props: { color: 'default' },
|
||||
style: {
|
||||
color: 'rgb(var(--mui-mainColorChannels-light) / 0.9)',
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-grey-A100)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'primary' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-primary-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'secondary' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'error' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-error-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'warning' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-warning-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'info' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-info-dark)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'success' },
|
||||
style: {
|
||||
'&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'var(--mui-palette-success-dark)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default fab
|
||||
@@ -0,0 +1,22 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const formControlLabel: Theme['components'] = {
|
||||
MuiFormControlLabel: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
marginInlineStart: theme.spacing(-2)
|
||||
}),
|
||||
label: {
|
||||
'&, &.Mui-disabled': {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default formControlLabel
|
||||
@@ -0,0 +1,140 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
const iconButton: Theme['components'] = {
|
||||
MuiIconButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'& .MuiSvgIcon-root, & i, & svg': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
},
|
||||
sizeSmall: ({ theme }) => ({
|
||||
padding: theme.spacing(1.75),
|
||||
fontSize: '1.25rem'
|
||||
}),
|
||||
sizeMedium: ({ theme }) => ({
|
||||
padding: theme.spacing(2),
|
||||
fontSize: '1.375rem'
|
||||
}),
|
||||
sizeLarge: ({ theme }) => ({
|
||||
padding: theme.spacing(2.25),
|
||||
fontSize: '1.5rem'
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { color: 'default' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': {
|
||||
backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)'
|
||||
}
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'primary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-primary-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'secondary' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'error' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-error-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-error-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'warning' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-warning-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-warning-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'info' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-info-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-info-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { color: 'success' },
|
||||
style: {
|
||||
'&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': {
|
||||
backgroundColor: 'var(--mui-palette-success-lighterOpacity)'
|
||||
},
|
||||
...(themeConfig.disableRipple && {
|
||||
'&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-success-lighterOpacity)' }
|
||||
}),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default iconButton
|
||||
@@ -0,0 +1,83 @@
|
||||
// Override Imports
|
||||
import Accordion from './accordion'
|
||||
import Alerts from './alerts'
|
||||
import Autocomplete from './autocomplete'
|
||||
import avatar from './avatar'
|
||||
import backdrop from './backdrop'
|
||||
import badges from './badges'
|
||||
import breadcrumbs from './breadcrumbs'
|
||||
import button from './button'
|
||||
import buttonGroup from './button-group'
|
||||
import card from './card'
|
||||
import Checkbox from './checkbox'
|
||||
import chip from './chip'
|
||||
import dialog from './dialog'
|
||||
import drawer from './drawer'
|
||||
import fab from './fab'
|
||||
import formControlLabel from './form-control-label'
|
||||
import iconButton from './icon-button'
|
||||
import input from './input'
|
||||
import list from './list'
|
||||
import menu from './menu'
|
||||
import pagination from './pagination'
|
||||
import paper from './paper'
|
||||
import popover from './popover'
|
||||
import progress from './progress'
|
||||
import Radio from './radio'
|
||||
import Rating from './rating'
|
||||
import Select from './select'
|
||||
import slider from './slider'
|
||||
import snackbar from './snackbar'
|
||||
import switchOverrides from './switch'
|
||||
import tablePagination from './table-pagination'
|
||||
import tabs from './tabs'
|
||||
import timeline from './timeline'
|
||||
import toggleButton from './toggle-button'
|
||||
import tooltip from './tooltip'
|
||||
import typography from './typography'
|
||||
|
||||
const overrides = () => {
|
||||
const skin = 'default'
|
||||
|
||||
return Object.assign(
|
||||
{},
|
||||
Accordion(skin),
|
||||
Alerts,
|
||||
Autocomplete(skin),
|
||||
avatar,
|
||||
backdrop,
|
||||
badges,
|
||||
breadcrumbs,
|
||||
button,
|
||||
buttonGroup,
|
||||
card(skin),
|
||||
Checkbox,
|
||||
chip,
|
||||
dialog(skin),
|
||||
drawer(skin),
|
||||
fab,
|
||||
formControlLabel,
|
||||
iconButton,
|
||||
input,
|
||||
list,
|
||||
menu(skin),
|
||||
pagination,
|
||||
paper,
|
||||
popover(skin),
|
||||
progress,
|
||||
Radio,
|
||||
Rating,
|
||||
Select,
|
||||
slider,
|
||||
snackbar(skin),
|
||||
switchOverrides,
|
||||
tablePagination,
|
||||
tabs,
|
||||
timeline,
|
||||
toggleButton,
|
||||
tooltip,
|
||||
typography
|
||||
)
|
||||
}
|
||||
|
||||
export default overrides
|
||||
@@ -0,0 +1,112 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const input: Theme['components'] = {
|
||||
MuiFormControl: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:has(.MuiRadio-root) .MuiFormHelperText-root, &:has(.MuiCheckbox-root) .MuiFormHelperText-root, &:has(.MuiSwitch-root) .MuiFormHelperText-root':
|
||||
{
|
||||
marginInline: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInputBase: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
lineHeight: 1.6,
|
||||
'&.MuiInput-underline': {
|
||||
'&:before': {
|
||||
borderColor: 'var(--mui-palette-customColors-inputBorder)'
|
||||
},
|
||||
'&:not(.Mui-disabled, .Mui-error):hover:before': {
|
||||
borderColor: 'var(--mui-palette-action-active)'
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled .MuiInputAdornment-root, &.Mui-disabled .MuiInputAdornment-root > *': {
|
||||
color: 'var(--mui-palette-action-disabled)'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiFilledInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:before': {
|
||||
borderBottom: '1px solid var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'&.Mui-disabled:before': {
|
||||
borderBottomStyle: 'solid'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInputLabel: {
|
||||
styleOverrides: {
|
||||
shrink: ({ ownerState }) => ({
|
||||
...(ownerState.variant === 'outlined' && {
|
||||
color: 'var(--mui-palette-text-secondary)',
|
||||
transform: 'translate(14px, -8px) scale(0.867)'
|
||||
}),
|
||||
...(ownerState.variant === 'filled' && {
|
||||
transform: 'translate(12px, 7px) scale(0.867)'
|
||||
}),
|
||||
...(ownerState.variant === 'standard' && {
|
||||
transform: 'translate(0, -1.5px) scale(0.867)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(.Mui-focused):not(.Mui-error):not(.Mui-disabled):hover .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'var(--mui-palette-action-active)'
|
||||
},
|
||||
'&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'var(--mui-palette-action-disabledBackground)'
|
||||
}
|
||||
},
|
||||
input: ({ theme, ownerState }) => ({
|
||||
...(ownerState?.size === 'medium' && {
|
||||
'&:not(.MuiInputBase-inputMultiline, .MuiInputBase-inputAdornedStart)': {
|
||||
paddingBlock: theme.spacing(4)
|
||||
},
|
||||
height: '1.5em'
|
||||
}),
|
||||
'& ~ .MuiOutlinedInput-notchedOutline': {
|
||||
borderColor: 'var(--mui-palette-customColors-inputBorder)'
|
||||
}
|
||||
}),
|
||||
notchedOutline: {
|
||||
'& legend': {
|
||||
fontSize: '0.867em'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiInputAdornment: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'& i, & svg': {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
'& *': {
|
||||
color: 'inherit !important'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiFormHelperText: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
lineHeight: 1,
|
||||
letterSpacing: 'unset'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default input
|
||||
@@ -0,0 +1,81 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const list: Theme['components'] = {
|
||||
MuiListItem: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
gap: theme.spacing(4)
|
||||
}),
|
||||
padding: ({ theme, ownerState }) => ({
|
||||
...(!ownerState.dense && {
|
||||
paddingBlock: theme.spacing(2),
|
||||
paddingInlineStart: theme.spacing(5)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiListItemAvatar: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minWidth: 'unset'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListItemIcon: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minWidth: 0,
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
fontSize: '1.375rem',
|
||||
'& > svg, & > i': {
|
||||
fontSize: 'inherit'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListItemButton: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
gap: theme.spacing(4),
|
||||
...(!ownerState.dense && {
|
||||
paddingBlock: theme.spacing(2)
|
||||
}),
|
||||
paddingInlineStart: theme.spacing(5),
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
'&:hover, &.Mui-focused, &.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
},
|
||||
'& .MuiTypography-root': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'& + .MuiListItemSecondaryAction-root .MuiIconButton-root': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiListItemText: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
margin: 0
|
||||
},
|
||||
primary: {
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiListSubheader: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
...theme.typography.subtitle2,
|
||||
paddingBlock: 10,
|
||||
paddingInline: theme.spacing(5)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default list
|
||||
@@ -0,0 +1,57 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const menu = (skin: Skin): Theme['components'] => ({
|
||||
MuiMenu: {
|
||||
defaultProps: {
|
||||
...(skin === 'bordered' && {
|
||||
slotProps: {
|
||||
paper: {
|
||||
elevation: 0
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
styleOverrides: {
|
||||
paper: ({ theme }) => ({
|
||||
marginBlockStart: theme.spacing(0.5),
|
||||
...(skin !== 'bordered' && {
|
||||
boxShadow: 'var(--mui-customShadows-lg)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiMenuItem: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
paddingBlock: theme.spacing(2),
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'& i, & svg': {
|
||||
fontSize: '1.375rem'
|
||||
},
|
||||
'& .MuiListItemIcon-root': {
|
||||
minInlineSize: 0
|
||||
},
|
||||
'&.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'& .MuiListItemIcon-root': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'&:hover, &.Mui-focused, &.Mui-focusVisible': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
color: 'var(--mui-palette-text-disabled)',
|
||||
opacity: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default menu
|
||||
@@ -0,0 +1,172 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const pagination: Theme['components'] = {
|
||||
MuiPagination: {
|
||||
styleOverrides: {
|
||||
ul: {
|
||||
rowGap: 6
|
||||
}
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'text', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-primary-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'text', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-secondary-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'standard' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
borderColor: 'var(--mui-palette-action-selected)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
backgroundColor: 'rgb(var(--mui-palette-primary-mainChannel) / var(--mui-palette-action-activatedOpacity))',
|
||||
borderColor: 'rgba(var(--mui-palette-primary-mainChannel) / 0.5)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'outlined', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
backgroundColor:
|
||||
'rgb(var(--mui-palette-secondary-mainChannel) / var(--mui-palette-action-activatedOpacity))',
|
||||
borderColor: 'rgba(var(--mui-palette-secondary-mainChannel) / 0.5)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root:not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-action-selected)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'standard' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--mui-palette-primary-mainOpacity)'
|
||||
}
|
||||
},
|
||||
'& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-action-focus)'
|
||||
},
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'primary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-primary-contrastText)',
|
||||
'&:not(.Mui-disabled)': {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--mui-palette-primary-dark)'
|
||||
}
|
||||
},
|
||||
'& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-primary-main)',
|
||||
color: 'var(--mui-palette-primary-contrastText)'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'secondary' },
|
||||
style: {
|
||||
'& .MuiPaginationItem-root.Mui-selected': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-secondary-contrastText)',
|
||||
'&:not(.Mui-disabled)': {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-dark)'
|
||||
}
|
||||
},
|
||||
'& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-mainOpacity)',
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
},
|
||||
'& .MuiPaginationItem-root.Mui-selected.Mui-disabled': {
|
||||
backgroundColor: 'var(--mui-palette-secondary-main)',
|
||||
color: 'var(--mui-palette-secondary-contrastText)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
MuiPaginationItem: {
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
...(ownerState.size === 'medium' && {
|
||||
height: '2.375rem',
|
||||
minWidth: '2.375rem'
|
||||
}),
|
||||
...(ownerState.shape !== 'rounded' && {
|
||||
borderRadius: '50px'
|
||||
}),
|
||||
'&.Mui-selected.Mui-disabled': {
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
opacity: 0.45
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45
|
||||
},
|
||||
...(ownerState.shape === 'rounded' &&
|
||||
ownerState.size === 'small' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
}),
|
||||
...(ownerState.shape === 'rounded' &&
|
||||
ownerState.size === 'large' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
})
|
||||
}),
|
||||
sizeSmall: {
|
||||
height: '2.125rem',
|
||||
minWidth: '2.125rem'
|
||||
},
|
||||
sizeLarge: {
|
||||
height: '2.625rem',
|
||||
minWidth: '2.625rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default pagination
|
||||
@@ -0,0 +1,14 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const paper: Theme['components'] = {
|
||||
MuiPaper: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundImage: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default paper
|
||||
@@ -0,0 +1,21 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const popover = (skin: Skin): Theme['components'] => ({
|
||||
MuiPopover: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
...(skin === 'bordered'
|
||||
? { boxShadow: 'none', border: '1px solid var(--mui-palette-divider)' }
|
||||
: {
|
||||
boxShadow: 'var(--mui-customShadows-sm)'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default popover
|
||||
@@ -0,0 +1,18 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const progress: Theme['components'] = {
|
||||
MuiLinearProgress: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
height: 6,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
'& .MuiLinearProgress-bar': {
|
||||
borderRadius: theme.shape.borderRadius
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default progress
|
||||
@@ -0,0 +1,81 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const IconChecked = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path
|
||||
d='M12 18.5a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13Z'
|
||||
fill='var(--mui-palette-common-white)'
|
||||
stroke='currentColor'
|
||||
strokeWidth='5'
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const UncheckedIcon = () => {
|
||||
return (
|
||||
<svg width='1em' height='1em' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M12 20a8 8 0 1 1 0-16 8 8 0 0 1 0 16Z' stroke='var(--mui-palette-text-secondary)' strokeWidth='2' />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const radio: Theme['components'] = {
|
||||
MuiRadio: {
|
||||
defaultProps: {
|
||||
icon: <UncheckedIcon />,
|
||||
checkedIcon: <IconChecked />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
padding: theme.spacing(1),
|
||||
'& svg': {
|
||||
fontSize: '1.25rem'
|
||||
}
|
||||
}
|
||||
: {
|
||||
padding: theme.spacing(1.5),
|
||||
'& svg': {
|
||||
fontSize: '1.5rem'
|
||||
}
|
||||
}),
|
||||
'&.Mui-checked:not(.Mui-disabled) svg': {
|
||||
filter: 'drop-shadow(var(--mui-customShadows-xs))'
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
'&:not(.Mui-checked)': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorPrimary': {
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorSecondary': {
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorError': {
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorWarning': {
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorInfo': {
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
},
|
||||
'&.Mui-checked.MuiRadio-colorSuccess': {
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default radio
|
||||
@@ -0,0 +1,35 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const rating: Theme['components'] = {
|
||||
MuiRating: {
|
||||
defaultProps: {
|
||||
emptyIcon: <i className='ri-star-line' />,
|
||||
icon: <i className='ri-star-fill' />
|
||||
},
|
||||
styleOverrides: {
|
||||
root: {
|
||||
gap: '2px',
|
||||
color: 'var(--mui-palette-warning-main)',
|
||||
'& i, & svg': {
|
||||
flexShrink: 0
|
||||
},
|
||||
'& .MuiRating-decimal > label:first-of-type, & .MuiRating-decimal > span:first-of-type': {
|
||||
zIndex: 1
|
||||
}
|
||||
},
|
||||
sizeSmall: {
|
||||
'& .MuiRating-icon i, & .MuiRating-icon svg': {
|
||||
fontSize: '1.25rem'
|
||||
}
|
||||
},
|
||||
sizeLarge: {
|
||||
'& .MuiRating-icon i, & .MuiRating-icon svg': {
|
||||
fontSize: '1.75rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default rating
|
||||
@@ -0,0 +1,61 @@
|
||||
// React Imports
|
||||
import React from 'react'
|
||||
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const SelectIcon = () => {
|
||||
return <i className='ri-arrow-down-s-line' />
|
||||
}
|
||||
|
||||
const iconStyles = (theme: Theme) => ({
|
||||
userSelect: 'none',
|
||||
display: 'inline-block',
|
||||
fill: 'currentColor',
|
||||
flexShrink: 0,
|
||||
transition: theme.transitions.create('fill', {
|
||||
duration: theme.transitions.duration.shorter
|
||||
}),
|
||||
fontSize: '1.25rem',
|
||||
position: 'absolute',
|
||||
right: '1rem',
|
||||
top: 'calc(50% - 0.5em)',
|
||||
pointerEvents: 'none'
|
||||
})
|
||||
|
||||
const select: Theme['components'] = {
|
||||
MuiSelect: {
|
||||
defaultProps: {
|
||||
IconComponent: SelectIcon
|
||||
},
|
||||
styleOverrides: {
|
||||
select: ({ theme, ownerState }) => ({
|
||||
...(ownerState.variant === 'outlined' && {
|
||||
minHeight: '1.5em'
|
||||
}),
|
||||
'&[aria-expanded="true"] ~ i, &[aria-expanded="true"] ~ svg': {
|
||||
transform: 'rotate(180deg)'
|
||||
},
|
||||
'& ~ i, & ~ svg': iconStyles(theme as Theme),
|
||||
'&.MuiInputBase-inputSizeSmall': {
|
||||
'& ~ i, & ~ svg': {
|
||||
height: '1.375rem',
|
||||
width: '1.375rem'
|
||||
}
|
||||
},
|
||||
'&:not(aria-label="Without label") ~ .MuiOutlinedInput-notchedOutline > legend > span': {
|
||||
paddingInline: '5px'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiNativeSelect: {
|
||||
styleOverrides: {
|
||||
select: ({ theme }) => ({
|
||||
'& + i, & + svg': iconStyles(theme as Theme)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default select
|
||||
@@ -0,0 +1,100 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const slider: Theme['components'] = {
|
||||
MuiSlider: {
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
boxSizing: 'border-box',
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? ownerState.size !== 'small'
|
||||
? { height: 6 }
|
||||
: { height: 4 }
|
||||
: ownerState.size !== 'small'
|
||||
? { width: 6 }
|
||||
: { width: 4 }),
|
||||
'&.Mui-disabled': {
|
||||
opacity: 0.45,
|
||||
color: `var(--mui-palette-${ownerState.color}-main)`
|
||||
}
|
||||
}),
|
||||
thumb: ({ ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
height: 14,
|
||||
width: 14,
|
||||
border: '2px solid currentColor',
|
||||
'&:hover, &.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 7px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
},
|
||||
'&.Mui-active.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 10px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
}
|
||||
}
|
||||
: {
|
||||
height: 22,
|
||||
width: 22,
|
||||
border: '4px solid currentColor'
|
||||
}),
|
||||
backgroundColor: 'var(--mui-palette-common-white)',
|
||||
...(!ownerState.disabled && {
|
||||
boxShadow: 'var(--mui-customShadows-sm)'
|
||||
}),
|
||||
'&:before': {
|
||||
boxShadow: 'none'
|
||||
},
|
||||
'&:after': {
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
height: 28,
|
||||
width: 28
|
||||
}
|
||||
: {
|
||||
height: 38,
|
||||
width: 38
|
||||
})
|
||||
},
|
||||
'&:hover, &.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 8px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
},
|
||||
'&.Mui-active.Mui-focusVisible': {
|
||||
boxShadow: `0 0 0 13px var(--mui-palette-${ownerState.color}-lightOpacity)`
|
||||
}
|
||||
}),
|
||||
rail: ({ ownerState }) => ({
|
||||
opacity: 1,
|
||||
color: `var(--mui-palette-${ownerState.color}-lightOpacity)`,
|
||||
...(ownerState.track === 'inverted' && {
|
||||
backgroundColor: `var(--mui-palette-${ownerState.color}-main)`
|
||||
})
|
||||
}),
|
||||
valueLabel: ({ theme, ownerState }) => ({
|
||||
...(ownerState.size === 'small'
|
||||
? {
|
||||
...theme.typography.caption,
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)',
|
||||
padding: theme.spacing(1, 2)
|
||||
}
|
||||
: {
|
||||
...theme.typography.body2,
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
borderRadius: 'var(--mui-shape-borderRadius)',
|
||||
padding: theme.spacing(1, 2.5)
|
||||
}),
|
||||
color: 'var(--mui-palette-customColors-tooltipText)',
|
||||
backgroundColor: 'var(--mui-palette-Tooltip-bg)',
|
||||
'&:before': {
|
||||
display: 'none'
|
||||
}
|
||||
}),
|
||||
track: ({ theme, ownerState }) => ({
|
||||
...(ownerState.track === 'inverted' && {
|
||||
backgroundColor: `color-mix(in srgb, ${theme.palette[ownerState.color || 'primary'].main} 16%, var(--mui-palette-background-paper))`,
|
||||
borderColor: `color-mix(in srgb, ${theme.palette[ownerState.color || 'primary'].main} 16%, var(--mui-palette-background-paper))`
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default slider
|
||||
@@ -0,0 +1,27 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { Skin } from '@core/types'
|
||||
|
||||
const snackbar = (skin: Skin): Theme['components'] => ({
|
||||
MuiSnackbarContent: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(0, 4),
|
||||
...(skin !== 'bordered'
|
||||
? {
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
}
|
||||
: {
|
||||
boxShadow: 'none'
|
||||
}),
|
||||
'& .MuiSnackbarContent-message': {
|
||||
paddingBlock: theme.spacing(3)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default snackbar
|
||||
@@ -0,0 +1,69 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const switchOverrides: Theme['components'] = {
|
||||
MuiSwitch: {
|
||||
defaultProps: {
|
||||
disableRipple: true
|
||||
},
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
'&:has(.Mui-disabled)': {
|
||||
opacity: 0.45
|
||||
},
|
||||
...(ownerState.size !== 'small'
|
||||
? {
|
||||
width: 46,
|
||||
height: 36,
|
||||
padding: theme.spacing(2.25, 2)
|
||||
}
|
||||
: {
|
||||
width: 42,
|
||||
height: 30,
|
||||
padding: theme.spacing(1.75, 2),
|
||||
'& .MuiSwitch-thumb': {
|
||||
width: 12,
|
||||
height: 12
|
||||
},
|
||||
'& .MuiSwitch-switchBase': {
|
||||
padding: 7,
|
||||
left: 3,
|
||||
'&.Mui-checked': {
|
||||
left: -3
|
||||
}
|
||||
}
|
||||
})
|
||||
}),
|
||||
switchBase: {
|
||||
top: 2,
|
||||
left: 1,
|
||||
'&.Mui-checked': {
|
||||
left: -7,
|
||||
color: 'var(--mui-palette-common-white)',
|
||||
'& + .MuiSwitch-track': {
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
'&.Mui-disabled + .MuiSwitch-track': {
|
||||
opacity: 1
|
||||
},
|
||||
'&:hover:not(:has(span.MuiTouchRipple-root))': {
|
||||
backgroundColor: 'transparent'
|
||||
}
|
||||
},
|
||||
thumb: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
boxShadow: 'var(--mui-customShadows-xs)'
|
||||
},
|
||||
track: {
|
||||
opacity: 1,
|
||||
borderRadius: 10,
|
||||
backgroundColor: 'var(--mui-palette-action-focus)',
|
||||
boxShadow: `0 0 4px rgb(0 0 0 / 0.16) inset`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default switchOverrides
|
||||
@@ -0,0 +1,42 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const tablePagination: Theme['components'] = {
|
||||
MuiTablePagination: {
|
||||
styleOverrides: {
|
||||
toolbar: ({ theme }) => ({
|
||||
paddingInlineEnd: `${theme.spacing(3)} !important`
|
||||
}),
|
||||
select: ({ theme }) => ({
|
||||
...theme.typography.body1,
|
||||
paddingInlineStart: 0,
|
||||
'& ~ i, & ~ svg': {
|
||||
fontSize: 20,
|
||||
right: '2px !important',
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
}
|
||||
}),
|
||||
selectLabel: ({ theme }) => ({
|
||||
...theme.typography.body1,
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
}),
|
||||
input: ({ theme }) => ({
|
||||
marginInlineEnd: theme.spacing(6)
|
||||
}),
|
||||
displayedRows: ({ theme }) => ({
|
||||
...theme.typography.body1
|
||||
}),
|
||||
actions: ({ theme }) => ({
|
||||
marginInlineStart: theme.spacing(6),
|
||||
'& .Mui-disabled': {
|
||||
color: 'var(--mui-palette-action-active)'
|
||||
},
|
||||
'& .MuiIconButton-root:last-of-type': {
|
||||
marginInlineStart: theme.spacing(2)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tablePagination
|
||||
@@ -0,0 +1,92 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const tabs: Theme['components'] = {
|
||||
MuiTabs: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
minBlockSize: 38,
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? {
|
||||
borderBlockEnd: '1px solid var(--mui-palette-divider)'
|
||||
}
|
||||
: {
|
||||
borderInlineEnd: '1px solid var(--mui-palette-divider)'
|
||||
}),
|
||||
'& .MuiTab-root:hover': {
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? {
|
||||
paddingBlockEnd: theme.spacing(1.5),
|
||||
...(ownerState.textColor === 'secondary'
|
||||
? {
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
borderBlockEnd: '2px solid var(--mui-palette-secondary-lightOpacity)'
|
||||
}
|
||||
: {
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
borderBlockEnd: '2px solid var(--mui-palette-primary-lightOpacity)'
|
||||
})
|
||||
}
|
||||
: {
|
||||
paddingInlineEnd: theme.spacing(5),
|
||||
...(ownerState.textColor === 'secondary'
|
||||
? {
|
||||
color: 'var(--mui-palette-secondary-main)',
|
||||
borderInlineEnd: '2px solid var(--mui-palette-secondary-mainOpacity)'
|
||||
}
|
||||
: {
|
||||
color: 'var(--mui-palette-primary-main)',
|
||||
borderInlineEnd: '2px solid var(--mui-palette-primary-mainOpacity)'
|
||||
})
|
||||
}),
|
||||
'& .MuiTabScrollButton-root': {
|
||||
borderRadius: theme.shape.borderRadius
|
||||
}
|
||||
},
|
||||
'& ~ .MuiTabPanel-root': {
|
||||
...(ownerState.orientation === 'horizontal'
|
||||
? {
|
||||
paddingBlockStart: theme.spacing(5)
|
||||
}
|
||||
: {
|
||||
paddingInlineStart: theme.spacing(5)
|
||||
})
|
||||
}
|
||||
}),
|
||||
vertical: {
|
||||
minWidth: 131,
|
||||
'& .MuiTab-root': {
|
||||
minWidth: 130
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTab: {
|
||||
styleOverrides: {
|
||||
root: ({ theme, ownerState }) => ({
|
||||
lineHeight: 1.4667,
|
||||
padding: theme.spacing(2, 5.5),
|
||||
minBlockSize: 38,
|
||||
color: 'var(--mui-palette-text-primary)',
|
||||
'& > .MuiTab-iconWrapper': {
|
||||
fontSize: '1.125rem',
|
||||
...(ownerState.iconPosition === 'start' && {
|
||||
marginInlineEnd: theme.spacing(1.5)
|
||||
}),
|
||||
...(ownerState.iconPosition === 'end' && {
|
||||
marginInlineStart: theme.spacing(1.5)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiTabPanel: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tabs
|
||||
@@ -0,0 +1,161 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const timeline: Theme['components'] = {
|
||||
MuiTimeline: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineDot: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
margin: theme.spacing(3, 0),
|
||||
boxShadow: 'none',
|
||||
'&:has(> i), &:has(> svg)': {
|
||||
padding: 6
|
||||
},
|
||||
'& > svg, & > i': {
|
||||
fontSize: '1.25rem'
|
||||
},
|
||||
'&:has(svg)': {
|
||||
width: 32,
|
||||
height: 32,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'outlined' },
|
||||
style: {
|
||||
padding: 5,
|
||||
'& + .MuiTimelineConnector-root': {
|
||||
backgroundColor: 'transparent',
|
||||
borderInlineStart: '1px dashed var(--mui-palette-divider)'
|
||||
},
|
||||
'&:has(+ .MuiTimelineConnector-root)': {
|
||||
marginBlock: '0.625rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'grey' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px rgb(var(--mui-mainColorChannels-light) / 0.04)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'primary' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-primary-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'secondary' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-secondary-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'error' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-error-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'warning' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-warning-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'info' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-info-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'filled', color: 'success' },
|
||||
style: {
|
||||
boxShadow: '0 0 0 3px var(--mui-palette-success-lightOpacity)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal' },
|
||||
style: {
|
||||
border: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'grey' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-action-selected)',
|
||||
color: 'var(--mui-palette-text-primary)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'primary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-primary-lightOpacity)',
|
||||
color: 'var(--mui-palette-primary-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'secondary' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-secondary-lightOpacity)',
|
||||
color: 'var(--mui-palette-secondary-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'error' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-error-lightOpacity)',
|
||||
color: 'var(--mui-palette-error-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'warning' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-warning-lightOpacity)',
|
||||
color: 'var(--mui-palette-warning-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'info' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-info-lightOpacity)',
|
||||
color: 'var(--mui-palette-info-main)'
|
||||
}
|
||||
},
|
||||
{
|
||||
props: { variant: 'tonal', color: 'success' },
|
||||
style: {
|
||||
backgroundColor: 'var(--mui-palette-success-lightOpacity)',
|
||||
color: 'var(--mui-palette-success-main)'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
MuiTimelineConnector: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
width: 1,
|
||||
backgroundColor: 'var(--mui-palette-divider)'
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiTimelineContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
paddingBottom: '1rem'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default timeline
|
||||
@@ -0,0 +1,34 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const toggleButton: Theme['components'] = {
|
||||
MuiToggleButtonGroup: {
|
||||
styleOverrides: {
|
||||
root: ({ ownerState }) => ({
|
||||
...(ownerState.size === 'small' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
}),
|
||||
...(ownerState.size === 'large' && {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
MuiToggleButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:not(.Mui-selected):not(.Mui-disabled)': {
|
||||
color: 'var(--mui-palette-text-secondary)'
|
||||
}
|
||||
},
|
||||
sizeSmall: {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)'
|
||||
},
|
||||
sizeLarge: {
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-lg)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default toggleButton
|
||||
@@ -0,0 +1,32 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const tooltip: Theme['components'] = {
|
||||
MuiTooltip: {
|
||||
styleOverrides: {
|
||||
popper: {
|
||||
'&[data-popper-placement*="bottom"] .MuiTooltip-tooltip': {
|
||||
marginTop: '6px !important'
|
||||
},
|
||||
'&[data-popper-placement*="top"] .MuiTooltip-tooltip': {
|
||||
marginBottom: '6px !important'
|
||||
},
|
||||
'&[data-popper-placement*="left"] .MuiTooltip-tooltip': {
|
||||
marginRight: '6px !important'
|
||||
},
|
||||
'&[data-popper-placement*="right"] .MuiTooltip-tooltip': {
|
||||
marginLeft: '6px !important'
|
||||
}
|
||||
},
|
||||
tooltip: ({ theme }) => ({
|
||||
borderRadius: 'var(--mui-shape-customBorderRadius-sm)',
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
lineHeight: 1.539,
|
||||
color: 'var(--mui-palette-customColors-tooltipText)',
|
||||
paddingInline: theme.spacing(3)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tooltip
|
||||
@@ -0,0 +1,68 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const typography: Theme['components'] = {
|
||||
MuiTypography: {
|
||||
styleOverrides: {
|
||||
gutterBottom: ({ theme }) => ({
|
||||
marginBottom: theme.spacing(2)
|
||||
})
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
props: { variant: 'h1' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h2' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h3' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h4' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h5' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'h6' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'subtitle1' },
|
||||
style: { color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'subtitle2' },
|
||||
style: { color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'body1' },
|
||||
style: { color: 'var(--mui-palette-text-secondary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'body2' },
|
||||
style: { color: 'var(--mui-palette-text-secondary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'button' },
|
||||
style: { color: 'var(--mui-palette-text-primary)' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'caption' },
|
||||
style: { color: 'var(--mui-palette-text-disabled)', display: 'inline-block' }
|
||||
},
|
||||
{
|
||||
props: { variant: 'overline' },
|
||||
style: { color: 'var(--mui-palette-text-primary)', display: 'inline-block' }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export default typography
|
||||
@@ -0,0 +1,39 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
// Type Imports
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
const shadows = (mode: SystemMode): Theme['shadows'] => {
|
||||
const color = `var(--mui-mainColorChannels-${mode}Shadow)`
|
||||
|
||||
return [
|
||||
'none',
|
||||
`0px 2px 1px -1px rgb(${color} / 0.2),0px 1px 1px 0px rgb(${color} / 0.14),0px 1px 3px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 1px -2px rgb(${color} / 0.2),0px 2px 2px 0px rgb(${color} / 0.14),0px 1px 5px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 3px -2px rgb(${color} / 0.2),0px 3px 4px 0px rgb(${color} / 0.14),0px 1px 8px 0px rgb(${color} / 0.12)`,
|
||||
`0px 2px 4px -1px rgb(${color} / 0.2),0px 4px 5px 0px rgb(${color} / 0.14),0px 1px 10px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 5px -1px rgb(${color} / 0.2),0px 5px 8px 0px rgb(${color} / 0.14),0px 1px 14px 0px rgb(${color} / 0.12)`,
|
||||
`0px 3px 5px -1px rgb(${color} / 0.2),0px 6px 10px 0px rgb(${color} / 0.14),0px 1px 18px 0px rgb(${color} / 0.12)`,
|
||||
`0px 4px 5px -2px rgb(${color} / 0.2),0px 7px 10px 1px rgb(${color} / 0.14),0px 2px 16px 1px rgb(${color} / 0.12)`,
|
||||
`0px 5px 5px -3px rgb(${color} / 0.2),0px 8px 10px 1px rgb(${color} / 0.14),0px 3px 14px 2px rgb(${color} / 0.12)`,
|
||||
`0px 5px 6px -3px rgb(${color} / 0.2),0px 9px 12px 1px rgb(${color} / 0.14),0px 3px 16px 2px rgb(${color} / 0.12)`,
|
||||
`0px 6px 6px -3px rgb(${color} / 0.2),0px 10px 14px 1px rgb(${color} / 0.14),0px 4px 18px 3px rgb(${color} / 0.12)`,
|
||||
`0px 6px 7px -4px rgb(${color} / 0.2),0px 11px 15px 1px rgb(${color} / 0.14),0px 4px 20px 3px rgb(${color} / 0.12)`,
|
||||
`0px 7px 8px -4px rgb(${color} / 0.2),0px 12px 17px 2px rgb(${color} / 0.14),0px 5px 22px 4px rgb(${color} / 0.12)`,
|
||||
`0px 7px 8px -4px rgb(${color} / 0.2),0px 13px 19px 2px rgb(${color} / 0.14),0px 5px 24px 4px rgb(${color} / 0.12)`,
|
||||
`0px 7px 9px -4px rgb(${color} / 0.2),0px 14px 21px 2px rgb(${color} / 0.14),0px 5px 26px 4px rgb(${color} / 0.12)`,
|
||||
`0px 8px 9px -5px rgb(${color} / 0.2),0px 15px 22px 2px rgb(${color} / 0.14),0px 6px 28px 5px rgb(${color} / 0.12)`,
|
||||
`0px 8px 10px -5px rgb(${color} / 0.2),0px 16px 24px 2px rgb(${color} / 0.14),0px 6px 30px 5px rgb(${color} / 0.12)`,
|
||||
`0px 8px 11px -5px rgb(${color} / 0.2),0px 17px 26px 2px rgb(${color} / 0.14),0px 6px 32px 5px rgb(${color} / 0.12)`,
|
||||
`0px 9px 11px -5px rgb(${color} / 0.2),0px 18px 28px 2px rgb(${color} / 0.14),0px 7px 34px 6px rgb(${color} / 0.12)`,
|
||||
`0px 9px 12px -6px rgb(${color} / 0.2),0px 19px 29px 2px rgb(${color} / 0.14),0px 7px 36px 6px rgb(${color} / 0.12)`,
|
||||
`0px 10px 13px -6px rgb(${color} / 0.2),0px 20px 31px 3px rgb(${color} / 0.14),0px 8px 38px 7px rgb(${color} / 0.12)`,
|
||||
`0px 10px 13px -6px rgb(${color} / 0.2),0px 21px 33px 3px rgb(${color} / 0.14),0px 8px 40px 7px rgb(${color} / 0.12)`,
|
||||
`0px 10px 14px -6px rgb(${color} / 0.2),0px 22px 35px 3px rgb(${color} / 0.14),0px 8px 42px 7px rgb(${color} / 0.12)`,
|
||||
`0px 11px 14px -7px rgb(${color} / 0.2),0px 23px 36px 3px rgb(${color} / 0.14),0px 9px 44px 8px rgb(${color} / 0.12)`,
|
||||
`0px 11px 15px -7px rgb(${color} / 0.2),0px 24px 38px 3px rgb(${color} / 0.14),0px 9px 46px 8px rgb(${color} / 0.12)`
|
||||
]
|
||||
}
|
||||
|
||||
export default shadows
|
||||
@@ -0,0 +1,5 @@
|
||||
const spacing = {
|
||||
spacing: (factor: number) => `${0.25 * factor}rem`
|
||||
}
|
||||
|
||||
export default spacing
|
||||
@@ -0,0 +1,88 @@
|
||||
// MUI Imports
|
||||
import type { Theme } from '@mui/material/styles'
|
||||
|
||||
const typography = (fontFamily: string): Theme['typography'] =>
|
||||
({
|
||||
fontFamily:
|
||||
typeof fontFamily === 'undefined' || 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(',')
|
||||
: fontFamily,
|
||||
fontSize: 13.125,
|
||||
h1: {
|
||||
fontSize: '2.875rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.478261
|
||||
},
|
||||
h2: {
|
||||
fontSize: '2.375rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.47368421
|
||||
},
|
||||
h3: {
|
||||
fontSize: '1.75rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.5
|
||||
},
|
||||
h4: {
|
||||
fontSize: '1.5rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.58334
|
||||
},
|
||||
h5: {
|
||||
fontSize: '1.125rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.5556
|
||||
},
|
||||
h6: {
|
||||
fontSize: '0.9375rem',
|
||||
fontWeight: 500,
|
||||
lineHeight: 1.46667
|
||||
},
|
||||
subtitle1: {
|
||||
fontSize: '0.9375rem',
|
||||
lineHeight: 1.46667
|
||||
},
|
||||
subtitle2: {
|
||||
fontSize: '0.8125rem',
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.53846154
|
||||
},
|
||||
body1: {
|
||||
fontSize: '0.9375rem',
|
||||
lineHeight: 1.46667
|
||||
},
|
||||
body2: {
|
||||
fontSize: '0.8125rem',
|
||||
lineHeight: 1.53846154
|
||||
},
|
||||
button: {
|
||||
fontSize: '0.9375rem',
|
||||
lineHeight: 1.46667,
|
||||
textTransform: 'none'
|
||||
},
|
||||
caption: {
|
||||
fontSize: '0.8125rem',
|
||||
lineHeight: 1.38462,
|
||||
letterSpacing: '0.4px'
|
||||
},
|
||||
overline: {
|
||||
fontSize: '0.75rem',
|
||||
lineHeight: 1.16667,
|
||||
letterSpacing: '0.8px'
|
||||
}
|
||||
}) as Theme['typography']
|
||||
|
||||
export default typography
|
||||
@@ -0,0 +1,16 @@
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
export type Skin = 'default' | 'bordered'
|
||||
|
||||
export type Mode = 'light' | 'dark'
|
||||
|
||||
export type SystemMode = 'light' | 'dark'
|
||||
|
||||
export type Direction = 'ltr' | 'rtl'
|
||||
|
||||
export type ChildrenType = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export type ThemeColor = 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success'
|
||||
@@ -0,0 +1,18 @@
|
||||
export type SystemConfig = {
|
||||
id: string;
|
||||
sessionCleanupIntervalMinutes: number;
|
||||
invoiceGenerationDayOfMonth: number;
|
||||
tokenExpirationMinutes: number;
|
||||
tokenCleanupIntervalMinutes: number;
|
||||
profilePictureUpdateIntervalDays: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type UpdateSystemConfigDto = {
|
||||
sessionCleanupIntervalMinutes?: number;
|
||||
invoiceGenerationDayOfMonth?: number;
|
||||
tokenExpirationMinutes?: number;
|
||||
tokenCleanupIntervalMinutes?: number;
|
||||
profilePictureUpdateIntervalDays?: number;
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import 'server-only'
|
||||
|
||||
// Next Imports
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
// Type Imports
|
||||
import type { Settings } from '@core/contexts/settingsContext'
|
||||
import type { SystemMode } from '@core/types'
|
||||
|
||||
// Config Imports
|
||||
import themeConfig from '@configs/themeConfig'
|
||||
|
||||
export const getSettingsFromCookie = (): Settings => {
|
||||
const cookieStore = cookies()
|
||||
|
||||
const cookieName = themeConfig.settingsCookieName
|
||||
|
||||
return JSON.parse(cookieStore.get(cookieName)?.value || '{}')
|
||||
}
|
||||
|
||||
export const getMode = () => {
|
||||
const settingsCookie = getSettingsFromCookie()
|
||||
|
||||
// Get mode from cookie or fallback to theme config
|
||||
const _mode = settingsCookie.mode || themeConfig.mode
|
||||
|
||||
return _mode
|
||||
}
|
||||
|
||||
export const getSystemMode = (): SystemMode => {
|
||||
const mode = getMode()
|
||||
|
||||
return mode
|
||||
}
|
||||
|
||||
export const getServerMode = () => {
|
||||
const mode = getMode()
|
||||
|
||||
return mode
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
'use client'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Type Imports
|
||||
import type { ChildrenType } from '@core/types'
|
||||
|
||||
// Util Imports
|
||||
import { blankLayoutClasses } from './utils/layoutClasses'
|
||||
|
||||
const BlankLayout = ({ children }: ChildrenType) => {
|
||||
return <div className={classnames(blankLayoutClasses.root, 'is-full bs-full')}>{children}</div>
|
||||
}
|
||||
|
||||
export default BlankLayout
|
||||
@@ -0,0 +1,11 @@
|
||||
'use client'
|
||||
|
||||
// React Imports
|
||||
import type { ReactElement } from 'react'
|
||||
|
||||
const LayoutWrapper = ({ verticalLayout }: { verticalLayout: ReactElement }) => {
|
||||
// Return the layout based on the layout context
|
||||
return <div className='flex flex-col flex-auto'>{verticalLayout}</div>
|
||||
}
|
||||
|
||||
export default LayoutWrapper
|
||||
@@ -0,0 +1,39 @@
|
||||
// React Imports
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Type Imports
|
||||
import type { ChildrenType } from '@core/types'
|
||||
|
||||
// Component Imports
|
||||
import LayoutContent from './components/vertical/LayoutContent'
|
||||
|
||||
// Util Imports
|
||||
import { verticalLayoutClasses } from './utils/layoutClasses'
|
||||
|
||||
type VerticalLayoutProps = ChildrenType & {
|
||||
navigation?: ReactNode
|
||||
navbar?: ReactNode
|
||||
footer?: ReactNode
|
||||
}
|
||||
|
||||
const VerticalLayout = (props: VerticalLayoutProps) => {
|
||||
// Props
|
||||
const { navbar, footer, navigation, children } = props
|
||||
|
||||
return (
|
||||
<div className={classnames(verticalLayoutClasses.root, 'flex flex-auto')}>
|
||||
{navigation || null}
|
||||
<div className={classnames(verticalLayoutClasses.contentWrapper, 'flex flex-col min-is-0 is-full')}>
|
||||
{navbar || null}
|
||||
{/* Content */}
|
||||
<LayoutContent>{children}</LayoutContent>
|
||||
{footer || null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerticalLayout
|
||||
@@ -0,0 +1,40 @@
|
||||
'use client'
|
||||
|
||||
// Third-party Imports
|
||||
import classnames from 'classnames'
|
||||
import type { CSSObject } from '@emotion/styled'
|
||||
|
||||
// Type Imports
|
||||
import type { ChildrenType } from '@core/types'
|
||||
|
||||
// Util Imports
|
||||
import { verticalLayoutClasses } from '@layouts/utils/layoutClasses'
|
||||
|
||||
// Styled Component Imports
|
||||
import StyledFooter from '@layouts/styles/vertical/StyledFooter'
|
||||
|
||||
type Props = ChildrenType & {
|
||||
overrideStyles?: CSSObject
|
||||
}
|
||||
|
||||
const Footer = (props: Props) => {
|
||||
// Props
|
||||
const { children, overrideStyles } = props
|
||||
|
||||
return (
|
||||
<StyledFooter
|
||||
overrideStyles={overrideStyles}
|
||||
className={classnames(
|
||||
verticalLayoutClasses.footer,
|
||||
verticalLayoutClasses.footerContentCompact,
|
||||
verticalLayoutClasses.footerStatic,
|
||||
verticalLayoutClasses.footerDetached,
|
||||
'is-full'
|
||||
)}
|
||||
>
|
||||
<div className={verticalLayoutClasses.footerContentWrapper}>{children}</div>
|
||||
</StyledFooter>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user