├── .babelrc ├── .editorconfig ├── .env.example ├── .eslintrc.js ├── .gitignore ├── .husky └── commit-msg ├── .prettierrc ├── Dockerfile ├── README.md ├── api ├── Api.js ├── CustomApi.js └── apiUrl.js ├── assets ├── fonts │ └── gotham-rounded │ │ ├── GothamRounded-Bold.otf │ │ ├── GothamRounded-BoldItalic.otf │ │ ├── GothamRounded-Book.otf │ │ ├── GothamRounded-BookItalic.otf │ │ ├── GothamRounded-Light.otf │ │ ├── GothamRounded-LightItalic.otf │ │ ├── GothamRounded-Medium.otf │ │ ├── GothamRounded-MediumItalic.otf │ │ ├── GothamRoundedBold_21016.ttf │ │ ├── GothamRoundedBook_21018.ttf │ │ ├── GothamRoundedLight_21020.ttf │ │ ├── GothamRoundedMedium_21022.ttf │ │ └── sharefonts.net.txt ├── images │ ├── 404.svg │ ├── Logo.png │ └── error.svg └── scss │ ├── app │ ├── _app.scss │ ├── _custom.scss │ ├── _responsive.scss │ ├── _transition.scss │ ├── _utils.scss │ ├── _variables.scss │ └── page │ │ ├── _auth.scss │ │ ├── _forgot-password.scss │ │ └── _login.scss │ ├── colors.scss │ ├── main.scss │ └── variables.scss ├── commitlint.config.js ├── components ├── Base │ ├── Button.vue │ ├── Card.vue │ ├── Dialog.vue │ ├── Input.vue │ ├── Select.vue │ └── Table.vue ├── Dialog │ └── Modal.vue ├── LoadingBar.vue ├── LoadingCustom.vue ├── PageTitle.vue └── layouts │ ├── TheAppBar.vue │ └── TheSideBar.vue ├── consts └── consts.js ├── docker-compose.yml ├── helpers └── Utils.js ├── jest.config.js ├── jsconfig.json ├── layouts ├── auth.vue ├── blank.vue ├── default.vue └── error.vue ├── middleware ├── authenticated.js └── guest.js ├── nuxt.config.js ├── package.json ├── pages ├── auth │ ├── component.vue │ ├── dropdown │ │ └── _id.vue │ ├── fetch.vue │ ├── home.vue │ └── table.vue ├── change-password.vue ├── forgot-password.vue ├── index.vue ├── login.vue ├── otp-code.vue └── testing.vue ├── payloads └── RequestFetch.js ├── plugins ├── api.js ├── axios.js ├── nuxt-client-init.js └── vee-validate.js ├── services └── fetchServices.js ├── static ├── favicon.ico ├── v.png └── vuetify-logo.svg ├── store ├── fetch.js ├── index.js └── sidebar.js └── test └── NuxtLogo.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "presets": [ 5 | [ 6 | "@babel/preset-env", 7 | { 8 | "targets": { 9 | "node": "current" 10 | } 11 | } 12 | ] 13 | ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NODE_ENV = "local" 2 | APP_TITLE="Starter Nuvue" 3 | BASE_URL= "https://randomuser.me" 4 | BASE_URL_SECOND = "https://randomuser.me" 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: '@babel/eslint-parser', 9 | requireConfigFile: false 10 | }, 11 | extends: [ 12 | '@nuxtjs', 13 | 'plugin:nuxt/recommended', 14 | 'prettier' 15 | ], 16 | plugins: [ 17 | ], 18 | // add your custom rules here 19 | rules: {} 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | 92 | # yarn 93 | yarn.lock 94 | 95 | # npm 96 | package-lock.json 97 | 98 | # storybook 99 | .nuxt-storybook 100 | storybook-static 101 | 102 | 103 | 104 | # Local Netlify folder 105 | .netlify 106 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile 2 | FROM node:16.14.0-alpine 3 | 4 | # create destination directory 5 | RUN mkdir -p /usr/src/nuxt-app 6 | WORKDIR /usr/src/nuxt-app 7 | 8 | # update and install dependency 9 | RUN apk update && apk upgrade 10 | RUN apk add git 11 | 12 | # copy the app, note .dockerignore 13 | COPY . /usr/src/nuxt-app/ 14 | RUN npm install 15 | RUN npm run build 16 | 17 | EXPOSE 3000 18 | 19 | ENV NUXT_HOST=0.0.0.0 20 | ENV NUXT_PORT=3000 21 | 22 | CMD [ "npm", "start" ] 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Starter Template Nuxt Vuetify CMS 2 | 3 |

4 | 5 |

