Skip to content

Commit 963e295

Browse files
added and styled basket, filters, profile component
1 parent 5586122 commit 963e295

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1616
-164
lines changed

package-lock.json

+30-1
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
@@ -65,6 +65,7 @@
6565
"prop-types": "^15.7.2",
6666
"react": "^16.8.4",
6767
"react-dom": "^16.8.4",
68+
"react-modal": "^3.9.1",
6869
"react-redux": "^7.1.0",
6970
"react-router-dom": "^5.0.1",
7071
"redux": "^4.0.4",

src/client/actions/basketActions.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { ADD_TO_BASKET, REMOVE_FROM_BASKET } from '../constants/constants';
1+
import {
2+
ADD_TO_BASKET,
3+
REMOVE_FROM_BASKET,
4+
CLEAR_BASKET,
5+
ADD_QTY_ITEM,
6+
MINUS_QTY_ITEM
7+
} from '../constants/constants';
28

39
export const addToBasket = product => ({
410
type: ADD_TO_BASKET,
@@ -9,3 +15,17 @@ export const removeFromBasket = id => ({
915
type: REMOVE_FROM_BASKET,
1016
payload: id
1117
});
18+
19+
export const clearBasket = () => ({
20+
type: CLEAR_BASKET
21+
});
22+
23+
export const addQtyItem = id => ({
24+
type: ADD_QTY_ITEM,
25+
payload: id
26+
});
27+
28+
export const minusQtyItem = id => ({
29+
type: MINUS_QTY_ITEM,
30+
payload: id
31+
});

src/client/actions/filterActions.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
SET_TEXT_FILTER,
3+
SET_BRAND_FILTER,
4+
SET_MAX_PRICE_FILTER,
5+
SET_MIN_PRICE_FILTER,
6+
RESET_FILTER,
7+
APPLY_FILTER
8+
} from '../constants/constants';
9+
10+
export const setTextFilter = keyword => ({
11+
type: SET_TEXT_FILTER,
12+
payload: keyword
13+
});
14+
15+
export const setBrandFilter = brand => ({
16+
type: SET_BRAND_FILTER,
17+
payload: brand
18+
});
19+
20+
export const setMinPriceFilter = min => ({
21+
type: SET_MIN_PRICE_FILTER,
22+
payload: min
23+
});
24+
25+
export const setMaxPriceFilter = max => ({
26+
type: SET_MAX_PRICE_FILTER,
27+
payload: max
28+
});
29+
30+
export const resetFilter = () => ({
31+
type: RESET_FILTER
32+
});
33+
34+
export const applyFilter = filters => ({
35+
type: APPLY_FILTER,
36+
payload: filters
37+
});

src/client/components/basket/Basket.jsx

+39-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,37 @@
11
import React from 'react';
22
import { connect } from 'react-redux';
3-
import { removeFromBasket } from '../../actions/basketActions';
43
import BasketItem from './BasketItem';
54
import BasketToggle from './BasketToggle';
65
import Button from '../ui/Button';
76

7+
import {
8+
removeFromBasket,
9+
clearBasket,
10+
addQtyItem,
11+
minusQtyItem
12+
} from '../../actions/basketActions';
813
import { displayMoney } from '../../helpers/utils';
914

10-
const Basket = ({ basket, dispatchRemoveFromBasket }) => {
15+
const Basket = ({ basket, action }) => {
16+
const calculateTotal = () => {
17+
let total = 0;
18+
19+
if (basket.length !== 0) {
20+
const result = basket.map(product => product.price * product.quantity).reduce((a, b) => a + b);
21+
total = result.toFixed(2);
22+
}
23+
24+
return displayMoney(total);
25+
};
26+
1127
return (
1228
<div className="basket">
1329
<div className="basket-list">
1430
<div className="basket-header">
15-
<h3 className="basket-header-title">My Basket</h3>
31+
<h3 className="basket-header-title">
32+
My Basket &nbsp;
33+
<span>({` ${basket.length} ${basket.length > 1 ? 'items' : 'item'}`})</span>
34+
</h3>
1635
<BasketToggle>
1736
{({ onClickToggle }) => (
1837
<span
@@ -25,22 +44,30 @@ const Basket = ({ basket, dispatchRemoveFromBasket }) => {
2544
</BasketToggle>
2645
<Button
2746
className="basket-clear button button-border button-border-gray button-small"
47+
onClick={action.clearBasket}
2848
>
2949
<span>Clear Basket</span>
3050
</Button>
3151
</div>
52+
{basket.length <= 0 && (
53+
<div className="basket-empty">
54+
<h5 className="basket-empty-msg">Your basket is empty</h5>
55+
</div>
56+
)}
3257
{basket.map(product => (
3358
<BasketItem
34-
key={product.productId}
59+
key={product.id}
3560
product={product}
36-
removeFrombasket={dispatchRemoveFromBasket}
61+
basket={basket}
62+
action={action}
63+
removeFrombasket={action.removeFromBasket}
3764
/>
3865
))}
3966
</div>
4067
<div className="basket-checkout">
4168
<div className="basket-total">
4269
<p className="basket-total-title">Total Amout:</p>
43-
<h2 className="basket-total-amount">${displayMoney(454546)}</h2>
70+
<h2 className="basket-total-amount">{calculateTotal()}</h2>
4471
</div>
4572
<Button
4673
className="basket-checkout-button button"
@@ -58,7 +85,12 @@ const mapStateToProps = ({ basket }) => ({
5885
});
5986

6087
const mapDispatchToProps = dispatch => ({
61-
dispatchRemoveFromBasket: id => dispatch(removeFromBasket(id))
88+
action: {
89+
removeFromBasket: id => dispatch(removeFromBasket(id)),
90+
clearBasket: () => dispatch(clearBasket()),
91+
addQtyItem: id => dispatch(addQtyItem(id)),
92+
minusQtyItem: id => dispatch(minusQtyItem(id))
93+
}
6294
});
6395

6496
export default connect(mapStateToProps, mapDispatchToProps)(Basket);

src/client/components/basket/BasketItem.jsx

+25-14
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
11
import React from 'react';
22
import Button from '../ui/Button';
3+
import BasketItemControl from './BasketItemControl';
34

4-
const BasketItem = ({ product, removeFrombasket }) => {
5+
const BasketItem = ({ action, basket, product, removeFrombasket }) => {
56
const onRemoveFromBasket = () => {
6-
removeFrombasket(product.productId);
7+
removeFrombasket(product.id);
78
};
89

910
return (
1011
<div className="basket-item">
11-
<div className="basket-item-img-wrapper">
12-
<img className="basket-item-img" src={product.productImage} alt=""/>
12+
<BasketItemControl
13+
action={action}
14+
basket={basket}
15+
product={product}
16+
/>
17+
<div className="basket-item-wrapper">
18+
<div className="basket-item-img-wrapper">
19+
<img className="basket-item-img" src={product.image} alt=""/>
20+
</div>
21+
<div className="basket-item-details">
22+
<h5 className="basket-item-name">{product.name}</h5>
23+
<h5 className="basket-item-price">
24+
$ {(product.price * product.quantity).toFixed(2)}
25+
<span>{` (x ${product.quantity}) `}</span>
26+
</h5>
27+
</div>
28+
<Button
29+
className="basket-item-remove button button-border button-border-gray button-small"
30+
onClick={onRemoveFromBasket}
31+
>
32+
Remove
33+
</Button>
1334
</div>
14-
<div className="basket-item-details">
15-
<h5 className="basket-item-name">{product.productName}</h5>
16-
<h5 className="basket-item-price">$ {product.productPrice}</h5>
17-
</div>
18-
<Button
19-
className="basket-item-remove button button-border button-border-gray button-small"
20-
onClick={onRemoveFromBasket}
21-
>
22-
Remove
23-
</Button>
2435
</div>
2536
);
2637
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
3+
4+
const BasketItemControl = ({ action, basket, product }) => {
5+
const onAddQty = () => {
6+
if (product.maxQuantity !== product.quantity) {
7+
action.addQtyItem(product.id);
8+
}
9+
};
10+
11+
const onMinusQty = () => {
12+
if (product.maxQuantity >= product.quantity && product.quantity >= 2) {
13+
action.minusQtyItem(product.id);
14+
}
15+
};
16+
17+
return (
18+
<div className="basket-item-control">
19+
<button
20+
className="button button-border button-border-gray button-small basket-control basket-control-add"
21+
disabled={product.maxQuantity === product.quantity}
22+
onClick={onAddQty}
23+
>
24+
+
25+
</button>
26+
<button
27+
className="button button-border button-border-gray button-small basket-control basket-control-minus"
28+
disabled={product.quantity === 1}
29+
onClick={onMinusQty}
30+
>
31+
-
32+
</button>
33+
</div>
34+
);
35+
};
36+
37+
export default BasketItemControl;

src/client/components/basket/BasketToggle.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const BasketToggle = (props) => {
44
document.addEventListener('click', () => {
55

66
// document.body.classList.remove('basket-open');
7-
console.log(document.activeElement);
7+
// console.log(document.activeElement);
88
});
99

1010
const onClickToggle = (e) => {

src/client/components/product/ProductAdmin.jsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { Link } from 'react-router-dom';
44
const ProductAdmin = ({ product }) => {
55
return (
66
<div>
7-
<h4>{product.productName} <span>{product.productPrice}</span></h4>
8-
<p>{product.productDescription}</p>
7+
<h4>{product.name} <span>{product.price}</span></h4>
8+
<p>{product.description}</p>
99
<span>{new Date(product.dateAdded).toString()}</span>
10-
<Link to={`/edititem/${product.productId}`}>Edit</Link>
10+
<Link to={`/edititem/${product.id}`}>Edit</Link>
1111
</div>
1212
);
1313
};

src/client/components/product/ProductClient.jsx

+30-18
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,40 @@
11
import React from 'react';
22
import Button from '../ui/Button';
3+
import ProductItem from './ProductItem';
34

4-
const ProductClient = ({ product, addToBasket }) => {
5-
const onAddToBasket = () => {
6-
addToBasket(product);
5+
const ProductClient = ({ product, onOpenModal, onClickProduct }) => {
6+
const onClickItem = () => {
7+
onOpenModal();
8+
onClickProduct(product);
79
};
810

911
return (
10-
<div className="product-card">
11-
<div className="product-card-content">
12-
<div className="product-card-img-wrapper">
13-
<img className="product-card-img" src={product.productImage} alt="" />
12+
<ProductItem product={product}>
13+
{({ state, action, foundOnBasket }) => (
14+
<div
15+
className="product-card"
16+
style={{ borderBottom: foundOnBasket() ? '1px solid #4a4a4a' : '' }}
17+
>
18+
<div
19+
className="product-card-content"
20+
onClick={onClickItem}
21+
>
22+
<div className="product-card-img-wrapper">
23+
<img className="product-card-img" src={product.image} alt="" />
24+
</div>
25+
<h5 className="product-card-name">{product.name}</h5>
26+
<p className="product-card-brand">{product.brand}</p>
27+
<h4 className="product-card-price">$ {product.price}</h4>
28+
</div>
29+
<Button
30+
className={`product-card-button button button-block ${foundOnBasket() ? 'button-border button-border-gray' : ''}`}
31+
onClick={action.onAddToBasket}
32+
>
33+
{foundOnBasket() ? 'Remove from basket' : 'Add to basket'}
34+
</Button>
1435
</div>
15-
<h5 className="product-card-name">{product.productName}</h5>
16-
<p className="product-card-brand">{product.productBrand}</p>
17-
<h4 className="product-card-price">$ {product.productPrice}</h4>
18-
</div>
19-
<Button
20-
className="product-card-button button button-block"
21-
onClick={onAddToBasket}
22-
>
23-
Add To Cart
24-
</Button>
25-
</div>
36+
)}
37+
</ProductItem>
2638
);
2739
};
2840

0 commit comments

Comments
 (0)