├── .gitignore
├── README.md
├── assets
├── README.md
└── scss
│ └── main.scss
├── assignments.txt
├── components
├── Logo.vue
├── Navbar.vue
├── PostCreate.vue
├── PostItem.vue
├── PostManage.vue
├── README.md
└── shared
│ └── Modal.vue
├── layouts
├── README.md
└── default.vue
├── middleware
└── README.md
├── nuxt.config.js
├── package-lock.json
├── package.json
├── pages
├── README.md
├── index.vue
├── manage.vue
└── posts
│ └── _id.vue
├── plugins
├── README.md
└── filters.js
├── resources
├── 1_Index-page.html
├── 2_Checkbox.html
├── 3_manage.html
├── 4_Modal.html
├── 5_Modal_Form.html
├── 6_Post_Update.html
├── 7_delete_button.html
└── 8_PostDetail.html
├── server
├── index.js
└── routes
│ └── index.js
├── static
├── README.md
└── favicon.ico
└── store
├── README.md
├── index.js
├── initial_data.json
└── post.js
/.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 | .editorconfig
83 |
84 | # Service worker
85 | sw.*
86 |
87 | # Mac OSX
88 | .DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nuxt-posts
2 |
3 | > My awe-inspiring Nuxt.js project
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | $ npm run install
10 |
11 | # serve with hot reload at localhost:3000
12 | $ npm run dev
13 |
14 | # build for production and launch server
15 | $ npm run build
16 | $ npm run start
17 |
18 | # generate static project
19 | $ npm run generate
20 | ```
21 |
22 | For detailed explanation on how things work, checkout [Nuxt.js docs](https://nuxtjs.org).
23 |
--------------------------------------------------------------------------------
/assets/README.md:
--------------------------------------------------------------------------------
1 | # ASSETS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
8 |
--------------------------------------------------------------------------------
/assets/scss/main.scss:
--------------------------------------------------------------------------------
1 |
2 |
3 | .markdown {
4 | p {
5 | margin: 5px 0;
6 | }
7 |
8 | h1, h2, h3 {
9 | font-weight: bold;
10 | }
11 |
12 | h1 {
13 | font-size: 23px;
14 | }
15 |
16 | h2 {
17 | font-size: 20px;
18 | }
19 |
20 | h3 {
21 | font-size: 17px;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/assignments.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------SERVER----------------
3 |
4 | 1. Update server endpoint to remove post
5 | HINT: is very similiar to patch endpoint, you don't need to send any data
6 | just provide post "id" in request params.
7 | 2. find index of post in array and remove post
8 | 3. to remove post from array you can use funtion "splice"
9 | 4. write file with initialData...
10 |
11 | --------------CLIENT----------------
12 |
13 | 1. Create new action "deletePost" expect to receive "id" of post in arguments of this function.
14 | 2. Find post index in array and if index is found send request to delete post
15 | HINT: this.$axios.$delete('endpoint')
16 | 3. In "then" block after promise is resolved commit mutation to remove post from list, use "splice" once more
17 | 4. after delete button is clicked dispatch action "deletePost"
18 |
19 | NOTE: One issue is expected. After post will be deleted, activePost will have still old value of deleted post.
20 | Don't worry about this issue right now. Bonus points if you can resolve it. In any case we will fix it in next lecture.
21 |
--------------------------------------------------------------------------------
/components/Logo.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
80 |
--------------------------------------------------------------------------------
/components/Navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
44 |
45 |
46 |
47 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/components/PostCreate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Create
6 |
7 |
8 |
45 |
46 |
47 |
48 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/components/PostItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
14 |
15 |
16 |
17 |
21 | Read
22 |
23 |
24 |
25 |
26 |
27 |
69 |
70 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/components/PostManage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Title
5 |
6 |
11 |
12 |
13 |
14 |
Subtitle
15 |
16 |
21 |
22 |
23 |
24 |
Content
25 |
26 |
30 |
31 |
32 |
33 |
Contet Preview
34 |
35 |
36 | Update
39 |
40 |
41 |
42 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/components/README.md:
--------------------------------------------------------------------------------
1 | # COMPONENTS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | The components directory contains your Vue.js Components.
6 |
7 | _Nuxt.js doesn't supercharge these components._
8 |
--------------------------------------------------------------------------------
/components/shared/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Open
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Modal title
16 |
17 |
18 |
19 |
22 |
30 |
31 |
32 |
33 |
34 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/layouts/README.md:
--------------------------------------------------------------------------------
1 | # LAYOUTS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Application Layouts.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
8 |
--------------------------------------------------------------------------------
/layouts/default.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
56 |
--------------------------------------------------------------------------------
/middleware/README.md:
--------------------------------------------------------------------------------
1 | # MIDDLEWARE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your application middleware.
6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
7 |
8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
9 |
--------------------------------------------------------------------------------
/nuxt.config.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 | mode: 'universal',
4 | /*
5 | ** Headers of the page
6 | */
7 | head: {
8 | title: process.env.npm_package_name || '',
9 | meta: [
10 | { charset: 'utf-8' },
11 | { name: 'viewport', content: 'width=device-width, initial-scale=1' },
12 | { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
13 | ],
14 | link: [
15 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
16 | ],
17 | script: [
18 | { src: 'https://cdn.jsdelivr.net/npm/marked/marked.min.js'}
19 | ]
20 | },
21 | /*
22 | ** Customize the progress-bar color
23 | */
24 | loading: { color: '#fff' },
25 | /*
26 | ** Global CSS
27 | */
28 | css: [
29 | '@/assets/scss/main.scss'
30 | ],
31 | /*
32 | ** Plugins to load before mounting the App
33 | */
34 | plugins: [
35 | {src: '~/plugins/filters.js'}
36 | ],
37 | /*
38 | ** Nuxt.js modules
39 | */
40 | modules: [
41 | // Doc:https://github.com/nuxt-community/modules/tree/master/packages/bulma
42 | '@nuxtjs/bulma',
43 | // Doc: https://axios.nuxtjs.org/usage
44 | '@nuxtjs/axios',
45 | ],
46 | /*
47 | ** Axios module configuration
48 | ** See https://axios.nuxtjs.org/options
49 | */
50 | axios: {
51 | },
52 | /*
53 | ** Build configuration
54 | */
55 | serverMiddleware: [
56 | '~/server/routes/index'
57 | ],
58 | build: {
59 | postcss: {
60 | preset: {
61 | features: {
62 | customProperties: false
63 | }
64 | }
65 | },
66 | /*
67 | ** You can extend webpack config here
68 | */
69 | extend(config, ctx) {
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nuxt-posts",
3 | "version": "1.0.0",
4 | "description": "My awe-inspiring Nuxt.js project",
5 | "author": "Filip Jerga",
6 | "private": true,
7 | "scripts": {
8 | "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
9 | "build": "nuxt build",
10 | "start": "cross-env NODE_ENV=production node server/index.js",
11 | "generate": "nuxt generate"
12 | },
13 | "dependencies": {
14 | "@nuxtjs/axios": "^5.3.6",
15 | "@nuxtjs/bulma": "^1.2.1",
16 | "body-parser": "^1.19.0",
17 | "cross-env": "^5.2.0",
18 | "express": "^4.16.4",
19 | "moment": "^2.24.0",
20 | "node-sass": "^4.12.0",
21 | "nuxt": "^2.0.0",
22 | "sass-loader": "^7.1.0"
23 | },
24 | "devDependencies": {
25 | "nodemon": "^1.18.9"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/pages/README.md:
--------------------------------------------------------------------------------
1 | # PAGES
2 |
3 | This directory contains your Application Views and Routes.
4 | The framework reads all the `*.vue` files inside this directory and creates the router of your application.
5 |
6 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
7 |
--------------------------------------------------------------------------------
/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
Newest Posts
12 |
13 |
14 |
25 |
26 | No Posts :(
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
88 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/pages/manage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
18 |
19 |
24 |
25 | {{post.title}}
26 |
27 |
28 |
{{post.subtitle}}
29 |
30 |
31 |
32 |
33 |
34 |
35 | There are no posts :(
36 |
37 |
38 |
44 |
45 |
60 |
61 |
62 |
63 |
114 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/pages/posts/_id.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Detail View
11 |
12 |
13 |
14 |
{{post.title}}
15 |
{{post.subtitle}}
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/plugins/README.md:
--------------------------------------------------------------------------------
1 | # PLUGINS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
8 |
--------------------------------------------------------------------------------
/plugins/filters.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import moment from 'moment'
3 |
4 |
5 | Vue.filter('formatDate', (date, dateFormat = 'LL') => {
6 | if (!date) {
7 | return ''
8 | }
9 |
10 | return moment(date).format(dateFormat)
11 | })
12 |
--------------------------------------------------------------------------------
/resources/1_Index-page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
Newest Posts
51 |
52 |
53 |
54 |
58 |
59 | by Filip Jerga, 27th Jan, 2019
60 |
61 |
62 |
63 |
67 |
68 | by Filip Jerga, 27th Jan, 2019
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | .post-content {
83 | font-style: italic;
84 | }
85 |
86 | .post {
87 | margin-bottom: 20px;
88 | padding: 5px;
89 | border-bottom: 2px solid transparent;
90 | }
91 |
92 | .post:hover {
93 | border-bottom: 2px solid #e8e8e8;
94 | }
95 |
--------------------------------------------------------------------------------
/resources/2_Checkbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Read
5 |
6 |
7 |
8 |
9 |
10 | .post-footer {
11 | font-style: italic;
12 | }
13 | .post {
14 | margin-bottom: 20px;
15 | padding: 5px;
16 | border-bottom: 2px solid transparent;
17 | display: flex;
18 | flex-direction: row;
19 | }
20 | .post-content {
21 | flex: 1;
22 | }
23 | .post-right {
24 | float: right;
25 | justify-content: flex-end;
26 | align-self: center;
27 | }
28 |
--------------------------------------------------------------------------------
/resources/3_manage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
42 |
43 |
44 |
45 |
56 |
57 |
58 |
59 |
60 |
65 |
66 | Some Title
67 |
68 |
71 |
72 |
73 |
74 |
75 |
80 |
81 | Some Title 2
82 |
83 |
84 |
Some Subtitle 2
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
John Smith
98 |
someone@gmail.com
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
122 |
123 |
124 |
125 |
128 |
129 |
143 |
--------------------------------------------------------------------------------
/resources/4_Modal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Create
6 |
7 |
8 |
9 |
10 |
11 | Modal title
12 |
13 |
14 |
17 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/resources/5_Modal_Form.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Title
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Subtitle
11 |
12 |
13 |
14 |
15 |
16 |
Content
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/resources/6_Post_Update.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Title
4 |
5 |
9 |
10 |
11 |
12 |
Subtitle
13 |
14 |
18 |
19 |
20 |
21 |
Content
22 |
23 |
26 |
27 |
28 | Update
29 |
30 |
--------------------------------------------------------------------------------
/resources/7_delete_button.html:
--------------------------------------------------------------------------------
1 |
2 | Delete
3 |
4 | .delete-button {
5 | display: block;
6 | width: 100px;
7 | margin-left: auto;
8 | margin-right: 0;
9 | }
10 |
--------------------------------------------------------------------------------
/resources/8_PostDetail.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Detail View
11 |
12 |
13 |
14 |
Some Title
15 |
Some Subtitle
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const consola = require('consola')
3 | const { Nuxt, Builder } = require('nuxt')
4 | const app = express()
5 |
6 | // Import and Set Nuxt.js options
7 | const config = require('../nuxt.config.js')
8 | config.dev = !(process.env.NODE_ENV === 'production')
9 |
10 | async function start() {
11 | // Init Nuxt.js
12 | const nuxt = new Nuxt(config)
13 |
14 | const { host, port } = nuxt.options.server
15 |
16 | // Build only in dev mode
17 | if (config.dev) {
18 | const builder = new Builder(nuxt)
19 | await builder.build()
20 | } else {
21 | await nuxt.ready()
22 | }
23 |
24 | // Give nuxt middleware to express
25 | app.use(nuxt.render)
26 |
27 | // Listen the server
28 | app.listen(port, host)
29 | consola.ready({
30 | message: `Server listening on http://${host}:${port}`,
31 | badge: true
32 | })
33 | }
34 | start()
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/server/routes/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const bodyParser = require('body-parser')
4 |
5 | const fs = require('fs')
6 | const path = require('path')
7 | const filePath = '../../store/initial_data.json'
8 | const initialData = require(filePath)
9 |
10 | app.use(bodyParser.json())
11 |
12 | app.get('/posts', function(req, res) {
13 | return res.json(initialData.posts)
14 | })
15 |
16 | app.post('/posts', function(req, res) {
17 | const post = req.body
18 | initialData.posts.push(post)
19 |
20 | fs.writeFile(path.join(__dirname, filePath), JSON.stringify(initialData, null, 2), function(err) {
21 | if (err) {
22 | return res.status(422).send(err)
23 | }
24 |
25 | return res.json('File Sucesfully updated')
26 | })
27 | })
28 |
29 | app.patch('/posts/:id', function(req, res) {
30 | const id = req.params.id
31 | const post = req.body
32 | const index = initialData.posts.findIndex(p => p._id === post._id)
33 | initialData.posts[index] = post
34 |
35 | if (index !== -1) {
36 | fs.writeFile(path.join(__dirname, filePath), JSON.stringify(initialData, null, 2), function(err) {
37 | if (err) {
38 | return res.status(422).send(err)
39 | }
40 |
41 | return res.json('File Sucesfully Updated')
42 | })
43 | } else {
44 | return res.status(422).send({error: 'Post cannot be updated!'})
45 | }
46 | })
47 |
48 | //
49 | app.delete('/posts/:id', function(req, res) {
50 | const id = req.params.id
51 | const index = initialData.posts.findIndex(p => p._id === id)
52 |
53 | if (index !== -1) {
54 | initialData.posts.splice(index, 1)
55 |
56 | fs.writeFile(path.join(__dirname, filePath), JSON.stringify(initialData, null, 2), function(err) {
57 | if (err) {
58 | return res.status(422).send(err)
59 | }
60 |
61 | return res.json({message: 'File Sucesfully Updated'})
62 | })
63 | } else {
64 | return res.status(422).send({error: 'Post cannot be updated!'})
65 | }
66 | })
67 |
68 |
69 |
70 |
71 | module.exports = {
72 | path: '/api',
73 | handler: app
74 | }
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/static/README.md:
--------------------------------------------------------------------------------
1 | # STATIC
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your static files.
6 | Each file inside this directory is mapped to `/`.
7 | Thus you'd want to delete this README.md before deploying to production.
8 |
9 | Example: `/static/robots.txt` is mapped as `/robots.txt`.
10 |
11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
12 |
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jerga99/nuxt-posts/232ada0ce60800fe9aa91a909f4c28890d59c8ac/static/favicon.ico
--------------------------------------------------------------------------------
/store/README.md:
--------------------------------------------------------------------------------
1 | # STORE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Vuex Store files.
6 | Vuex Store option is implemented in the Nuxt.js framework.
7 |
8 | Creating a file in this directory automatically activates the option in the framework.
9 |
10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
11 |
--------------------------------------------------------------------------------
/store/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jerga99/nuxt-posts/232ada0ce60800fe9aa91a909f4c28890d59c8ac/store/index.js
--------------------------------------------------------------------------------
/store/initial_data.json:
--------------------------------------------------------------------------------
1 | {
2 | "posts": [
3 | {
4 | "title": "sdasdasdadasd",
5 | "subtitle": "adadadad",
6 | "content": "adadadda",
7 | "_id": "jg4stma",
8 | "createdAt": 1563560226848
9 | },
10 | {
11 | "title": "asdada",
12 | "subtitle": "dadada",
13 | "content": "dasdadd",
14 | "_id": "jgx0htk",
15 | "createdAt": 1563560230288
16 | },
17 | {
18 | "title": "New Post",
19 | "subtitle": "New post with markdown",
20 | "content": "# h1 Heading 8-)\n## h2 Heading\n### h3 Heading\n#### h4 Heading\n##### h5 Heading\n",
21 | "_id": "m9cafnc",
22 | "createdAt": 1563567352609
23 | },
24 | {
25 | "title": "Amazing New Post! UPDATED",
26 | "subtitle": "Amazing new post subtitle",
27 | "content": "---\n__Advertisement :)__\n\n- __[pica](https://nodeca.github.io/pica/demo/)__ - high quality and fast image\n resize in browser.\n- __[babelfish](https://github.com/nodeca/babelfish/)__ - developer friendly\n i18n with plurals support and easy syntax.\n\nYou will like those projects!\n\n---\n\n# h1 Heading 8-)\n## h2 Heading\n### h3 Heading\n#### h4 Heading\n##### h5 Heading\n###### h6 Heading\n\n\n## Horizontal Rules\n\n___\n\n---\n\n***\n\n\n## Typographic replacements\n\nEnable typographer option to see result.\n\n(c) (C) (r) (R) (tm) (TM) (p) (P) +-\n\ntest.. test... test..... test?..... test!....\n\n!!!!!! ???? ,, -- ---\n\n\"Smartypants, double quotes\" and 'single quotes'",
28 | "_id": "vidi2j3",
29 | "createdAt": 1563612079853
30 | }
31 | ]
32 | }
--------------------------------------------------------------------------------
/store/post.js:
--------------------------------------------------------------------------------
1 |
2 | import INITIAL_DATA from './initial_data.json'
3 | import Vue from 'vue'
4 |
5 |
6 | export function fetchPostsAPI() {
7 | return new Promise((resolve, reject) => {
8 | setTimeout(() => {
9 | resolve(INITIAL_DATA.posts)
10 | }, 0)
11 | })
12 | }
13 |
14 |
15 | export const state = () => {
16 | return {
17 | items: [],
18 | archivedItems: [],
19 | item: {}
20 | }
21 | }
22 |
23 | // Getters are like computed properties but for Vuex
24 | export const getters = {
25 | hasEmptyItems(state) {
26 | return state.items.length === 0
27 | }
28 | }
29 |
30 | // Very good spot to send a request to a server. Usualy Actions resolve into some data
31 | export const actions = {
32 | getArchivedPosts({commit}) {
33 | const archivedPosts = localStorage.getItem('archived_posts')
34 | if (archivedPosts) {
35 | commit('setArchivedPosts', JSON.parse(archivedPosts))
36 | return archivedPosts
37 | } else {
38 | localStorage.setItem('archived_posts', JSON.stringify([]))
39 | return []
40 | }
41 | },
42 | togglePost({state, commit, dispatch}, postId) {
43 | if (state.archivedItems.includes(postId)) {
44 | // remove post id
45 | const index = state.archivedItems.findIndex(pId => pId === postId)
46 | commit('removeArchivedPost', index)
47 | dispatch('persistArchivedPosts')
48 | return postId
49 | } else {
50 | // add Post id
51 | commit('addArchivedPost', postId)
52 | dispatch('persistArchivedPosts')
53 | return postId
54 | }
55 | },
56 | persistArchivedPosts({state}) {
57 | localStorage.setItem('archived_posts', JSON.stringify(state.archivedItems))
58 | },
59 | fetchPosts({commit}) {
60 | return this.$axios.$get('/api/posts')
61 | .then((posts) => {
62 | commit('setPosts', posts)
63 | return posts
64 | })
65 | },
66 | fetchPostById({commit}, postId) {
67 | return this.$axios.$get('/api/posts')
68 | .then((posts) => {
69 | const selectedPost = posts.find((p) => p._id === postId)
70 | commit('setPost', selectedPost)
71 | return selectedPost
72 | })
73 | },
74 | createPost({commit}, postData) {
75 | postData._id = Math.random().toString(36).substr(2, 7)
76 | postData.createdAt = (new Date()).getTime()
77 |
78 | return this.$axios.$post('/api/posts', postData)
79 | .then((res) => {
80 | commit('addPost', postData)
81 | return postData
82 | })
83 | },
84 | updatePost({commit, state}, postData) {
85 | const index = state.items.findIndex((post) => {
86 | return post._id === postData._id
87 | })
88 |
89 | if (index !== -1) {
90 | return this.$axios.$patch(`/api/posts/${postData._id}`, postData)
91 | .then((res) => {
92 | commit('replacePost', {post: postData, index})
93 | return postData
94 | })
95 | }
96 | },
97 | deletePost({commit, state}, postId) {
98 | const index = state.items.findIndex((post) => {
99 | return post._id === postId
100 | })
101 |
102 | if (index !== -1) {
103 | return this.$axios.$delete(`/api/posts/${postId}`)
104 | .then((res) => {
105 | commit('deletePost', index)
106 | return postId
107 | })
108 | }
109 | }
110 | }
111 |
112 | // Mutations are simple functions that have access to a state.
113 | // Mutations are used to assign values to a state
114 | export const mutations = {
115 | setArchivedPosts(state, archivedPosts) {
116 | state.archivedItems = archivedPosts
117 | },
118 | addArchivedPost(state, postId) {
119 | state.archivedItems.push(postId)
120 | },
121 | removeArchivedPost(state, index) {
122 | state.archivedItems.splice(index, 1)
123 | },
124 | setPosts(state, posts) {
125 | state.items = posts
126 | },
127 | setPost(state, post) {
128 | state.item = post
129 | },
130 | addPost(state, post) {
131 | state.items.push(post)
132 | },
133 | replacePost(state, {post, index}) {
134 | Vue.set(state.items, index, post)
135 | },
136 | deletePost(state, postIndex) {
137 | state.items.splice(postIndex, 1)
138 | }
139 | }
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------