From 5c513fe45dfc0d35f4f95c6187048aa646983b26 Mon Sep 17 00:00:00 2001 From: Luan Ribeiro Date: Tue, 19 May 2020 20:02:18 -0300 Subject: [PATCH] Adding routes, cart and bussines logic on components --- .eslintrc.json | 17 ++++- package.json | 2 +- src/components/Card/index.jsx | 53 +++++++++------- src/components/Card/styles.js | 25 ++++---- src/components/Layout/index.jsx | 39 +++++++----- src/components/Layout/styles.js | 48 ++++++++------ src/components/Message/index.jsx | 25 +++----- src/pages/Cart/index.jsx | 48 ++++++++++++-- src/pages/Cart/styles.js | 63 +++++++++++++++++++ src/pages/RegisterProduct/index.jsx | 97 ++++++++++++++++++----------- src/routes.jsx | 16 ++--- src/services/api.js | 5 ++ src/store/actions/index.js | 12 ---- src/store/card/index.js | 11 ++++ src/store/cart/index.js | 11 ++++ src/store/fetchActions/index.js | 24 +++++++ src/store/index.js | 16 +++-- src/store/message/index.js | 13 ++++ src/store/reducers/card.js | 16 ----- src/store/reducers/index.js | 10 --- src/store/reducers/message.js | 19 ------ src/store/types/index.js | 5 -- yarn.lock | 34 +++++++--- 23 files changed, 397 insertions(+), 212 deletions(-) create mode 100644 src/services/api.js delete mode 100644 src/store/actions/index.js create mode 100644 src/store/card/index.js create mode 100644 src/store/cart/index.js create mode 100644 src/store/fetchActions/index.js create mode 100644 src/store/message/index.js delete mode 100644 src/store/reducers/card.js delete mode 100644 src/store/reducers/index.js delete mode 100644 src/store/reducers/message.js delete mode 100644 src/store/types/index.js diff --git a/.eslintrc.json b/.eslintrc.json index 68c8a9f..48a0b1c 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -37,13 +37,16 @@ } } ], - "eslint-no-undef": "on", + "includeExports": 0, + "eslint-no-undef": 0, + "import/named": 0, "no-underscore-dangle": 0, + "react/jsx-wrap-multilines": "off", "react/no-array-index-key": "off", "eslintimport/extensions": 0, "import/no-unresolved": 0, "import/no-named-as-default-member": 0, - "import/no-named-as-default-member": 0, + "import/no-extraneous-dependencies": 0, "react/display-name": 1, "jsx-a11y/rule-name": 0, "react/jsx-filename-extension": [ @@ -52,11 +55,19 @@ "extensions": [".js", ".jsx"] } ], + "import/no-useless-path-segments": [ + "error", + { + "noUselessIndex": true + } + ], + "import/no-duplicates": ["error", { "considerQueryString": true }], "global-require": "off", "import/prefer-default-export": "off", "no-unused-expressions": ["error", { "allowTaggedTemplates": true }], "no-return-assign": ["off"], "prefer-promise-reject-errors": ["off"], - "react/prop-types": ["warn"] + "react/prop-types": ["warn"], + "react/jsx-one-expression-per-line": ["off"] } } diff --git a/package.json b/package.json index 39e4918..7b77c46 100644 --- a/package.json +++ b/package.json @@ -29,9 +29,9 @@ "webpack" ], "dependencies": { + "@reduxjs/toolkit": "^1.3.6", "react": "16.13.1", "react-dom": "16.13.1", - "react-icons": "^3.10.0", "react-redux": "7.2.0", "react-router-dom": "^5.2.0", "redux": "4.0.5", diff --git a/src/components/Card/index.jsx b/src/components/Card/index.jsx index 05b6f8b..cb19b7d 100644 --- a/src/components/Card/index.jsx +++ b/src/components/Card/index.jsx @@ -1,28 +1,37 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import * as S from './styles' +import React, { useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import * as S from './styles'; + +import { getAllCards } from '../../store/fetchActions'; +import { addItem } from '../../store/cart'; const Card = () => { - - const cardShoes = useSelector(state => state.card) - + const cardShoes = useSelector((state) => state.card); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(getAllCards()); + }, [dispatch]); + + const addItemCart = (card) => { + dispatch(addItem(card)); + }; + return ( - { - cardShoes.map((card, index) => ( - - - {card.name} - {card.description} - {card.price} - - Add to cart - - - )) - } + {cardShoes.map((card, index) => ( + + + {card.name} + {card.description} + R$ {card.price} + + addItemCart(card)}> Add to cart + + + ))} - ) -} + ); +}; -export default Card \ No newline at end of file +export default Card; diff --git a/src/components/Card/styles.js b/src/components/Card/styles.js index ea52948..d4c3685 100644 --- a/src/components/Card/styles.js +++ b/src/components/Card/styles.js @@ -1,4 +1,4 @@ -import styled from 'styled-components' +import styled from 'styled-components'; /** Card Product */ export const BgCard = styled.section` @@ -7,7 +7,7 @@ export const BgCard = styled.section` margin-bottom: 200px; display: flex; flex-wrap: wrap; -` +`; export const Card = styled.section` max-width: 230px; margin: 1%; @@ -15,29 +15,29 @@ export const Card = styled.section` border-radius: 5px; padding: 1.3rem; box-shadow: 1px 2px 5px #d1d1d1; -` +`; export const ImgCardProduct = styled.img` max-width: 100%; max-height: 100%; -` +`; export const TitleCardProduct = styled.h2` padding: 1.5rem 1.2rem; -` +`; export const DescCardProduct = styled.p` padding: 0 1.3rem; color: grey; -` +`; export const PriceCardProduct = styled.h4` padding: 1.3rem 1.2rem; font-size: 2rem; -` +`; /** Closing Card Product */ /** Button Payment */ export const Payment = styled.section` - max-width: 250px; -` + max-width: 250px; +`; export const Button = styled.button` width: 100%; background: black; @@ -49,9 +49,10 @@ export const Button = styled.button` text-decoration: none; text-align: center; padding: 1rem 0; - transition: .2s linear; + transition: 0.2s linear; + cursor: pointer; &:hover { background: #058cfa; } -` -/** Closing Payment */ \ No newline at end of file +`; +/** Closing Payment */ diff --git a/src/components/Layout/index.jsx b/src/components/Layout/index.jsx index 6a9384e..5308f70 100644 --- a/src/components/Layout/index.jsx +++ b/src/components/Layout/index.jsx @@ -1,31 +1,34 @@ -import React from 'react' -import { Link } from 'react-router-dom' -import * as S from './styles' +import React from 'react'; +import { NavLink } from 'react-router-dom'; +import { useSelector } from 'react-redux'; +import * as S from './styles'; const Layout = ({ children }) => { + const length = useSelector((state) => state.cart.length); + return ( - - Shoe Store - + + Product Store + - + - + About - + - + - + Register Product - + @@ -33,12 +36,14 @@ const Layout = ({ children }) => { Logout - Cart + + {length} + - { children } + {children} - ) -} + ); +}; -export default Layout \ No newline at end of file +export default Layout; diff --git a/src/components/Layout/styles.js b/src/components/Layout/styles.js index 9fe2503..570bd90 100644 --- a/src/components/Layout/styles.js +++ b/src/components/Layout/styles.js @@ -1,41 +1,43 @@ -import styled from 'styled-components' +import styled from 'styled-components'; export const BgContainer = styled.section` max-width: 1200px; min-height: 100%; position: relative; margin: 0 auto; -` +`; /** Header */ export const SectionLeft = styled.section` - display: flex; - width: 100%; -` + display: flex; + width: 100%; +`; export const SectionRight = styled.section` display: flex; - margin-right: 10px; + justify-content: center; + align-items: center; align-self: center; -` + margin-right: 10px; +`; export const BgHeader = styled.section` display: flex; justify-content: space-between; max-width: 1200px; - background: #058cfa; + background: black; border-radius: 0 0 10px 10px; -` +`; export const Title = styled.h1` color: white; font-size: 1.5rem; padding: 1.2rem 1rem; text-decoration: none; -` +`; export const Nav = styled.nav` margin-left: 5%; -` +`; export const Ul = styled.ul` - display: flex; -` + display: flex; +`; export const A = styled.a` text-decoration: none; height: 100%; @@ -44,12 +46,20 @@ export const A = styled.a` &:hover { background: #0474cf; } -` -export const Li = styled.li`` +`; +export const Li = styled.li``; -export const Cart = styled.section` - padding: 0 1rem; -` -export const Logout = styled.section`` +export const Logout = styled.section` + color: white; + font-weight: bold; + margin-right: 10px; +`; +export const Cart = styled.section` + padding: 0.5rem; + color: black; + margin-right: 10px; + font-weight: bold; + background: white; +`; /** Closing Header */ diff --git a/src/components/Message/index.jsx b/src/components/Message/index.jsx index a011567..46db2d9 100644 --- a/src/components/Message/index.jsx +++ b/src/components/Message/index.jsx @@ -1,22 +1,11 @@ -import React from 'react' -import * as S from './styles' -import { useSelector } from 'react-redux' +import React from 'react'; +import { useSelector } from 'react-redux'; +import * as S from './styles'; const Message = () => { - - const isShow = useSelector(state => state.message.showMessage) + const isShow = useSelector((state) => state.message.showMessage); - return ( - <> - { - isShow && ( - - Cadastro com Sucesso! - - ) - } - - ) -} + return <>{isShow && Cadastro com Sucesso!}; +}; -export default Message \ No newline at end of file +export default Message; diff --git a/src/pages/Cart/index.jsx b/src/pages/Cart/index.jsx index 4be0cc9..0a1578c 100644 --- a/src/pages/Cart/index.jsx +++ b/src/pages/Cart/index.jsx @@ -1,7 +1,47 @@ -import React from 'react' +import React from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { removeItem } from '../../store/cart'; + +import Layout from '../../components/Layout'; +import * as S from './styles'; const Cart = () => { - return

