unknown 3 lat temu
rodzic
commit
0e007681cc

Plik diff jest za duży
+ 1 - 1
.eslintcache


+ 22 - 2
src/App.tsx

@@ -1,7 +1,10 @@
 import { lazy } from 'react';
 import { BrowserRouter, Switch, Route } from 'react-router-dom';
+import { connect } from 'react-redux';
+import { ToastContainer } from 'react-toastify';
 
 import s from './App.module.css';
+import { IAppProps, IAppState } from './typescript/app/interfaces';
 
 const Navigation = lazy(
   () =>
@@ -32,7 +35,8 @@ const Loader = lazy(
   () => import('./components/Loader/Loader' /* webpackChunkName: "Loader" */),
 );
 
-function App() {
+function App({ isLoading }: IAppProps) {
+  console.log(isLoading, 'isLoading');
   return (
     <div className={s.appWrapper}>
       <BrowserRouter>
@@ -49,9 +53,25 @@ function App() {
           </Route>
           <Route></Route>
         </Switch>
+        {isLoading && <Loader />}
+        <ToastContainer
+          position="top-right"
+          autoClose={3000}
+          hideProgressBar={false}
+          newestOnTop={false}
+          closeOnClick
+          rtl={false}
+          pauseOnFocusLoss
+          draggable
+          pauseOnHover
+        />
       </BrowserRouter>
     </div>
   );
 }
 
-export default App;
+const mapStateToProps = (state: IAppState) => ({
+  isLoading: state.isLoading.flag,
+});
+
+export default connect(mapStateToProps)(App);

+ 23 - 5
src/components/Goods/DetailGood/DetailGood.tsx

@@ -1,12 +1,15 @@
-import React, { useEffect, useState } from 'react';
+import { useEffect, useState } from 'react';
+import { connect } from 'react-redux';
 import { useRouteMatch } from 'react-router-dom';
 
 import s from './DetailGood.module.css';
 import { goodById, makeOrderById } from '../../../api-data';
 import { IGoodDetail } from '../../../typescript/goods/interfaces';
 import { TRouteMatchId } from '../../../typescript/goods/types';
+import { actionLoading } from '../../../redux/loading/action';
+import { TDispatchLoading } from '../../../typescript/goods/types';
 
-function DetailGood() {
+function DetailGood({ dispatchLoading }: TDispatchLoading) {
   const {
     params: { id },
   }: TRouteMatchId = useRouteMatch();
@@ -17,8 +20,19 @@ function DetailGood() {
   const [good, setGood] = useState<IGoodDetail | null>(null);
 
   useEffect(() => {
-    goodById<IGoodDetail>(id).then(data => setGood(data));
-  }, [id]);
+    async function getGood() {
+      try {
+        dispatchLoading(true);
+        const data = await goodById<IGoodDetail>(id);
+        setGood(data);
+      } catch (e) {
+        console.error(e);
+      } finally {
+        dispatchLoading(false);
+      }
+    }
+    getGood();
+  }, [dispatchLoading, id]);
 
   return good ? (
     <div className={s.detailGood_wrapper}>
@@ -46,4 +60,8 @@ function DetailGood() {
   ) : null;
 }
 
-export default DetailGood;
+const mapDispatchToProps = (dispatch: any) => ({
+  dispatchLoading: (value: boolean) => dispatch(actionLoading(value)),
+});
+
+export default connect(null, mapDispatchToProps)(DetailGood);

+ 2 - 3
src/components/Goods/Goods.tsx

@@ -1,7 +1,6 @@
 import { useEffect, useState } from 'react';
-import { Route } from 'react-router-dom';
+import { Route, useRouteMatch } from 'react-router-dom';
 import { connect } from 'react-redux';
-import { useRouteMatch } from 'react-router-dom';
 
 import s from './Goods.module.css';
 import { asyncGetGoods } from '../../redux/goods/operation';
@@ -15,7 +14,7 @@ const Goods = ({ goodsArr, getGoods }: IGoodsProps) => {
   const {
     params: { name: routName },
   }: TRouteMatchName = useRouteMatch();
-  console.log(routName);
+
   useEffect(() => {
     getGoods();
   }, [getGoods]);

+ 5 - 0
src/redux/categories/operation/index.ts

@@ -2,15 +2,20 @@ import {
   actionGetCategoriesSusses,
   actionGetCategoriesReject,
 } from '../action';
+import { actionLoading } from '../../loading/action';
 import { categoriesGQL } from '../../../api-data';
 import { ICategory } from '../../../typescript/categories/interfaces';
 
 const asyncGetCategories = () => async (dispatch: any) => {
   try {
+    dispatch(actionLoading(true));
+
     const data = await categoriesGQL<ICategory[]>();
     data && dispatch(actionGetCategoriesSusses(data));
   } catch (e) {
     dispatch(actionGetCategoriesReject());
+  } finally {
+    dispatch(actionLoading(false));
   }
 };
 

+ 4 - 0
src/redux/goods/operation/index.ts

@@ -1,13 +1,17 @@
 import { actionGetGoodsSusses, actionGetGoodsReject } from '../action';
+import { actionLoading } from '../../loading/action';
 import { goodsGQL } from '../../../api-data';
 import { IGood } from '../../../typescript/goods/interfaces';
 
 const asyncGetGoods = () => async (dispatch: any) => {
   try {
+    dispatch(actionLoading(true));
     const data = await goodsGQL<IGood[]>();
     data && dispatch(actionGetGoodsSusses(data));
   } catch (e) {
     dispatch(actionGetGoodsReject());
+  } finally {
+    dispatch(actionLoading(false));
   }
 };
 

+ 8 - 0
src/redux/loading/action/index.ts

@@ -0,0 +1,8 @@
+import { loadingActionType } from '../actionType';
+
+const actionLoading = (value: boolean) => ({
+  type: loadingActionType.isLoading,
+  payload: value,
+});
+
+export { actionLoading };

+ 3 - 0
src/redux/loading/actionType/index.ts

@@ -0,0 +1,3 @@
+export const loadingActionType = {
+  isLoading: 'loading/success',
+};

+ 14 - 0
src/redux/loading/reducer/index.ts

@@ -0,0 +1,14 @@
+import { loadingActionType } from '../actionType';
+import { ILoadingReducer } from '../../../typescript/reduxTs/loading/interfaces';
+
+export function LoadingReducer(
+  state = { flag: false },
+  { type, payload }: ILoadingReducer,
+) {
+  switch (type) {
+    case loadingActionType.isLoading:
+      return { flag: payload };
+    default:
+      return state;
+  }
+}

+ 2 - 0
src/redux/rootReducer/index.js

@@ -1,8 +1,10 @@
 import { combineReducers } from 'redux';
 import { categoriesReducer } from '../categories/reducer';
 import { goodsReducer } from '../goods/reducer';
+import { LoadingReducer } from '../loading/reducer';
 
 export const rootReducer = combineReducers({
   categories: categoriesReducer,
   goods: goodsReducer,
+  isLoading: LoadingReducer,
 });

+ 9 - 0
src/typescript/app/interfaces.ts

@@ -0,0 +1,9 @@
+export interface IAppState {
+  isLoading: {
+    flag: boolean;
+  };
+}
+
+export interface IAppProps {
+  isLoading: boolean;
+}

+ 4 - 0
src/typescript/goods/types.ts

@@ -9,3 +9,7 @@ export type TRouteMatchName = {
     name: string;
   };
 };
+
+export type TDispatchLoading = {
+  dispatchLoading: (value: boolean) => any;
+};

+ 1 - 1
src/typescript/reduxTs/categories/interfaces.ts

@@ -2,6 +2,6 @@ import { ICategory } from '../../categories/interfaces';
 import { ETypes } from './enum';
 
 export interface ICategoriesReducer {
-  type: ETypes;
+  type: ETypes.success | ETypes.reject;
   payload: ICategory[];
 }

+ 1 - 1
src/typescript/reduxTs/goods/interfaces.ts

@@ -2,6 +2,6 @@ import { IGood } from '../../goods/interfaces';
 import { ETypes } from './enum';
 
 export interface IGoodsReducer {
-  type: ETypes;
+  type: ETypes.reject | ETypes.success;
   payload: IGood[];
 }

+ 3 - 0
src/typescript/reduxTs/loading/enum.ts

@@ -0,0 +1,3 @@
+export enum ETypes {
+  isLoading = 'loading/success',
+}

+ 7 - 0
src/typescript/reduxTs/loading/interfaces.ts

@@ -0,0 +1,7 @@
+import { ETypes } from './enum';
+import { TPayloadLoading } from './types';
+
+export interface ILoadingReducer {
+  type: ETypes.isLoading;
+  payload: TPayloadLoading;
+}

+ 3 - 0
src/typescript/reduxTs/loading/types.ts

@@ -0,0 +1,3 @@
+export type TPayloadLoading = {
+  payload: boolean;
+};