Skip to content

Commit

Permalink
redux thunk added
Browse files Browse the repository at this point in the history
  • Loading branch information
Amir Amiri committed Mar 5, 2023
1 parent 2e5fb9a commit 717ce5d
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 40 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"react-scripts": "5.0.1",
"redux": "^4.2.1",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7",
"sass": "^1.55.0",
"styled-components": "^5.3.6",
Expand Down
8 changes: 8 additions & 0 deletions src/components/spinner/spinner.component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SpinnerContainer, SpinnerOverlay } from "./spinner.styles";

const Spinner = () =>
<SpinnerOverlay>
<SpinnerContainer />
</SpinnerOverlay>

export default Spinner;
30 changes: 30 additions & 0 deletions src/components/spinner/spinner.styles.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import styled from "styled-components";

export const SpinnerOverlay = styled.div`
height: 60vh;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
`;

export const SpinnerContainer = styled.div`
display: inline-block;
width: 50px;
height: 50px;
border: 3px solid rgba(195, 195, 195, 0.6);
border-radius: 50%;
border-top-color: #636767;
animation: spin 1s ease-in-out infinite;
-webkit-animation: spin 1s ease-in-out infinite;
@keyframes spin {
to {
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes spin {
to {
-webkit-transform: rotate(360deg);
}
}
`;
11 changes: 7 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import { store } from './store/store';
import { store, persistor } from './store/store';
import { PersistGate } from 'redux-persist/integration/react';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
<PersistGate loading={null} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>
</React.StrictMode>
);
Expand Down
10 changes: 7 additions & 3 deletions src/routes/categories-preview/categories-preview.component.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Fragment } from "react";
import { useSelector } from "react-redux";
import { categoriesMapSelector } from "../../store/category/category.selector";
import { categoriesMapSelector, selectCategoriesIsLoading } from "../../store/category/category.selector";
import CategoryPreview from "../../components/category-preview/category-preview.component";
import Spinner from "../../components/spinner/spinner.component";