Hello Cart

-} + const cart = useSelector((state) => state.cart); + const dispatch = useDispatch(); + + const removeItemCart = (id) => { + dispatch(removeItem(id)); + }; + + return ( + + + {cart.length === 0 ? ( + No Product in Cart + ) : ( + <> + {cart.map((item, index) => ( + + + {item.name} + + + {item.name} + {item.description} + R$ {item.price} + Check-out + removeItemCart(item._id)}> + {' '} + Remove from cart{' '} + + + + ))} + + )} + + + ); +}; -export default Cart \ No newline at end of file +export default Cart; diff --git a/src/pages/Cart/styles.js b/src/pages/Cart/styles.js index e69de29..760b19f 100644 --- a/src/pages/Cart/styles.js +++ b/src/pages/Cart/styles.js @@ -0,0 +1,63 @@ +import styled from 'styled-components'; + +export const NoProductCart = styled.section` + margin: 20px auto; + padding: 1rem; + font-weight: bold; + color: grey; +`; + +export const BgSectionCart = styled.section` + max-width: 1200px; + margin: 0 auto; + margin-top: 2rem; + margin-bottom: 2rem; + display: flex; + flex-direction: column; + border: 1px solid grey; +`; + +export const CardCartImg = styled.section` + img { + width: 500px; + height: 500px; + } +`; + +export const CardCartInfoContainer = styled.section` + display: flex; + margin: 0 auto; +`; + +export const CardCartInfo = styled.section` + margin: 150px auto; +`; +export const CardInfoTitle = styled.h1` + text-align: center; + padding: 0.5rem 1rem; +`; +export const CardInfoDesc = styled.p` + text-align: center; + padding: 0.5rem 1rem; +`; +export const CardInfoPrice = styled.h3` + text-align: center; + padding: 0.5rem 1rem; +`; +export const CardInfoButton = styled.button` + margin: 10px auto; + background: black; + color: white; + border: none; + font-size: 1rem; + font-weight: bold; + display: block; + text-decoration: none; + text-align: center; + padding: 1rem; + transition: 0.2s linear; + cursor: pointer; + &:hover { + background: #058cfa; + } +`; diff --git a/src/pages/RegisterProduct/index.jsx b/src/pages/RegisterProduct/index.jsx index f806b9b..71fbeed 100644 --- a/src/pages/RegisterProduct/index.jsx +++ b/src/pages/RegisterProduct/index.jsx @@ -1,57 +1,84 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import Layout from "../../components/Layout" -import * as S from './styles' -import { addCard } from '../../store/actions' -import Message from '../../components/Message' -import { showMessage, hideMessage } from "../../store/actions" +import React, { useState } from 'react'; +import { useDispatch } from 'react-redux'; +import * as S from './styles'; +import Layout from '../../components/Layout'; +import Message from '../../components/Message'; +import { addCardFetch } from '../../store/fetchActions'; +import { showMessage, hideMessage } from '../../store/message'; const RegisterProduct = () => { - const [form, setForm] = useState({ - url: "", - name: "", - description: "", - price: "" - }) + url: '', + name: '', + description: '', + price: '', + }); - const dispatch = useDispatch() + const dispatch = useDispatch(); const fChange = (evt) => { setForm({ ...form, - [evt.target.name]: evt.target.value - }) - } + [evt.target.name]: evt.target.value, + }); + }; const onSubmit = (evt) => { evt.preventDefault(); - dispatch(addCard(form)) + + dispatch(addCardFetch(form)); + setForm({ - url: "", - name: "", - description: "", - price: "" - }) - dispatch(showMessage()) + url: '', + name: '', + description: '', + price: '', + }); + + dispatch(showMessage()); + setTimeout(() => { - dispatch(hideMessage()) - }, 2000) - } + dispatch(hideMessage()); + }, 2000); + }; return ( Register Product
- - - - - Add to cart + + + + + Add to Product
- ) -} + ); +}; -export default RegisterProduct \ No newline at end of file +export default RegisterProduct; diff --git a/src/routes.jsx b/src/routes.jsx index e20415f..b8bf575 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -1,9 +1,10 @@ -import React from 'react' -import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom' +import React from 'react'; +import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom'; -import App from './app' -import About from './pages/About' -import RegisterProduct from './pages/RegisterProduct' +import App from './app'; +import About from './pages/About'; +import RegisterProduct from './pages/RegisterProduct'; +import Cart from './pages/Cart'; const Routes = () => ( @@ -11,9 +12,10 @@ const Routes = () => ( + -) +); -export default Routes \ No newline at end of file +export default Routes; diff --git a/src/services/api.js b/src/services/api.js new file mode 100644 index 0000000..515303a --- /dev/null +++ b/src/services/api.js @@ -0,0 +1,5 @@ +import axios from 'axios'; + +export default axios.create({ + baseURL: 'http://localhost:4000/', +}); diff --git a/src/store/actions/index.js b/src/store/actions/index.js deleted file mode 100644 index 97f58de..0000000 --- a/src/store/actions/index.js +++ /dev/null @@ -1,12 +0,0 @@ -export const addCard = card => ({ - type: "ADD_CARD", - card -}) - -export const showMessage = () => ({ - type: "SHOW_MESSAGE" -}) - -export const hideMessage = () => ({ - type: "HIDE_MESSAGE" -}) \ No newline at end of file diff --git a/src/store/card/index.js b/src/store/card/index.js new file mode 100644 index 0000000..a7b2058 --- /dev/null +++ b/src/store/card/index.js @@ -0,0 +1,11 @@ +import { createAction, createReducer } from '@reduxjs/toolkit'; + +const INITIAL_STATE = []; + +export const addCard = createAction('ADD_CARD'); +export const addCards = createAction('ADD_CARDS'); + +export default createReducer(INITIAL_STATE, { + [addCard.type]: (state, action) => [...state, action.payload], + [addCards.type]: (state, action) => [...action.payload], +}); diff --git a/src/store/cart/index.js b/src/store/cart/index.js new file mode 100644 index 0000000..1b33293 --- /dev/null +++ b/src/store/cart/index.js @@ -0,0 +1,11 @@ +import { createAction, createReducer } from '@reduxjs/toolkit'; + +const INITIAL_STATE = []; + +export const addItem = createAction('ADD_ITEM'); +export const removeItem = createAction('REMOVE_ITEM'); + +export default createReducer(INITIAL_STATE, { + [addItem.type]: (state, action) => [...state, action.payload], + [removeItem.type]: (state, action) => state.filter((item) => item._id !== action.payload), +}); diff --git a/src/store/fetchActions/index.js b/src/store/fetchActions/index.js new file mode 100644 index 0000000..a9e6864 --- /dev/null +++ b/src/store/fetchActions/index.js @@ -0,0 +1,24 @@ +import api from '../../services/api'; +import { addCards, addCard } from '../card'; + +export const getAllCards = () => { + return (dispatch) => { + api + .get('products') + .then((res) => { + dispatch(addCards(res.data)); + }) + .catch(console.log); + }; +}; + +export const addCardFetch = (card) => { + return (dispatch) => { + api + .post('products', card) + .then((res) => { + dispatch(addCard(res.data)); + }) + .catch(console.log); + }; +}; diff --git a/src/store/index.js b/src/store/index.js index 3490e41..70639a9 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,6 +1,14 @@ -import { createStore } from 'redux'; -import reducers from './reducers'; +import { configureStore } from '@reduxjs/toolkit'; -const store = createStore(reducers); +import cardReducer from './card'; +import messageReducer from './message'; +import cartReducer from './cart'; -export default store; \ No newline at end of file +export default configureStore({ + reducer: { + card: cardReducer, + message: messageReducer, + cart: cartReducer, + }, +}); +// default with redux-thunk diff --git a/src/store/message/index.js b/src/store/message/index.js new file mode 100644 index 0000000..c03ee6c --- /dev/null +++ b/src/store/message/index.js @@ -0,0 +1,13 @@ +import { createAction, createReducer } from '@reduxjs/toolkit'; + +const INITIAL_STATE = { + showMessage: false, +}; + +export const showMessage = createAction('SHOW_MESSAGE'); +export const hideMessage = createAction('HIDE_MESSAGE'); + +export default createReducer(INITIAL_STATE, { + [showMessage.type]: (state) => [{ ...state, showMessage: true }], + [hideMessage.type]: (state) => [{ ...state, showMessage: false }], +}); diff --git a/src/store/reducers/card.js b/src/store/reducers/card.js deleted file mode 100644 index 0cae1d6..0000000 --- a/src/store/reducers/card.js +++ /dev/null @@ -1,16 +0,0 @@ -const INITIAL_STATE = [{ - url: "https://images-na.ssl-images-amazon.com/images/I/61Ez19M9BZL._AC_UY580_.jpg", - name: "A Name Product", - description: "Example for um description", - price: "R$ 29.90" -}] - -export default (state = INITIAL_STATE, action) => { - switch(action.type) { - case "ADD_CARD": return [ - ...state, - action.card - ] - default: return state; - } -} \ No newline at end of file diff --git a/src/store/reducers/index.js b/src/store/reducers/index.js deleted file mode 100644 index 1331112..0000000 --- a/src/store/reducers/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers } from 'redux'; -import cardReducer from './card' -import messageReducer from '../reducers/message' - -const reducers = combineReducers ({ - card: cardReducer, - message: messageReducer -}) - -export default reducers \ No newline at end of file diff --git a/src/store/reducers/message.js b/src/store/reducers/message.js deleted file mode 100644 index 6590ec6..0000000 --- a/src/store/reducers/message.js +++ /dev/null @@ -1,19 +0,0 @@ -const INITIAL_STATE = { - showMessage: false -}; - -export default (state = INITIAL_STATE, action) => { - switch(action.type) { - case "SHOW_MESSAGE": - return { - ...state, - showMessage: true - } - case "HIDE_MESSAGE": - return { - ...state, - showMessage: false - } - default: return state; - } -} \ No newline at end of file diff --git a/src/store/types/index.js b/src/store/types/index.js deleted file mode 100644 index b53a397..0000000 --- a/src/store/types/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export const Types = { - ADD_CARD: "ADD_CARD", - SHOW_MESSAGE: "SHOW_MESSAGE", - HIDE_MESSAGE: "HIDE_MESSAGE" -}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d156537..bf8f813 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1141,6 +1141,16 @@ resolved "https://registry.yarnpkg.com/@most/prelude/-/prelude-1.7.3.tgz#51db3f3ba3ed65431b6eea89ecb0a31826af640c" integrity sha512-qWWEnA22UP1lzFfKx75XMut6DUUXGRKe7qv2k+Bgs7ju8lwb5RjsZYyQZ+VcsYvHcIavHKzseLlBMLOe2CvUZw== +"@reduxjs/toolkit@^1.3.6": + version "1.3.6" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.3.6.tgz#306171fce2ab7423931736c34fa82190959dcd62" + integrity sha512-eNYURfoJa6mRNU5YtBVbmE5+nDoc4lpjZ181PBwRC6nIFYZdNR3GcoQ4uomFt8eHpXAUAdpCdxBlDsmwyXOt9Q== + dependencies: + immer "^6.0.1" + redux "^4.0.0" + redux-thunk "^2.3.0" + reselect "^4.0.0" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -5086,6 +5096,11 @@ ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== +immer@^6.0.1: + version "6.0.5" + resolved "https://registry.yarnpkg.com/immer/-/immer-6.0.5.tgz#77187d13b71c6cee40dde3b8e87a50a7a636d630" + integrity sha512-Q2wd90qrgFieIpLzAO2q9NLEdmyp/sr76Ml4Vm5peUKgyTa2CQa3ey8zuzwSKOlKH7grCeGBGUcLLVCVW1aguA== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -8305,13 +8320,6 @@ react-dom@16.13.1: prop-types "^15.6.2" scheduler "^0.19.1" -react-icons@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.10.0.tgz#6c217a2dde2e8fa8d293210023914b123f317297" - integrity sha512-WsQ5n1JToG9VixWilSo1bHv842Cj5aZqTGiS3Ud47myF6aK7S/IUY2+dHcBdmkQcCFRuHsJ9OMUI0kTDfjyZXQ== - dependencies: - camelcase "^5.0.0" - react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.9.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -8458,7 +8466,12 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" -redux@4.0.5: +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== + +redux@4.0.5, redux@^4.0.0: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== @@ -8636,6 +8649,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +reselect@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" + integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"