Skip to content

Commit

Permalink
cart complete
Browse files Browse the repository at this point in the history
  • Loading branch information
Facundo Martinez authored and Facundo Martinez committed Feb 16, 2021
1 parent 99f7b20 commit 0241f8d
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 4 deletions.
10 changes: 10 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Dashboard from "./pages/Dashboard";
import Admin from "./pages/Admin";
import Search from "./pages/Search";
import ProductDetails from "./pages/ProductDetails";
import Cart from "./pages/Cart";

const App = () => {
const dispatch = useDispatch();
Expand Down Expand Up @@ -69,6 +70,15 @@ const App = () => {
</MainLayout>
)}
/>
<Route
exact
path="/cart"
render={() => (
<MainLayout>
<Cart />
</MainLayout>
)}
/>
<Route
path="/registration"
render={() => (
Expand Down
62 changes: 62 additions & 0 deletions src/components/Checkout/Item/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from "react";
import { useDispatch } from "react-redux";

import {
removeCartItem,
addProduct,
reduceCartItem,
} from "./../../../redux/Cart/cart.actions";

const Item = (product) => {
const dispatch = useDispatch();
const {
productName,
productThumbnail,
productPrice,
quantity,
documentID,
} = product;
const handleRemoveCartItem = (documentID) => {
dispatch(removeCartItem({ documentID }));
};
const handleAddProduct = (product) => {
dispatch(addProduct(product));
};
const handleReduceItem = (product) => {
dispatch(reduceCartItem(product));
};
return (
<table className="cartItem" border="0" cellSpacing="0" cellPadding="0">
<tbody>
<tr>
<td>
<img src={productThumbnail} alt={productName} />
</td>
<td>{productName}</td>
<td>
<span
onClick={() => handleReduceItem(product)}
className="cartBtn"
>{`< `}</span>
<span>{quantity}</span>
<span
onClick={() => handleAddProduct(product)}
className="cartBtn"
>{` >`}</span>
</td>
<td>${productPrice}</td>
<td align="center">
<span
className="cartBtn"
onClick={() => handleRemoveCartItem(documentID)}
>
X
</span>
</td>
</tr>
</tbody>
</table>
);
};

export default Item;
104 changes: 104 additions & 0 deletions src/components/Checkout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from "react";
import { useSelector } from "react-redux";
import {
selectCartItems,
selectCartTotal,
} from "./../../redux/Cart/cart.selectors";
import { createStructuredSelector } from "reselect";
import { useHistory } from "react-router-dom";
import "./styles.scss";
import Button from "../forms/Button";
import Item from "./Item";

const Checkout = () => {
const history = useHistory();
const { cartItems } = useSelector(
createStructuredSelector({ cartItems: selectCartItems })
);
const { total } = useSelector(
createStructuredSelector({ total: selectCartTotal })
);
const errorMsg = "You have no items in your cart.";
return (
<div className="checkout">
<h1>Checkout</h1>
<div className="cart">
{cartItems.length > 0 ? (
<table border="0" cellPadding="0" cellSpacing="0">
<tbody>
<tr>
<table
className="checkoutHeader"
border="0"
cellPadding="10"
cellSpacing="0"
>
<tbody>
<tr>
<th>Product</th>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
<th>Remove</th>
</tr>
</tbody>
</table>
</tr>

<tr>
<table border="0" cellPadding="0" cellSpacing="0">
<tbody>
{cartItems.map((item, index) => {
return (
<tr key={index}>
<td>
<Item {...item} />
</td>
</tr>
);
})}
</tbody>
</table>
</tr>

<tr>
<table
align="right"
border="0"
cellSpacing="0"
cellPadding="10"
>
<tr align="right">
<td>
<h3>Total: ${total}</h3>
</td>
</tr>
<tr>
<table border="0" cellPadding="10" cellSpacing="0">
<tbody>
<tr>
<td>
<Button onClick={() => history.goBack()}>
Continue Shopping
</Button>
</td>
<td>
<Button>Checkout</Button>
</td>
</tr>
</tbody>
</table>
</tr>
</table>
</tr>
</tbody>
</table>
) : (
<p>{errorMsg}</p>
)}
</div>
</div>
);
};

export default Checkout;
53 changes: 53 additions & 0 deletions src/components/Checkout/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.checkout {
margin: 2rem auto;

h1 {
display: block;
width: 100%;
}

h1,
p {
text-align: center;
}

.checkoutHeader {
border-bottom: 1px solid black;
}

.cart {
max-width: 100rem;
margin: 0 auto;

table {
width: 100%;
}
}

.checkoutHeader,
.cart {
width: 100%;
text-align: left;

th,
td {
width: 22%;
}
}

.cartItem {
td img {
display: block;
width: 100%;
}
}

.cartBtns {
display: block;
width: 100%;
}

.cartBtn {
cursor: pointer;
}
}
2 changes: 1 addition & 1 deletion src/components/Header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const Header = () => {
<div className="callToActions">
<ul>
<li>
<Link to="/">Your Cart: ({totalNumCartItems})</Link>
<Link to="/cart">Your Cart: ({totalNumCartItems})</Link>
</li>
{currentUser && [
<li>
Expand Down
4 changes: 3 additions & 1 deletion src/components/ProductCard/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from "react";
import { useParams } from "react-router-dom";
import { useParams, useHistory } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import {
fetchProductStart,
Expand All @@ -15,6 +15,7 @@ const mapState = (state) => ({

const ProductCard = ({}) => {
const dispatch = useDispatch();
const history = useHistory();
const { productID } = useParams();
const { product } = useSelector(mapState);

Expand All @@ -35,6 +36,7 @@ const ProductCard = ({}) => {
const handleAddToCart = (product) => {
if (!product) return;
dispatch(addProduct(product));
history.push("/cart");
};

return (
Expand Down
4 changes: 3 additions & 1 deletion src/components/ProductsResults/Product/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from "react";
import { Link } from "react-router-dom";
import { Link, useHistory } from "react-router-dom";
import Button from "../../forms/Button";
import { useDispatch } from "react-redux";
import { addProduct } from "./../../../redux/Cart/cart.actions";

const Product = (product) => {
const dispatch = useDispatch();
const history = useHistory();
const { productThumbnail, productName, productPrice, documentID } = product;
if (
!documentID ||
Expand All @@ -20,6 +21,7 @@ const Product = (product) => {
const handleAddToCart = (product) => {
if (!product) return;
dispatch(addProduct(product));
history.push("/cart");
};
return (
<div className="product">
Expand Down
12 changes: 12 additions & 0 deletions src/pages/Cart/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import Checkout from "../../components/Checkout";

const Cart = () => {
return (
<div>
<Checkout />
</div>
);
};

export default Cart;
10 changes: 10 additions & 0 deletions src/redux/Cart/cart.actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ export const addProduct = (nextCartItem) => ({
type: cartTypes.ADD_TO_CART,
payload: nextCartItem,
});

export const removeCartItem = (cartItem) => ({
type: cartTypes.REMOVE_CART_ITEM,
payload: cartItem,
});

export const reduceCartItem = (cartItem) => ({
type: cartTypes.REDUCE_CART_ITEM,
payload: cartItem,
});
22 changes: 21 additions & 1 deletion src/redux/Cart/cart.reducers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import cartTypes from "./cart.types";
import { handleAddToCart } from "./cart.utils";
import {
handleAddToCart,
handleRemoveCartItem,
handleReduceCartItem,
} from "./cart.utils";

const INITIAL_STATE = {
cartItems: [],
Expand All @@ -15,6 +19,22 @@ const cartReducer = (state = INITIAL_STATE, action) => {
nextCartItem: action.payload,
}),
};
case cartTypes.REMOVE_CART_ITEM:
return {
...state,
cartItems: handleRemoveCartItem({
prevCartItems: state.cartItems,
cartItemToRemove: action.payload,
}),
};
case cartTypes.REDUCE_CART_ITEM:
return {
...state,
cartItems: handleReduceCartItem({
prevCartItems: state.cartItems,
cartItemToReduce: action.payload,
}),
};
default:
return state;
}
Expand Down
8 changes: 8 additions & 0 deletions src/redux/Cart/cart.selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ export const selectCartItemsCount = createSelector(
(cartItems) =>
cartItems.reduce((quantity, cartItem) => quantity + cartItem.quantity, 0)
);

export const selectCartTotal = createSelector([selectCartItems], (cartItems) =>
cartItems.reduce(
(quantity, cartItem) =>
quantity + cartItem.quantity * cartItem.productPrice,
0
)
);
2 changes: 2 additions & 0 deletions src/redux/Cart/cart.types.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const cartTypes = {
ADD_TO_CART: "ADD_TO_CART",
REMOVE_CART_ITEM: "REMOVE_CART_ITEM",
REDUCE_CART_ITEM: "REDUCE_CART_ITEM",
};

export default cartTypes;
Loading

0 comments on commit 0241f8d

Please sign in to comment.