diff --git a/src/App.js b/src/App.js index 738f30d..5156b1f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,7 @@ import React from 'react'; import { Route,Switch, Redirect } from 'react-router-dom'; import {connect} from 'react-redux'; +import { createStructuredSelector } from 'reselect'; import './App.css'; @@ -8,9 +9,12 @@ import './App.css'; import HomePage from './pages/homepage/homepage.component'; import Header from './components/header/header.component'; import ShopPage from './pages/shop/shop.component'; +import CheckoutPage from './pages/checkout/checkout.component'; import SignInAndSignUp from './pages/signin-and-singup/signin-and-singup.component'; import { auth,createUserProfileDocument } from './fireabase/firebase.utils'; import { setCurrentUser } from './redux/user/user.actions'; +import { selectCurrentUser } from './redux/user/user.selectors'; + @@ -46,6 +50,7 @@ class App extends React.Component { + this.props.currentUser?( @@ -60,8 +65,8 @@ class App extends React.Component { ); } } -const mapStateToProps = ({user}) => ({ - currentUser: user.currentUser +const mapStateToProps = createStructuredSelector ({ + currentUser: selectCurrentUser }) const mapDispatchProps = dispatch => ({ setCurrentUser: user => dispatch(setCurrentUser(user)) diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/src/components/cart-dropdown/cart-dropdown.component.jsx b/src/components/cart-dropdown/cart-dropdown.component.jsx index 55d1222..06b090e 100644 --- a/src/components/cart-dropdown/cart-dropdown.component.jsx +++ b/src/components/cart-dropdown/cart-dropdown.component.jsx @@ -4,25 +4,31 @@ import { connect } from 'react-redux'; import CustomButton from '../custom-button/custom-button.component'; import CartItem from '../cart-item/cart-item-component'; import { selectCartItems } from '../../redux/cart/cart.selector'; +import { createStructuredSelector } from 'reselect'; +import { withRouter } from 'react-router-dom' +import { toggleCartHidden } from '../../redux/cart/cart.actions' import './cart-dropdown.styles.scss'; -const CartDropDown = ({cartItems}) => ( +const CartDropDown = ({cartItems, history, dispatch}) => (
{ - cartItems.map(cartItem=>( - + cartItems.length ? + cartItems.map(cartItem=>( + ) - ) + ) + : + Tu carrito esta vacio. }
- GO TO CHECKOUT + {history.push('/checkout'); dispatch(toggleCartHidden())}}>GO TO CHECKOUT
) -const mapStateToProps = (state) => ({ - cartItems: selectCartItems (state) +const mapStateToProps = createStructuredSelector ({ + cartItems: selectCartItems }) -export default connect(mapStateToProps)(CartDropDown); \ No newline at end of file +export default withRouter(connect(mapStateToProps)(CartDropDown)); \ No newline at end of file diff --git a/src/components/cart-dropdown/cart-dropdown.styles.scss b/src/components/cart-dropdown/cart-dropdown.styles.scss index 6191636..1050e77 100644 --- a/src/components/cart-dropdown/cart-dropdown.styles.scss +++ b/src/components/cart-dropdown/cart-dropdown.styles.scss @@ -11,6 +11,10 @@ right: 40px; z-index: 5; + .empty-message { + font-size: 18px; + margin: 50px auto; + } .cart-items { height: 240px; display: flex; diff --git a/src/components/cart-icon/cart-icon.component.jsx b/src/components/cart-icon/cart-icon.component.jsx index 8a9b12a..6c18d9e 100644 --- a/src/components/cart-icon/cart-icon.component.jsx +++ b/src/components/cart-icon/cart-icon.component.jsx @@ -7,6 +7,8 @@ import { selectCartItemsCount } from '../../redux/cart/cart.selector' import { ReactComponent as ShoppingIcon } from '../../assets/shopping-bag.svg'; +import {createStructuredSelector} from 'reselect'; + import './cart-icon.styles.scss'; const CartIcon = ({toggleCartHidden, itemCount}) => ( @@ -19,8 +21,8 @@ const mapDispatchToProps = dispatch =>({ toggleCartHidden: ()=> dispatch(toggleCartHidden()) }); -const mapStateToProps = state => ({ - itemCount: selectCartItemsCount(state) +const mapStateToProps = createStructuredSelector ({ + itemCount: selectCartItemsCount }) export default connect(mapStateToProps, mapDispatchToProps)(CartIcon); \ No newline at end of file diff --git a/src/components/checkout-item/checkout-item.component.jsx b/src/components/checkout-item/checkout-item.component.jsx new file mode 100644 index 0000000..06a808d --- /dev/null +++ b/src/components/checkout-item/checkout-item.component.jsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import './checkout-item.styles.scss'; + +const CheckoutItem = ({cartItem:{name, imageUrl, price, quantity}}) => ( +
+
+ item +
+ {name} + {quantity} + {price} +
+
+) + +export default CheckoutItem; \ No newline at end of file diff --git a/src/components/checkout-item/checkout-item.styles.scss b/src/components/checkout-item/checkout-item.styles.scss new file mode 100644 index 0000000..f9b320e --- /dev/null +++ b/src/components/checkout-item/checkout-item.styles.scss @@ -0,0 +1,33 @@ +.checkout-item { + width: 100%; + display: flex; + min-height: 100px; + border-bottom: 1px solid darkgrey; + padding: 15px 0; + font-size: 20px; + align-items: center; + + .image-container { + width: 23%; + padding-right: 15px; + + img { + width: 100%; + height: 100%; + } + } + .name, + .quantity, + .price { + width: 23%; + } + + .quantity { + padding-left: 20px; + } + + .remove-button { + padding-left: 12px; + cursor: pointer; + } +} diff --git a/src/components/header/header.component.jsx b/src/components/header/header.component.jsx index 21e6687..1d835d1 100644 --- a/src/components/header/header.component.jsx +++ b/src/components/header/header.component.jsx @@ -4,9 +4,14 @@ import {ReactComponent as Logo} from '../../assets/crown.svg'; import CartIcon from '../cart-icon/cart-icon.component'; import CartDropDown from '../cart-dropdown/cart-dropdown.component'; +import {createStructuredSelector} from 'reselect'; + import {auth} from '../../fireabase/firebase.utils'; import './header.styles.scss'; import { connect } from 'react-redux'; +import { selectCurrentUser } from '../../redux/user/user.selectors' +import { selectCartHidden } from '../../redux/cart/cart.selector' + const Header = ({currentUser, hidden}) => (
@@ -32,8 +37,9 @@ const Header = ({currentUser, hidden}) => (
) -const mapStateToProps = ({user:{currentUser},cart:{hidden}}) => ({ - currentUser, hidden +const mapStateToProps = createStructuredSelector ({ + currentUser: selectCurrentUser, + hidden: selectCartHidden }) export default connect(mapStateToProps)(Header); \ No newline at end of file diff --git a/src/pages/checkout/checkout.component.jsx b/src/pages/checkout/checkout.component.jsx new file mode 100644 index 0000000..61c5d1d --- /dev/null +++ b/src/pages/checkout/checkout.component.jsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import { createStructuredSelector } from 'reselect' + +import { selectCartItems, selectCartTotal } from '../../redux/cart/cart.selector'; + +import CheckoutItem from '../../components/checkout-item/checkout-item.component' + +import './checkout.styles.scss'; + +const CheckoutPage = ({cartItems, cartTotal}) => ( +
+
+
+ Producto +
+
+ Descripcion +
+
+ Cantidad +
+
+ Precio +
+
+ Remover +
+
+ { + cartItems.map( + cartItem=> + ) + } +
+ TOTAL: ${cartTotal} +
+
+) +const mapStateToProps = createStructuredSelector({ + cartItems: selectCartItems, + cartTotal: selectCartTotal +}) + +export default connect(mapStateToProps)(CheckoutPage); \ No newline at end of file diff --git a/src/pages/checkout/checkout.styles.scss b/src/pages/checkout/checkout.styles.scss new file mode 100644 index 0000000..9abbdd7 --- /dev/null +++ b/src/pages/checkout/checkout.styles.scss @@ -0,0 +1,31 @@ +.checkout-page { + width: 55%; + min-height: 90vh; + display: flex; + flex-direction: column; + align-items: center; + margin: 50px auto 0; + + .checkout-header { + width: 100%; + padding: 10px 0; + display: flex; + justify-content: space-between; + border-bottom: 1px solid darkgrey; + + .header-block { + text-transform: capitalize; + width: 23%; + + &:last-child { + width: 8%; + } + } + } + + .total { + margin-top: 30px; + margin-left: auto; + font-size: 36px; + } +} diff --git a/src/redux/cart/cart.selector.js b/src/redux/cart/cart.selector.js index db7cd1f..2d5ad61 100644 --- a/src/redux/cart/cart.selector.js +++ b/src/redux/cart/cart.selector.js @@ -13,4 +13,19 @@ export const selectCartItemsCount = createSelector( cartItems.reduce( (accumulateQuantity, cartItem) => accumulateQuantity + cartItem.quantity, 0 ) -); \ No newline at end of file +); + +export const selectCartTotal = createSelector( + [selectCartItems], + cartItems=> + cartItems.reduce( + (accumulateQuantity, cartItem) => + accumulateQuantity + cartItem.quantity * cartItem.price, + 0 + ) +) + +export const selectCartHidden = createSelector( + [selectCart], + cart=>cart.hidden +) \ No newline at end of file diff --git a/src/redux/user/user.selectors.js b/src/redux/user/user.selectors.js new file mode 100644 index 0000000..86eb0e5 --- /dev/null +++ b/src/redux/user/user.selectors.js @@ -0,0 +1,8 @@ +import { createSelector } from 'reselect'; + +const selectUser = state => state.user + +export const selectCurrentUser = createSelector ( + [selectUser], + user=>user.currentUser +) \ No newline at end of file