From 2ee225c11b2ff9e5d80c6bfae75da72ec5757d4a Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Sun, 15 Apr 2018 11:42:04 +0700 Subject: [PATCH 01/14] Completed --- index.html | 56 +++++++++++++++++++++++++---- public/script.js | 93 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index 52365f64..6652ca11 100644 --- a/index.html +++ b/index.html @@ -2,29 +2,68 @@ - Codestin Search App - + + - + -
+

Vue.js Poster Store

+
-

Products go here.

+
Loading...
+
+ Found {{ results.length }} results for search term {{ lastSearch }}. +
+
+
+
+ +
+
+
+

{{ item.title }}

+

Price: {{ price | currency }}

+ +
+
+
+
No more items.
+

Shopping Cart

-
+ +
  • +
    {{ item.title }}
    +
    + + {{ item.price | currency }} x {{ item.qty }} + + + +
    +
  • +
    + +
    +
    Total: {{ total | currency }}
    +
    +
    +
    No items in the cart.
    @@ -33,7 +72,10 @@

    Shopping Cart

    - + + + + diff --git a/public/script.js b/public/script.js index a96bcad1..ec8b5479 100644 --- a/public/script.js +++ b/public/script.js @@ -1 +1,92 @@ -console.log('It works.'); +var PRICE = 9.99; +var LOAD_NUM = 10; + +new Vue({ + el: '#app', + data: { + total: 0, + items: [], + results: [], + cart: [], + newSearch: 'anime', + lastSearch: '', + loading: false, + price: PRICE + }, + mounted: function() { + this.onSubmit(); + var elem = document.getElementById('product-list-bottom'); + var watcher = scrollMonitor.create(elem); + var vue = this; + watcher.enterViewport(function() { + vue.appendItems(); + }); + }, + filters: { + currency: function(price) { + return '$'.concat(price.toFixed(2)); + } + }, + computed: { + noMoreItems: function() { + return this.results.length === this.items.length && this.results.length; + } + }, + methods: { + appendItems: function() { + if (this.items.length < this.results.length) { + var append = this.results.slice(this.items.length, this.items.length + LOAD_NUM); + this.items = this.items.concat(append); + } + }, + onSubmit: function() { + this.lastSearch = this.newSearch; + this.loading = true; + this.items = []; + this.results = []; + this.$http + .get('/search/'.concat(this.newSearch)) + .then(function(res) { + this.loading = false; + this.results = res.data; + this.appendItems(); + }) + ; + }, + addItem: function(index) { + var item = this.items[index]; + var found = false; + for (var i = 0; i < this.cart.length; i++) { + if (this.cart[i].id === item.id) { + this.cart[i].qty++; + found = true; + } + } + if (!found) { + this.cart = this.cart.concat({ + id: item.id, + title: item.title, + qty: 1, + price: PRICE + }); + } + this.total += PRICE; + }, + inc: function(item) { + item.qty++; + this.total += PRICE; + }, + dec: function(item) { + item.qty--; + this.total -= PRICE; + if (item.qty <= 0) { + for (var i = 0; i < this.cart.length; i++) { + if (this.cart[i].id === item.id) { + this.cart.splice(i, 1); + break; + } + } + } + } + } +}); From e8085266f39c25484b7cdb1837505122cb4c735a Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Thu, 19 Apr 2018 13:20:07 +0700 Subject: [PATCH 02/14] Removing v-cloak --- index.html | 2 +- public/style.css | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/index.html b/index.html index 6652ca11..66302f4b 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ -
    +

    Vue.js Poster Store

    -
    No more items.
    +
    No more items.
    diff --git a/public/script.js b/public/script.js index ec8b5479..46c41368 100644 --- a/public/script.js +++ b/public/script.js @@ -27,11 +27,6 @@ new Vue({ return '$'.concat(price.toFixed(2)); } }, - computed: { - noMoreItems: function() { - return this.results.length === this.items.length && this.results.length; - } - }, methods: { appendItems: function() { if (this.items.length < this.results.length) { From a1823d81a63f5b732c39784b5ac66975f56f62f4 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Thu, 19 Apr 2018 14:46:06 +0700 Subject: [PATCH 05/14] Created watcher --- public/script.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/public/script.js b/public/script.js index c38f64cb..a031fba9 100644 --- a/public/script.js +++ b/public/script.js @@ -32,6 +32,14 @@ new Vue({ return this.results.length === this.items.length && this.results.length; } }, + watch: { + cart: { + handler: function() { + console.log('cart changed'); + }, + deep: true + } + }, methods: { appendItems: function() { if (this.items.length < this.results.length) { From 1af14c405b98266dca110812738e720832951008 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Thu, 19 Apr 2018 14:52:01 +0700 Subject: [PATCH 06/14] Updating AJAX call --- public/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/script.js b/public/script.js index a031fba9..88f06e1b 100644 --- a/public/script.js +++ b/public/script.js @@ -34,8 +34,8 @@ new Vue({ }, watch: { cart: { - handler: function() { - console.log('cart changed'); + handler: function(val) { + this.$http.post('/cart_update', val); }, deep: true } From 1d1f6ca845bb6ec80ca4ea48732c8bef2dec00d2 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Thu, 19 Apr 2018 15:09:16 +0700 Subject: [PATCH 07/14] Adding pusher to server --- .env_sample | 4 ++++ index.js | 12 ++++++++++++ package.json | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.env_sample b/.env_sample index 91f1b735..451f8238 100644 --- a/.env_sample +++ b/.env_sample @@ -1,3 +1,7 @@ IMGUR_CLIENT_ID=x PORT=3000 NODE_ENV=development +PUSHER_APP_ID= +PUSHER_KEY= +PUSHER_SECRET= +PUSHER_CLUSTER= diff --git a/index.js b/index.js index 2021aebe..c851340b 100644 --- a/index.js +++ b/index.js @@ -4,9 +4,17 @@ var path = require('path'); var server = require('http').createServer(app); var axios = require('axios'); var querystring = require('querystring'); +var Pusher = require('pusher'); require('dotenv').config(); +var pusher = new Pusher({ + appId: process.env.PUSHER_APP_ID, + key: process.env.PUSHER_KEY, + secret: process.env.PUSHER_SECRET, + cluster: process.env.PUSHER_CLUSTER +}); + var bodyParser = require('body-parser'); app.use( bodyParser.json() ); @@ -31,6 +39,10 @@ app.get('/search/:query', function(req, res) { ; }); +app.post('/cart_update', function(req, res) { + pusher.trigger('cart', 'update', req.body); +}); + app.use('/node_modules', express.static(path.join(__dirname, 'node_modules'))); app.use('/public', express.static(path.join(__dirname, 'public'))); diff --git a/package.json b/package.json index 3cc682d9..3828465a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "start": "nodemon ./index.js --ignore node_modules/ -e js,html,css" }, "author": "Anthony Gore ", - "repository" : { + "repository": { "type": "git", "url": "https://github.com/vuejsdevelopers/vuejs-poster-shop" }, @@ -27,6 +27,7 @@ "body-parser": "~1.18.2", "dotenv": "~2.0.0", "express": "^4.14.0", + "pusher": "^1.5.1", "querystring": "~0.2.0", "scrollmonitor": "~1.2.0", "vue": "~2.1.0", From 36f96f2bed1ec6da15133e74dd74557c6d286615 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Thu, 19 Apr 2018 15:27:13 +0700 Subject: [PATCH 08/14] Pusher client --- index.html | 1 + package.json | 1 + public/script.js | 23 +++++++++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 6652ca11..a5ad48e6 100644 --- a/index.html +++ b/index.html @@ -75,6 +75,7 @@

    Shopping Cart

    + diff --git a/package.json b/package.json index 3828465a..afee0afa 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dotenv": "~2.0.0", "express": "^4.14.0", "pusher": "^1.5.1", + "pusher-js": "^4.2.2", "querystring": "~0.2.0", "scrollmonitor": "~1.2.0", "vue": "~2.1.0", diff --git a/public/script.js b/public/script.js index 88f06e1b..5756a985 100644 --- a/public/script.js +++ b/public/script.js @@ -1,6 +1,11 @@ var PRICE = 9.99; var LOAD_NUM = 10; +var pusher = new Pusher('c5f886b768d885937f95', { + cluster: 'ap1', + encrypted: true +}); + new Vue({ el: '#app', data: { @@ -11,7 +16,8 @@ new Vue({ newSearch: 'anime', lastSearch: '', loading: false, - price: PRICE + price: PRICE, + pusherUpdate: false }, mounted: function() { this.onSubmit(); @@ -21,6 +27,15 @@ new Vue({ watcher.enterViewport(function() { vue.appendItems(); }); + var channel = pusher.subscribe('cart'); + channel.bind('update', function(data) { + vue.pusherUpdate = true; + vue.cart = data; + vue.total = 0; + for (var i = 0; i < vue.cart.length; i++) { + vue.total += PRICE * vue.cart[i].qty; + } + }); }, filters: { currency: function(price) { @@ -35,7 +50,11 @@ new Vue({ watch: { cart: { handler: function(val) { - this.$http.post('/cart_update', val); + if (!this.pusherUpdate) { + this.$http.post('/cart_update', val); + } else { + this.pusherUpdate = false; + } }, deep: true } From edb85b0445faedb15b8a7434b57c600386d92ac4 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Sun, 22 Apr 2018 09:22:37 +0700 Subject: [PATCH 09/14] Removing additional code --- public/script.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/public/script.js b/public/script.js index 5756a985..1c3a999b 100644 --- a/public/script.js +++ b/public/script.js @@ -16,8 +16,7 @@ new Vue({ newSearch: 'anime', lastSearch: '', loading: false, - price: PRICE, - pusherUpdate: false + price: PRICE }, mounted: function() { this.onSubmit(); @@ -29,12 +28,7 @@ new Vue({ }); var channel = pusher.subscribe('cart'); channel.bind('update', function(data) { - vue.pusherUpdate = true; - vue.cart = data; - vue.total = 0; - for (var i = 0; i < vue.cart.length; i++) { - vue.total += PRICE * vue.cart[i].qty; - } + console.log(data); }); }, filters: { @@ -50,11 +44,7 @@ new Vue({ watch: { cart: { handler: function(val) { - if (!this.pusherUpdate) { - this.$http.post('/cart_update', val); - } else { - this.pusherUpdate = false; - } + this.$http.post('/cart_update', val); }, deep: true } From 1b61bddd11d9f8b6cd84bf8504eaf4b5ba1a9f0e Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Sun, 22 Apr 2018 10:43:12 +0700 Subject: [PATCH 10/14] Adding code --- public/script.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/public/script.js b/public/script.js index 1c3a999b..5756a985 100644 --- a/public/script.js +++ b/public/script.js @@ -16,7 +16,8 @@ new Vue({ newSearch: 'anime', lastSearch: '', loading: false, - price: PRICE + price: PRICE, + pusherUpdate: false }, mounted: function() { this.onSubmit(); @@ -28,7 +29,12 @@ new Vue({ }); var channel = pusher.subscribe('cart'); channel.bind('update', function(data) { - console.log(data); + vue.pusherUpdate = true; + vue.cart = data; + vue.total = 0; + for (var i = 0; i < vue.cart.length; i++) { + vue.total += PRICE * vue.cart[i].qty; + } }); }, filters: { @@ -44,7 +50,11 @@ new Vue({ watch: { cart: { handler: function(val) { - this.$http.post('/cart_update', val); + if (!this.pusherUpdate) { + this.$http.post('/cart_update', val); + } else { + this.pusherUpdate = false; + } }, deep: true } From 542ad023452c646f7ab3bc1678b9c6fcb80a2cb5 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Sun, 22 Apr 2018 10:50:50 +0700 Subject: [PATCH 11/14] Removing my key --- public/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/script.js b/public/script.js index 1c3a999b..ca34df67 100644 --- a/public/script.js +++ b/public/script.js @@ -1,8 +1,8 @@ var PRICE = 9.99; var LOAD_NUM = 10; -var pusher = new Pusher('c5f886b768d885937f95', { - cluster: 'ap1', +var pusher = new Pusher('[PUSHER_KEY]', { + cluster: '[PUSHER_CLUSTER]', encrypted: true }); From 30b91f1fe9e8a903c92e04a31630dca7ab6adea5 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Mon, 23 Apr 2018 12:33:23 +0700 Subject: [PATCH 12/14] Adding computed property # Conflicts: # public/script.js --- index.html | 2 +- public/script.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index cde14540..66302f4b 100644 --- a/index.html +++ b/index.html @@ -41,7 +41,7 @@

    {{ item.title }}

    -
    No more items.
    +
    No more items.
    diff --git a/public/script.js b/public/script.js index 46c41368..9c1d565e 100644 --- a/public/script.js +++ b/public/script.js @@ -27,6 +27,11 @@ new Vue({ return '$'.concat(price.toFixed(2)); } }, + computed: { + noMoreItems: function() { + return this.results.length === this.items.length && this.results.length > 0; + } + }, methods: { appendItems: function() { if (this.items.length < this.results.length) { From 21cda4a03dc97b879d3e4baa14e879870c328892 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Mon, 23 Apr 2018 12:34:29 +0700 Subject: [PATCH 13/14] Adding v-cloak --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index cde14540..c458c4d5 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ -
    +

    Vue.js Poster Store

    From 97e2e38c3937c5b781538239261bd860a2628722 Mon Sep 17 00:00:00 2001 From: Anthony Gore Date: Mon, 23 Apr 2018 12:35:34 +0700 Subject: [PATCH 14/14] Adding CSS rule back in --- public/style.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/style.css b/public/style.css index 1dce9620..ce9d0387 100644 --- a/public/style.css +++ b/public/style.css @@ -22,6 +22,10 @@ button:focus, input:focus { opacity: 0.8; } +[v-cloak] { + display: none !important; +} + .fade-enter-active { transition: opacity .5s }