const CategoriesPreview = () => {
const categoriesMap = useSelector(categoriesMapSelector);
const isLoading = useSelector(selectCategoriesIsLoading);

return (
<Fragment>

{
Object.keys(categoriesMap).map(title => {
isLoading ? (<Spinner />) :
(Object.keys(categoriesMap).map(title => {
const products = categoriesMap[title];
return <CategoryPreview key={title} title={title} products={products} />
})
}))
}

</Fragment>
Expand Down
17 changes: 11 additions & 6 deletions src/routes/category/category-component.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Fragment, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useSelector } from "react-redux";
import { categoriesMapSelector } from "../../store/category/category.selector";
import { categoriesMapSelector, selectCategoriesIsLoading } from "../../store/category/category.selector";
import ProductCard from '../../components/product-card/product-card.component';
import './category.styles.scss';
import Spinner from '../../components/spinner/spinner.component';

const Category = () => {
const { category } = useParams()
const isLoading = useSelector(selectCategoriesIsLoading);
const categoriesMap = useSelector(categoriesMapSelector);
const [products, setProducts] = useState(categoriesMap[category])
useEffect(() => {
Expand All @@ -18,11 +20,14 @@ const Category = () => {
<h2 className='category-title'>
{category}
</h2>
<div className='category-container'>
{products &&
products.map((product) => <ProductCard key={product.id} product={product} />)
}
</div>
{
isLoading ? (<Spinner />) : (<div className='category-container'>
{products &&
products.map((product) => <ProductCard key={product.id} product={product} />)
}
</div>)
}

</Fragment>

)
Expand Down
6 changes: 2 additions & 4 deletions src/routes/shop/shop.component.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useEffect } from 'react';
import { Routes, Route } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { GetCategoriesAndDocuments } from '../../utils/firebase/firebase.utils';
import { setCategories } from '../../store/category/category.action';
import { fetchCategoriesAsync } from '../../store/category/category.action';
import CategoriesPreview from '../categories-preview/categories-preview.component';
import Category from '../category/category-component';
import './shop.styles.scss';
Expand All @@ -12,8 +11,7 @@ const Shop = () => {

useEffect(() => {
const getCategoriesMap = async () => {
const categoriesArray = await GetCategoriesAndDocuments();
dispatch(setCategories(categoriesArray))
dispatch(fetchCategoriesAsync())
}

getCategoriesMap();
Expand Down
18 changes: 17 additions & 1 deletion src/store/category/category.action.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import { createAction } from "../../utils/reducer/reducer.utils"
import { CATEGORIES_ACTION_TYPE } from "./category.types"
import { GetCategoriesAndDocuments } from '../../utils/firebase/firebase.utils';

export const setCategories = (categories) => createAction(CATEGORIES_ACTION_TYPE.SET_CATEGORIES, categories)

export const setCategories = (categories) => createAction(CATEGORIES_ACTION_TYPE.SET_CATEGORIES, categories)
export const fetchCategoriesStart = () => createAction(CATEGORIES_ACTION_TYPE.FETCH_CATEGORIES_START)
export const fetchCategoriesSuccess = (categoriesArray) => createAction(CATEGORIES_ACTION_TYPE.FETCH_CATEGORIES_SUCCESS, categoriesArray)
export const fetchCategoriesFailed = (error) => createAction(CATEGORIES_ACTION_TYPE.FETCH_CATEGORIES_FAILED, error)


export const fetchCategoriesAsync = () => async (dispatch) => {
dispatch(fetchCategoriesStart())
try {
const categoriesArray = await GetCategoriesAndDocuments();
dispatch(fetchCategoriesSuccess(categoriesArray));
} catch (error) {
dispatch(fetchCategoriesFailed(error));
}

}
12 changes: 9 additions & 3 deletions src/store/category/category.reducer.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { CATEGORIES_ACTION_TYPE } from "./category.types";

const CATEGORIES_INITIAL_STATE = {
categories: []
categories: [],
isLoading: false,
error: null
}

export const categoryReducer = (state = CATEGORIES_INITIAL_STATE, action = {}) => {
const { type, payload } = action

switch (type) {
case CATEGORIES_ACTION_TYPE.SET_CATEGORIES:
return { ...state, categories: payload }
case CATEGORIES_ACTION_TYPE.FETCH_CATEGORIES_START:
return { ...state, isLoading: true }
case CATEGORIES_ACTION_TYPE.FETCH_CATEGORIES_SUCCESS:
return { ...state, categories: payload, isLoading: false }
case CATEGORIES_ACTION_TYPE.FETCH_CATEGORIES_FAILED:
return { ...state, error: payload, isLoading: false }
default:
return state;
}
Expand Down
5 changes: 5 additions & 0 deletions src/store/category/category.selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ export const categoriesMapSelector = createSelector(
acc[title.toLowerCase()] = items;
return acc;
}, {})
)

export const selectCategoriesIsLoading = createSelector(
[selectCategoryReducer],
(categoriesSlice) => categoriesSlice.isLoading
)
5 changes: 4 additions & 1 deletion src/store/category/category.types.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export const CATEGORIES_ACTION_TYPE = {
'SET_CATEGORIES': 'category/SET_CATEGORIES'
'FETCH_CATEGORIES_START': 'category/FETCH_CATEGORIES_START',
'FETCH_CATEGORIES_SUCCESS': 'category/FETCH_CATEGORIES_SUCCESS',
'FETCH_CATEGORIES_FAILED': 'category/FETCH_CATEGORIES_FAILED'

}
32 changes: 14 additions & 18 deletions src/store/store.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import { compose, createStore, applyMiddleware } from "redux";
import { persistStore, persistReducer } from "redux-persist";
import logger from "redux-logger";
import { rootReducer } from "./root-reducer";
import storage from "redux-persist/lib/storage";
import thunk from "redux-thunk";


const loggerMiddleware = (store) => (next) => (action) => {
console.log(store)

if (!action.type) {
return next(action);
}

console.log('type', action.type)
console.log('payload', action.payload)
console.log('currentState', store.getState())

next(action);
console.log('nextState', store.getState())

const persistConfig = {
key: 'root',
storage,
whitelist: ['cart']
}

const middleWares = [logger]
const persistedReducer = persistReducer(persistConfig, rootReducer);
const middleWares = [process.env.NODE_ENV === 'development' && logger, thunk].filter(Boolean)

const composeEnhancer = (process.env.NODE_ENV !== 'production' && window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
const composeEnhancers = composeEnhancer(applyMiddleware(...middleWares))

const composeEnhancers = compose(applyMiddleware(...middleWares))
export const store = createStore(persistedReducer, undefined, composeEnhancers)

export const store = createStore(rootReducer, undefined, composeEnhancers)
export const persistor = persistStore(store)
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8186,6 +8186,16 @@ redux-logger@^3.0.6:
dependencies:
deep-diff "^0.3.5"

redux-persist@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==

redux-thunk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"
integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==

redux@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
Expand Down

0 comments on commit 717ce5d

Please sign in to comment.