6 | 7 | Starter template Nuxt 2 and Vuetify, Service Pattern, Composition APi, default page like Login, Forgot Password, OTP Code, and Auth System using Nuxt Auth 8 | 9 | Built with: 10 | * [Nuxt 2](https://nuxtjs.org/) 11 | * [Nuxt Auth 5](https://auth.nuxtjs.org/) 12 | * [Nuxt Axios](https://axios.nuxtjs.org/) 13 | * [Nuxt DotEnv](https://www.npmjs.com/package/@nuxtjs/dotenv) 14 | * [Nuxt Composition Api](https://composition-api.nuxtjs.org/) 15 | * [Vuetify 2](https://vuetifyjs.com/) 16 | * [Babel](https://babeljs.io/) 17 | * [Vue Loading Overlay](https://www.browsersync.io/) 18 | * [ESLint](http://eslint.org/) 19 | * [Include Media](https://eduardoboucas.github.io/include-media) 20 | * [SASS](http://sass-lang.com/) 21 | * [Webpack 2](https://webpack.js.org/) 22 | * [Yarn](https://yarnpkg.com/en/docs/install) 23 | 24 | 25 | ## COMMIT STYLE GUIDE 26 | 27 | https://github.com/BaihakiTanjung/Aturan-Pengembangan-Aplikasi 28 | 29 | ## Folder structure 30 | 31 | | Folder name | Children | Goal | 32 | | ------------- |:-------------:| -----:| 33 | | /api | apiUrl | Wrapper Axios Call Methods | 34 | |/services | | Return Axios evocation. Services | 35 | | /assets | /scss | | 36 | | | /images | | 37 | | | /fonts | | 38 | | /consts | consts | Constant Variable | 39 | | /components | .vue | Vue component | 40 | | /helpers | Utils | Utilty Functions | 41 | | /layouts | .vue | Nuxt layout. Contains views. | 42 | | /middleware | | Nuxt Middleware | 43 | | /pages | .vue | View. Rendered inside layout. | 44 | | /plugins | | Plugins run before instantiating Vue root. Plugins are declared inside nuxt.config.js | 45 | | /static | | | 46 | | /store | | Vuex | 47 | | /payloads | | Mode Data | 48 | 49 | ## Build Setup 50 | 51 | ```bash 52 | # install dependencies 53 | $ yarn install 54 | 55 | $ rename env.example to env 56 | 57 | # serve with hot reload at localhost:3000 58 | $ yarn dev 59 | 60 | # build for production and launch server 61 | $ yarn build 62 | $ yarn start 63 | 64 | # generate static project 65 | $ yarn generate 66 | 67 | 68 | 69 | ``` 70 | 71 | For detailed explanation on how things work, check out the [documentation](https://nuxtjs.org). 72 | 73 | ## Special Directories 74 | 75 | You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality. 76 | 77 | ### `assets` 78 | 79 | The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts. 80 | 81 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/assets). 82 | 83 | ### `components` 84 | 85 | The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components. 86 | 87 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/components). 88 | 89 | ### `layouts` 90 | 91 | Layouts are a great help when you want to change the look and feel of your Nuxt app, whether you want to include a sidebar or have distinct layouts for mobile and desktop. 92 | 93 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts). 94 | 95 | 96 | ### `pages` 97 | 98 | This directory contains your application views and routes. Nuxt will read all the `*.vue` files inside this directory and setup Vue Router automatically. 99 | 100 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/get-started/routing). 101 | 102 | ### `plugins` 103 | 104 | The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use `Vue.use()`, you should create a file in `plugins/` and add its path to plugins in `nuxt.config.js`. 105 | 106 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/plugins). 107 | 108 | ### `static` 109 | 110 | This directory contains your static files. Each file inside this directory is mapped to `/`. 111 | 112 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 113 | 114 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/static). 115 | 116 | ### `store` 117 | 118 | This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex. 119 | 120 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/store). 121 | 122 | 123 | ### `docker` 124 | 125 | 126 | Docker compose 127 | 128 | ```bash 129 | docker-compose up --build -d 130 | ``` 131 | 132 | 133 | Running docker in local 134 | 135 | ```bash 136 | docker run -it -p 3000:3000 starter-nuxt 137 | ``` 138 | 139 | Running docker in development 140 | 141 | ```bash 142 | docker run -it -p 3000:3000 -e NODE_ENV=development starter-nuxt 143 | ``` 144 | 145 | Running docker in production 146 | 147 | ```bash 148 | docker run -it -p 3000:3000 -e NODE_ENV=production starter-nuxt 149 | ``` 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /api/Api.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper Axios Methods Api 3 | */ 4 | 5 | import { PREFIX } from './ApiUrl.js' 6 | 7 | class Api { 8 | constructor($axios) { 9 | this.$axios = $axios 10 | } 11 | 12 | async doGet(url, params) { 13 | return await this.$axios 14 | .get(PREFIX + url, params) 15 | .then((res) => res.data) 16 | .catch((err) => err) 17 | } 18 | 19 | async doPost(url, params) { 20 | return await this.$axios 21 | .post(PREFIX + url, params) 22 | .then((res) => res.data) 23 | .catch((error) => { 24 | throw error 25 | }) 26 | } 27 | 28 | async doPut(url, params) { 29 | return await this.$axios 30 | .put(PREFIX + url, params) 31 | .then((res) => res.data) 32 | .catch((error) => { 33 | throw error 34 | }) 35 | } 36 | 37 | async doDelete(url, params) { 38 | return await this.$axios 39 | .delete(PREFIX + url, params) 40 | .then((res) => res.data) 41 | .catch((error) => { 42 | throw error 43 | }) 44 | } 45 | 46 | async doGetBlob(url, params) { 47 | return await this.$axios 48 | .post(PREFIX + url, params, { responseType: 'blob' }) 49 | .then((res) => res.data) 50 | .catch((error) => { 51 | throw error 52 | }) 53 | } 54 | 55 | async doPostMultipart(url, params) { 56 | return await this.$axios 57 | .post(PREFIX + url, params, { 58 | headers: { 59 | 'Content-Type': 'multipart/form-data', 60 | }, 61 | }) 62 | .then((res) => res.data) 63 | .catch((error) => { 64 | throw error 65 | }) 66 | } 67 | } 68 | 69 | export default new Api() 70 | -------------------------------------------------------------------------------- /api/CustomApi.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper Axios Methods Custom Api 3 | */ 4 | 5 | import axios from 'axios' 6 | import { PREFIX } from '~/api/ApiUrl.js' 7 | 8 | class CustomApi { 9 | async doGet(url, params) { 10 | return await axios 11 | .get(url + PREFIX, params) 12 | .then((res) => res.data) 13 | .catch((err) => err) 14 | } 15 | 16 | async doPost(url, params) { 17 | return await axios 18 | .post(url + PREFIX, params) 19 | .then((res) => res.data) 20 | .catch((error) => { 21 | throw error 22 | }) 23 | } 24 | 25 | async doPut(url, params) { 26 | return await axios 27 | .put(url + PREFIX, params) 28 | .then((res) => res.data) 29 | .catch((error) => { 30 | throw error 31 | }) 32 | } 33 | 34 | async doDelete(url, params) { 35 | return await axios 36 | .delete(url + PREFIX, params) 37 | .then((res) => res.data) 38 | .catch((error) => { 39 | throw error 40 | }) 41 | } 42 | 43 | async doGetBlob(url, params) { 44 | return await axios 45 | .post(url + PREFIX, params, { responseType: 'blob' }) 46 | .then((res) => res.data) 47 | .catch((error) => { 48 | throw error 49 | }) 50 | } 51 | 52 | async doPostMultipart(url, params) { 53 | return await axios 54 | .post(url + PREFIX, params, { 55 | headers: { 56 | 'Content-Type': 'multipart/form-data', 57 | }, 58 | }) 59 | .then((res) => res.data) 60 | .catch((error) => { 61 | throw error 62 | }) 63 | } 64 | } 65 | 66 | export default new CustomApi() 67 | -------------------------------------------------------------------------------- /api/apiUrl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * BASE URLS 3 | */ 4 | 5 | export const PREFIX = '/api/' 6 | -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-Bold.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-BoldItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-BoldItalic.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-Book.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-Book.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-BookItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-BookItalic.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-Light.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-LightItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-LightItalic.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-Medium.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRounded-MediumItalic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRounded-MediumItalic.otf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRoundedBold_21016.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRoundedBold_21016.ttf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRoundedBook_21018.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRoundedBook_21018.ttf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRoundedLight_21020.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRoundedLight_21020.ttf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/GothamRoundedMedium_21022.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/fonts/gotham-rounded/GothamRoundedMedium_21022.ttf -------------------------------------------------------------------------------- /assets/fonts/gotham-rounded/sharefonts.net.txt: -------------------------------------------------------------------------------- 1 | Free download fonts at http://sharefonts.net -------------------------------------------------------------------------------- /assets/images/404.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /assets/images/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/images/Logo.png -------------------------------------------------------------------------------- /assets/images/error.svg: -------------------------------------------------------------------------------- 1 | feeling blue -------------------------------------------------------------------------------- /assets/scss/app/_app.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/scss/app/_app.scss -------------------------------------------------------------------------------- /assets/scss/app/_custom.scss: -------------------------------------------------------------------------------- 1 | body { 2 | height: 100%; 3 | } 4 | 5 | a { 6 | text-decoration: none; 7 | } 8 | 9 | .v-navigation-drawer__border { 10 | background-color: transparent !important; 11 | } 12 | 13 | .error-404 { 14 | background-color: $primary; 15 | } 16 | 17 | .v-navigation-drawer { 18 | background: transparent !important; 19 | } 20 | 21 | @import 'page/auth'; 22 | @import 'page/login'; 23 | @import 'page/forgot-password'; 24 | -------------------------------------------------------------------------------- /assets/scss/app/_responsive.scss: -------------------------------------------------------------------------------- 1 | @import 'include-media'; 2 | 3 | $breakpoints: ( 4 | phone: 640px, 5 | tablet: 768px, 6 | desktop: 1024px 7 | ) !default; 8 | 9 | @include media('desktop') { 13 | } 14 | -------------------------------------------------------------------------------- /assets/scss/app/_transition.scss: -------------------------------------------------------------------------------- 1 | .page-enter-active, 2 | .page-leave-active, 3 | .layout-enter-active, 4 | .layout-leave-active { 5 | transition: opacity 0.4s; 6 | } 7 | 8 | .page-enter, 9 | .page-leave-active, 10 | .layout-enter, 11 | .layout-leave-active { 12 | opacity: 0; 13 | } 14 | -------------------------------------------------------------------------------- /assets/scss/app/_utils.scss: -------------------------------------------------------------------------------- 1 | // Text 2 | .text-primary { 3 | color: $primary; 4 | } 5 | 6 | .text-gray { 7 | color: $gray; 8 | } 9 | 10 | // height 11 | .h-100 { 12 | height: 100vh !important; 13 | } 14 | -------------------------------------------------------------------------------- /assets/scss/app/_variables.scss: -------------------------------------------------------------------------------- 1 | // Variable 2 | 3 | -------------------------------------------------------------------------------- /assets/scss/app/page/_auth.scss: -------------------------------------------------------------------------------- 1 | .auth { 2 | background-color: $primary !important; 3 | 4 | .theme--light.v-application { 5 | min-height: 100vh !important; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /assets/scss/app/page/_forgot-password.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/scss/app/page/_forgot-password.scss -------------------------------------------------------------------------------- /assets/scss/app/page/_login.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/assets/scss/app/page/_login.scss -------------------------------------------------------------------------------- /assets/scss/colors.scss: -------------------------------------------------------------------------------- 1 | // Variable 2 | $primary: var(--v-primary-base); 3 | $secondary: var(--v-secondary-base); 4 | $accent: var(--v-accent-base); 5 | $warning: var(--v-warning-base); 6 | $info: var(--v-info-base); 7 | $success: var(--v-success-base); 8 | $gray: #8798ad; 9 | -------------------------------------------------------------------------------- /assets/scss/main.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | @import 'app/variables'; 3 | 4 | // Responsive 5 | @import 'app/responsive'; 6 | 7 | // Transition 8 | @import 'app/transition'; 9 | 10 | @import 'app/app'; 11 | @import 'app/utils'; 12 | @import 'app/custom'; 13 | 14 | -------------------------------------------------------------------------------- /assets/scss/variables.scss: -------------------------------------------------------------------------------- 1 | // Ref: https://github.com/nuxt-community/vuetify-module#customvariables 2 | // 3 | 4 | // Fonts 5 | @font-face { 6 | font-family: 'Gotham Rounded'; 7 | src: url('~assets/fonts/gotham-rounded/GothamRounded-Book.otf'); 8 | } 9 | 10 | // The variables you want to modify 11 | $body-font-family: 'Gotham Rounded'; 12 | $font-size-root: 12px; 13 | $container-max-widths: ( 14 | 'md': 1100px, 15 | 'lg': 1310px, 16 | 'xl': 1440px, 17 | ); 18 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | [ 8 | 'feat', 9 | 'fix', 10 | 'docs', 11 | 'chore', 12 | 'style', 13 | 'refactor', 14 | 'ci', 15 | 'test', 16 | 'revert', 17 | 'perf', 18 | 'build', 19 | 'vercel', 20 | ], 21 | ], 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /components/Base/Button.vue: -------------------------------------------------------------------------------- 1 | 6 | 21 | -------------------------------------------------------------------------------- /components/Base/Card.vue: -------------------------------------------------------------------------------- 1 | 6 | 31 | 36 | -------------------------------------------------------------------------------- /components/Base/Dialog.vue: -------------------------------------------------------------------------------- 1 | 20 | 47 | 68 | -------------------------------------------------------------------------------- /components/Base/Input.vue: -------------------------------------------------------------------------------- 1 | 8 | 31 | -------------------------------------------------------------------------------- /components/Base/Select.vue: -------------------------------------------------------------------------------- 1 | 10 | 41 | -------------------------------------------------------------------------------- /components/Base/Table.vue: -------------------------------------------------------------------------------- 1 | 15 | 33 | -------------------------------------------------------------------------------- /components/Dialog/Modal.vue: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /components/LoadingBar.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 45 | -------------------------------------------------------------------------------- /components/LoadingCustom.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | 37 | -------------------------------------------------------------------------------- /components/PageTitle.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | -------------------------------------------------------------------------------- /components/layouts/TheAppBar.vue: -------------------------------------------------------------------------------- 1 | 56 | 90 | -------------------------------------------------------------------------------- /components/layouts/TheSideBar.vue: -------------------------------------------------------------------------------- 1 | 77 | 89 | 94 | -------------------------------------------------------------------------------- /consts/consts.js: -------------------------------------------------------------------------------- 1 | /* 2 | * COMMON CONSTS 3 | */ 4 | export const DAY_OF_MONTH = Array.from({length: 31}, (v, k) => k+1) 5 | export const HOUR_OF_DAY = Array.from({length: 25}, (v, k) => ({ hour: k, name: `${k} giờ` })) 6 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | starter-nuxt: 5 | build: . 6 | container_name: starter-nuxt 7 | restart: unless-stopped 8 | networks: 9 | - starter-nuxt 10 | command: 'npm run start' 11 | 12 | 13 | nginx: 14 | image: nginx:alpine 15 | container_name: starter-nuxt 16 | restart: unless-stopped 17 | ports: 18 | - 3010:3010 19 | volumes: 20 | - ./docker-compose/nginx:/etc/nginx/conf.d/ 21 | networks: 22 | - starter-nuxt 23 | 24 | networks: 25 | starter-nuxt: 26 | driver: bridge 27 | -------------------------------------------------------------------------------- /helpers/Utils.js: -------------------------------------------------------------------------------- 1 | import Swal from 'sweetalert2' 2 | // import XLSX from 'xlsx' 3 | // import { format, parseISO } from 'date-fns' 4 | 5 | const showSuccessPopup = (titleMessage, textMessage) => { 6 | return Swal.fire({ 7 | title: titleMessage, 8 | text: textMessage, 9 | icon: 'success', 10 | showConfirmButton: false, 11 | timer: 1500, 12 | }) 13 | } 14 | 15 | const showFailedPopup = (titleMessage, textMessage) => { 16 | return Swal.fire({ 17 | title: titleMessage, 18 | text: textMessage, 19 | icon: 'error', 20 | showConfirmButton: false, 21 | timer: 1500, 22 | }) 23 | } 24 | 25 | const showConfirmPopup = (textMessage) => { 26 | return Swal.fire({ 27 | title: 'Apakah kamu yakin?', 28 | text: textMessage, 29 | icon: 'warning', 30 | confirmButtonText: 'Ya, Lanjut', 31 | showCancelButton: true, 32 | cancelButtonText: 'Batal', 33 | confirmButtonColor: '#1abc9c', 34 | }) 35 | } 36 | 37 | const downloadFile = (res, filename, extension) => { 38 | const url = window.URL.createObjectURL(new Blob([res.data])) 39 | const link = document.createElement('a') 40 | link.href = url 41 | link.setAttribute('download', `${filename}.${extension}`) 42 | document.body.appendChild(link) 43 | link.click() 44 | } 45 | 46 | // const downloadToExcel = (data, name) => { 47 | // // export json to Worksheet of Excel 48 | // // only array possible 49 | // const dataWS = XLSX.utils.json_to_sheet(data) 50 | 51 | // // A workbook is the name given to an Excel file 52 | // const wb = XLSX.utils.book_new() // make Workbook of Excel 53 | 54 | // // add Worksheet to Workbook 55 | // // Workbook contains one or more worksheets 56 | // XLSX.utils.book_append_sheet(wb, dataWS, name) // sheetAName is name of Worksheet 57 | 58 | // // export Excel file 59 | // XLSX.writeFile(wb, `${name}.xlsx`) // name of the file is 'book.xlsx' 60 | // } 61 | 62 | // const formatDateSql = (dateParams) => { 63 | // return format(parseISO(dateParams), 'yyyy-MM-dd HH:mm:ss') 64 | // } 65 | 66 | // const formatDateYMD = (dateParams) => { 67 | // return format(parseISO(dateParams), 'yyyy-MM-dd') 68 | // } 69 | 70 | const removeDuplicateArray = (arr) => { 71 | const s = new Set(arr) 72 | const it = s.values() 73 | return Array.from(it) 74 | } 75 | 76 | const formatCurrency = (number) => { 77 | return ( 78 | 'Rp ' + 79 | Math.floor(number) 80 | .toString() 81 | .replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.') 82 | ) 83 | } 84 | 85 | export { 86 | showSuccessPopup, 87 | showFailedPopup, 88 | showConfirmPopup, 89 | // downloadToExcel, 90 | // formatDateSql, 91 | // formatDateYMD, 92 | removeDuplicateArray, 93 | formatCurrency, 94 | downloadFile, 95 | } 96 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleNameMapper: { 3 | '^@/(.*)$': '/$1', 4 | '^~/(.*)$': '/$1', 5 | '^vue$': 'vue/dist/vue.common.js' 6 | }, 7 | moduleFileExtensions: [ 8 | 'js', 9 | 'vue', 10 | 'json' 11 | ], 12 | transform: { 13 | '^.+\\.js$': 'babel-jest', 14 | '.*\\.(vue)$': 'vue-jest' 15 | }, 16 | collectCoverage: true, 17 | collectCoverageFrom: [ 18 | '/components/**/*.vue', 19 | '/pages/**/*.vue' 20 | ], 21 | testEnvironment: 'jsdom' 22 | } 23 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "~/*": ["./*"], 6 | "@/*": ["./*"], 7 | "~~/*": ["./*"], 8 | "@@/*": ["./*"] 9 | } 10 | }, 11 | "exclude": ["node_modules", ".nuxt", "dist"] 12 | } 13 | -------------------------------------------------------------------------------- /layouts/auth.vue: -------------------------------------------------------------------------------- 1 | 13 | 25 | 30 | -------------------------------------------------------------------------------- /layouts/blank.vue: -------------------------------------------------------------------------------- 1 | 14 | 26 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 69 | 74 | -------------------------------------------------------------------------------- /layouts/error.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 87 | 88 | 93 | -------------------------------------------------------------------------------- /middleware/authenticated.js: -------------------------------------------------------------------------------- 1 | export default function({ $auth, redirect }) { 2 | if (!$auth.$state.loggedIn) { 3 | return redirect("/login"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /middleware/guest.js: -------------------------------------------------------------------------------- 1 | export default function ({ store, route, redirect }) { 2 | if (route.path === '/login') { 3 | if (store.state.auth.loggedIn) { 4 | redirect('/auth/home') 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | // import colors from 'vuetify/es5/util/colors' 2 | // const nodeEnv = process.env.NODE_ENV 3 | const baseUrl = process.env.BASE_URL || 'http://localhost:3000' 4 | const appTitle = process.env.APP_TITLE 5 | 6 | export default { 7 | // Global page headers: https://go.nuxtjs.dev/config-head 8 | head: { 9 | title: appTitle, 10 | htmlAttrs: { 11 | lang: 'id', 12 | }, 13 | meta: [ 14 | { charset: 'utf-8' }, 15 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 16 | { hid: 'description', name: 'description', content: '' }, 17 | { name: 'format-detection', content: 'telephone=no' }, 18 | ], 19 | link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }], 20 | }, 21 | 22 | // Global CSS: https://go.nuxtjs.dev/config-css 23 | css: ['@/assets/scss/main.scss', '@/assets/scss/colors.scss'], 24 | 25 | styleResources: { 26 | scss: ['./assets/scss/*.scss'], 27 | }, 28 | 29 | // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins 30 | plugins: [ 31 | '@/plugins/axios.js', 32 | '@/plugins/api.js', 33 | '@/plugins/vee-validate.js', 34 | ], 35 | 36 | // Auto import components: https://go.nuxtjs.dev/config-components 37 | components: true, 38 | 39 | // Loading 40 | loading: '~/components/LoadingBar.vue', 41 | 42 | // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules 43 | buildModules: [ 44 | // https://go.nuxtjs.dev/eslint 45 | '@nuxtjs/eslint-module', 46 | // https://go.nuxtjs.dev/vuetify 47 | '@nuxtjs/vuetify', 48 | '@nuxtjs/composition-api/module', 49 | ], 50 | 51 | // Modules: https://go.nuxtjs.dev/config-modules 52 | modules: [ 53 | // https://go.nuxtjs.dev/axios 54 | '@nuxtjs/axios', 55 | '@nuxtjs/auth-next', 56 | '@nuxtjs/dotenv', 57 | '@nuxtjs/style-resources', 58 | ], 59 | 60 | ssr: false, 61 | target: 'spa', 62 | 63 | auth: { 64 | strategies: { 65 | local: { 66 | token: { 67 | property: 'content.access_token', 68 | global: true, 69 | required: true, 70 | type: 'Bearer', 71 | }, 72 | user: { 73 | property: false, // here should be `false`, as you defined in user endpoint `propertyName` 74 | // autoFetch: true 75 | }, 76 | endpoints: { 77 | login: { 78 | url: '/api/login', 79 | method: 'post', 80 | propertyName: false, 81 | }, 82 | user: { 83 | url: '/api/auth/user', 84 | method: 'get', 85 | propertyName: false, 86 | }, 87 | logout: { 88 | url: '/api/auth/logout', 89 | method: 'post', 90 | propertyName: false, 91 | }, 92 | }, 93 | }, 94 | }, 95 | }, 96 | 97 | // Axios module configuration: https://go.nuxtjs.dev/config-axios 98 | axios: { 99 | headers: { 100 | common: { 101 | Accept: 'application/json', 102 | }, 103 | }, 104 | // credentials: true, 105 | baseURL: baseUrl, 106 | }, 107 | 108 | // Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify 109 | vuetify: { 110 | customVariables: ['~/assets/scss/variables.scss'], 111 | treeShake: true, 112 | theme: { 113 | dark: false, 114 | options: { customProperties: true }, 115 | themes: { 116 | light: { 117 | primary: '#1869ac', 118 | secondary: '#00DC82', 119 | accent: '#00bcd4', 120 | error: '#f44336', 121 | warning: '#ffc107', 122 | info: '#009688', 123 | success: '#4caf50', 124 | }, 125 | dark: { 126 | primary: '#1869ac', 127 | secondary: '#00DC82', 128 | accent: '#00bcd4', 129 | error: '#f44336', 130 | warning: '#ffc107', 131 | info: '#009688', 132 | success: '#4caf50', 133 | }, 134 | }, 135 | }, 136 | }, 137 | 138 | transition: { 139 | name: 'page', 140 | mode: 'out-in', 141 | }, 142 | 143 | // Build Configuration: https://go.nuxtjs.dev/config-build 144 | build: { 145 | transpile: ['vee-validate'], 146 | }, 147 | extends: ['@nuxtjs'], 148 | } 149 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starter-template-nuxt-vuetify-cms", 3 | "version": "1.0.0", 4 | "private": true, 5 | "author": "baihakitanjung", 6 | "scripts": { 7 | "dev": "nuxt", 8 | "build": "nuxt build", 9 | "start": "nuxt start", 10 | "generate": "nuxt generate", 11 | "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", 12 | "lint": "yarn lint:js", 13 | "test": "jest", 14 | "prepare": "husky install" 15 | }, 16 | "dependencies": { 17 | "@nuxtjs/auth-next": "^5.0.0-1648802546.c9880dc", 18 | "@nuxtjs/axios": "^5.13.6", 19 | "@nuxtjs/composition-api": "^0.33.0", 20 | "@nuxtjs/dotenv": "^1.4.1", 21 | "core-js": "^3.21.1", 22 | "include-media": "^1.4.10", 23 | "nuxt": "^2.15.8", 24 | "sweetalert2": "^11.4.23", 25 | "vee-validate": "3", 26 | "vue-loading-overlay": "^3.4.2", 27 | "vue-server-renderer": "2.6.14", 28 | "vue-template-compiler": "2.6.14", 29 | "vuetify": "^2.6.4" 30 | }, 31 | "devDependencies": { 32 | "@babel/eslint-parser": "^7.17.0", 33 | "@commitlint/cli": "^16.2.4", 34 | "@commitlint/config-conventional": "^16.2.4", 35 | "@nuxtjs/eslint-config": "^8.0.0", 36 | "@nuxtjs/eslint-module": "^3.0.2", 37 | "@nuxtjs/style-resources": "^1.2.1", 38 | "@nuxtjs/vuetify": "^1.12.3", 39 | "@vue/test-utils": "^1.3.0", 40 | "babel-core": "7.0.0-bridge.0", 41 | "babel-jest": "^27.5.1", 42 | "eslint": "^8.3.0", 43 | "eslint-config-prettier": "^8.5.0", 44 | "eslint-plugin-nuxt": "^2.0.0", 45 | "eslint-plugin-vue": "^7.20.0", 46 | "husky": "^7.0.4", 47 | "jest": "^27.5.1", 48 | "node-sass": "^6.0.1", 49 | "prettier": "^2.6.1", 50 | "prop-types": "^15.8.1", 51 | "sass": "^1.49.11", 52 | "sass-loader": "^10.2.1", 53 | "vue-jest": "^3.0.7" 54 | }, 55 | "peerDependencies": { 56 | "prop-types": "^15.6.0" 57 | }, 58 | "pnpm": { 59 | "overrides": { 60 | "nth-check@<2.0.1": ">=2.0.1", 61 | "glob-parent@<5.1.2": ">=5.1.2" 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pages/auth/component.vue: -------------------------------------------------------------------------------- 1 | 2 | 63 | 85 | 92 | -------------------------------------------------------------------------------- /pages/auth/dropdown/_id.vue: -------------------------------------------------------------------------------- 1 | 6 | 23 | -------------------------------------------------------------------------------- /pages/auth/fetch.vue: -------------------------------------------------------------------------------- 1 | 16 | 49 | -------------------------------------------------------------------------------- /pages/auth/home.vue: -------------------------------------------------------------------------------- 1 | 10 | 22 | -------------------------------------------------------------------------------- /pages/auth/table.vue: -------------------------------------------------------------------------------- 1 | 10 | 50 | -------------------------------------------------------------------------------- /pages/change-password.vue: -------------------------------------------------------------------------------- 1 | 36 | 61 | -------------------------------------------------------------------------------- /pages/forgot-password.vue: -------------------------------------------------------------------------------- 1 | 30 | 56 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | -------------------------------------------------------------------------------- /pages/login.vue: -------------------------------------------------------------------------------- 1 | 47 | 78 | -------------------------------------------------------------------------------- /pages/otp-code.vue: -------------------------------------------------------------------------------- 1 | 26 | 48 | -------------------------------------------------------------------------------- /pages/testing.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 29 | -------------------------------------------------------------------------------- /payloads/RequestFetch.js: -------------------------------------------------------------------------------- 1 | // request Fetch payload axios 2 | 3 | export default class RequestFetch { 4 | id 5 | } 6 | -------------------------------------------------------------------------------- /plugins/api.js: -------------------------------------------------------------------------------- 1 | import Api from '@/api/Api.js' 2 | 3 | export default ({ $axios }, inject) => { 4 | Api.$axios = $axios 5 | inject('Api', Api) 6 | } 7 | -------------------------------------------------------------------------------- /plugins/axios.js: -------------------------------------------------------------------------------- 1 | export default ({ $axios, redirect, store, route, error }) => { 2 | $axios.setBaseURL(process.env.BASE_URL) 3 | 4 | $axios.onRequest((config) => { 5 | store.commit('SET_LOADING', true) 6 | const accessToken = store.getters['user/access_token'] 7 | if (accessToken) { 8 | config.headers.common.Authorization = `Bearer ${accessToken}` 9 | } 10 | }) 11 | 12 | $axios.onResponse((response) => { 13 | store.commit('SET_LOADING', false) 14 | }) 15 | 16 | $axios.onError((err) => { 17 | const code = parseInt(err.response && err.response.status) 18 | if (code === 401) { 19 | redirect('/login') 20 | } 21 | 22 | if (code === 403 || code === 404 || code === 500) { 23 | error({ statusCode: code, message: err.response.statusText }) 24 | } 25 | 26 | store.commit('SET_LOADING', false) 27 | 28 | return error.response 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /plugins/nuxt-client-init.js: -------------------------------------------------------------------------------- 1 | export default async (ctx) => { 2 | await ctx.store.dispatch('nuxtClientInit', ctx) 3 | } -------------------------------------------------------------------------------- /plugins/vee-validate.js: -------------------------------------------------------------------------------- 1 | import { 2 | extend, 3 | ValidationObserver, 4 | ValidationProvider, 5 | setInteractionMode, 6 | } from 'vee-validate' 7 | import { required, email, confirmed } from 'vee-validate/dist/rules' 8 | import Vue from 'vue' 9 | Vue.component('ValidationProvider', ValidationProvider) 10 | Vue.component('ValidationObserver', ValidationObserver) 11 | 12 | setInteractionMode('lazy') 13 | 14 | extend('required', { 15 | ...required, 16 | message: '{_field_} tidak boleh kosong', 17 | }) 18 | 19 | extend('email', { 20 | ...email, 21 | message: 'Email harus valid', 22 | }) 23 | 24 | extend('confirmed', { 25 | ...confirmed, 26 | message: 'Konfirmasi password tidak sama', 27 | }) 28 | -------------------------------------------------------------------------------- /services/fetchServices.js: -------------------------------------------------------------------------------- 1 | import Api from '~/api/Api.js' 2 | 3 | class FetchServices { 4 | async GetFetch({ request }) { 5 | const res = await Api.doGet(``, request) 6 | // console.debug('GET FETCH', res) 7 | return res 8 | } 9 | } 10 | 11 | export default new FetchServices() 12 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/static/favicon.ico -------------------------------------------------------------------------------- /static/v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BaihakiTanjung/starter-template-nuxt-vuetify-cms/1b479399058ef96f900fd12adf54090e87b577db/static/v.png -------------------------------------------------------------------------------- /static/vuetify-logo.svg: -------------------------------------------------------------------------------- 1 | Artboard 46 2 | -------------------------------------------------------------------------------- /store/fetch.js: -------------------------------------------------------------------------------- 1 | import fetchServices from '~/services/fetchServices' 2 | import { showFailedPopup } from '@/helpers/Utils' 3 | 4 | export const state = () => ({ 5 | items: '', 6 | }) 7 | 8 | export const getters = { 9 | items: (state) => state.items, 10 | } 11 | 12 | export const mutations = { 13 | SET_ITEMS(state, items) { 14 | state.items = items 15 | }, 16 | } 17 | 18 | export const actions = { 19 | async getFetch(context, payload) { 20 | try { 21 | const res = await fetchServices.GetFetch({}) 22 | context.commit('SET_ITEMS', res) 23 | return res 24 | } catch (error) { 25 | showFailedPopup({ msg: error }) 26 | throw error 27 | } 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | export const state = () => ({ 2 | pageTitle: '', 3 | isLoading: false, 4 | }) 5 | 6 | export const getters = { 7 | pageTitle: (state) => state.pageTitle, 8 | isLoading: (state) => state.isLoading, 9 | } 10 | 11 | export const mutations = { 12 | SET_PAGE_TITLE(state, title) { 13 | state.pageTitle = title 14 | }, 15 | SET_LOADING(state, isLoading) { 16 | state.isLoading = isLoading 17 | }, 18 | } 19 | 20 | export const actions = {} 21 | -------------------------------------------------------------------------------- /store/sidebar.js: -------------------------------------------------------------------------------- 1 | export const state = () => ({ 2 | items: [ 3 | { title: 'Home', to: '/auth/home', icon: 'mdi-home' }, 4 | { title: 'Component', to: '/auth/component', icon: 'mdi-card' }, 5 | { title: 'Fetch', to: '/auth/fetch', icon: 'mdi-restart' }, 6 | { title: 'Table', to: '/auth/table', icon: 'mdi-table' }, 7 | { 8 | title: 'Dropdown', 9 | to: '/auth/about', 10 | icon: 'mdi-form-dropdown', 11 | children: [ 12 | { 13 | title: 'Dropdown 1', 14 | to: '/auth/dropdown/1', 15 | icon: 'mdi-form-dropdown', 16 | }, 17 | { 18 | title: 'Dropdown 2', 19 | to: '/auth/dropdown/2', 20 | icon: 'mdi-form-dropdown', 21 | children: [ 22 | { 23 | title: 'Dropdown 2.1', 24 | to: '/auth/dropdown/21', 25 | icon: 'mdi-form-dropdown', 26 | }, 27 | { 28 | title: 'Dropdown 2.2', 29 | to: '/auth/dropdown/22', 30 | icon: 'mdi-form-dropdown', 31 | }, 32 | ], 33 | }, 34 | { 35 | title: 'Dropdown 3', 36 | to: '/auth/dropdown/3', 37 | icon: 'mdi-form-dropdown', 38 | }, 39 | ], 40 | }, 41 | ], 42 | }) 43 | -------------------------------------------------------------------------------- /test/NuxtLogo.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from '@vue/test-utils' 2 | import NuxtLogo from '@/components/NuxtLogo.vue' 3 | 4 | describe('NuxtLogo', () => { 5 | test('is a Vue instance', () => { 6 | const wrapper = mount(NuxtLogo) 7 | expect(wrapper.vm).toBeTruthy() 8 | }) 9 | }) 10 | --------------------------------------------------------------------------------