├── .browserslistrc ├── .editorconfig ├── .eslintrc.cjs ├── .gitignore ├── .stylelintrc.json ├── .vscode ├── extensions.json ├── settings.json ├── vue-ts.code-snippets └── vue.code-snippets ├── README.md ├── auto-imports.d.ts ├── env.d.ts ├── index.html ├── package.json ├── pnpm-lock.yaml ├── public ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── loader.css └── site.webmanifest ├── shims.d.ts ├── src ├── App.vue ├── assets │ └── images │ │ ├── avatars │ │ ├── avatar-1.png │ │ ├── avatar-2.png │ │ ├── avatar-3.png │ │ ├── avatar-4.png │ │ ├── avatar-5.png │ │ └── avatar-6.png │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── pages │ │ ├── auth-bg-dark.svg │ │ ├── auth-bg-light.svg │ │ ├── book-pen.png │ │ ├── cactus.png │ │ ├── cover.jpg │ │ ├── error-message-404.png │ │ ├── girl-forgot-something.png │ │ ├── lights.jpg │ │ ├── pineapple.jpg │ │ ├── sunset.jpg │ │ ├── sunshine.jpg │ │ ├── umbrella.jpg │ │ ├── working-desk-with-laptop.png │ │ └── working-laptop-while-sitting-chair.png │ │ ├── product │ │ ├── camera.png │ │ ├── grinder.png │ │ ├── headphone.png │ │ ├── iphone.png │ │ ├── laptop.png │ │ ├── monitor.png │ │ ├── online-school-equipment-home-2.jpg │ │ ├── online-school-equipment-home.jpg │ │ ├── printer.png │ │ └── smart-watch.png │ │ └── svg │ │ ├── binance.svg │ │ ├── bitcoin.svg │ │ ├── bnb.svg │ │ ├── cardano.svg │ │ ├── checkbox-checked.svg │ │ ├── checkbox-indeterminate.svg │ │ ├── checkbox-unchecked.svg │ │ ├── doge.svg │ │ ├── ethereum.svg │ │ ├── radio-checked.svg │ │ ├── radio-unchecked.svg │ │ ├── tether.svg │ │ └── usdc.svg ├── components │ ├── BackToTop.vue │ ├── BuyNow.vue │ ├── CleaveInput.vue │ ├── FloatingCard.vue │ ├── Logo.vue │ ├── NavUserProfileMenu.vue │ ├── ThemeSwitcher.vue │ └── shims.d.ts ├── layouts │ ├── blank.vue │ ├── components │ │ ├── footer │ │ │ └── index.vue │ │ ├── navbar │ │ │ └── index.vue │ │ ├── types.d.ts │ │ ├── utils.ts │ │ └── vertical-nav │ │ │ ├── VerticalNavGroup.vue │ │ │ ├── VerticalNavGroupItems.vue │ │ │ ├── VerticalNavLink.vue │ │ │ └── index.vue │ └── default.vue ├── main.ts ├── menus │ └── vertical.ts ├── plugins │ ├── iconify │ │ ├── build-icons.ts │ │ └── package.json │ ├── vuetify │ │ ├── defaults.ts │ │ ├── icons.ts │ │ ├── index.ts │ │ ├── theme.ts │ │ └── vuetify.ts │ └── webfontloader.ts ├── router │ ├── index.ts │ └── type.d.ts ├── styles │ ├── _utilities.scss │ ├── index.scss │ ├── layouts │ │ ├── _box-layout.scss │ │ ├── _main-content.scss │ │ ├── _navbar.scss │ │ └── _vertical-nav.scss │ ├── libs │ │ ├── _perfect-scrollbar.scss │ │ ├── apex-chart.scss │ │ ├── quill-editor.scss │ │ ├── swiper.scss │ │ ├── toastify.scss │ │ └── vue-datepicker.scss │ ├── mixin │ │ └── mixin.scss │ ├── pages │ │ ├── auth.scss │ │ └── misc.scss │ ├── skins │ │ ├── default.scss │ │ └── index.scss │ ├── user-custom │ │ └── style.scss │ └── vuetify │ │ ├── _overrides.scss │ │ └── _variables.scss ├── utils │ └── rgbToHex.ts └── views │ ├── Blank.vue │ ├── ForgotPassword.vue │ ├── Login.vue │ ├── NotFound.vue │ ├── Register.vue │ ├── Search.vue │ ├── cards │ ├── CardBanner.vue │ ├── CardBasic.vue │ ├── CardFloating.vue │ ├── CardImg.vue │ ├── CardPost.vue │ ├── CardStatistics.vue │ ├── CardTask.vue │ ├── CardTimeline.vue │ ├── CardUser.vue │ └── index.vue │ ├── crypto │ └── index.vue │ ├── dashboard │ └── analytics │ │ ├── DashboardChart.vue │ │ ├── DashboardChartBar.vue │ │ ├── LeadingTeamsCard.vue │ │ ├── LocationsCard.vue │ │ ├── MarketShareCard.vue │ │ ├── NewCustomersCard.vue │ │ ├── PayingCustomersCard.vue │ │ ├── PopularSellersCard.vue │ │ ├── SocialMediaCard.vue │ │ ├── TasksCard.vue │ │ ├── TopCouponsCard.vue │ │ ├── TotalOrderTrendCard.vue │ │ ├── TotalOrdersCard.vue │ │ ├── WeatherCard.vue │ │ ├── WeeklySalesCard.vue │ │ └── index.vue │ └── forms │ └── examples │ └── Advertising.vue ├── tsconfig.json └── vite.config.ts /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | not ie 11 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # Matches multiple files with brace expansion notation 12 | # Set default charset 13 | [*.{js,py}] 14 | charset = utf-8 15 | 16 | # 4 space indentation 17 | [*.py] 18 | indent_style = space 19 | indent_size = 4 20 | 21 | # 2 space indentation 22 | [*.{vue,scss,ts}] 23 | indent_style = space 24 | indent_size = 2 25 | 26 | # Tab indentation (no size specified) 27 | [Makefile] 28 | indent_style = tab 29 | 30 | # Indentation override for all JS under lib directory 31 | [lib/**.js] 32 | indent_style = space 33 | indent_size = 2 34 | 35 | # Matches the exact files either package.json or .travis.yml 36 | [{package.json,.travis.yml}] 37 | indent_style = space 38 | indent_size = 2 39 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: [ 7 | '@antfu/eslint-config-vue', 8 | 'plugin:vue/vue3-recommended', 9 | 'plugin:import/recommended', 10 | 'plugin:import/typescript', 11 | 'plugin:promise/recommended', 12 | 'plugin:sonarjs/recommended', 13 | 'plugin:@typescript-eslint/recommended', 14 | 'plugin:case-police/recommended', 15 | 'plugin:regexp/recommended', 16 | 17 | // 'plugin:unicorn/recommended', 18 | ], 19 | parser: 'vue-eslint-parser', 20 | parserOptions: { 21 | ecmaVersion: 13, 22 | parser: '@typescript-eslint/parser', 23 | sourceType: 'module', 24 | }, 25 | plugins: [ 26 | 'vue', 27 | '@typescript-eslint', 28 | 'regex', 29 | 'regexp', 30 | ], 31 | ignorePatterns: ['src/plugins/iconify/*.js','node_modules', 'dist', '*.d.ts', 'vendor', '*.json', '*.cjs'], 32 | rules: { 33 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 34 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 35 | 36 | // indentation (Already present in TypeScript) 37 | 'comma-spacing': ['error', { before: false, after: true }], 38 | 'key-spacing': ['error', { afterColon: true }], 39 | 'n/prefer-global/process': ['off'], 40 | 'sonarjs/cognitive-complexity': ['off'], 41 | 42 | 'vue/first-attribute-linebreak': ['error', { 43 | singleline: 'beside', 44 | multiline: 'below', 45 | }], 46 | 47 | 'antfu/top-level-function': 'off', 48 | '@typescript-eslint/no-explicit-any': 'off', 49 | 50 | // indentation (Already present in TypeScript) 51 | 'indent': ['error', 2], 52 | 53 | // Enforce trailing comma (Already present in TypeScript) 54 | 'comma-dangle': ['error', 'always-multiline'], 55 | 56 | // Enforce consistent spacing inside braces of object (Already present in TypeScript) 57 | 'object-curly-spacing': ['error', 'always'], 58 | 59 | // Enforce camelCase naming convention 60 | 'camelcase': 'off', 61 | 62 | // Disable max-len 63 | 'max-len': 'off', 64 | 65 | // we don't want it 66 | 'semi': ['error', 'never'], 67 | 68 | // add parens ony when required in arrow function 69 | 'arrow-parens': ['error', 'as-needed'], 70 | 71 | // add new line above comment 72 | 'newline-before-return': 'error', 73 | 74 | // add new line above comment 75 | 'lines-around-comment': [ 76 | 'error', 77 | { 78 | beforeBlockComment: true, 79 | beforeLineComment: true, 80 | allowBlockStart: true, 81 | allowClassStart: true, 82 | allowObjectStart: true, 83 | allowArrayStart: true, 84 | }, 85 | ], 86 | 87 | // Ignore _ as unused variable 88 | '@typescript-eslint/no-unused-vars': ['error', { varsIgnorePattern: '^_+$', argsIgnorePattern: '^_+$' }], 89 | 90 | 'array-element-newline': ['error', 'consistent'], 91 | 'array-bracket-newline': ['error', 'consistent'], 92 | 93 | 'vue/multi-word-component-names': 'off', 94 | 95 | 'padding-line-between-statements': [ 96 | 'error', 97 | { blankLine: 'always', prev: 'expression', next: 'const' }, 98 | { blankLine: 'always', prev: 'const', next: 'expression' }, 99 | { blankLine: 'always', prev: 'multiline-const', next: '*' }, 100 | { blankLine: 'always', prev: '*', next: 'multiline-const' }, 101 | ], 102 | 103 | // Plugin: eslint-plugin-import 104 | 'import/prefer-default-export': 'off', 105 | 'import/newline-after-import': ['error', { count: 1 }], 106 | 'no-restricted-imports': ['error', 'vuetify/components'], 107 | 108 | // For omitting extension for ts files 109 | 'import/extensions': [ 110 | 'error', 111 | 'ignorePackages', 112 | { 113 | js: 'never', 114 | jsx: 'never', 115 | ts: 'never', 116 | tsx: 'never', 117 | }, 118 | ], 119 | 'regex/invalid': [ 120 | 'error', 121 | [ 122 | { 123 | regex: '@/assets/images', 124 | replacement: '@images', 125 | message: 'Use \'@images\' path alias for image imports', 126 | }, 127 | { 128 | regex: '@/styles', 129 | replacement: '@styles', 130 | message: 'Use \'@styles\' path alias for importing styles from \'src/assets/styles\'', 131 | }, 132 | { 133 | regex: '@/plugins', 134 | replacement: '@plugins', 135 | message: 'Use \'@plugins\' path alias for importing styles from \'src/plugins/\'', 136 | }, 137 | ] 138 | ], 139 | 140 | // Thanks: https://stackoverflow.com/a/63961972/10796681 141 | 'no-shadow': 'off', 142 | '@typescript-eslint/no-shadow': ['error'], 143 | 144 | '@typescript-eslint/consistent-type-imports': 'error', 145 | 146 | // Plugin: eslint-plugin-promise 147 | 'promise/always-return': 'off', 148 | 'promise/catch-or-return': 'off', 149 | 150 | // ESLint plugin vue 151 | 'vue/block-tag-newline': 'error', 152 | 'vue/component-api-style': 'error', 153 | 'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: false, ignores: ['/^swiper-/'] }], 154 | 'vue/custom-event-name-casing': ['error', 'camelCase', { 155 | ignores: [ 156 | '/^(click):[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?/', 157 | ], 158 | }], 159 | 'vue/define-macros-order': 'error', 160 | 'vue/html-comment-content-newline': 'error', 161 | 'vue/html-comment-content-spacing': 'error', 162 | 'vue/html-comment-indent': 'error', 163 | 'vue/match-component-file-name': 'error', 164 | 'vue/no-child-content': 'error', 165 | 'vue/require-default-prop': 'off', 166 | 167 | 'vue/no-duplicate-attr-inheritance': 'error', 168 | 'vue/no-empty-component-block': 'error', 169 | 'vue/no-multiple-objects-in-class': 'error', 170 | 'vue/no-reserved-component-names': 'error', 171 | 'vue/no-template-target-blank': 'error', 172 | 'vue/no-useless-mustaches': 'error', 173 | 'vue/no-useless-v-bind': 'error', 174 | 'vue/padding-line-between-blocks': 'error', 175 | 'vue/prefer-separate-static-class': 'error', 176 | 'vue/prefer-true-attribute-shorthand': 'off', 177 | 'vue/v-on-function-call': 'error', 178 | 'vue/no-restricted-class': ['error', '/^(p|m)(l|r)-/'], 179 | 'vue/valid-v-slot': ['error', { 180 | allowModifiers: true, 181 | }], 182 | 183 | // -- Extension Rules 184 | 'vue/no-irregular-whitespace': 'error', 185 | 'vue/template-curly-spacing': 'error', 186 | 187 | // -- Sonarlint 188 | 'sonarjs/no-duplicate-string': 'off', 189 | 'sonarjs/no-nested-template-literals': 'off', 190 | 'vue/no-v-html': 'off', 191 | 'vue/no-v-text-v-html-on-component': 'off', 192 | }, 193 | settings: { 194 | 'import/resolver': { 195 | node: true, 196 | typescript: {}, 197 | }, 198 | }, 199 | } 200 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | 24 | # iconify dist files 25 | src/plugins/iconify/icons.css 26 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-standard-scss", 4 | "stylelint-config-idiomatic-order", 5 | "@stylistic/stylelint-config" 6 | ], 7 | "plugins": [ 8 | "stylelint-use-logical-spec", 9 | "@stylistic/stylelint-plugin" 10 | ], 11 | "overrides": [ 12 | { 13 | "files": [ 14 | "**/*.scss" 15 | ], 16 | "customSyntax": "postcss-scss" 17 | }, 18 | { 19 | "files": [ 20 | "**/*.vue" 21 | ], 22 | "customSyntax": "postcss-html" 23 | } 24 | ], 25 | "rules": { 26 | "@stylistic/max-line-length": [ 27 | 220, 28 | { 29 | "ignore": "comments" 30 | } 31 | ], 32 | "@stylistic/indentation": 2, 33 | "liberty/use-logical-spec": true, 34 | "selector-class-pattern": null, 35 | "color-function-notation": null, 36 | "annotation-no-unknown": [ 37 | true, 38 | { 39 | "ignoreAnnotations": [ 40 | "default" 41 | ] 42 | } 43 | ], 44 | "media-feature-range-notation": null 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "editorconfig.editorconfig", 5 | "xabikos.javascriptsnippets", 6 | "stylelint.vscode-stylelint", 7 | "fabiospampinato.vscode-highlight", 8 | "github.vscode-pull-request-github", 9 | "vue.volar", 10 | "cipchk.cssrem", 11 | "antfu.iconify", 12 | "dongido.sync-env" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "files.insertFinalNewline": true, 4 | "javascript.updateImportsOnFileMove.enabled": "always", 5 | "[javascript]": { 6 | "editor.defaultFormatter": "dbaeumer.vscode-eslint" 7 | }, 8 | "[typescript]": { 9 | "editor.defaultFormatter": "dbaeumer.vscode-eslint", 10 | "editor.autoClosingBrackets": "always" 11 | }, 12 | "[markdown]": { 13 | "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" 14 | }, 15 | // SCSS 16 | "[scss]": { 17 | "editor.defaultFormatter": "stylelint.vscode-stylelint" 18 | }, 19 | // JSON 20 | "[json]": { 21 | "editor.defaultFormatter": "vscode.json-language-features" 22 | }, 23 | "[jsonc]": { 24 | "editor.defaultFormatter": "vscode.json-language-features" 25 | }, 26 | // Vue 27 | "[vue]": { 28 | "editor.defaultFormatter": "dbaeumer.vscode-eslint", 29 | }, 30 | // Extension: Volar 31 | "volar.preview.port": 3000, 32 | "volar.completion.preferredTagNameCase": "pascal", 33 | "editor.codeActionsOnSave": { 34 | "source.fixAll.eslint": "explicit", 35 | "source.fixAll.stylelint": "explicit", 36 | "source.organizeImports": "explicit" 37 | }, 38 | "eslint.alwaysShowStatus": true, 39 | "eslint.format.enable": true, 40 | "eslint.packageManager": "yarn", 41 | // Extension: Stylelint 42 | "stylelint.packageManager": "yarn", 43 | "stylelint.validate": [ 44 | "css", 45 | "scss", 46 | "vue" 47 | ], 48 | // Extension: Spell Checker 49 | "cSpell.words": [ 50 | "Composables", 51 | "Customizer", 52 | "flagpack", 53 | "psudo", 54 | "stylelint", 55 | "touchless", 56 | "triggerer", 57 | "vuetify", 58 | "nuxt" 59 | ], 60 | // Extension: fabiospampinato.vscode-highlight 61 | "highlight.regexFlags": "gi", 62 | "highlight.regexes": { 63 | // We flaged this for enforcing logical CSS properties 64 | "(100vh|translate|margin:|padding:|margin-left|margin-right|rotate|text-align|border-top|border-right|border-bottom|border-left|float|background-position|transform|width|height|top|left|bottom|right|float|clear|(p|m)(l|r)-|border-(start|end)-(start|end)-radius)": [ 65 | { 66 | // "rangeBehavior": 1, 67 | "borderWidth": "1px", 68 | "borderColor": "tomato", 69 | "borderStyle": "solid" 70 | } 71 | ], 72 | "(overflow-x:|overflow-y:)": [ 73 | { 74 | // "rangeBehavior": 1, 75 | "borderWidth": "1px", 76 | "borderColor": "green", 77 | "borderStyle": "solid" 78 | } 79 | ] 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /.vscode/vue-ts.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Vue TS - DefineProps": { 3 | "prefix": "dprops", 4 | "body": [ 5 | "defineProps<${1:Props}>()" 6 | ], 7 | "description": "DefineProps in script setup" 8 | }, 9 | "Vue TS - Props interface": { 10 | "prefix": "iprops", 11 | "body": [ 12 | "interface Props {", 13 | " ${1}", 14 | "}" 15 | ], 16 | "description": "Create props interface in script setup" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/vue.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "script": { 3 | "prefix": "vue-sfc-ts", 4 | "body": [ 5 | "", 8 | "", 9 | "", 12 | "", 13 | "", 16 | "" 17 | ], 18 | "description": "Vue SFC Typescript" 19 | }, 20 | "template": { 21 | "scope": "vue", 22 | "prefix": "template", 23 | "body": [ 24 | "" 27 | ], 28 | "description": "Create