Skip to content

Commit 353fd5a

Browse files
twishasaraiyabogas04
authored andcommitted
Product page Fix #41 (#50)
* added product details page * Add Clean URL for product Page Integrate Product Description with API Add isomorphic-unfetch for easy client and server side fetch Signed-off-by: Anshul Mittal <[email protected]> * Modify SwitchCase for eslint to properly indent switch statements Signed-off-by: Anshul Mittal <[email protected]> * Add review changes Add url of now deployment in API fetch Signed-off-by: Anshul Mittal <[email protected]> * Add eslint space-comment in config Signed-off-by: Anshul Mittal <[email protected]> * Move getInititalProps as static function Signed-off-by: Anshul Mittal <[email protected]> * Add propTypes for ProductPage Signed-off-by: Anshul Mittal <[email protected]> * Resolve errors raised by spaced-comment in Eslint Signed-off-by: Anshul Mittal <[email protected]> * Change URL in Item.js and add Error page if invalid product link is accessed Signed-off-by: Anshul Mittal <[email protected]> * Break down page into components * Add review changes * add review changes #2 * Add blank array for imageUrls in Item.test.js for jest change id to number instead of string Signed-off-by: Anshul Mittal <[email protected]> * Modify Item.test.js Signed-off-by: Anshul Mittal <[email protected]>
1 parent 78558a5 commit 353fd5a

File tree

21 files changed

+437
-30
lines changed

21 files changed

+437
-30
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ module.exports = {
2222
semi: ['error', 'always'],
2323
'react/jsx-uses-vars': 1,
2424
'react/jsx-uses-react': 1,
25+
'spaced-comment': ['error', 'always', { exceptions: ['-', '+'] }],
2526
},
2627
};

components/Breadcrumb/Breadcrumb.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
export default class Breadcrumb extends React.Component {
5+
static propTypes = {
6+
path: PropTypes.string,
7+
};
8+
9+
render() {
10+
const { path } = this.props;
11+
return (
12+
<React.Fragment>
13+
<style jsx>{`
14+
.breadcrumb {
15+
margin: 20px;
16+
}
17+
`}</style>
18+
<div className="breadcrumb">
19+
<a href="/">Home</a>
20+
{path.replace(/%20/g, ' ')}
21+
</div>
22+
</React.Fragment>
23+
);
24+
}
25+
}

components/Breadcrumb/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './Breadcrumb';

components/Carousel/Carousel.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
export default class Carousel extends React.PureComponent {
5+
constructor(props){
6+
super(props);
7+
this.displayImage = React.createRef();
8+
}
9+
static propTypes = {
10+
imageUrls: PropTypes.array,
11+
};
12+
13+
changeImage = e => {
14+
this.displayImage.current.src = e.target.src;
15+
};
16+
17+
render() {
18+
const { imageUrls } = this.props;
19+
return (
20+
<React.Fragment>
21+
<style jsx>{`
22+
.image_container {
23+
width: 50%;
24+
}
25+
.thumbnail_big {
26+
width: 90%;
27+
height: 480px;
28+
margin: 20px;
29+
}
30+
.thumbnail_small {
31+
margin: 10px;
32+
width: 20%;
33+
height: 66px;
34+
}
35+
@media (max-width: 650px) {
36+
.image_container {
37+
width: 100%;
38+
}
39+
}
40+
`}</style>
41+
<div className="image_container">
42+
<img
43+
className="thumbnail_big"
44+
ref={this.displayImage}
45+
src={imageUrls[0]}
46+
/>
47+
<div>
48+
{imageUrls.map((src,i) => (
49+
<img key={i} className="thumbnail_small" src={src} onMouseOver={this.changeImage} />
50+
)
51+
)}
52+
</div>
53+
</div>
54+
</React.Fragment>
55+
);
56+
}
57+
}

components/Carousel/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './Carousel';

components/Item/Item.js

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
2+
import Link from 'next/link';
23
import Rupee from '../Icons/Rupee';
4+
import PropTypes from 'prop-types';
35

