├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── favicon.ico
├── index.html
└── jokes.json
└── src
├── App.vue
├── assets
├── logo.png
└── logo.svg
├── components
├── AddForm.vue
├── ListJokes.vue
└── Login.vue
├── main.js
├── plugins
└── vuetify.js
├── router.js
├── state
├── modules
│ ├── auth.js
│ ├── index.js
│ └── jokes.js
└── store.js
└── views
└── Home.vue
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not ie <= 8
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | 'extends': [
7 | 'plugin:vue/essential',
8 | 'eslint:recommended'
9 | ],
10 | rules: {
11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
13 | },
14 | parserOptions: {
15 | parser: 'babel-eslint'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw*
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # quote-fun
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Run your tests
19 | ```
20 | npm run test
21 | ```
22 |
23 | ### Lints and fixes files
24 | ```
25 | npm run lint
26 | ```
27 |
28 | ### Customize configuration
29 | See [Configuration Reference](https://cli.vuejs.org/config/).
30 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quote-fun",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "lodash": "^4.17.11",
12 | "vue": "^2.6.6",
13 | "vue-router": "^3.0.1",
14 | "vuetify": "^1.5.5",
15 | "vuex": "^3.0.1"
16 | },
17 | "devDependencies": {
18 | "@vue/cli-plugin-babel": "^3.5.0",
19 | "@vue/cli-plugin-eslint": "^3.5.0",
20 | "@vue/cli-service": "^3.5.0",
21 | "babel-eslint": "^10.0.1",
22 | "eslint": "^5.8.0",
23 | "eslint-plugin-vue": "^5.0.0",
24 | "material-design-icons-iconfont": "^4.0.5",
25 | "stylus": "^0.54.5",
26 | "stylus-loader": "^3.0.1",
27 | "vue-cli-plugin-vuetify": "^0.5.0",
28 | "vue-template-compiler": "^2.5.21",
29 | "vuetify-loader": "^1.0.5"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ErikCH/VuexModules/4cda2008ca31661d4264d3577cf856a21d72ee29/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | quote-fun
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/public/jokes.json:
--------------------------------------------------------------------------------
1 | {
2 | "jokeList": "jokes",
3 | "jokes": [
4 | {
5 | "id": 1,
6 | "question": "Did you hear about the restaurant on the moon?",
7 | "answer": "Great food, no atmosphere.",
8 | "votes": 0
9 | },
10 | {
11 | "id": 2,
12 | "question": "What do you call a fake noodle",
13 | "answer": "An Impasta.",
14 | "votes": 0
15 | },
16 | {
17 | "id": 3,
18 | "question": "How many apples grow on a tree?",
19 | "answer": "All of them.",
20 | "votes": 0
21 | },
22 | {
23 | "id": 4,
24 | "question": "Want to hear a joke about paper?",
25 | "answer": "Nevermind it's tearable.",
26 | "votes": 0
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Jokes App
8 |
9 |
10 |
11 | Login
12 | Welcome {{userName}}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
35 |
36 |
43 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ErikCH/VuexModules/4cda2008ca31661d4264d3577cf856a21d72ee29/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/AddForm.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Add Joke
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Add
23 |
24 |
25 |
26 |
27 |
28 |
50 |
51 |
--------------------------------------------------------------------------------
/src/components/ListJokes.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | arrow_upward
10 | {{votes}}
11 | arrow_downward
12 |
13 |
14 | {{question}}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | {{answer}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
50 |
51 |
--------------------------------------------------------------------------------
/src/components/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Add Login
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Add
23 |
24 |
25 |
26 |
27 |
28 |
47 |
48 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import './plugins/vuetify';
3 | import App from './App.vue';
4 | import store from './state/store';
5 | import router from './router'
6 |
7 | Vue.config.productionTip = false;
8 |
9 | new Vue({
10 | store,
11 | router,
12 | render: h => h(App)
13 | }).$mount('#app');
14 |
--------------------------------------------------------------------------------
/src/plugins/vuetify.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuetify from 'vuetify/lib'
3 | import 'vuetify/src/stylus/app.styl'
4 |
5 | Vue.use(Vuetify, {
6 | iconfont: 'md',
7 | })
8 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Router from 'vue-router';
3 | import Home from './views/Home.vue';
4 | import AddForm from './components/AddForm.vue';
5 | import Login from './components/Login.vue';
6 |
7 | Vue.use(Router);
8 |
9 | export default new Router({
10 | mode: 'history',
11 | base: process.env.BASE_URL,
12 | routes: [
13 | {
14 | path: '/',
15 | name: 'home',
16 | component: Home
17 | },
18 | {
19 | path: '/login',
20 | name: 'login',
21 | component: Login
22 | },
23 | {
24 | path: '/add-joke',
25 | name: 'add',
26 | component: AddForm
27 | // route level code-splitting
28 | // this generates a separate chunk (about.[hash].js) for this route
29 | // which is lazy-loaded when the route is visited.
30 | // component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
31 | }
32 | ]
33 | });
34 |
--------------------------------------------------------------------------------
/src/state/modules/auth.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 |
4 | username: ''
5 | },
6 | getters: {
7 | username: state => state.username
8 | },
9 | actions: {
10 | addUserName({commit}, username) {
11 | commit('ADD_USERNAME', username);
12 | }
13 | },
14 | mutations: {
15 | ADD_USERNAME(state, name) {
16 | state.username = name;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/state/modules/index.js:
--------------------------------------------------------------------------------
1 |
2 | import camelCase from 'lodash/camelCase'
3 |
4 | const requireModule = require.context(".", false, /\.js$/); //extract js files inside modules folder
5 | const modules = {};
6 |
7 | requireModule.keys().forEach(fileName => {
8 | if (fileName === "./index.js") return; //reject the index.js file
9 |
10 | const moduleName = camelCase(fileName.replace(/(\.\/|\.js)/g, "")); //
11 |
12 | modules[moduleName] = requireModule(fileName).default;
13 | });
14 | export default modules;
--------------------------------------------------------------------------------
/src/state/modules/jokes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | jokes: {},
4 | },
5 | getters: {
6 | jokes: state => state.jokes,
7 | latestId: state => {
8 | let id = 0;
9 | state.jokes.jokes.forEach(m => {
10 | if (m.id > id) {
11 | id = m.id;
12 | }
13 | });
14 | return id;
15 | },
16 | },
17 | actions: {
18 | async initStore({state, commit}) {
19 | if (!state.jokes['jokes']) {
20 | const jokes = await fetch('/jokes.json');
21 | commit('SET_JOKES', await jokes.json());
22 | }
23 | },
24 | addJoke({commit}, joke) {
25 | commit('ADD_JOKE', joke);
26 | },
27 | },
28 | mutations: {
29 | SET_JOKES(state, jokes) {
30 | state.jokes = jokes;
31 | },
32 | ADD_JOKE(state, joke) {
33 | state.jokes.jokes.push(joke);
34 | console.log('added', state.jokes);
35 | },
36 | }
37 | }
--------------------------------------------------------------------------------
/src/state/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 | import jokes from './modules/jokes'
4 | import auth from './modules/auth'
5 | import modules from './modules'
6 |
7 | Vue.use(Vuex);
8 |
9 | export default new Vuex.Store({
10 | strict: true,
11 | modules: {
12 | jokes,
13 | auth
14 | },
15 | });
16 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Add Joke
10 |
11 |
12 |
13 |
14 |
37 |
--------------------------------------------------------------------------------