Skip to content

Commit 4475321

Browse files
authored
Patrick/add cart page (#11)
* adding removeCart type, action, and reducer * adding Cart View
1 parent b1dbdaf commit 4475321

File tree

7 files changed

+92
-9
lines changed

7 files changed

+92
-9
lines changed

src/actions/cart.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ import { Product } from '../types/product';
22
import { CartTypes } from '../types/cart';
33
import { createAction } from '../types/helpers';
44

5-
export type CartActionTypes = ReturnType<typeof addToCart>
5+
export type CartActionTypes = ReturnType<typeof addToCart> | ReturnType<typeof removeFromCart>;
66

77
// TODO: update cart in local storage with a cart service
88

99
export const addToCart = (product: Product) => {
10-
// NOTE: this will be removed in the next PR
11-
console.log(`product added: ${JSON.stringify(product)}`);
1210
return createAction({
1311
type: CartTypes.AddToCart,
1412
product,
1513
});
1614
};
15+
16+
export const removeFromCart = (index: number) => {
17+
return createAction({
18+
type: CartTypes.RemoveFromCart,
19+
index,
20+
});
21+
};

src/components/Cart.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
import React from 'react';
2-
import { Container } from 'react-bootstrap';
2+
import { Button } from 'react-bootstrap';
3+
import { Link } from 'react-router-dom';
4+
import {
5+
Container,
6+
Col,
7+
Row,
8+
} from 'react-bootstrap';
9+
import CartItems from './CartItems';
10+
import { CartViewModifier } from '../types/cart';
311

412
const Cart = () => {
5-
return (
13+
return(
614
<Container>
7-
<h1>Cart</h1>
15+
<Row>
16+
<Col>
17+
<span style={{float:'right'}}><Link to="/">Keep shoppe-ing</Link></span>
18+
<h4>Your Cart</h4>
19+
</Col>
20+
</Row>
21+
<Row>
22+
<Col>
23+
<CartItems cartView={CartViewModifier.DELETE} />
24+
<Link to="/checkout" style={{float:'right', padding:'1rem 0 0 0'}}>
25+
<Button variant="primary">Continue to Checkout</Button>
26+
</Link>
27+
</Col>
28+
</Row>
829
</Container>
9-
);
30+
)
1031
};
1132

1233
export default Cart;

src/components/CartButton.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Button } from 'react-bootstrap';
33
import { useSelector } from 'react-redux';
44
import { Link } from 'react-router-dom';
55
import { AppState } from '../store';
6-
import { Product } from '../types/product';
76

87
const CartButton = () => {
98

src/components/CartItems.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react';
2+
import { useSelector, useDispatch } from 'react-redux'
3+
import { ListGroup } from 'react-bootstrap';
4+
import { AppDispatch } from '../actions';
5+
import { AppState } from "../store";
6+
import { CartViewModifier } from '../types/cart';
7+
import { removeFromCart } from '../actions/cart';
8+
9+
type Props = {
10+
cartView?: CartViewModifier
11+
}
12+
13+
const CartItems: React.FC<Props> = ({ cartView = CartViewModifier.NONE }) => {
14+
const products = useSelector((state: AppState) => state.cartState.products);
15+
const dispatch = useDispatch<AppDispatch>();
16+
const cartTotal = products.reduce((total, prod) => total + prod.price, 0);
17+
return (
18+
<ListGroup>
19+
{ products.map((product, i) => (
20+
<ListGroup.Item key={product.id}>
21+
{product.title}
22+
<span className='cart-price'>${product.price} <span className='text-muted'>{product.unit}</span>
23+
{cartView === CartViewModifier.DELETE &&
24+
<span className='fa fa-times text-danger remove-item' onClick={() => dispatch(removeFromCart(i))}></span>
25+
}
26+
</span>
27+
</ListGroup.Item>
28+
))}
29+
<ListGroup.Item>
30+
<strong>Total</strong> <span className='cart-price'><strong>${cartTotal.toFixed(2)}</strong></span>
31+
</ListGroup.Item>
32+
</ListGroup>
33+
);
34+
};
35+
36+
export default CartItems;

src/index.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,14 @@ a.header-link {
2929
background-repeat: no-repeat;
3030
background-position: center;
3131
background-size: cover;
32+
}
33+
34+
.cart-price {
35+
float: right;
36+
}
37+
38+
.remove-item {
39+
display: inline-block;
40+
padding-left: 1rem;
41+
cursor: pointer;
3242
}

src/store/reducers/cart.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ import { AppActions } from '../../actions';
33
import { CartTypes } from '../../types/cart';
44
import { Product } from '../../types/product';
55

6+
const sortByTitle = (prod1: Product, prod2: Product) => {
7+
return prod1.title.localeCompare(prod2.title);
8+
}
9+
610
const productsReducer = (state: Product[] = [], action: AppActions): Product[] => {
711
switch(action.type) {
812
case CartTypes.AddToCart:
9-
return [...state, action.product];
13+
return [...state, action.product].sort(sortByTitle);
14+
case CartTypes.RemoveFromCart:
15+
return state.filter((_, index) => index !== action.index)
1016
default:
1117
return state;
1218
}

src/types/cart.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
export enum CartTypes {
22
AddToCart = 'ADD_TO_CART',
3+
RemoveFromCart = 'REMOVE_FROM_CART',
34
};
5+
6+
export enum CartViewModifier {
7+
NONE,
8+
DELETE,
9+
};

0 commit comments

Comments
 (0)