46
const Item = props => (
57
<React.Fragment>
@@ -78,17 +80,17 @@ const Item = props => (
7880
}
7981
`}</style>
8082
<li className="product_card">
81-
<a href="#">
82-
<img width="100%" src={props.imageUrl} alt={props.name} />
83-
</a>
83+
<Link href={`/product/${props.id}`}>
84+
<img width="100%" src={props.imageUrls[0]} alt={props.name} />
85+
</Link>
8486
<div className="product_body">
8587
<div className="product_name">
8688
<a href="#">{props.name}</a>
8789
</div>
8890
<div className="product_price">
89-
{/*This code handles price.*/}
90-
{/*If discounted price is available, it displays discounted price and strikes-through original price.*/}
91-
{/*If discounted price is not available, it displays original price.*/}
91+
{/* This code handles price. */}
92+
{/* If discounted price is available, it displays discounted price and strikes-through original price. */}
93+
{/* If discounted price is not available, it displays original price. */}
9294
{props.discountedPrice && (
9395
<span>
9496
<Rupee height=".8em" />
@@ -109,12 +111,19 @@ const Item = props => (
109111
</div>
110112
</div>
111113
<div className="product_buttons">
112-
{/*Add the buttons later*/}
114+
{/* Add the buttons later */}
113115
<div className="add_button">Add</div>
114116
<div className="save_for_later">SaveForLater</div>
115117
</div>
116118
</li>
117119
</React.Fragment>
118120
);
119121

122+
Item.propTypes = {
123+
id: PropTypes.number,
124+
name: PropTypes.string,
125+
originalPrice: PropTypes.number,
126+
discountedPrice: PropTypes.number,
127+
imageUrls: PropTypes.arrayOf(PropTypes.string),
128+
};
120129
export default Item;

components/Item/__tests__/Item.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Item from '../Item';
55

66
describe('<Item />', () => {
77
it('renders correctly', () => {
8-
const wrapper = mount(<Item name="Item one" id="123" />);
8+
const wrapper = mount(<Item name="Item one" id={1234} imageUrls={['']} />);
99
expect(wrapper).toMatchSnapshot();
1010
});
1111
});

components/Item/__tests__/__snapshots__/Item.test.js.snap

+11-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
exports[`<Item /> renders correctly 1`] = `
44
<Item
5-
id="123"
5+
id={1234}
6+
imageUrls={
7+
Array [
8+
"",
9+
]
10+
}
611
name="Item one"
712
>
813
<JSXStyle
@@ -12,16 +17,17 @@ exports[`<Item /> renders correctly 1`] = `
1217
<li
1318
className="jsx-3347001721 product_card"
1419
>
15-
<a
16-
className="jsx-3347001721"
17-
href="#"
20+
<Link
21+
href="/product/1234"
1822
>
1923
<img
2024
alt="Item one"
2125
className="jsx-3347001721"
26+
onClick={[Function]}
27+
src=""
2228
width="100%"
2329
/>
24-
</a>
30+
</Link>
2531
<div
2632
className="jsx-3347001721 product_body"
2733
>

components/NavBar/__tests__/Navbar.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* globals describe, it, expect */
22
import React from 'react';
33
import { mount } from 'enzyme';
4-
import { shallowToJson } from 'enzyme-to-json'; //removes unnecessary JSON from snapshot
4+
import { shallowToJson } from 'enzyme-to-json'; // removes unnecessary JSON from snapshot
55
import Navbar from '../';
66
import links from '../../../constants/links';
77

components/ProductInfo/ProductInfo.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import Rupee from '../Icons/Rupee';
4+
5+
export default class ProductInfo extends React.PureComponent {
6+
static propTypes = {
7+
name: PropTypes.string,
8+
originalPrice: PropTypes.number,
9+
discountedPrice: PropTypes.number,
10+
description: PropTypes.string,
11+
};
12+
static defaultProps = {
13+
description: 'No description available',
14+
};
15+
render() {
16+
const { name, originalPrice, discountedPrice, description } = this.props;
17+
return (
18+
<React.Fragment>
19+
<div className="product_info_container">
20+
<h1>{name}</h1>
21+
{originalPrice ? (
22+
<s>
23+
<Rupee />
24+
{originalPrice}
25+
</s>
26+
) : (
27+
<span>
28+
<Rupee />
29+
{originalPrice}
30+
</span>
31+
)}
32+
{discountedPrice && (
33+
<span>
34+
<Rupee />
35+
<strong>{discountedPrice}</strong>
36+
</span>
37+
)}
38+
<p>{description}</p>
39+
</div>
40+
</React.Fragment>
41+
);
42+
}
43+
}

components/ProductInfo/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './ProductInfo';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
export default class QuantityButton extends React.Component {
5+
static propTypes = {
6+
qty: PropTypes.number,
7+
increment: PropTypes.func,
8+
decrement: PropTypes.func,
9+
};
10+
11+
render() {
12+
const { qty, increment, decrement } = this.props;
13+
return (
14+
<React.Fragment>
15+
<style jsx>{`
16+
.quantity_container {
17+
display: flex;
18+
flex-direction: row;
19+
flex-wrap: wrap;
20+
}
21+
.increment_button,
22+
.decrement_button {
23+
width: 44px;
24+
height: 40px;
25+
margin: 0px;
26+
border: 1px solid #535766;
27+
text-align: center;
28+
font-size: 16pt;
29+
font-weight: 500;
30+
color: #535766;
31+
}
32+
.quantity {
33+
width: 80px;
34+
height: 20px;
35+
border: 1px solid #535766;
36+
text-align: center;
37+
padding: 9px;
38+
}
39+
.disabled {
40+
cursor: not-allowed;
41+
}
42+
`}</style>
43+
<div className="quantity_container">
44+
<button className="increment_button" onClick={increment}>
45+
+
46+
</button>
47+
<div className="quantity">{this.props.qty}</div>
48+
<button
49+
disabled={!qty}
50+
className={'decrement_button ' + (qty ? '' : 'disabled')}
51+
onClick={decrement}
52+
>
53+
-
54+
</button>
55+
</div>
56+
</React.Fragment>
57+
);
58+
}
59+
}

components/QuantityButton/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './QuantityButton';

package-lock.json

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"babel-core": "7.0.0-bridge.0",
66
"babel-jest": "22.4.3",
77
"express": "^4.16.3",
8+
"isomorphic-unfetch": "^2.0.0",
89
"next": "^6.0.3",
910
"prop-types": "^15.6.2",
1011
"react": "^16.4.1",

pages/index.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,10 @@ export default class IndexPage extends React.PureComponent {
5252
<h2>Items</h2>
5353
<ul>
5454
{this.state.items.map(
55-
({ id, name, imageUrl, originalPrice, discountedPrice }) => (
55+
(item) => (
5656
<Item
57-
key={id}
58-
name={name}
59-
imageUrl={imageUrl}
60-
originalPrice={originalPrice}
61-
discountedPrice={discountedPrice}
57+
key={item.id}
58+
{...item}
6259
/>
6360
)
6461
)}

0 commit comments

Comments
 (0)