Skip to content

Commit 584eb15

Browse files
committed
4B: merged master
2 parents 0e3f289 + 07ee310 commit 584eb15

File tree

8 files changed

+162
-74
lines changed

8 files changed

+162
-74
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
package-lock.json
33
Exercises.pdf
4+
.idea/

cli-socks/src/App.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
<div class="links">
77
<router-link to="/">Home</router-link> |
8-
<router-link to="/counter" title="Vuex example">Counter</router-link>
8+
<router-link to="/counter" title="Vuex example">Counter</router-link> |
9+
<router-link to="/cart" title="Cart summary">Cart</router-link>
910
</div>
1011
</div>
1112

cli-socks/src/components/Product.vue

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66

77
<div class="product-info">
88
<h1>
9-
{{ product.name }}
9+
{{ title }}
1010
<!-- eslint-disable-next-line vue/no-unused-vars -->
1111
<i v-for="i in averageReviewScore" class="fa fa-star" :key="i"></i>
1212
</h1>
1313

14-
<div>All reviews:</div>
14+
<div v-if="product.reviews.length">All reviews:</div>
1515
<div v-for="j in product.reviews" :key="j.name+j.rating">
1616
<label>{{ j.name}}: </label>
1717
<i v-for="k in j.rating" class="fa fa-star" :key="k"></i>
1818
</div>
1919

2020
<div>
21-
<p v-if="product.inventory > 10">In Stock</p>
22-
<p v-else-if="product.inventory">Almost sold out</p>
21+
<p v-if="selectedVariant.inventory > 10">In Stock</p>
22+
<p v-else-if="selectedVariant.inventory">Almost sold out</p>
2323
<p v-else>Out of Stock</p>
2424
</div>
2525

@@ -28,12 +28,20 @@
2828

2929
<button
3030
@click="addToCart"
31-
:disabled="!product.inventory"
32-
:class="['add-to-cart', product.inventory ? '' : 'disabledButton']"
31+
:disabled="!selectedVariant.inventory"
32+
:class="['add-to-cart', selectedVariant.inventory ? '' : 'disabledButton']"
3333
>
3434
Add to Cart
3535
</button>
3636

