diff --git a/assets/styles.css b/assets/styles.css index 4a34b36c6..f912bd997 100644 --- a/assets/styles.css +++ b/assets/styles.css @@ -25,7 +25,7 @@ body { margin: 25px 100px; float: right; border: 1px solid #d8d8d8; - padding: 10px 30px; + padding: 30px 30px; background-color: white; -webkit-box-shadow: 0px 2px 15px -12px rgba(0, 0, 0, 0.57); -moz-box-shadow: 0px 2px 15px -12px rgba(0, 0, 0, 0.57); @@ -88,6 +88,10 @@ li { box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.57); } +.out-of-stock-img { + opacity: 0.5; +} + p { font-size: 22px; } diff --git a/components/ProductDisplay.js b/components/ProductDisplay.js index b764ac127..a29247eba 100644 --- a/components/ProductDisplay.js +++ b/components/ProductDisplay.js @@ -5,98 +5,83 @@ app.component('product-display', { required: true } }, - template: - /*html*/ - ` - <div class="product-display"> - + template: + /*html*/ + `<div class="product-display"> <div class="product-container"> <div class="product-image"> - <img :src="image" /> + <img v-bind:src="image"> </div> - <div class="product-info"> - <h1>{{ productName }}</h1> + <h1>{{ title }}</h1> + <p v-if="inStock">In Stock</p> <p v-else>Out of Stock</p> - <p>Shipping: {{ shipping }}</p> + <p>Shipping: {{ shipping }}</p> <ul> <li v-for="detail in details">{{ detail }}</li> </ul> - <div class="color-circle" + <div v-for="(variant, index) in variants" - :key="variant.id" - :style="{ backgroundColor: variant.color }" - @mouseover="updateProduct(index)" - > - </div> - - <button class="button" v-on:click="addToCart" - :disabled="!inStock" - :class="{ disabledButton: !inStock }" - > - Add to cart + :key="variant.id" + @mouseover="updateVariant(index)" + class="color-circle" + :style="{ backgroundColor: variant.color }"> + </div> + + <button + class="button" + :class="{ disabledButton: !inStock }" + :disabled="!inStock" + v-on:click="addToCart"> + Add to Cart </button> </div> </div> - - <review-list :reviews="reviews"></review-list> - <review-form @review-submitted="addReview" ></review-form> - </div> - `, + <review-list v-show="reviews.length" :reviews="reviews"></review-list> + <review-form @review-submitted="addReview"></review-form> + </div>`, data() { return { - product: 'Socks', - brand: 'Vue Mastery', - selectedVariant: 0, - details: ['80% cotton', '20% polyester', 'Gender-neutral'], - variants: [ - { - id: 2234, - color: 'green', - image: './assets/images/socks_green.jpg', - quantity: 10 - }, - { - id: 2235, - color: 'blue', - image: './assets/images/socks_blue.jpg', - quantity: 0 - } - ], - reviews: [], - tabs: ['review-form', 'review-list'], - activeTab: 'review-form' + product: 'Socks', + brand: 'Vue Mastery', + selectedVariant: 0, + reviews: [], + details: ['50% cotton', '30% wool', '20% polyester'], + variants: [ + { id: 2234, color: 'green', image: './assets/images/socks_green.jpg', quantity: 50 }, + { id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg', quantity: 0 }, + ] } }, methods: { - addToCart() { - this.$emit('add-to-cart', this.variants[this.selectedVariant].id) - }, - updateProduct(index) { - this.selectedVariant = index - }, - addReview(review) { - this.reviews.push(review) - } + addToCart() { + this.$emit('add-to-cart', this.variants[this.selectedVariant].id) + }, + updateVariant(index) { + this.selectedVariant = index + }, + addReview(review) { + this.reviews.push(review); + } }, computed: { - productName() { - return this.brand + ' ' + this.product - }, - image() { - return this.variants[this.selectedVariant].image - }, - inStock() { - return this.variants[this.selectedVariant].quantity - }, - shipping() { - if (this.premium) { - return 'Free' + title() { + return this.brand + ' ' + this.product + }, + image() { + return this.variants[this.selectedVariant].image + }, + inStock() { + return this.variants[this.selectedVariant].quantity + }, + shipping() { + if (this.premium) { + return 'Free' + } + return 2.99 } - return 2.99 - } } -}) +}) \ No newline at end of file diff --git a/components/ReviewForm.js b/components/ReviewForm.js index 6e24ea34d..a87ee6d50 100644 --- a/components/ReviewForm.js +++ b/components/ReviewForm.js @@ -1,52 +1,53 @@ app.component('review-form', { - template: + template: /*html*/ - ` - <form class="review-form" @submit.prevent="onSubmit"> + `<form class="review-form" @submit.prevent="onSubmit"> <h3>Leave a review</h3> - <label for="name">Name:</label> - <input id="name" v-model="name"> - + <input id="name" v-model="name" required> + <label for="review">Review:</label> - <textarea id="review" v-model="text"></textarea> - + <textarea id="review" v-model="review" required></textarea> + <label for="rating">Rating:</label> - <select id="rating" v-model.number="rating"> + <select id="rating" v-model.number="rating" required> <option>5</option> <option>4</option> <option>3</option> <option>2</option> <option>1</option> </select> + + <label for="recommendation">Would you recommend this product?</label> + <select id="recommendation" v-model="recommendation" required> + <option>Yes</option> + <option>No</option> + </select> - <input class="button" type="submit" value="Submit"> - - </form> - `, - data() { - return { - name: '', - text: '', - rating: null - } - }, - methods: { - onSubmit() { - if (this.name === '' || this.text === '' || this.rating === null) { - alert('Review is incomplete. Please fill out every field.') - return + <input class="button" type="submit" value="Submit"> + </form>`, + data() { + return { + name: '', + review: '', + rating: null, + recommendation: null } + }, + methods: { + onSubmit() { + let productReview = { + name: this.name, + review: this.review, + rating: this.rating, + recommendation: this.recommendation + } + this.$emit('review-submitted', productReview) - const review = { - name: this.name, - text: this.text, - rating: this.rating - } - this.$emit('review-submitted', review) - this.name = '' - this.text = '' - this.rating = null + this.name = '', + this.review = '', + this.rating = null + this.recommendation = null + } } - } -}) + }) \ No newline at end of file diff --git a/components/ReviewList.js b/components/ReviewList.js index 5f6f68df3..7c2ddb4c7 100644 --- a/components/ReviewList.js +++ b/components/ReviewList.js @@ -1,22 +1,20 @@ app.component('review-list', { - template: + props: { + reviews: { + type: Array, + required: true + } + }, + template: /*html*/ - ` - <div v-if="reviews.length" class="review-container"> - <h3>Reviews:</h3> - <ul> - <li v-for="(review, index) in reviews" :key="index"> - {{ review.name }} gave this {{ review.rating }} stars - <br/> - "{{ review.text }}" - </li> - </ul> - </div> - `, - props: { - reviews: { - type: Array, - required: true - } - } -}) + `<div class="review-container"> + <h3>Reviews:</h3> + <ul> + <li v-for="(review, index) in reviews" :key="index"> + {{ review.name }} gave {{ review.rating }} stars and {{ review.recommendation === "Yes" ? "recommends this product" : "does not recommend this product" }} + <br/> + {{ review.review }} + </li> + </ul> + </div>` +}) \ No newline at end of file diff --git a/index.html b/index.html index fc2738025..f19a0ea1d 100644 --- a/index.html +++ b/index.html @@ -6,14 +6,27 @@ <!-- Import Styles --> <link rel="stylesheet" href="./assets/styles.css" /> <!-- Import Vue.js --> - <script src="https://unpkg.com/vue@3.0.0-beta.12/dist/vue.global.js"></script> + <script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script> </head> <body> <div id="app"> - <h1>Product goes here</h1> + <div class="nav-bar"></div> + + <div class="cart">Cart({{ cart.length }})</div> + <product-display :premium="premium" @add-to-cart="updateCart"></product-display> </div> - <!-- Import JS --> + <!-- Import App --> <script src="./main.js"></script> + + <!-- Import Components --> + <script src="./components/ProductDisplay.js"></script> + <script src="./components/ReviewForm.js"></script> + <script src="./components/ReviewList.js"></script> + + <!-- Mount App --> + <script> + const mountedApp = app.mount('#app') + </script> </body> </html> diff --git a/main.js b/main.js index 0083deb17..7da486383 100644 --- a/main.js +++ b/main.js @@ -1 +1,14 @@ -const product = "Socks" +const app = Vue.createApp({ + data() { + return { + cart: [], + premium: true + } + }, + methods: { + updateCart(id) { + this.cart.push(id) + } + } + }) + \ No newline at end of file