diff --git a/.gitignore b/.gitignore index b6e4761..070642b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# JetBrains +**/.idea/** # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/assets/images/socks_blue.jpg b/assets/images/socks_blue.jpg new file mode 100644 index 0000000..000c7aa Binary files /dev/null and b/assets/images/socks_blue.jpg differ diff --git a/assets/images/socks_green.jpg b/assets/images/socks_green.jpg new file mode 100644 index 0000000..01f0fe0 Binary files /dev/null and b/assets/images/socks_green.jpg differ diff --git a/assets/styles.css b/assets/styles.css new file mode 100644 index 0000000..74c4c5b --- /dev/null +++ b/assets/styles.css @@ -0,0 +1,182 @@ +body { + background-color: #f2f2f2; + margin: 0px; + font-family: tahoma; + color: #282828; +} + +.button { + margin: 30px; + background-color: #39495c; + border-radius: 5px; + font-size: 18px; + width: 200px; + height: 60px; + color: white; + padding: 20px; + box-shadow: inset 0 -0.6em 1em -0.35em rgba(0, 0, 0, 0.17), + inset 0 0.6em 2em -0.3em rgba(255, 255, 255, 0.15), + inset 0 0 0em 0.05em rgba(255, 255, 255, 0.12); + text-align: center; + cursor: pointer; +} + +.cart { + margin: 25px 100px; + float: right; + border: 1px solid #d8d8d8; + padding: 10px 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); + box-shadow: 2px 15px -12px rgba(0, 0, 0, 0.57); +} + +.color-circle { + width: 50px; + height: 50px; + margin-top: 8px; + border: 2px solid #d8d8d8; + border-radius: 50%; +} + + +.disabledButton { + background-color: #d8d8d8; + cursor: not-allowed; +} + +h1 { + font-size: 50px; +} + +h3 { + font-size: 25px; +} + +img { + border: 2px solid #d8d8d8; + width: 70%; + margin: 40px; + padding: 15px; + -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); + box-shadow: 2px 15px -12px rgba(0, 0, 0, 0.57); +} + +input { + width: 100%; + height: 40px; + margin-bottom: 20px; +} + +label { + font-size: 20px; + margin-bottom: 5px; +} + +li { + font-size: 18px; +} + +.nav-bar { + background: linear-gradient(-90deg, #84cf6a, #16c0b0); + height: 60px; + margin-bottom: 25px; + -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); + box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.57); +} + +.out-of-stock-img { + opacity:0.5 +} + +p { + font-size: 22px; +} + +.product-display { + display: flex; + flex-direction: column; + padding: 1rem; +} + +.product-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + +.product-image, +.product-info { + width: 50%; +} + +.review-form { + display: flex; + flex-direction: column; + width: 425px; + padding: 20px; + margin: 40px; + border: 2px solid #d8d8d8; + 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); + box-shadow: 2px 15px -12px rgba(0, 0, 0, 0.57); +} + +.review-container { + width: 425px; + padding: 20px; + background-color: white; + -webkit-box-shadow: 0px 2px 20px -12px rgba(0, 0, 0, 0.57); + -moz-box-shadow: 0px 2px 20px -12px rgba(0, 0, 0, 0.57); + box-shadow: 2px 20px -12px rgba(0, 0, 0, 0.57); + margin-left: 40px; + border: 2px solid #d8d8d8; +} + +.review-container li { + margin-bottom: 30px; +} + +.review-form .button { + display: block; + margin: 30px auto; +} + +select { + height: 40px; + font-size: 20px; + background-color: white; + cursor: pointer; +} + +textarea { + width: 95%; + height: 70px; + padding: 10px; + font-size: 20px; + margin-bottom: 20px; +} + +ul { + list-style-type: none; +} + +@media only screen and (max-width: 600px) { + .container { + flex-direction: column; + } + + .product-image, + .product-info { + margin-left: 10px; + width: 100%; + } + + .review-form { + width: 90%; + } +} diff --git a/components/ProductDisplay.js b/components/ProductDisplay.js new file mode 100644 index 0000000..dd6e2b1 --- /dev/null +++ b/components/ProductDisplay.js @@ -0,0 +1,120 @@ +app.component('product-display', { + props: { + brand:{ + type: String, + required: true + } + }, + template: + `
+
+
+ +
+
+ +

{{ title }}

+

+ Only {{ inStock }} left! +

+

+ In Stock +