37+
<button
38+
@click="removeFromCart"
39+
:disabled="cartLength === 0"
40+
:class="['remove-from-cart', cartLength > 0 ? '' : 'disabledButton']"
41+
>
42+
Remove from cart
43+
</button>
44+
3745
<div v-for="(variant, index) in product.variants"
3846
:key="variant.id"
3947
class="color-box"
@@ -59,17 +67,19 @@ import ProductReview from './ProductReview.vue';
5967
6068
export default class Product extends Vue {
6169
@Prop({default: false}) private premium!: boolean;
70+
@Prop() private cartLength!: number;
6271
6372
product = {
6473
name: "Vue Socks",
6574
brand: "Vue",
75+
price: 5,
6676
variants: [
67-
{id: 1, color: "green"},
68-
{id: 2, color: "blue"}
77+
{id: 1, color: "green", inventory: 3},
78+
{id: 2, color: "blue", inventory: 5}
6979
],
7080
inventory: 3,
7181
reviews: []
72-
}
82+
};
7383
7484
selectedVariantIndex = 0;
7585
@@ -81,13 +91,27 @@ export default class Product extends Vue {
8191
if (!this.product.reviews.length) {
8292
return null;
8393
}
84-
return Math.round(this.product.reviews.map(x => x.rating).reduce((a, c) => a + c, 0) / this.product.reviews.length);
94+
const reviews = this.product.reviews as any;
95+
const totalStars = reviews
96+
.map((x: any) => x.rating)
97+
.reduce((a: any, c: any) => a + c, 0);
98+
99+
return Math.round(totalStars / this.product.reviews.length);
100+
}
101+
102+
get title() {
103+
return `${this.product.name} ($${this.product.price})`;
85104
}
86105
87106
addToCart() {
88-
this.product.inventory--;
107+
this.selectedVariant.inventory--;
108+
this.$emit('add-to-cart', {product: this.product, variant: this.selectedVariant});
109+
}
110+
111+
removeFromCart() {
112+
this.product.inventory++;
89113
const selectedVariant = this.product.variants[this.selectedVariantIndex];
90-
this.$emit('add-to-cart', {product: this.product, variant: selectedVariant});
114+
this.$emit('remove-from-cart', {product: this.product, variant: selectedVariant})
91115
}
92116
93117
addReview(review: any) {
@@ -148,6 +172,18 @@ button.add-to-cart {
148172
position: absolute;
149173
top: 85px;
150174
right: 13px;
175+
}
176+
177+
button.remove-from-cart {
178+
border: none;
179+
background-color: #F12321;
180+
color: white;
181+
height: 40px;
182+
width: 100px;
183+
font-size: 14px;
184+
position: absolute;
185+
top: 135px;
186+
right: 13px;
151187
}
152188
153189
.disabledButton {

cli-socks/src/components/ProductReview.vue

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
<label>Name</label>
55
<input v-model="name" @keydown.ctrl.v.prevent="blockPaste">
66

7-
<div class="error" v-for="error in errors" :key="error">
8-
* {{ error }}
9-
</div>
10-
7+
<ul class="error" v-for="error in errors" :key="error">
8+
<li>{{error}}</li>
9+
</ul>
10+
1111
<label>Rating</label>
1212
<select v-model.number="rating">
1313
<option disabled value="">select</option>
@@ -45,10 +45,18 @@ export default class ProductReview extends Vue {
4545
this.errors = [];
4646
if (!this.rating) {
4747
this.errors.push('Please select a rating');
48+
}
49+
if (!this.name) {
50+
this.errors.push('Please provide your name');
51+
}
52+
if (!this.acceptTerms) {
53+
this.errors.push('Please accept the terms');
54+
}
55+
if (this.errors.length) {
4856
return;
4957
}
5058
51-
const review = {name: this.name, rating: this.rating}
59+
const review = {name: this.name, rating: this.rating};
5260
console.log('Submitting', review);
5361
this.$emit('add-review', review);
5462
}
@@ -72,7 +80,7 @@ h3 {
7280
}
7381
7482
input:not([type=checkbox]) {
75-
width: 100%;
83+
width: 100%;
7684
height: 25px;
7785
margin-bottom: 10px;
7886
}

cli-socks/src/router.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Router from "vue-router";
33
import Home from "./views/Home.vue";
44
import Product from "./components/Product.vue";
55

6+
import Cart from "./views/Cart.vue";
67
Vue.use(Router);
78

89
export default new Router({
@@ -26,7 +27,16 @@ export default new Router({
2627
name: 'product',
2728
path: '/product/:id',
2829
component: Product
29-
}
30+
},
31+
{
32+
path: "/cart",
33+
name: "cart",
34+
component: Cart
35+
},
36+
// {
37+
// path: '/product/:id',
38+
// component: () => import(/* webpackChunkName: "productDetail" */ "./views/ProductPage.vue")
39+
// }
3040
// Get id with: {{ $route.params.id }}
3141
// Example:
3242
// path: "/user/:username/post/:post_id"

cli-socks/src/store.ts

Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,81 +3,87 @@ import Vuex from "vuex";
33

44
Vue.use(Vuex);
55

6-
// Exercise 5? Kill the counter store and use the products store below!
6+
7+
const productList = [{
8+
name: "Vue Socks",
9+
brand: "Vue",
10+
price: 5,
11+
variants: [
12+
{id: 1, color: "green"},
13+
{id: 2, color: "blue"}
14+
],
15+
inventory: 3,
16+
reviews: []
17+
},
18+
{
19+
name: "Angular Socks",
20+
brand: "angular",
21+
price: 15,
22+
variants: [
23+
{id: 1, color: "red"},
24+
{id: 2, color: "blue"}
25+
],
26+
inventory: 3,
27+
reviews: []
28+
},
29+
{
30+
name: "npm Socks",
31+
brand: "npm",
32+
price: 3,
33+
variants: [
34+
{id: 1, color: "red"},
35+
],
36+
inventory: 3,
37+
reviews: []
38+
}];
39+
740

841
export default new Vuex.Store({
9-
// ~ component.data
1042
state: {
11-
count: 0
43+
premium: true,
44+
cart: [],
45+
products: productList
1246
},
1347

14-
// ~ component.methods
15-
actions: {},
48+
actions: {
1649

17-
// ~ component.computed
50+
},
1851
getters: {
19-
countAlias(state) {
20-
return state.count;
21-
}
52+
2253
},
2354

24-
// ~ redux.reducers
2555
mutations: {
26-
increment(state) {
27-
state.count++;
28-
},
29-
decrement(state) {
30-
state.count--;
56+
addToCart(state, product) {
57+
const cart = state.cart as any;
58+
cart.push(product);
3159
}
3260
},
3361
});
3462

3563

36-
// const productList = [{
37-
// name: "Vue Socks",
38-
// brand: "Vue",
39-
// variants: [
40-
// {id: 1, color: "green"},
41-
// {id: 2, color: "blue"}
42-
// ],
43-
// inventory: 3,
44-
// reviews: []
45-
// },
46-
// {
47-
// name: "Angular Socks",
48-
// brand: "Angular",
49-
// variants: [
50-
// {id: 1, color: "red"},
51-
// {id: 2, color: "blue"}
52-
// ],
53-
// inventory: 3,
54-
// reviews: []
55-
// },
56-
// {
57-
// name: "npm Socks",
58-
// brand: "npm",
59-
// variants: [
60-
// {id: 1, color: "red"},
61-
// ],
62-
// inventory: 3,
63-
// reviews: []
64-
// }];
65-
66-
6764
// export default new Vuex.Store({
65+
// // ~ component.data
6866
// state: {
69-
// premium: true,
70-
// cart: [],
71-
// products: productList
67+
// count: 0
7268
// },
7369

70+
// // ~ component.methods
7471
// actions: {},
75-
// getters: {},
7672

73+
// // ~ component.computed
74+
// getters: {
75+
// countAlias(state) {
76+
// return state.count;
77+
// }
78+
// },
79+
80+
// // ~ redux.reducers
7781
// mutations: {
78-
// addToCart(state, product) {
79-
// const cart = state.cart as any;
80-
// cart.push(product);
82+
// increment(state) {
83+
// state.count++;
84+
// },
85+
// decrement(state) {
86+
// state.count--;
8187
// }
8288
// },
8389
// });

cli-socks/src/views/Cart.vue

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<template>
2+
<div>
3+
HELLO FROM THE CART
4+
</div>
5+
6+
</template>
7+
8+
<script>
9+
import {Component, Vue} from "vue-property-decorator";
10+
11+
@Component({
12+
components: {}
13+
})
14+
export default class Cart extends Vue {
15+
16+
}
17+
</script>
18+
19+
<style scoped>
20+
21+
</style>

cli-socks/src/views/Home.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div>
3-
<!--<Product :premium="premium" @add-to-cart="updateCart"></Product>-->
3+
<!--<Product :premium="premium" @add-to-cart="updateCart" @remove-from-cart="removeFromCart" :cartLength="cart.length"></Product>-->
44
<ProductLine v-for="k in products" :key="k.name" :product="k"></ProductLine>
55

66
<div class="cart">
@@ -42,5 +42,10 @@ export default class Home extends Vue {
4242
console.log("Adding to cart:", product);
4343
this.cart.push(product);
4444
}
45+
46+
removeFromCart(product: any) {
47+
let index = this.cart.indexOf(product);
48+
this.cart.splice(index);
49+
}
4550
}
4651
</script>

0 commit comments

Comments
 (0)