From 942b17c865cd74f14179aacc28e3f322b0ef1934 Mon Sep 17 00:00:00 2001 From: MicahMonfrini Date: Fri, 28 Apr 2017 21:11:55 -0500 Subject: [PATCH 1/3] Reviews component created --- README.md | 10 +++++----- package.json | 1 + src/components/ProductDetail.js | 5 +++-- src/components/Reviews.js | 16 ++++++++++++++++ src/state.js | 2 +- yarn.lock | 12 ++++-------- 6 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 src/components/Reviews.js diff --git a/README.md b/README.md index 258a878..6999f4c 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ Fork, clone, run yarn install, yarn start, pull request #### Do - * Add a new class component for Reviews - * Make sure to use extends and super - * Import and use this component in ProductDetail + + + * This component will take a product from props * It will show the number of reviews followed by "review" or "reviews" depending on if there is one or more reviews - * It will create a list of the reviews description which will inititally be hidden + * It will create a list of the reviews description which will initially be hidden * When the word "review" is clicked show the reviews - * When clicked again, hide the reviews \ No newline at end of file + * When clicked again, hide the reviews diff --git a/package.json b/package.json index 3b7c33e..618c13e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "foreman": "^2.0.0", "json-server": "^0.9.6", + "prop-types": "^15.5.8", "react": "^15.5.4", "react-dom": "^15.5.4" }, diff --git a/src/components/ProductDetail.js b/src/components/ProductDetail.js index 885919a..d1450b8 100644 --- a/src/components/ProductDetail.js +++ b/src/components/ProductDetail.js @@ -1,4 +1,5 @@ import React from "react"; +import Reviews from "./Reviews"; function ProductDetail(props) { const {name,description,rating,imgUrl} = props.product; @@ -14,11 +15,11 @@ function ProductDetail(props) {

{name}

-

{description} +

{description}

-

15 reviews

+

{stars}

diff --git a/src/components/Reviews.js b/src/components/Reviews.js new file mode 100644 index 0000000..531b7df --- /dev/null +++ b/src/components/Reviews.js @@ -0,0 +1,16 @@ +import React, {Component} from "react"; + +class Reviews extends Component { + constructor(props) { + super(props); + } + + render() { + return ( +
+
+ ); + } +} + +export default Reviews; diff --git a/src/state.js b/src/state.js index badf378..6c2e011 100644 --- a/src/state.js +++ b/src/state.js @@ -221,4 +221,4 @@ export default { } ] }] -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 5390255..53179bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2570,11 +2570,11 @@ got@^5.0.0: unzip-response "^1.0.2" url-parse-lax "^1.0.0" -graceful-fs@4.1.10: +graceful-fs@4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.10.tgz#f2d720c22092f743228775c75e3612632501f131" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@^4.1.11: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -4517,7 +4517,7 @@ promise@7.1.1, promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.7, prop-types@~15.5.7: +prop-types@^15.5.7, prop-types@^15.5.8, prop-types@~15.5.7: version "15.5.8" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394" dependencies: @@ -4557,14 +4557,10 @@ q-io@1.13.2: qs "^1.2.1" url2 "^0.0.0" -q@1.4.1: +q@1.4.1, q@^1.0.1, q@^1.1.2: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" -q@^1.0.1, q@^1.1.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" - qs@6.4.0, qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" From ac5059ef0ea24f437aced4e54f0dc8221840597d Mon Sep 17 00:00:00 2001 From: MicahMonfrini Date: Fri, 5 May 2017 22:45:57 -0500 Subject: [PATCH 2/3] add review toggle --- src/App.js | 73 ++++++++++++++++++-------------- src/components/ProductDetail.js | 74 +++++++++++++++++++++++---------- src/components/Reviews.js | 35 +++++++++++++++- src/state.js | 20 ++++----- 4 files changed, 136 insertions(+), 66 deletions(-) diff --git a/src/App.js b/src/App.js index 8dfa97f..ec38ec6 100644 --- a/src/App.js +++ b/src/App.js @@ -1,39 +1,48 @@ -import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; -import NavBar from './components/NavBar'; -import Footer from './components/Footer'; -import ProductDetail from './components/ProductDetail'; -import Carousel from './components/Carousel'; -function App (props) { +import React from "react"; +import "./App.css"; +import NavBar from "./components/NavBar"; +import Footer from "./components/Footer"; +import ProductDetail from "./components/ProductDetail"; +import Carousel from "./components/Carousel"; +import PropTypes from "prop-types"; - var products = props.state.products.map(function(prod){ - return ; - }); +function App(props) { + + const products = props.state.products.map(function (prod) { return ( -
- -
-
-
-

Shop Name