+

+ Out of Stock +

+ + +
    +
  • + {{detail}} +
  • +
+ + +
+
+ + +
+ {{ size.size }} +
+ + + + +
+
+
+ + + `, + data() { + return { + product: 'Socks', + selectedVariant: 0, + inventory: 11, + details: ['50% cotton', '30% wool', '20% polyester'], + variants: [ + {id: 1, color: 'green', image: './assets/images/socks_green.jpg', quantity: 11, ordered: 0}, + {id: 2, color: 'blue', image: './assets/images/socks_blue.jpg', quantity: 0, ordered: 0}, + ], + sizes: [ + {id: 3, size: 'small'}, + {id: 4, size: 'large'}, + ] + } + }, + methods: { + addToCart() { + this.variants[this.selectedVariant].ordered += 1 + this.variants[this.selectedVariant].quantity -= 1 + this.$emit('add-to-cart', this.titleLong) + }, + removeFromCart() { + this.variants[this.selectedVariant].ordered -= 1 + this.variants[this.selectedVariant].quantity += 1 + this.$emit('remove-from-cart', this.titleLong) + }, + updateVariant(index) { + this.selectedVariant = index + }, + }, + computed: { + title() { + return this.brand + ' ' + this.product + }, + titleLong() { + return this.brand + + '-' + this.product + + '-' + this.variants[this.selectedVariant].id + }, + image() { + return this.variants[this.selectedVariant].image + }, + + cartContains() { + return (this.variants[this.selectedVariant].ordered > 0) + }, + inStock() { + return this.variants[this.selectedVariant].quantity + }, + + } +}) \ No newline at end of file diff --git a/components/ReviewForm.js b/components/ReviewForm.js new file mode 100644 index 0000000..341fd98 --- /dev/null +++ b/components/ReviewForm.js @@ -0,0 +1,53 @@ +app.component('review-form', { + template: + `
+

Leave a review

+ + + + + + + + + + + +
`, + data() { + return { + name: '', + review: '', + rating: null + } + }, + methods: { + onSubmit() { + if (this.name == '' || this.review == '' || this.rating == null) { + alert("Review is incomplete. Please fill out every field.") + return + } + + let productReview = { + name: this.name, + review: this.review, + rating: this.rating + } + this.addReview(productReview) + + this.name = '' + this.review = '' + this.rating = null + }, + addReview(review){ + // TODO: Append review to json + axios.post('./reviews.json', JSON.stringify(review)) + } + } +}) \ No newline at end of file diff --git a/components/ReviewList.js b/components/ReviewList.js new file mode 100644 index 0000000..8504c9a --- /dev/null +++ b/components/ReviewList.js @@ -0,0 +1,38 @@ +app.component('review-list', { + template: + ` +
+

Reviews:

+ +
+ `, + data() { + return { + current_reviews: this.reviews + } + }, + methods: { + load() { + data = this + axios.get('./reviews.json') + .then( function (response) { + data.current_reviews = response.data.reviews + }) + .catch( function (error) { + console.log("FAIL: " + error) + }) + }, + }, + computed: { + reviews() { + this.load() + return this.current_reviews + }, + } +}) \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..2075800 --- /dev/null +++ b/index.html @@ -0,0 +1,36 @@ + + + + + Vue Mastery + + + + + + + + + + + + + +
+
+ Cart({{ cart }}) +
+




+ + + +
+ + + + + diff --git a/main.js b/main.js new file mode 100644 index 0000000..38e2d8e --- /dev/null +++ b/main.js @@ -0,0 +1,18 @@ +const app = Vue.createApp({ + data() { + return { + cart: [], + } + }, + methods: { + addToCart(item) { + this.cart.push(item) + }, + removeFromCart(item) { + index = this.cart.indexOf(item) + if (index > -1) { + this.cart.splice(index, 1) + } + }, + }, +}) diff --git a/reviews.json b/reviews.json new file mode 100644 index 0000000..4a0a1b3 --- /dev/null +++ b/reviews.json @@ -0,0 +1,24 @@ +{ + "reviews": [ + { + "name": "Joe", + "review": "Good stuff", + "rating": 4 + }, + { + "name": "Jack", + "review": "Bad stuff", + "rating": 1 + }, + { + "name": "Jerry", + "review": "Ok stuff", + "rating": 3 + }, + { + "name": "Jim", + "review": "Great stuff", + "rating": 5 + } + ] +}