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.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
- )
-}
+ );
+};
-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"