- -
-
- -
- {products} -
-
-
+ + ); + }); + return ( +
+ +
+
+
+

Shop Name

+ -
- ); +
+ +
+ {products} +
+
+
+
+
+
+ ); } +App.propTypes = { + state: PropTypes.object.isRequired +}; + export default App; diff --git a/src/components/ProductDetail.js b/src/components/ProductDetail.js index d1450b8..62761b1 100644 --- a/src/components/ProductDetail.js +++ b/src/components/ProductDetail.js @@ -1,31 +1,59 @@ -import React from "react"; +import React, {Component} from "react"; import Reviews from "./Reviews"; +import PropTypes from "prop-types"; -function ProductDetail(props) { - const {name,description,rating,imgUrl} = props.product; - const stars = []; - for (let i = 0; i < rating; i++) { - stars.push(); +class ProductDetail extends Component { + constructor(props) { + super(props); + this.state = { + showReviews: false + }; } - return ( -
-
- -
-

{name} -

-

{description} -

-
-
- -

- {stars} -

+ displayStars() { + const stars = []; + for (let i = 0; i < this.props.product.rating; i++) { + stars.push(); + } + return stars; + } + + toggleReviews() { + this.setState({ + showReviews: !this.state.showReviews + }); + } + + render() { + return ( +
+
+ +
+

{this.props.product.name} +

+

{this.props.product.description} +

+
+
+ { + this.toggleReviews(); + }} + product={this.props.product} /> +

+ {this.displayStars()} +

+
-
- ); + ); + } } + +ProductDetail.propTypes = { + product: PropTypes.object.isRequired, +}; + export default ProductDetail; diff --git a/src/components/Reviews.js b/src/components/Reviews.js index 531b7df..543977a 100644 --- a/src/components/Reviews.js +++ b/src/components/Reviews.js @@ -1,16 +1,49 @@ import React, {Component} from "react"; +import PropTypes from "prop-types"; class Reviews extends Component { constructor(props) { super(props); + this.state = { + reviews: this.props.product.reviews, + reviewText: "Reviews", + reviewDetails: this.props.product.reviewDetails + }; + } + + showReviewDetails() { + this.state.reviewDetails.map((each, index) => { + return ( +

+ {each.description} +

+ ); + }); + } + + countReviews() { + if (this.state.reviews <= 1) { + this.setState({ + reviewText: "Review" + }); + } } render() { + this.countReviews(); return ( -
+
+ {this.state.reviews} {this.state.reviewText} + {this.props.showReviews && this.showReviewDetails()}
); } } +Reviews.propTypes = { + showReviews: PropTypes.bool.isRequired, + toggleReviews: PropTypes.func.isRequired, + product: PropTypes.object.isRequired +}; + export default Reviews; diff --git a/src/state.js b/src/state.js index 6c2e011..602390e 100644 --- a/src/state.js +++ b/src/state.js @@ -9,7 +9,7 @@ export default { "imgUrl": "http://dummyimage.com/136x167.bmp/cc0000/ffffff", "price": "$95.11", "category": "food", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -49,7 +49,7 @@ export default { "imgUrl": "http://dummyimage.com/125x134.jpg/cc0000/ffffff", "price": "$37.09", "category": "food", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -75,7 +75,7 @@ export default { "imgUrl": "http://dummyimage.com/149x190.jpg/dddddd/000000", "price": "$51.83", "category": "food", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -95,7 +95,7 @@ export default { "imgUrl": "http://dummyimage.com/162x153.jpg/cc0000/ffffff", "price": "$86.93", "category": "electronics", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -115,7 +115,7 @@ export default { "imgUrl": "http://dummyimage.com/120x245.jpg/cc0000/ffffff", "price": "$70.10", "category": "electronics", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -135,7 +135,7 @@ export default { "imgUrl": "http://dummyimage.com/211x227.bmp/5fa2dd/ffffff", "price": "$39.25", "category": "electronics", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -155,7 +155,7 @@ export default { "imgUrl": "http://dummyimage.com/212x144.jpg/ff4444/ffffff", "price": "$99.91", "category": "sporting", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -175,7 +175,7 @@ export default { "imgUrl": "http://dummyimage.com/204x175.jpg/5fa2dd/ffffff", "price": "$67.17", "category": "sporting", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -195,7 +195,7 @@ export default { "imgUrl": "http://dummyimage.com/212x108.bmp/cc0000/ffffff", "price": "$96.84", "category": "sporting", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 }, { @@ -215,7 +215,7 @@ export default { "imgUrl": "http://dummyimage.com/189x109.png/cc0000/ffffff", "price": "$74.37", "category": "sporting", - "reviews": [{ + "reviewDetails": [{ "description": "architect revolutionary deliverables", "rating": 2 } From 9341c29aede94edcfa98866cb296100a7a4e14c6 Mon Sep 17 00:00:00 2001 From: MicahMonfrini Date: Sat, 6 May 2017 11:59:10 -0500 Subject: [PATCH 3/3] display toggled reviews --- README.md | 10 +++++----- src/components/Reviews.js | 9 +++------ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 6999f4c..400cc05 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ Fork, clone, run yarn install, yarn start, pull request - * This component will take a product from props - * It will show the number of reviews followed by "review" or "reviews" depending on if there is one or more reviews - * It will create a list of the reviews description which will initially be hidden - * When the word "review" is clicked show the reviews - * When clicked again, hide the reviews + + + + diff --git a/src/components/Reviews.js b/src/components/Reviews.js index 543977a..04b4750 100644 --- a/src/components/Reviews.js +++ b/src/components/Reviews.js @@ -12,7 +12,7 @@ class Reviews extends Component { } showReviewDetails() { - this.state.reviewDetails.map((each, index) => { + return this.state.reviewDetails.map((each, index) => { return (

{each.description} @@ -21,16 +21,13 @@ class Reviews extends Component { }); } - countReviews() { + render() { + console.log(this.showReviewDetails()); if (this.state.reviews <= 1) { this.setState({ reviewText: "Review" }); } - } - - render() { - this.countReviews(); return (

{this.state.reviews} {this.state.reviewText}