diff --git a/package.json b/package.json
index f00a292..b79e871 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0",
+ "redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"styled-components": "^5.2.3",
"web-vitals": "^0.2.4"
diff --git a/src/components/collections-overview/collections-overview.container.jsx b/src/components/collections-overview/collections-overview.container.jsx
new file mode 100644
index 0000000..7f28365
--- /dev/null
+++ b/src/components/collections-overview/collections-overview.container.jsx
@@ -0,0 +1,17 @@
+import { connect } from 'react-redux';
+import { compose } from 'redux';
+import { createStructuredSelector } from 'reselect';
+import { selectIsCollectionFetching } from '../../redux/shop/shop.selector';
+import WithSpinner from '../with-spinner/with-spinner.component';
+import CollectionOverview from './collections-overview.component';
+
+const mapStateToProps = createStructuredSelector({
+ isLoading: selectIsCollectionFetching
+})
+
+const CollectionOverviewContainer = compose(
+ connect(mapStateToProps),
+ WithSpinner
+)(CollectionOverview);
+
+export default CollectionOverviewContainer;
\ No newline at end of file
diff --git a/src/components/header/header.component.jsx b/src/components/header/header.component.jsx
index 3f4f642..dfe4b3b 100644
--- a/src/components/header/header.component.jsx
+++ b/src/components/header/header.component.jsx
@@ -20,10 +20,10 @@ const Header = ({currentUser, hidden}) => (
-
+
SHOP
-
+
CONTACT
{
diff --git a/src/pages/collection/collection.conatiner.jsx b/src/pages/collection/collection.conatiner.jsx
new file mode 100644
index 0000000..d3e7595
--- /dev/null
+++ b/src/pages/collection/collection.conatiner.jsx
@@ -0,0 +1,18 @@
+import { connect } from 'react-redux';
+import { compose } from 'redux';
+import { createStructuredSelector } from 'reselect';
+
+import { selectIsCollectionsLoaded } from '../../redux/shop/shop.selector';
+import WithSpinner from '../../components/with-spinner/with-spinner.component';
+import CollectionPage from '../collection/collection.component';
+
+const mapStateToProps = createStructuredSelector ({
+ isLoading: state=> !selectIsCollectionsLoaded(state)
+})
+
+const CollectionPageContainer = compose(
+ connect(mapStateToProps),
+ WithSpinner
+)(CollectionPage);
+
+export default CollectionPageContainer;
\ No newline at end of file
diff --git a/src/pages/shop/shop.component.jsx b/src/pages/shop/shop.component.jsx
index d19c949..4260313 100644
--- a/src/pages/shop/shop.component.jsx
+++ b/src/pages/shop/shop.component.jsx
@@ -2,50 +2,34 @@ import React from 'react';
import { Route } from 'react-router-dom';
import {connect} from 'react-redux';
-import CollectionOverview from '../../components/collections-overview/collections-overview.component';
-import CollectionPage from '../collection/collection.component';
+import CollectionOverviewContainer from '../../components/collections-overview/collections-overview.container';
+import CollectionPageContainer from '../collection/collection.conatiner';
-import {firestore, convertCollectionsSnapshotToMap} from '../../fireabase/firebase.utils';
-import { updateCollections } from '../../redux/shop/shop.actions';
-import WithSpinner from '../../components/with-spinner/with-spinner.component';
-const CollectionsOverviewWithSpinner = WithSpinner(CollectionOverview);
-const CollectionPageWithSpinner = WithSpinner(CollectionPage);
+import { fetchCollectionsStartAsync } from '../../redux/shop/shop.actions';
-class ShopPage extends React.Component {
- state = {
- loading: true
- }
- unsubscribeFromSnapshot = null;
+class ShopPage extends React.Component {
componentDidMount() {
- const {updateCollections} = this.props;
- const collectionRef = firestore.collection('collections');
-
- //this.unsubscribeFromSnapshot =
-
- collectionRef.get().then( snapshot=>{
- const collectionsMap = convertCollectionsSnapshotToMap(snapshot);
- updateCollections(collectionsMap);
- this.setState({loading:false});
- }
- );
+ const {fetchCollectionsStartAsync} = this.props;
+ fetchCollectionsStartAsync();
}
render() {
const { match } = this.props;
- const { loading } = this.state;
+
return(
- } />
- } />
+
+
);
}
}
+
const mapDispatchToProps = dispatch => ({
- updateCollections: collectionsMap => dispatch(updateCollections(collectionsMap))
+ fetchCollectionsStartAsync: () => dispatch(fetchCollectionsStartAsync())
})
export default connect(null, mapDispatchToProps)(ShopPage);
\ No newline at end of file
diff --git a/src/redux/shop/shop.actions.js b/src/redux/shop/shop.actions.js
index 878115b..737aa1b 100644
--- a/src/redux/shop/shop.actions.js
+++ b/src/redux/shop/shop.actions.js
@@ -1,6 +1,29 @@
import ShopActionTypes from './shop.type';
+import {firestore, convertCollectionsSnapshotToMap} from '../../fireabase/firebase.utils';
-export const updateCollections = collectionsMap => ({
- type: ShopActionTypes.UPDATE_COLLECTIONS,
- payload: collectionsMap
-});
\ No newline at end of file
+export const fetchCollectionsStart = () => ({
+ type: ShopActionTypes.FETCH_COLLECTIONS_START
+});
+
+export const fetchCollectionsSuccess = collectionMap => ({
+ type: ShopActionTypes.FETCH_COLLECTIONS_SUCCESS,
+ payload: collectionMap
+})
+export const fetchCollectionsFailure = errorMessage => ({
+ type: ShopActionTypes.FETCH_COLLECTIONS_FAILURE,
+ payload: errorMessage
+})
+
+export const fetchCollectionsStartAsync = () => {
+ return dispatch => {
+ const collectionRef = firestore.collection('collections');
+ dispatch(fetchCollectionsStart());
+
+ collectionRef.get().then(
+ snapshot=>{
+ const collectionsMap = convertCollectionsSnapshotToMap(snapshot);
+ dispatch(fetchCollectionsSuccess(collectionsMap));
+ }
+ ).catch(error=> dispatch(fetchCollectionsFailure(error)));
+ }
+}
\ No newline at end of file
diff --git a/src/redux/shop/shop.reducer.js b/src/redux/shop/shop.reducer.js
index 266d989..fbd8d79 100644
--- a/src/redux/shop/shop.reducer.js
+++ b/src/redux/shop/shop.reducer.js
@@ -1,17 +1,34 @@
import ShopActionTypes from './shop.type';
const INITIAL_STATE = {
- collections: null
+ collections: null,
+ isFetching: false,
+ errorMessage: undefined
}
export const shopReducer = (state=INITIAL_STATE, action) => {
switch(action.type){
- case ShopActionTypes.UPDATE_COLLECTIONS:
+ case ShopActionTypes.FETCH_COLLECTIONS_START:
return {
...state,
+ isFetching: true
+ };
+
+ case ShopActionTypes.FETCH_COLLECTIONS_SUCCESS:
+ return {
+ ...state,
+ isFetching: false,
collections: action.payload
}
+ case ShopActionTypes.FETCH_COLLECTIONS_FAILURE:
+ return {
+ ...state,
+ isFetching: false,
+ errorMessage: action.payload
+ }
default:
return state;
}
-};
\ No newline at end of file
+};
+
+export default shopReducer;
\ No newline at end of file
diff --git a/src/redux/shop/shop.selector.js b/src/redux/shop/shop.selector.js
index b4e00fa..9cedead 100644
--- a/src/redux/shop/shop.selector.js
+++ b/src/redux/shop/shop.selector.js
@@ -23,4 +23,14 @@ export const selectShopCollection = memoize((collectionUrlParam) =>
export const selectCollectionForPreview = createSelector(
[selectShopCollectionWMemoize],
collections=> collections ? Object.keys(collections).map(key=>collections[key]) : []
+)
+
+export const selectIsCollectionFetching = createSelector (
+ [selectShop],
+ shop => shop.isFetching
+)
+
+export const selectIsCollectionsLoaded = createSelector(
+ [selectShop],
+ shop => !! shop.collections
)
\ No newline at end of file
diff --git a/src/redux/shop/shop.type.js b/src/redux/shop/shop.type.js
index 47dee69..dbc59f5 100644
--- a/src/redux/shop/shop.type.js
+++ b/src/redux/shop/shop.type.js
@@ -1,5 +1,7 @@
const ShopActionTypes = {
- UPDATE_COLLECTIONS: 'UPDATE_COLLECTIONS'
+ FETCH_COLLECTIONS_START: 'FETCH_COLLECTIONS_START',
+ FETCH_COLLECTIONS_SUCCESS: 'FETCH_COLLECTIONS_SUCCESS',
+ FETCH_COLLECTIONS_FAILURE: 'FETCH_COLLECTIONS_FAILURE'
}
export default ShopActionTypes;
\ No newline at end of file
diff --git a/src/redux/store.js b/src/redux/store.js
index 4386144..bc6edfa 100644
--- a/src/redux/store.js
+++ b/src/redux/store.js
@@ -1,10 +1,11 @@
import {createStore, applyMiddleware} from 'redux';
import logger from 'redux-logger';
-import { persistStore } from 'redux-persist'
+import { persistStore } from 'redux-persist';
+import thunk from 'redux-thunk';
import rootReducer from './root-reducer';
-const middlewares = [];
+const middlewares = [thunk];
if(process.env.NODE_ENV==='development'){
middlewares.push(logger);
diff --git a/yarn.lock b/yarn.lock
index 383d41c..1490378 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10706,6 +10706,11 @@ redux-persist@^6.0.0:
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==
+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:
version "4.0.5"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"