Selaa lähdekoodia

+PromisesClear

ilya_shyian 1 vuosi sitten
vanhempi
commit
0a8ef945ac
65 muutettua tiedostoa jossa 450 lisäystä ja 500 poistoa
  1. 2 2
      src/App.js
  2. 2 3
      src/actions/actionCatByIdFull.js
  3. 16 7
      src/actions/actionCategoriesSearchPage.js
  4. 0 10
      src/actions/actionCategoriesSearchPageClear.js
  5. 17 11
      src/actions/actionCategoryPage.js
  6. 0 9
      src/actions/actionCategoryPageClear.js
  7. 9 4
      src/actions/actionCategoryUpdate.js
  8. 6 9
      src/actions/actionCategoryUpsert.js
  9. 16 21
      src/actions/actionCatsFind.js
  10. 2 3
      src/actions/actionGoodPage.js
  11. 9 4
      src/actions/actionGoodUpdate.js
  12. 6 9
      src/actions/actionGoodUpsert.js
  13. 2 2
      src/actions/actionGoodsPage.js
  14. 0 6
      src/actions/actionGoodsSearchPageClear.js
  15. 13 7
      src/actions/actionLogin.js
  16. 8 5
      src/actions/actionLogout.js
  17. 18 11
      src/actions/actionOrderPage.js
  18. 0 10
      src/actions/actionOrderPageClear.js
  19. 16 21
      src/actions/actionOrdersFind.js
  20. 16 9
      src/actions/actionOrdersPage.js
  21. 0 6
      src/actions/actionOrdersPageClear.js
  22. 17 8
      src/actions/actionOrdersSearchPage.js
  23. 0 6
      src/actions/actionOrdersSearchPageClear.js
  24. 9 0
      src/actions/actionPromisesClear.js
  25. 11 5
      src/actions/actionRegister.js
  26. 12 7
      src/actions/actionUpdateAvatar.js
  27. 10 7
      src/actions/actionUploadFiles.js
  28. 18 10
      src/actions/actionUserPage.js
  29. 0 8
      src/actions/actionUserPageClear.js
  30. 11 7
      src/actions/actionUserUpdate.js
  31. 8 10
      src/actions/actionUserUpsert.js
  32. 16 21
      src/actions/actionUsersAll.js
  33. 19 24
      src/actions/actionUsersFind.js
  34. 13 7
      src/actions/actionUsersPage.js
  35. 0 6
      src/actions/actionUsersPageClear.js
  36. 13 7
      src/actions/actionUsersSearchPage.js
  37. 0 6
      src/actions/actionUsersSearchPageClear.js
  38. 6 5
      src/components/CartPage/CartItem.js
  39. 3 3
      src/components/CartPage/index.js
  40. 1 1
      src/components/GoodsPage/index.js
  41. 0 1
      src/components/LayoutPage/GoodsSearchPageContainer.js
  42. 0 1
      src/components/LayoutPage/index.js
  43. 8 5
      src/components/Root/index.js
  44. 3 7
      src/components/admin/AdminCategoryPage/CategoryForm.js
  45. 2 5
      src/components/admin/AdminGoodPage/GoodForm.js
  46. 11 21
      src/components/admin/AdminLayoutPage/AdminCategoryLayout/AdminCategoriesPageContainer.js
  47. 12 23
      src/components/admin/AdminLayoutPage/AdminCategoryLayout/AdminCategoriesSearchPageContainer.js
  48. 1 2
      src/components/admin/AdminLayoutPage/AdminCategoryLayout/AdminCategoryPageContainer.js
  49. 1 2
      src/components/admin/AdminLayoutPage/AdminGoodLayout/AdminGoodsSearchPageContainer.js
  50. 1 2
      src/components/admin/AdminLayoutPage/AdminOrderLayout/AdminOrderPageContainer.js
  51. 1 2
      src/components/admin/AdminLayoutPage/AdminOrderLayout/AdminOrdersPageContainer.js
  52. 3 3
      src/components/admin/AdminLayoutPage/AdminOrderLayout/AdminOrdersSearchPageContainer.js
  53. 1 2
      src/components/admin/AdminLayoutPage/AdminUserLayout/AdminUserPageContainer.js
  54. 1 2
      src/components/admin/AdminLayoutPage/AdminUserLayout/AdminUsersPageContainer.js
  55. 1 2
      src/components/admin/AdminLayoutPage/AdminUserLayout/AdminUsersSearchPageContainer.js
  56. 2 5
      src/components/admin/AdminOrderPage/OrderForm.js
  57. 5 7
      src/components/admin/AdminUserPage.js/UserForm.js
  58. 0 1
      src/components/admin/AdminUsersPage/AdminUserList.js
  59. 8 6
      src/components/common/DrawerCart/DrawerCart.js
  60. 7 6
      src/components/layout/Header/LogoutIcon/index.js
  61. 4 4
      src/components/layout/Header/index.js
  62. 10 0
      src/reducers/authReducer.js
  63. 15 71
      src/reducers/feedReducer.js
  64. 2 3
      src/reducers/index.js
  65. 26 0
      src/reducers/promiseReducer.js

+ 2 - 2
src/App.js

@@ -1,7 +1,7 @@
 import "./App.css";
 import { Box } from "@mui/material";
 import { BrowserRouter } from "react-router-dom";
-import { Root } from "./components/Root";
+import { CRoot, Root } from "./components/Root";
 import { Provider } from "react-redux";
 import { store } from "./reducers";
 import { UIContextProvider } from "./components/UIContext";
@@ -12,7 +12,7 @@ function App() {
             <BrowserRouter>
                 <UIContextProvider>
                     <Box className="App">
-                        <Root />
+                        <CRoot />
                     </Box>
                 </UIContextProvider>
             </BrowserRouter>

+ 2 - 3
src/actions/actionCatByIdFull.js

@@ -3,6 +3,7 @@ import { actionFeedClear, actionPromiseClear } from "../reducers";
 import { actionFeedCategoryGoods } from "../reducers/feedReducer";
 import { promiseWorker } from "../reducers/promiseReducer";
 import { actionCatById } from "./actionCatById";
+import { actionPromisesClear } from "./actionPromisesClear";
 
 export const actionCatByIdFull = ({ _id, orderBy }) => ({ type: "CAT_BY_ID_FULL", payload: { _id, orderBy } });
 
@@ -13,12 +14,10 @@ export function* catByIdFullWorker(action) {
 
     yield put(actionFeedClear());
     yield put(actionPromiseClear("feedCategoryGoods"));
-    console.log(category);
     yield put(actionFeedCategoryGoods({ category, orderBy, skip: 0 }));
 
     yield take("CAT_BY_ID_FULL_CLEAR");
 
-    yield put(actionPromiseClear("catById"));
+    yield put(actionPromisesClear(["catById", "feedCategoryGoods"]));
     yield put(actionFeedClear());
-    yield put(actionPromiseClear("feedCategoryGoods"));
 }

+ 16 - 7
src/actions/actionCategoriesSearchPage.js

@@ -1,9 +1,18 @@
+import { put, take } from "redux-saga/effects";
 import { actionFeedCatsFind, actionFeedClear, actionPromiseClear } from "../reducers";
 
-export const actionCategoriesSearchPage =
-    ({ orderBy = "_id", text = "" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedCatsFind"));
-        dispatch(actionFeedCatsFind({ text, orderBy, skip: 0 }));
-    };
+export const actionCategoriesSearchPage = ({ orderBy = "_id", text = "" } = {}) => ({
+    type: "CATEGORIES_SEARCH_PAGE",
+    payload: { orderBy, text },
+});
+
+export function* categoriesSearchPageWorker(action) {
+    const { orderBy = "_id", text = "" } = action.payload || {};
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedCatsFind"));
+    yield put(actionFeedCatsFind({ text, orderBy, skip: 0 }));
+
+    yield take("CATEGORIES_SEARCH_PAGE_CLEAR");
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedCatsFind"));
+}

+ 0 - 10
src/actions/actionCategoriesSearchPageClear.js

@@ -1,10 +0,0 @@
-import { actionFeedClear, actionPromiseClear } from "../reducers";
-
-export const actionCategoriesSearchPageClear = () => async (dispatch, getState) => {
-    dispatch(actionFeedClear());
-    dispatch(actionPromiseClear("feedCatsFind"));
-};
-
-const actions = {
-    actionCategoriesSearchPageClear: "actionCategoriesSearchPageClear",
-};

+ 17 - 11
src/actions/actionCategoryPage.js

@@ -1,17 +1,23 @@
+import { put, take } from "redux-saga/effects";
 import { actionPromiseClear } from "../reducers";
 import { actionCatAll } from "./actionCatAll";
 import { actionCatById } from "./actionCatById";
 import { actionGoodsAll } from "./actionGoodsAll";
+import { actionPromisesClear } from "./actionPromisesClear";
 
-export const actionCategoryPage =
-    ({ _id, promiseName = "catById" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionGoodsAll());
-        dispatch(actionCatAll());
+export const actionCategoryPage = ({ _id, promiseName = "catById" } = {}) => ({ type: "CATEGORY_PAGE", payload: { _id, promiseName } });
+export function* categoryPageWorker(action) {
+    const { _id, promiseName = "catById" } = action.payload || {};
+    yield put(actionGoodsAll());
+    yield put(actionCatAll());
 
-        if (_id) {
-            dispatch(actionCatById({ _id, promiseName }));
-        } else {
-            dispatch(actionPromiseClear(promiseName));
-        }
-    };
+    if (_id) {
+        yield put(actionCatById({ _id, promiseName }));
+    } else {
+        yield put(actionPromiseClear(promiseName));
+    }
+
+    yield take("CATEGORY_PAGE_CLEAR");
+
+    yield put(actionPromisesClear([promiseName, "catAll", "goodsAll"]));
+}

+ 0 - 9
src/actions/actionCategoryPageClear.js

@@ -1,9 +0,0 @@
-import { actionPromiseClear } from "../reducers";
-
-export const actionCategoryPageClear =
-    ({ promiseName = "catById" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionPromiseClear("goodsAll"));
-        dispatch(actionPromiseClear(promiseName));
-        dispatch(actionPromiseClear("catAll"));
-    };

+ 9 - 4
src/actions/actionCategoryUpdate.js

@@ -1,7 +1,12 @@
+import { call, put } from "redux-saga/effects";
+import { promiseWorker } from "../reducers/promiseReducer";
 import { actionCatAll } from "./actionCatAll";
 import { actionCategoryUpsert } from "./actionCategoryUpsert";
 
-export const actionCategoryUpdate = (category) => async (dispatch, getState) => {
-    await dispatch(actionCategoryUpsert(category));
-    await dispatch(actionCatAll());
-};
+export const actionCategoryUpdate = (category) => ({ type: "CATEGORY_UPDATE", payload: category });
+
+export function* categoryUpdateWorker(action) {
+    const category = action.payload || {};
+    yield call(promiseWorker, actionCategoryUpsert(category));
+    yield put(actionCatAll());
+}

+ 6 - 9
src/actions/actionCategoryUpsert.js

@@ -1,12 +1,11 @@
 import { gql } from "../helpers";
 import { actionPromise } from "../reducers";
 
-export const actionCategoryUpsert = (category) => async (dispatch) => {
-    dispatch(
-        actionPromise(
-            "categoryUpsert",
-            gql(
-                `mutation CatUpsert($category:CategoryInput!){
+export const actionCategoryUpsert = (category) =>
+    actionPromise(
+        "categoryUpsert",
+        gql(
+            `mutation CatUpsert($category:CategoryInput!){
                     CategoryUpsert(category:$category){
                         _id name
                         parent{
@@ -20,8 +19,6 @@ export const actionCategoryUpsert = (category) => async (dispatch) => {
                         }
                     }
                 }`,
-                { category }
-            )
+            { category }
         )
     );
-};

+ 16 - 21
src/actions/actionCatsFind.js

@@ -1,14 +1,11 @@
 import { gql } from "../helpers";
 import { actionPromise } from "../reducers";
 
-export const actionCatsFind =
-    ({ text = "", limit = 7, skip = 0, promiseName = "catsFind", orderBy = "_id" }) =>
-    async (dispatch, getState) => {
-        dispatch(
-            actionPromise(
-                promiseName,
-                gql(
-                    `query CatsFind($query:String){
+export const actionCatsFind = ({ text = "", limit = 7, skip = 0, promiseName = "catsFind", orderBy = "_id" }) =>
+    actionPromise(
+        promiseName,
+        gql(
+            `query CatsFind($query:String){
                         CategoryFind(query: $query){
                             _id name 
                             parent{
@@ -17,17 +14,15 @@ export const actionCatsFind =
 
                         }
                     }`,
+            {
+                query: JSON.stringify([
+                    { name__contains: text, _id__contains: text },
                     {
-                        query: JSON.stringify([
-                            { name__contains: text, _id__contains: text },
-                            {
-                                limit: !!limit ? limit : 5,
-                                skip,
-                                orderBy,
-                            },
-                        ]),
-                    }
-                )
-            )
-        );
-    };
+                        limit: !!limit ? limit : 5,
+                        skip,
+                        orderBy,
+                    },
+                ]),
+            }
+        )
+    );

+ 2 - 3
src/actions/actionGoodPage.js

@@ -2,6 +2,7 @@ import { put, take } from "redux-saga/effects";
 import { actionPromiseClear } from "../reducers";
 import { actionCatAll } from "./actionCatAll";
 import { actionGoodById } from "./actionGoodById";
+import { actionPromisesClear } from "./actionPromisesClear";
 
 export const actionGoodPage = ({ _id, promiseName } = {}) => ({
     type: "GOOD_PAGE",
@@ -20,7 +21,5 @@ export function* goodPageWorker(action) {
 
     yield take("GOOD_PAGE_CLEAR");
 
-    yield put(actionPromiseClear(promiseName));
-    yield put(actionPromiseClear("goodsAll"));
-    yield put(actionPromiseClear("goodUpsert"));
+    yield put(actionPromisesClear([promiseName, "goodUpsert", "goodsAll"]));
 }

+ 9 - 4
src/actions/actionGoodUpdate.js

@@ -1,7 +1,12 @@
+import { call, put } from "redux-saga/effects";
+import { promiseWorker } from "../reducers/promiseReducer";
 import { actionGoodsAll } from "./actionGoodsAll";
 import { actionGoodUpsert } from "./actionGoodUpsert";
 
-export const actionGoodUpdate = (good) => async (dispatch, getState) => {
-    await dispatch(actionGoodUpsert(good));
-    await dispatch(actionGoodsAll());
-};
+export const actionGoodUpdate = (good) => ({ type: "GOOD_UPDATE", payload: good });
+
+export function* goodUpdateWorker(action) {
+    const good = action.payload || {};
+    yield call(promiseWorker, actionGoodUpsert(good));
+    yield put(actionGoodsAll());
+}

+ 6 - 9
src/actions/actionGoodUpsert.js

@@ -1,18 +1,15 @@
 import { gql } from "../helpers";
 import { actionPromise } from "../reducers";
 
-export const actionGoodUpsert = (good) => async (dispatch) => {
-    dispatch(
-        actionPromise(
-            "goodUpsert",
-            gql(
-                `mutation GoodUpsert($good:GoodInput!){
+export const actionGoodUpsert = (good) =>
+    actionPromise(
+        "goodUpsert",
+        gql(
+            `mutation GoodUpsert($good:GoodInput!){
                     GoodUpsert(good:$good){
                         _id name
                     }
                   }`,
-                { good }
-            )
+            { good }
         )
     );
-};

+ 2 - 2
src/actions/actionGoodsPage.js

@@ -1,5 +1,6 @@
 import { put, take } from "redux-saga/effects";
 import { actionFeedClear, actionFeedGoods, actionPromiseClear } from "../reducers";
+import { actionPromisesClear } from "./actionPromisesClear";
 
 export const actionGoodsPage = ({ orderBy }) => ({ type: "GOODS_PAGE", payload: { orderBy } });
 export function* goodsPageWorker(action) {
@@ -11,6 +12,5 @@ export function* goodsPageWorker(action) {
     yield take("GOODS_PAGE_CLEAR");
 
     yield put(actionFeedClear());
-    yield put(actionPromiseClear("feedGoodsAll"));
-    yield put(actionPromiseClear("goodUpsert"));
+    yield put(actionPromisesClear(["goodUpsert", "feedGoodsAll"]));
 }

+ 0 - 6
src/actions/actionGoodsSearchPageClear.js

@@ -1,6 +0,0 @@
-import { actionFeedClear, actionPromiseClear } from "../reducers";
-
-export const actionGoodsSearchPageClear = () => async (dispatch, getState) => {
-    dispatch(actionFeedClear());
-    dispatch(actionPromiseClear("feedGoodsFind"));
-};

+ 13 - 7
src/actions/actionLogin.js

@@ -3,10 +3,15 @@ import { gql } from "../helpers";
 import { actionAuthLogin } from "../reducers";
 import { actionAboutMe } from "./actionAboutMe";
 import { actionLogout } from "./actionLogout";
+import { promiseWorker } from "../reducers/promiseReducer";
+import { call, put } from "redux-saga/effects";
 
-export const actionLogin = (username, password) => async (dispatch, getState) => {
-    await dispatch(actionLogout());
-    const token = await dispatch(
+export const actionLogin = (username, password) => ({ type: "LOGIN", payload: { username, password } });
+export function* loginWorker(action) {
+    const { username, password } = action.payload || {};
+    yield call(promiseWorker, actionLogout());
+    const token = yield call(
+        promiseWorker,
         actionPromise(
             "login",
             gql(
@@ -19,11 +24,12 @@ export const actionLogin = (username, password) => async (dispatch, getState) =>
             )
         )
     );
+
     if (typeof token === "string") {
-        await dispatch(actionAuthLogin(token));
+        yield put(actionAuthLogin(token));
     } else {
-        await dispatch(actionAuthLogin(token.token));
+        yield put(actionAuthLogin(token.token));
     }
 
-    await dispatch(actionAboutMe());
-};
+    yield put(actionAboutMe());
+}

+ 8 - 5
src/actions/actionLogout.js

@@ -1,8 +1,11 @@
+import { put } from "redux-saga/effects";
 import { actionCartClear, actionPromiseClear } from "../reducers";
 import { actionAuthLogout } from "../reducers";
 
-export const actionLogout = () => async (dispatch) => {
-    dispatch(actionCartClear());
-    dispatch(actionAuthLogout());
-    dispatch(actionPromiseClear("aboutMe"));
-};
+export const actionLogout = () => ({ type: "LOGOUT" });
+
+export function* logoutWorker() {
+    yield put(actionCartClear());
+    yield put(actionAuthLogout());
+    yield put(actionPromiseClear("aboutMe"));
+}

+ 18 - 11
src/actions/actionOrderPage.js

@@ -1,17 +1,24 @@
+import { put, take } from "redux-saga/effects";
 import { actionPromiseClear } from "../reducers";
 import { actionGoodsAll } from "./actionGoodsAll";
 import { actionOrderById } from "./actionOrderById";
+import { actionPromisesClear } from "./actionPromisesClear";
 import { actionUsersAll } from "./actionUsersAll";
 
-export const actionOrderPage =
-    ({ _id, promiseName = "orderById" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionUsersAll());
-        dispatch(actionGoodsAll());
+export const actionOrderPage = ({ _id, promiseName = "orderById" } = {}) => ({ type: "ORDER_PAGE", payload: { _id, promiseName } });
 
-        if (_id) {
-            dispatch(actionOrderById({ _id, promiseName }));
-        } else {
-            dispatch(actionPromiseClear(promiseName));
-        }
-    };
+export function* orderPageWorker(action) {
+    const { _id, promiseName = "orderById" } = action.payload || {};
+    yield put(actionUsersAll());
+    yield put(actionGoodsAll());
+
+    if (_id) {
+        yield put(actionOrderById({ _id, promiseName }));
+    } else {
+        yield put(actionPromiseClear(promiseName));
+    }
+
+    yield take("ORDER_PAGE_CLEAR");
+
+    yield put(actionPromisesClear(["orderUpsert", "goodsAll", promiseName, "usersAll"]));
+}

+ 0 - 10
src/actions/actionOrderPageClear.js

@@ -1,10 +0,0 @@
-import { actionPromiseClear } from "../reducers";
-
-export const actionOrderPageClear =
-    ({ promiseName = "orderById" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionPromiseClear("usersAll"));
-        dispatch(actionPromiseClear("goodsAll"));
-        dispatch(actionPromiseClear(promiseName));
-        dispatch(actionPromiseClear("orderUpsert"));
-    };

+ 16 - 21
src/actions/actionOrdersFind.js

@@ -1,14 +1,11 @@
 import { gql } from "../helpers";
 import { actionPromise } from "../reducers";
 
-export const actionOrdersFind =
-    ({ text = "", limit = 7, skip = 0, promiseName = "ordersFind", orderBy = "_id", status = "0" }) =>
-    async (dispatch, getState) => {
-        dispatch(
-            actionPromise(
-                promiseName,
-                gql(
-                    `query OrdersFind($query:String){
+export const actionOrdersFind = ({ text = "", limit = 7, skip = 0, promiseName = "ordersFind", orderBy = "_id", status = "0" }) =>
+    actionPromise(
+        promiseName,
+        gql(
+            `query OrdersFind($query:String){
                         OrderFind(query: $query){
                             _id status price 
                             owner{
@@ -16,17 +13,15 @@ export const actionOrdersFind =
                             }
                         }
                     }`,
+            {
+                query: JSON.stringify([
+                    { owner__username__contains: text, _id__contains: text, status__contains: text, status },
                     {
-                        query: JSON.stringify([
-                            { owner__username__contains: text, _id__contains: text, status__contains: text, status },
-                            {
-                                limit: !!limit ? limit : 5,
-                                skip,
-                                orderBy,
-                            },
-                        ]),
-                    }
-                )
-            )
-        );
-    };
+                        limit: !!limit ? limit : 5,
+                        skip,
+                        orderBy,
+                    },
+                ]),
+            }
+        )
+    );

+ 16 - 9
src/actions/actionOrdersPage.js

@@ -1,9 +1,16 @@
-import { actionFeedCats, actionFeedClear, actionFeedOrders, actionPromiseClear } from "../reducers";
-
-export const actionOrdersPage =
-    ({ orderBy = "_id", status = "0" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedOrdersAll"));
-        dispatch(actionFeedOrders({ skip: 0, orderBy, status }));
-    };
+import { put, take } from "redux-saga/effects";
+import { actionFeedClear, actionFeedOrders, actionPromiseClear } from "../reducers";
+
+export const actionOrdersPage = ({ orderBy = "_id", status = "0" } = {}) => ({ type: "ORDERS_PAGE", payload: { orderBy, status } });
+
+export function* ordersPageWorker(action) {
+    const { orderBy = "_id", status = "0" } = action.paylaod || {};
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedOrdersAll"));
+    yield put(actionFeedOrders({ skip: 0, orderBy, status }));
+
+    yield take("ORDERS_PAGE_CLEAR");
+
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedOrdersAll"));
+}

+ 0 - 6
src/actions/actionOrdersPageClear.js

@@ -1,6 +0,0 @@
-import { actionFeedClear, actionPromiseClear } from "../reducers";
-
-export const actionOrdersPageClear = () => async (dispatch, getState) => {
-    dispatch(actionFeedClear());
-    dispatch(actionPromiseClear("feedOrdersAll"));
-};

+ 17 - 8
src/actions/actionOrdersSearchPage.js

@@ -1,9 +1,18 @@
-import { actionFeedCats, actionFeedCatsFind, actionFeedClear, actionFeedOrdersFind, actionPromiseClear } from "../reducers";
+import { put, take } from "redux-saga/effects";
+import { actionFeedClear, actionFeedOrdersFind, actionPromiseClear } from "../reducers";
 
-export const actionOrdersSearchPage =
-    ({ orderBy = "_id", text, status } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedOrdersFind"));
-        dispatch(actionFeedOrdersFind({ text, orderBy, skip: 0, status }));
-    };
+export const actionOrdersSearchPage = ({ orderBy = "_id", text, status } = {}) => ({
+    type: "ORDERS_SEARCH_PAGE",
+    payload: { orderBy, text, status },
+});
+export function* ordersSearchPageWorker(action) {
+    const { orderBy = "_id", text, status } = action.payload || {};
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedOrdersFind"));
+    yield put(actionFeedOrdersFind({ text, orderBy, skip: 0, status }));
+
+    yield take("ORDERS_SEARCH_PAGE_CLEAR");
+
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedOrdersFind"));
+}

+ 0 - 6
src/actions/actionOrdersSearchPageClear.js

@@ -1,6 +0,0 @@
-import { actionFeedClear, actionPromiseClear } from "../reducers";
-
-export const actionOrdersSearchPageClear = () => async (dispatch, getState) => {
-    dispatch(actionFeedClear());
-    dispatch(actionPromiseClear("feedOrdersFind"));
-};

+ 9 - 0
src/actions/actionPromisesClear.js

@@ -0,0 +1,9 @@
+import { all, put } from "redux-saga/effects";
+import { actionPromiseClear } from "../reducers";
+
+export const actionPromisesClear = ({ promises = [] } = {}) => ({ type: "PROMISES_CLEAR", payload: promises });
+
+export function* promisesClearWorker(action) {
+    const promises = action.payload || [];
+    yield all(promises.map((promise) => put(actionPromiseClear(promise))));
+}

+ 11 - 5
src/actions/actionRegister.js

@@ -1,9 +1,15 @@
+import { call, put, select } from "redux-saga/effects";
 import { gql } from "../helpers";
 import { actionPromise } from "../reducers";
+import { promiseWorker } from "../reducers/promiseReducer";
 import { actionLogin } from "./actionLogin";
 
-export const actionRegister = (username, password) => async (dispatch, getState) => {
-    await dispatch(
+export const actionRegister = (username, password) => ({ type: "REGISTER", payload: { username, password } });
+
+export function* registerWorker(action) {
+    const { username, password } = action.payload || {};
+    yield call(
+        promiseWorker,
         actionPromise(
             "register",
             gql(
@@ -21,8 +27,8 @@ export const actionRegister = (username, password) => async (dispatch, getState)
     );
     const {
         promise: { register },
-    } = getState();
+    } = yield select();
     if (register.status === "FULFILLED") {
-        dispatch(actionLogin(username, password));
+        yield put(actionLogin(username, password));
     }
-};
+}

+ 12 - 7
src/actions/actionUpdateAvatar.js

@@ -1,10 +1,15 @@
+import { call, put, select } from "redux-saga/effects";
 import { actionPromiseClear } from "../reducers";
+import { promiseWorker } from "../reducers/promiseReducer";
 import { actionAboutMe } from "./actionAboutMe";
 import { actionUploadFile } from "./actionUploadFile";
 import { actionUserUpsert } from "./actionUserUpsert";
 
-export const actionUpdateAvatar = (file) => async (dispatch, getState) => {
-    await dispatch(actionUploadFile(file));
+export const actionUpdateAvatar = (file) => ({ type: "UPDATE_AVATAR", payload: file });
+
+export function* updateAvatarWorker(action) {
+    const file = action.payload;
+    yield call(promiseWorker, actionUploadFile(file));
 
     const {
         promise: {
@@ -13,13 +18,13 @@ export const actionUpdateAvatar = (file) => async (dispatch, getState) => {
                 status,
             },
         },
-    } = getState();
+    } = yield select();
 
-    await dispatch(actionUserUpsert({ avatar: { _id } }));
+    yield call(promiseWorker, actionUserUpsert({ avatar: { _id } }));
 
     if (status === "FULFILLED") {
-        await dispatch(actionAboutMe());
+        yield put(actionAboutMe());
     }
 
-    await dispatch(actionPromiseClear("uploadFile"));
-};
+    yield put(actionPromiseClear("uploadFile"));
+}

+ 10 - 7
src/actions/actionUploadFiles.js

@@ -1,8 +1,11 @@
-import { actionUploadFile } from './actionUploadFile';
-import { actionPromise } from '../reducers';
+import { actionUploadFile } from "./actionUploadFile";
+import { actionPromise } from "../reducers";
+import { all, call, put } from "redux-saga/effects";
+import { promiseWorker } from "../reducers/promiseReducer";
 
-export const actionUploadFiles =
-    (files = []) =>
-    async (dispatch, getState) => {
-        dispatch(actionPromise('uploadFiles', Promise.all(files?.map((file) => dispatch(actionUploadFile(file))))));
-    };
+export const actionUploadFiles = (files = []) => ({ type: "UPLOAD_FILES", payload: files });
+
+export function* uploadFilesWorker(action) {
+    const files = action.payload || [];
+    yield call(promiseWorker, actionPromise("uploadFiles", yield all(files.map((file) => call(promiseWorker, actionUploadFile(file))))));
+}

+ 18 - 10
src/actions/actionUserPage.js

@@ -1,13 +1,21 @@
+import { put, take } from "redux-saga/effects";
 import { actionPromiseClear } from "../reducers";
 import { actionUserById } from "./actionUserById";
 
-export const actionUserPage =
-    ({ _id, promiseName = "userById" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionPromiseClear("uploadFile"));
-        if (_id) {
-            dispatch(actionUserById({ _id, promiseName }));
-        } else {
-            dispatch(actionPromiseClear(promiseName));
-        }
-    };
+export const actionUserPage = ({ _id, promiseName = "userById" } = {}) => ({ type: "USER_PAGE", payload: { _id, promiseName } });
+
+export function* userPageWorker(action) {
+    const { _id, promiseName = "userById" } = action.payload || {};
+    yield put(actionPromiseClear("uploadFile"));
+
+    if (_id) {
+        yield put(actionUserById({ _id, promiseName }));
+    } else {
+        yield put(actionPromiseClear(promiseName));
+    }
+
+    yield take("USER_PAGE_CLEAN");
+
+    yield put(actionPromiseClear(promiseName));
+    yield put(actionPromiseClear("uploadFile"));
+}

+ 0 - 8
src/actions/actionUserPageClear.js

@@ -1,8 +0,0 @@
-import { actionPromiseClear } from "../reducers";
-
-export const actionUserPageClear =
-    ({ promiseName = "userById" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionPromiseClear(promiseName));
-        dispatch(actionPromiseClear("uploadFile"));
-    };

+ 11 - 7
src/actions/actionUserUpdate.js

@@ -1,24 +1,28 @@
+import { call, put, select } from "redux-saga/effects";
 import { actionPromiseClear } from "../reducers";
+import { promiseWorker } from "../reducers/promiseReducer";
 import { actionAboutMe } from "./actionAboutMe";
-import { actionUploadFile } from "./actionUploadFile";
 import { actionUserUpsert } from "./actionUserUpsert";
 
-export const actionUserUpdate = (user) => async (dispatch, getState) => {
-    await dispatch(actionUserUpsert(user));
+export const actionUserUpdate = (user) => ({ type: "USER_UPDATE", payload: user });
 
+export function* userUpdateWorker(action) {
+    const user = action.payload || {};
     if (!user) {
         return;
     }
 
+    yield call(promiseWorker, actionUserUpsert(user));
+
     const {
         promise: {
             userUpsert: { status },
         },
-    } = getState();
+    } = yield select();
 
     if (status === "FULFILLED") {
-        await dispatch(actionAboutMe());
+        yield put(actionAboutMe());
     }
 
-    await dispatch(actionPromiseClear("userUpsert"));
-};
+    yield put(actionPromiseClear("userUpsert"));
+}

+ 8 - 10
src/actions/actionUserUpsert.js

@@ -1,24 +1,22 @@
 import { gql } from "../helpers";
 import { actionPromise } from "../reducers";
 
-export const actionUserUpsert = (user) => async (dispatch, getState) => {
+export const actionUserUpsert = (user) => {
     if (!user?.password?.length) {
         delete user.password;
     }
 
-    await dispatch(
-        actionPromise(
-            "userUpsert",
-            gql(
-                `mutation userUpsert($user:UserInput!){
+    return actionPromise(
+        "userUpsert",
+        gql(
+            `mutation userUpsert($user:UserInput!){
               UserUpsert(user:$user){
                   _id username 
               }
           }`,
-                {
-                    user,
-                }
-            )
+            {
+                user,
+            }
         )
     );
 };

+ 16 - 21
src/actions/actionUsersAll.js

@@ -1,14 +1,11 @@
 import { actionPromise } from "../reducers";
 import { gql } from "../helpers";
 
-export const actionUsersAll =
-    ({ limit = 0, skip = 0, promiseName = "adminUsersAll", orderBy = "_id" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(
-            actionPromise(
-                promiseName,
-                gql(
-                    `query UsersAll($query:String){
+export const actionUsersAll = ({ limit = 0, skip = 0, promiseName = "adminUsersAll", orderBy = "_id" } = {}) =>
+    actionPromise(
+        promiseName,
+        gql(
+            `query UsersAll($query:String){
                         UserFind(query: $query){
                             _id username is_active acl
                             avatar{
@@ -16,17 +13,15 @@ export const actionUsersAll =
                             }
                         }
                     }`,
+            {
+                query: JSON.stringify([
+                    {},
                     {
-                        query: JSON.stringify([
-                            {},
-                            {
-                                limit: !!limit ? limit : 100,
-                                skip: skip,
-                                orderBy,
-                            },
-                        ]),
-                    }
-                )
-            )
-        );
-    };
+                        limit: !!limit ? limit : 100,
+                        skip: skip,
+                        orderBy,
+                    },
+                ]),
+            }
+        )
+    );

+ 19 - 24
src/actions/actionUsersFind.js

@@ -1,14 +1,11 @@
 import { actionPromise } from "../reducers";
 import { gql } from "../helpers";
 
-export const actionUsersFind =
-    ({ text = "", limit = 0, skip = 0, promiseName = "adminUsersFind", orderBy = "_id" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(
-            actionPromise(
-                promiseName,
-                gql(
-                    `query UsersFind($query:String){
+export const actionUsersFind = ({ text = "", limit = 0, skip = 0, promiseName = "adminUsersFind", orderBy = "_id" } = {}) =>
+    actionPromise(
+        promiseName,
+        gql(
+            `query UsersFind($query:String){
                         UserFind(query: $query){
                             _id username acl is_active
                             avatar{
@@ -16,20 +13,18 @@ export const actionUsersFind =
                             }
                         }
                     }`,
+            {
+                query: JSON.stringify([
                     {
-                        query: JSON.stringify([
-                            {
-                                username__contains: text,
-                                _id__contains: text,
-                            },
-                            {
-                                limit: !!limit ? limit : 100,
-                                skip: skip,
-                                orderBy,
-                            },
-                        ]),
-                    }
-                )
-            )
-        );
-    };
+                        username__contains: text,
+                        _id__contains: text,
+                    },
+                    {
+                        limit: !!limit ? limit : 100,
+                        skip: skip,
+                        orderBy,
+                    },
+                ]),
+            }
+        )
+    );

+ 13 - 7
src/actions/actionUsersPage.js

@@ -1,9 +1,15 @@
+import { put, take } from "redux-saga/effects";
 import { actionFeedClear, actionFeedUsers, actionPromiseClear } from "../reducers";
 
-export const actionUsersPage =
-    ({ orderBy = "_id" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedUsersAll"));
-        dispatch(actionFeedUsers({ skip: 0, orderBy }));
-    };
+export const actionUsersPage = ({ orderBy = "_id" } = {}) => ({ type: "USERS_PAGE", payload: { orderBy } });
+
+export function* usersPageWorker(action) {
+    const { orderBy = "_id" } = action.payload || {};
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedUsersAll"));
+    yield put(actionFeedUsers({ skip: 0, orderBy }));
+    yield take("USERS_PAGE_CLEAN");
+
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedUsersAll"));
+}

+ 0 - 6
src/actions/actionUsersPageClear.js

@@ -1,6 +0,0 @@
-import { actionFeedClear, actionPromiseClear } from "../reducers";
-
-export const actionUsersPageClear = () => async (dispatch, getState) => {
-    dispatch(actionFeedClear());
-    dispatch(actionPromiseClear("feedUsersAll"));
-};

+ 13 - 7
src/actions/actionUsersSearchPage.js

@@ -1,9 +1,15 @@
+import { put, take } from "redux-saga/effects";
 import { actionFeedClear, actionFeedUsersFind, actionPromiseClear } from "../reducers";
 
-export const actionUsersSearchPage =
-    ({ orderBy = "_id", text = "" } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(actionFeedClear());
-        dispatch(actionPromiseClear("feedUsersFind"));
-        dispatch(actionFeedUsersFind({ skip: 0, orderBy, text }));
-    };
+export const actionUsersSearchPage = ({ orderBy = "_id", text = "" } = {}) => ({ type: "USERS_SEARCH_PAGE", payload: { orderBy, text } });
+
+export function* usersSearchPageWorker(action) {
+    const { orderBy = "_id", text = "" } = action.payload || {};
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedUsersFind"));
+    yield put(actionFeedUsersFind({ skip: 0, orderBy, text }));
+
+    yield take("USERS_SEARCH_PAGE_CLEAR");
+    yield put(actionFeedClear());
+    yield put(actionPromiseClear("feedUsersFind"));
+}

+ 0 - 6
src/actions/actionUsersSearchPageClear.js

@@ -1,6 +0,0 @@
-import { actionFeedClear, actionPromiseClear } from "../reducers";
-
-export const actionUsersSearchPageClear = () => async (dispatch, getState) => {
-    dispatch(actionFeedClear());
-    dispatch(actionPromiseClear("feedUsersFind"));
-};

+ 6 - 5
src/components/CartPage/CartItem.js

@@ -4,16 +4,15 @@ import { IoCloseOutline } from "react-icons/io5";
 import { AiOutlinePlus, AiOutlineMinus } from "react-icons/ai";
 import { actionCartChange } from "../../reducers";
 import { useEffect, useState } from "react";
-import { useDispatch } from "react-redux";
 import { backendURL, mediaURL } from "../../helpers";
 
-const { Typography, Stack, IconButton, TextField, ButtonGroup, Button, TableCell, TableRow, Input } = require("@mui/material");
+import { Typography, Stack, IconButton, TableCell, TableRow } from "@mui/material";
+import { connect } from "react-redux";
 
-export const CartItem = ({ order, onDeleteClick }) => {
+export const CartItem = ({ order, onDeleteClick, onChange }) => {
     const { good, count = 1 } = order || {};
     const { _id, images = [], name = "", price = 0, amount = 1 } = good;
 
-    const dispatch = useDispatch();
     const [countInput, setCountInput] = useState(count || 1);
 
     useEffect(() => {
@@ -21,7 +20,7 @@ export const CartItem = ({ order, onDeleteClick }) => {
     }, [count]);
 
     useEffect(() => {
-        dispatch(actionCartChange(good, +countInput));
+        onChange(good, +countInput);
     }, [countInput]);
 
     const handleChange = (count) => {
@@ -75,3 +74,5 @@ export const CartItem = ({ order, onDeleteClick }) => {
         </TableRow>
     );
 };
+
+export const CCartItem = connect(null, { onChange: (good, countInput) => actionCartChange(good, +countInput) })(CartItem);

+ 3 - 3
src/components/CartPage/index.js

@@ -1,12 +1,12 @@
 import { Box, Button, Stack, Table, TableBody, TableCell, TableRow, Typography } from "@mui/material";
 import { useFormik } from "formik";
 import { useContext, useEffect, useState } from "react";
-import { connect, useDispatch, useSelector } from "react-redux";
+import { connect, useSelector } from "react-redux";
 import { useNavigate } from "react-router-dom";
 import { actionOrderUpdate } from "../../actions/actionOrderUpdate";
 import { actionCartDelete } from "../../reducers";
 import { UIContext } from "../UIContext";
-import { CartItem } from "./CartItem";
+import { CCartItem } from "./CartItem";
 
 export const CartPage = ({ onConfirm, promiseStatus, serverErrors, onDeleteClick }) => {
     const cart = useSelector((state) => state.cart || {});
@@ -67,7 +67,7 @@ export const CartPage = ({ onConfirm, promiseStatus, serverErrors, onDeleteClick
                 <Table className="table">
                     <TableBody>
                         {Object.entries(cart).map(([_id, order]) => (
-                            <CartItem order={order} onDeleteClick={(good) => onDeleteClick(good)} key={_id} />
+                            <CCartItem order={order} onDeleteClick={(good) => onDeleteClick(good)} key={_id} />
                         ))}
 
                         <TableRow>

+ 1 - 1
src/components/GoodsPage/index.js

@@ -22,7 +22,7 @@ const GoodsPage = ({ category = {}, goods = [] }) => {
             <Stack>
                 <Box className="sortOptionsWrapper">
                     <SortOptions
-                        defaultOption={searchParams.get("orderBy", null)}
+                        defaultOption={searchParams.get("orderBy", "createdAt")}
                         onClick={(option) => {
                             searchParams.set("orderBy", option.value);
                             setSearchParams(searchParams);

+ 0 - 1
src/components/LayoutPage/GoodsSearchPageContainer.js

@@ -2,7 +2,6 @@ import { useEffect } from "react";
 import { connect } from "react-redux";
 import { useSearchParams } from "react-router-dom";
 import { actionGoodsSearchPage } from "../../actions/actionGoodsSearchPage";
-import { actionGoodsSearchPageClear } from "../../actions/actionGoodsSearchPageClear";
 import { actionFeedGoodsFind } from "../../reducers";
 import { InfScroll } from "../common/InfScroll";
 import { CGoodsPage } from "../GoodsPage";

+ 0 - 1
src/components/LayoutPage/index.js

@@ -7,7 +7,6 @@ import { actionGoodsPopular } from "../../actions/actionGoodsPopular";
 import { actionOrders } from "../../actions/actionOrders";
 import { AdminLayoutPage } from "../admin/AdminLayoutPage";
 import { CCartPage } from "../CartPage";
-import { GoodList } from "../common/GoodList";
 import { CProtectedRoute } from "../common/ProtectedRoute";
 import { CDashboardPage } from "../DashboardPage";
 import { GoodPage } from "../GoodPage";

+ 8 - 5
src/components/Root/index.js

@@ -1,18 +1,19 @@
 import { Navigate, Route, Routes } from "react-router-dom";
 
 import { Box } from "@mui/material";
-import styles from "react-responsive-carousel/lib/styles/carousel.min.css";
 import { actionPageStart } from "../../actions/actionPageStart";
-import { useDispatch } from "react-redux";
 
 import { AuthPage } from "../AuthPage";
 import { LayoutPage } from "../LayoutPage";
 import { CProtectedRoute } from "../common/ProtectedRoute";
 import { Error404 } from "../common/Error404";
+import { useEffect } from "react";
+import { connect } from "react-redux";
 
-const Root = () => {
-    const dispatch = useDispatch();
-    dispatch(actionPageStart());
+const Root = ({ onLoad }) => {
+    useEffect(() => {
+        onLoad();
+    }, []);
 
     return (
         <Box className="Root">
@@ -33,4 +34,6 @@ const Root = () => {
     );
 };
 
+export const CRoot = connect(null, { onLoad: () => actionPageStart() })(Root);
+
 export { Root };

+ 3 - 7
src/components/admin/AdminCategoryPage/CategoryForm.js

@@ -1,8 +1,7 @@
-import { connect, useDispatch } from "react-redux";
+import { connect } from "react-redux";
 import { useState, useEffect, useContext } from "react";
 import Select from "react-select";
 import { actionCategoryUpdate } from "../../../actions/actionCategoryUpdate";
-import { actionPromiseClear } from "../../../reducers";
 import { Box, Button, InputLabel, Stack, TextField } from "@mui/material";
 import { UIContext } from "../../UIContext";
 import { useFormik } from "formik";
@@ -10,6 +9,7 @@ import * as Yup from "yup";
 import { ConfirmModal } from "../../common/ConfirmModal";
 import { useNavigate } from "react-router-dom";
 import { actionCategoryDelete } from "../../../actions/actionCategoryDelete";
+import { actionPromisesClear } from "../../../actions/actionPromisesClear";
 
 const categorySchema = Yup.object().shape({
     name: Yup.string().required("Обов'язкове"),
@@ -36,7 +36,6 @@ const CategoryForm = ({
     const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
     const [promiseTimeOut, setPromiseTimeOut] = useState(null);
     const navigate = useNavigate();
-    const dispatch = useDispatch();
 
     const formik = useFormik({
         initialValues: {
@@ -113,9 +112,6 @@ const CategoryForm = ({
                 message: "Помилка",
             });
         }
-        return () => {
-            dispatch(actionPromiseClear("categoryDelete"));
-        };
     }, [deletePromiseStatus]);
 
     useEffect(() => {
@@ -229,7 +225,7 @@ export const CCategoryForm = connect(
     }),
     {
         onSave: (cat) => actionCategoryUpdate(cat),
-        onClose: () => actionPromiseClear("categoryUpsert"),
+        onClose: () => actionPromisesClear(["categoryUpsert", "categoryDelete"]),
         onDelete: (category) => actionCategoryDelete({ category }),
     }
 )(CategoryForm);

+ 2 - 5
src/components/admin/AdminGoodPage/GoodForm.js

@@ -1,4 +1,4 @@
-import { connect, useDispatch } from "react-redux";
+import { connect } from "react-redux";
 import { useState, useEffect, useContext } from "react";
 import { actionPromiseClear } from "../../../reducers";
 import Select from "react-select";
@@ -48,7 +48,6 @@ export const GoodForm = ({
     const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
     const [promiseTimeOut, setPromiseTimeOut] = useState(null);
     const navigate = useNavigate();
-    const dispatch = useDispatch();
 
     const formik = useFormik({
         initialValues: {
@@ -120,9 +119,7 @@ export const GoodForm = ({
                 message: "Помилка",
             });
         }
-        return () => {
-            
-        };
+        return () => {};
     }, [deletePromiseStatus]);
 
     useEffect(() => {

+ 11 - 21
src/components/admin/AdminLayoutPage/AdminCategoryLayout/AdminCategoriesPageContainer.js

@@ -1,13 +1,12 @@
 import { connect } from "react-redux";
 import { useEffect } from "react";
-import { useDispatch } from "react-redux";
 import { useSearchParams } from "react-router-dom";
 import { actionCategoriesPage } from "../../../../actions/actionCategoriesPage";
-import { actionFeedAdd, actionFeedCats } from "../../../../reducers";
+import { actionFeedCats } from "../../../../reducers";
 import { AdminCategoriesPage } from "../../AdminCategoriesPage";
+import { InfScroll } from "../../../common/InfScroll";
 
 const AdminCategoriesPageContainer = ({ feed, cats, promiseStatus, onLoad, onUnmount, onScroll }) => {
-    const dispatch = useDispatch();
     const [searchParams] = useSearchParams();
     const orderBy = searchParams.get("orderBy") || "_id";
 
@@ -18,24 +17,15 @@ const AdminCategoriesPageContainer = ({ feed, cats, promiseStatus, onLoad, onUnm
         };
     }, [orderBy]);
 
-    useEffect(() => {
-        window.onscroll = (e) => {
-            if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 200) {
-                if (promiseStatus !== "PENDING") {
-                    onScroll({ feed, orderBy });
-                }
-            }
-        };
-        return () => {
-            window.onscroll = null;
-        };
-    }, [feed, promiseStatus]);
-
-    useEffect(() => {
-        if (cats.length) dispatch(actionFeedAdd(cats));
-    }, [cats]);
-
-    return <AdminCategoriesPage orderBy={orderBy} />;
+    return (
+        <InfScroll
+            items={cats}
+            component={AdminCategoriesPage}
+            promiseStatus={promiseStatus}
+            onScroll={() => onScroll({ feed, orderBy })}
+            orderBy={orderBy}
+        />
+    );
 };
 
 export const CAdminCategoriesPageContainer = connect(

+ 12 - 23
src/components/admin/AdminLayoutPage/AdminCategoryLayout/AdminCategoriesSearchPageContainer.js

@@ -1,14 +1,12 @@
 import { connect } from "react-redux";
 import { useEffect } from "react";
-import { useDispatch } from "react-redux";
 import { useSearchParams } from "react-router-dom";
 import { actionCategoriesSearchPage } from "../../../../actions/actionCategoriesSearchPage";
-import { actionCategoriesSearchPageClear } from "../../../../actions/actionCategoriesSearchPageClear";
-import { actionFeedAdd, actionFeedCatsFind } from "../../../../reducers";
+import { actionFeedCatsFind } from "../../../../reducers";
 import { AdminCategoriesPage } from "../../AdminCategoriesPage";
+import { InfScroll } from "../../../common/InfScroll";
 
 const AdminCategoriesSearchPageContainer = ({ feed, cats, promiseStatus, onLoad, onUnmount, onScroll }) => {
-    const dispatch = useDispatch();
     const [searchParams] = useSearchParams();
     const orderBy = searchParams.get("orderBy") || "_id";
     const text = searchParams.get("text") || "";
@@ -20,24 +18,15 @@ const AdminCategoriesSearchPageContainer = ({ feed, cats, promiseStatus, onLoad,
         };
     }, [orderBy, text]);
 
-    useEffect(() => {
-        window.onscroll = (e) => {
-            if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 200) {
-                if (promiseStatus !== "PENDING") {
-                    onScroll({ feed, orderBy, text });
-                }
-            }
-        };
-        return () => {
-            window.onscroll = null;
-        };
-    }, [promiseStatus, feed, text]);
-
-    useEffect(() => {
-        if (cats?.length) dispatch(actionFeedAdd(cats));
-    }, [cats]);
-
-    return <AdminCategoriesPage orderBy={orderBy} />;
+    return (
+        <InfScroll
+            items={cats}
+            component={AdminCategoriesPage}
+            promiseStatus={promiseStatus}
+            onScroll={() => onScroll({ feed, orderBy, text })}
+            orderBy={orderBy}
+        />
+    );
 };
 
 export const CAdminCategoriesSearchPageContainer = connect(
@@ -47,7 +36,7 @@ export const CAdminCategoriesSearchPageContainer = connect(
         promiseStatus: state.promise?.feedCatsFind?.status || null,
     }),
     {
-        onUnmount: () => actionCategoriesSearchPageClear(),
+        onUnmount: () => ({ type: "CATEGORIES_SEARCH_PAGE_CLEAR" }),
         onLoad: ({ orderBy, text }) => actionCategoriesSearchPage({ orderBy, text }),
         onScroll: ({ feed, orderBy, text }) => actionFeedCatsFind({ text, skip: feed?.length || 0, orderBy }),
     }

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminCategoryLayout/AdminCategoryPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useParams } from "react-router-dom";
 import { actionCategoryPage } from "../../../../actions/actionCategoryPage";
-import { actionCategoryPageClear } from "../../../../actions/actionCategoryPageClear";
 import { CAdminCategoryPage } from "../../AdminCategoryPage";
 
 const AdminCategoryPageContainer = ({ onUnmount, onLoad }) => {
@@ -19,6 +18,6 @@ const AdminCategoryPageContainer = ({ onUnmount, onLoad }) => {
 };
 
 export const CAdminCategoryPageContainer = connect(null, {
-    onUnmount: () => actionCategoryPageClear({ promiseName: "adminCatById" }),
+    onUnmount: () => ({ type: "CATEGORY_PAGE_CLEAR" }),
     onLoad: (_id) => actionCategoryPage({ _id, promiseName: "adminCatById" }),
 })(AdminCategoryPageContainer);

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminGoodLayout/AdminGoodsSearchPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useSearchParams } from "react-router-dom";
 import { actionGoodsSearchPage } from "../../../../actions/actionGoodsSearchPage";
-import { actionGoodsSearchPageClear } from "../../../../actions/actionGoodsSearchPageClear";
 import { actionFeedGoodsFind } from "../../../../reducers";
 import { InfScroll } from "../../../common/InfScroll";
 import { AdminGoodsPage } from "../../AdminGoodsPage";
@@ -37,7 +36,7 @@ export const CAdminGoodsSearchPageContainer = connect(
         promiseStatus: state.promise?.feedGoodsFind?.status || null,
     }),
     {
-        onUnmount: () => actionGoodsSearchPageClear(),
+        onUnmount: () => ({ type: "GOODS_SEARCH_CLEAR" }),
         onLoad: ({ orderBy, text }) => actionGoodsSearchPage({ orderBy, text }),
         onScroll: ({ feed, orderBy, text }) => actionFeedGoodsFind({ text, skip: feed?.length || 0, orderBy }),
     }

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminOrderLayout/AdminOrderPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useParams } from "react-router-dom";
 import { actionOrderPage } from "../../../../actions/actionOrderPage";
-import { actionOrderPageClear } from "../../../../actions/actionOrderPageClear";
 import { CAdminOrderPage } from "../../AdminOrderPage";
 
 const AdminOrderPageContainer = ({ onLoad, onUnmount }) => {
@@ -19,6 +18,6 @@ const AdminOrderPageContainer = ({ onLoad, onUnmount }) => {
 };
 
 export const CAdminOrderPageContainer = connect(null, {
-    onUnmount: () => actionOrderPageClear({ promiseName: "adminOrderById" }),
+    onUnmount: () => ({ type: "ORDER_PAGE_CLEAR" }),
     onLoad: (_id) => actionOrderPage({ _id, promiseName: "adminOrderById" }),
 })(AdminOrderPageContainer);

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminOrderLayout/AdminOrdersPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useSearchParams } from "react-router-dom";
 import { actionOrdersPage } from "../../../../actions/actionOrdersPage";
-import { actionOrdersPageClear } from "../../../../actions/actionOrdersPageClear";
 import { actionFeedOrders } from "../../../../reducers";
 import { InfScroll } from "../../../common/InfScroll";
 import { AdminOrdersPage } from "../../AdminOrdersPage";
@@ -37,7 +36,7 @@ export const CAdminOrdersPageContainer = connect(
         promiseStatus: state.promise?.feedOrdersAll?.status || null,
     }),
     {
-        onUnmount: () => actionOrdersPageClear(),
+        onUnmount: () => ({ type: "ORDERS_PAGE_CLEAR" }),
         onLoad: ({ orderBy, status }) => actionOrdersPage({ orderBy, status }),
         onScroll: ({ feed, orderBy, status }) => actionFeedOrders({ skip: feed?.length || 0, orderBy, status }),
     }

+ 3 - 3
src/components/admin/AdminLayoutPage/AdminOrderLayout/AdminOrdersSearchPageContainer.js

@@ -1,10 +1,10 @@
 import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useSearchParams } from "react-router-dom";
-import { actionOrdersSearchPageClear } from "../../../../actions/actionOrdersSearchPageClear";
 import { actionFeedOrdersFind } from "../../../../reducers";
 import { InfScroll } from "../../../common/InfScroll";
 import { AdminOrdersPage } from "../../AdminOrdersPage";
+import { actionOrdersSearchPage } from "../../../../actions/actionOrdersSearchPage";
 
 const AdminOrdersSearchPageContainer = ({ feed, orders, promiseStatus, onLoad, onUnmount, onScroll }) => {
     const [searchParams] = useSearchParams();
@@ -37,8 +37,8 @@ export const CAdminOrdersSearchPageContainer = connect(
         promiseStatus: state.promise?.feedOrdersFind?.status || null,
     }),
     {
-        onUnmount: () => actionOrdersSearchPageClear(),
-        onLoad: ({ orderBy, text, status }) => actionOrdersSearchPageClear({ orderBy, text, status }),
+        onUnmount: () => ({ type: "ORDERS_SEARCH_PAGE_CLEAR" }),
+        onLoad: ({ orderBy, text, status }) => actionOrdersSearchPage({ orderBy, text, status }),
         onScroll: ({ feed, orderBy, text, status }) => actionFeedOrdersFind({ text, skip: feed?.length || 0, orderBy, status }),
     }
 )(AdminOrdersSearchPageContainer);

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminUserLayout/AdminUserPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useParams } from "react-router-dom";
 import { actionUserPage } from "../../../../actions/actionUserPage";
-import { actionUserPageClear } from "../../../../actions/actionUserPageClear";
 import { CAdminUserPage } from "../../AdminUserPage.js";
 
 const AdminUserPageContainer = ({ onLoad, onUnmount }) => {
@@ -21,6 +20,6 @@ const AdminUserPageContainer = ({ onLoad, onUnmount }) => {
 };
 
 export const CAdminUserPageContainer = connect(null, {
-    onUnmount: () => actionUserPageClear({ promiseName: "adminUserById" }),
+    onUnmount: () => ({ type: "USER_PAGE_CLEAN" }),
     onLoad: (_id) => actionUserPage({ _id, promiseName: "adminUserById" }),
 })(AdminUserPageContainer);

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminUserLayout/AdminUsersPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useSearchParams } from "react-router-dom";
 import { actionUsersPage } from "../../../../actions/actionUsersPage";
-import { actionUsersPageClear } from "../../../../actions/actionUsersPageClear";
 import { actionFeedUsers } from "../../../../reducers";
 import { InfScroll } from "../../../common/InfScroll";
 import { AdminUsersPage } from "../../AdminUsersPage";
@@ -36,7 +35,7 @@ export const CAdminUsersPageContainer = connect(
         promiseStatus: state.promise?.feedUsersAll?.status || null,
     }),
     {
-        onUnmount: () => actionUsersPageClear(),
+        onUnmount: () => ({ type: "USERS_PAGE_CLEAN" }),
         onLoad: ({ orderBy }) => actionUsersPage({ orderBy }),
         onScroll: ({ feed, orderBy }) => actionFeedUsers({ skip: feed?.length || 0, orderBy }),
     }

+ 1 - 2
src/components/admin/AdminLayoutPage/AdminUserLayout/AdminUsersSearchPageContainer.js

@@ -2,7 +2,6 @@ import { connect } from "react-redux";
 import { useEffect } from "react";
 import { useSearchParams } from "react-router-dom";
 import { actionUsersSearchPage } from "../../../../actions/actionUsersSearchPage";
-import { actionUsersSearchPageClear } from "../../../../actions/actionUsersSearchPageClear";
 import { actionFeedUsersFind } from "../../../../reducers";
 import { InfScroll } from "../../../common/InfScroll";
 import { AdminUsersPage } from "../../AdminUsersPage";
@@ -37,7 +36,7 @@ export const CAdminUsersSearchPageContainer = connect(
         promiseStatus: state.promise?.feedUsersFind?.status || null,
     }),
     {
-        onUnmount: () => actionUsersSearchPageClear(),
+        onUnmount: () => ({ type: "USERS_SEARCH_PAGE_CLEAR" }),
         onLoad: ({ orderBy, text }) => actionUsersSearchPage({ orderBy, text }),
         onScroll: ({ feed, orderBy, text }) => actionFeedUsersFind({ text, skip: feed?.length || 0, orderBy }),
     }

+ 2 - 5
src/components/admin/AdminOrderPage/OrderForm.js

@@ -11,6 +11,7 @@ import { OrderGoodsEditor } from "./OrderGoodsEditor";
 import { useNavigate } from "react-router-dom";
 import { actionOrderDelete } from "../../../actions/actionOrderDelete";
 import { ConfirmModal } from "../../common/ConfirmModal";
+import { actionPromisesClear } from "../../../actions/actionPromisesClear";
 
 export const OrderForm = ({
     serverErrors = [],
@@ -31,7 +32,6 @@ export const OrderForm = ({
     const [promiseTimeOut, setPromiseTimeOut] = useState(null);
     const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
     const navigate = useNavigate();
-    const dispatch = useDispatch();
 
     const formik = useFormik({
         initialValues: {},
@@ -104,9 +104,6 @@ export const OrderForm = ({
                 message: "Помилка",
             });
         }
-        return () => {
-            dispatch(actionPromiseClear("orderDelete"));
-        };
     }, [deletePromiseStatus]);
 
     useEffect(() => {
@@ -189,7 +186,7 @@ export const COrderForm = connect(
     }),
     {
         onSave: (order) => actionOrderUpdate(order),
-        onClose: () => actionPromiseClear("orderUpsert"),
+        onClose: () => actionPromisesClear(["orderUpsert", "orderDelete"]),
         onDelete: (order) => actionOrderDelete({ order }),
     }
 )(OrderForm);

+ 5 - 7
src/components/admin/AdminUserPage.js/UserForm.js

@@ -1,6 +1,5 @@
-import { connect, useDispatch } from "react-redux";
+import { connect } from "react-redux";
 import { useState, useEffect, useContext } from "react";
-import { actionPromiseClear } from "../../../reducers";
 import { actionUserUpdate } from "../../../actions/actionUserUpdate";
 import { UIContext } from "../../UIContext";
 import Select from "react-select";
@@ -12,6 +11,7 @@ import { MdVisibility, MdVisibilityOff } from "react-icons/md";
 import { aclList } from "../../../helpers";
 import { actionUploadFile } from "../../../actions/actionUploadFile";
 import { ProfileImageEditor } from "../../common/ProfileImageEditor";
+import { actionPromisesClear } from "../../../actions/actionPromisesClear";
 
 const CProfileImageEditor = connect(null, {
     onFileDrop: (acceptedFiles) => actionUploadFile(acceptedFiles[0]),
@@ -29,7 +29,7 @@ export const UserForm = ({
     onSaveClick,
     onSave,
     onClose,
-    onDelete,
+    onUnmount,
     promiseStatus,
     deletePromiseStatus,
     avatar = null,
@@ -41,7 +41,6 @@ export const UserForm = ({
 
     const [acl, setAcl] = useState([]);
     const navigate = useNavigate();
-    const dispatch = useDispatch();
 
     const formik = useFormik({
         initialValues: {
@@ -58,7 +57,6 @@ export const UserForm = ({
             user?._id && (userToSave._id = user._id);
             userToSave.acl = acl;
             avatar ? (userToSave.avatar = avatar) : delete userToSave.avatar;
-            console.log(userToSave);
             onSaveClick && onSaveClick();
             onSave(userToSave);
             setPromiseTimeOut(setTimeout(() => formik.setSubmitting(false), 3000));
@@ -112,7 +110,7 @@ export const UserForm = ({
             });
         }
         return () => {
-            dispatch(actionPromiseClear("userDelete"));
+            onUnmount && onUnmount();
         };
     }, [deletePromiseStatus]);
 
@@ -241,6 +239,6 @@ export const CUserForm = connect(
     }),
     {
         onSave: (user) => actionUserUpdate(user),
-        onClose: () => actionPromiseClear("userUpsert"),
+        onClose: () => actionPromisesClear(["userUpsert", "userDelete"]),
     }
 )(UserForm);

+ 0 - 1
src/components/admin/AdminUsersPage/AdminUserList.js

@@ -18,7 +18,6 @@ const CSearchResults = connect((state) => ({ items: state.promise.adminUsersFind
 const AdminUserList = ({ users, orderBy = "_id" }) => {
     const [searchParams, setSearchParams] = useSearchParams();
     const navigate = useNavigate();
-    console.log(1);
     return (
         <Box className="AdminUserList">
             <Box className="searchBarWrapper">

+ 8 - 6
src/components/common/DrawerCart/DrawerCart.js

@@ -1,16 +1,14 @@
 import { useNavigate } from "react-router-dom";
-import { actionCartDelete } from "../../../reducers";
 import { IoMdClose } from "react-icons/io";
 
 import { Divider, Typography, Button, Stack, IconButton } from "@mui/material";
-import { useSelector, useDispatch } from "react-redux";
 import { DrawerCartItem } from "./DrawerCartItem";
 import { DrawerRight } from "../DrawerRight";
 import { Box } from "@mui/system";
+import { connect } from "react-redux";
+import { actionCartDelete } from "../../../reducers";
 
-export const DrawerCart = ({ isOpen = false, onClose = null } = {}) => {
-    const cart = useSelector((state) => state.cart || {});
-    const dispatch = useDispatch();
+export const DrawerCart = ({ cart = {}, isOpen = false, onClose = null, onDeleteClick } = {}) => {
     const navigate = useNavigate();
 
     return (
@@ -28,7 +26,7 @@ export const DrawerCart = ({ isOpen = false, onClose = null } = {}) => {
 
                     <Divider />
                     {Object.entries(cart).map(([_id, order]) => (
-                        <DrawerCartItem order={order} onDeleteClick={(good) => dispatch(actionCartDelete(good))} key={_id} />
+                        <DrawerCartItem order={order} onDeleteClick={(good) => onDeleteClick(good)} key={_id} />
                     ))}
 
                     {!!Object.keys(cart).length && (
@@ -47,3 +45,7 @@ export const DrawerCart = ({ isOpen = false, onClose = null } = {}) => {
         </DrawerRight>
     );
 };
+
+export const CDrawerCart = connect((state) => ({ cart: state.cart || {} }), {
+    onDeleteClick: (good) => actionCartDelete(good),
+})(DrawerCart);

+ 7 - 6
src/components/layout/Header/LogoutIcon/index.js

@@ -1,17 +1,18 @@
 import { Box, IconButton } from "@mui/material";
-import { useDispatch, useSelector } from "react-redux";
 import { MdLogout } from "react-icons/md";
 import { actionLogout } from "../../../../actions/actionLogout";
+import { connect } from "react-redux";
 
-export const LogoutIcon = () => {
-    const dispatch = useDispatch();
-    const token = useSelector((state) => state.auth?.token || null);
-
+export const LogoutIcon = ({ token, onClick }) => {
     return token ? (
         <Box className="LogoutIcon">
-            <IconButton onClick={() => dispatch(actionLogout())}>
+            <IconButton onClick={onClick}>
                 <MdLogout className="LogoutLogo" />
             </IconButton>
         </Box>
     ) : null;
 };
+
+export const CLogoutIcon = connect((state) => ({ token: state.auth?.token || null }), {
+    onClick: () => actionLogout(),
+})(LogoutIcon);

+ 4 - 4
src/components/layout/Header/index.js

@@ -4,12 +4,12 @@ import { useSelector } from "react-redux";
 import { createSearchParams, Link, useNavigate, useSearchParams } from "react-router-dom";
 import { ReactComponent as ShoppingLogo } from "../../../images/shopping-logo.svg";
 import { AuthModal } from "../../common/AuthModal";
-import { DrawerCart } from "../../common/DrawerCart/DrawerCart";
+import { CDrawerCart } from "../../common/DrawerCart/DrawerCart";
 import { CSearchBar } from "../../common/SearchBar";
 import { CSearchResults } from "../../common/SearchBar/SearchResults";
 import { AvatarButton } from "./AvatarButton";
 import { CCartIcon } from "./CartIcon";
-import { LogoutIcon } from "./LogoutIcon";
+import { CLogoutIcon } from "./LogoutIcon";
 
 const Header = () => {
     const rootCats = useSelector((state) => state?.promise?.rootCats?.payload || []);
@@ -53,7 +53,7 @@ const Header = () => {
                     <Stack direction="row" spacing={3}>
                         {token ? (
                             <Stack direction="row" spacing={3}>
-                                <LogoutIcon />
+                                <CLogoutIcon />
                                 <AvatarButton onClick={() => navigate("/dashboard/")} />
                             </Stack>
                         ) : (
@@ -71,7 +71,7 @@ const Header = () => {
                     </Stack>
                 </Toolbar>
             </AppBar>
-            <DrawerCart isOpen={isCartDrawerOpen} onClose={() => setIsCartDrawerOpen(false)} />
+            <CDrawerCart isOpen={isCartDrawerOpen} onClose={() => setIsCartDrawerOpen(false)} />
             <AuthModal open={isAuthModalOpen} onClose={() => setIsAuthModalOpen(false)} />
         </Box>
     );

+ 10 - 0
src/reducers/authReducer.js

@@ -1,3 +1,7 @@
+import { takeLatest } from "redux-saga/effects";
+import { loginWorker } from "../actions/actionLogin";
+import { logoutWorker } from "../actions/actionLogout";
+import { registerWorker } from "../actions/actionRegister";
 import { jwtDecode } from "../helpers";
 
 export function authReducer(state, { type, token }) {
@@ -31,4 +35,10 @@ export const actionAuthLogin = (token) => ({
     token: token,
 });
 
+export function* authWatcher() {
+    yield takeLatest("LOGIN", loginWorker);
+    yield takeLatest("LOGOUT", logoutWorker);
+    yield takeLatest("REGISTER", registerWorker);
+}
+
 export const actionAuthLogout = () => ({ type: "AUTH_LOGOUT" });

+ 15 - 71
src/reducers/feedReducer.js

@@ -7,7 +7,6 @@ import { actionOrdersFind } from "../actions/actionOrdersFind";
 import { actionCategoryGoods } from "../actions/actionCategoryGoods";
 import { actionUsersFind } from "../actions/actionUsersFind";
 import { actionUsersAll } from "../actions/actionUsersAll";
-import { put, takeLatest, takeLeading } from "redux-saga/effects";
 
 function feedReducer(state = { payload: [] }, { type, payload = [] }) {
     if (type === "FEED_ADD") {
@@ -25,77 +24,29 @@ function feedReducer(state = { payload: [] }, { type, payload = [] }) {
 
 const actionFeedAdd = (payload) => ({ type: "FEED_ADD", payload });
 const actionFeedClear = () => ({ type: "FEED_CLEAR" });
+const actionFeedGoods = ({ skip = 0, orderBy = "_id" }) => actionGoodsAll({ skip, limit: 1, promiseName: "feedGoodsAll", orderBy });
 
-const actionFeedGoods = ({ skip = 0, orderBy = "_id" } = {}) => ({
-    type: "FEED_GOODS",
-    payload: { skip, orderBy },
-});
+const actionFeedCategoryGoods = ({ skip = 0, orderBy = "_id", category }) =>
+    actionCategoryGoods({ skip, limit: 1, promiseName: "feedCategoryGoods", orderBy, category });
 
-function* feedGoodsWorker(action) {
-    const { skip = 0, orderBy = "_id" } = action.payload || {};
-    yield put(actionGoodsAll({ skip, limit: 1, promiseName: "feedGoodsAll", orderBy }));
-}
-
-const actionFeedCategoryGoods = ({ skip = 0, orderBy = "_id", category } = {}) => ({
-    type: "FEED_CATEGORY_GOODS",
-    payload: { skip, orderBy, category },
-});
-
-function* feedCategoryGoodsWorker(action) {
-    const { skip = 0, orderBy = "_id", category } = action.payload || {};
-
-    yield put(actionCategoryGoods({ skip, limit: 1, promiseName: "feedCategoryGoods", orderBy, category }));
-}
-
-const actionFeedGoodsFind = ({ skip = 0, text = "", orderBy = "_id" } = {}) => ({
-    type: "FEED_GOODS_FIND",
-    payload: { skip, text, orderBy },
-});
+const actionFeedGoodsFind = ({ skip = 0, text = "", orderBy = "_id" }) =>
+    actionGoodsFind({ skip, limit: 1, promiseName: "feedGoodsFind", text, orderBy });
 
-function* feedGoodsFindWorker(action) {
-    const { skip = 0, text = "", orderBy = "_id" } = action.payload || {};
-    yield put(actionGoodsFind({ skip, limit: 1, promiseName: "feedGoodsFind", text, orderBy }));
-}
-
-const actionFeedCatsFind =
-    ({ skip = 0, text = "", orderBy = "_id" }) =>
-    async (dispatch, getState) => {
-        await dispatch(actionCatsFind({ skip, promiseName: "feedCatsFind", text, limit: 1, orderBy }));
-    };
-
-const actionFeedCats = ({ skip = 0, orderBy = "_id" } = {}) => ({
-    type: "FEED_CATS",
-    payload: { skip, orderBy },
-});
+const actionFeedCatsFind = ({ skip = 0, text = "", orderBy = "_id" }) =>
+    actionCatsFind({ skip, promiseName: "feedCatsFind", text, limit: 1, orderBy });
 
-function* feedCatsWorker(action) {
-    const { skip = 0, orderBy = "_id" } = action.payload || {};
-    yield put(actionCatAll({ promiseName: "feedCatAll", skip, limit: 1, orderBy }));
-}
+const actionFeedCats = ({ skip = 0, orderBy = "_id" }) => actionCatAll({ promiseName: "feedCatAll", skip, limit: 1, orderBy });
 
-const actionFeedOrders =
-    ({ skip = 0, orderBy = "_id", status = 0 }) =>
-    async (dispatch, getState) => {
-        await dispatch(actionOrdersAll({ skip, limit: 1, promiseName: "feedOrdersAll", orderBy, status }));
-    };
+const actionFeedOrders = ({ skip = 0, orderBy = "_id", status = 0 }) =>
+    actionOrdersAll({ skip, limit: 1, promiseName: "feedOrdersAll", orderBy, status });
 
-const actionFeedOrdersFind =
-    ({ skip = 0, text = "", orderBy = "_id", status = "0" }) =>
-    async (dispatch, getState) => {
-        await dispatch(actionOrdersFind({ skip, limit: 1, promiseName: "feedOrdersFind", text, orderBy, status }));
-    };
+const actionFeedOrdersFind = ({ skip = 0, text = "", orderBy = "_id", status = "0" }) =>
+    actionOrdersFind({ skip, limit: 1, promiseName: "feedOrdersFind", text, orderBy, status });
 
-const actionFeedUsersFind =
-    ({ skip = 0, text = "", orderBy = "_id" }) =>
-    async (dispatch, getState) => {
-        await dispatch(actionUsersFind({ skip, promiseName: "feedUsersFind", text, limit: 1, orderBy }));
-    };
+const actionFeedUsersFind = ({ skip = 0, text = "", orderBy = "_id" }) =>
+    actionUsersFind({ skip, promiseName: "feedUsersFind", text, limit: 1, orderBy });
 
-const actionFeedUsers =
-    ({ skip = 0, orderBy = "_id" }) =>
-    async (dispatch, getState) => {
-        await dispatch(actionUsersAll({ promiseName: "feedUsersAll", skip, limit: 1, orderBy }));
-    };
+const actionFeedUsers = ({ skip = 0, orderBy = "_id" }) => actionUsersAll({ promiseName: "feedUsersAll", skip, limit: 1, orderBy });
 
 export {
     actionFeedCats,
@@ -111,10 +62,3 @@ export {
     actionFeedUsers,
     actionFeedUsersFind,
 };
-
-export function* feedWatcher() {
-    yield takeLeading("FEED_CATEGORY_GOODS", feedCategoryGoodsWorker);
-    yield takeLeading("FEED_GOODS_FIND", feedGoodsFindWorker);
-    yield takeLeading("FEED_GOODS", feedGoodsWorker);
-    yield takeLeading("FEED_CATS", feedCatsWorker);
-}

+ 2 - 3
src/reducers/index.js

@@ -2,7 +2,7 @@ import { createStore, combineReducers, applyMiddleware } from "redux";
 import { all, put, takeEvery, takeLatest, takeLeading, select } from "redux-saga/effects";
 import thunk from "redux-thunk";
 import createSagaMiddleware from "redux-saga";
-import { authReducer, actionAuthLogin, actionAuthLogout } from "./authReducer";
+import { authReducer, actionAuthLogin, actionAuthLogout, authWatcher } from "./authReducer";
 import {
     promiseReducer,
     actionPending,
@@ -25,7 +25,6 @@ import {
     feedReducer,
     actionFeedUsers,
     actionFeedUsersFind,
-    feedWatcher,
 } from "./feedReducer";
 
 export { cartReducer, actionCartAdd, actionCartChange, actionCartDelete, actionCartClear };
@@ -57,7 +56,7 @@ export const store = createStore(
 );
 
 function* rootSaga() {
-    yield all([promiseWatcher(), feedWatcher()]);
+    yield all([promiseWatcher(), authWatcher()]);
 }
 
 sagaMiddleware.run(rootSaga);

+ 26 - 0
src/reducers/promiseReducer.js

@@ -3,12 +3,25 @@ import { aboutMeWorker } from "../actions/actionAboutMe";
 import { catByIdFullWorker } from "../actions/actionCatByIdFull";
 import { categoriesPageWorker } from "../actions/actionCategoriesPage";
 import { categoryGoodsWorker } from "../actions/actionCategoryGoods";
+import { categoryPageWorker } from "../actions/actionCategoryPage";
+import { categoryUpdateWorker } from "../actions/actionCategoryUpdate";
 import { goodPageWorker } from "../actions/actionGoodPage";
 import { goodsFindWorker } from "../actions/actionGoodsFind";
 import { goodsPageWorker } from "../actions/actionGoodsPage";
 import { goodsSearchPageWorker } from "../actions/actionGoodsSearchPage";
+import { goodUpdateWorker } from "../actions/actionGoodUpdate";
+import { orderPageWorker } from "../actions/actionOrderPage";
+import { ordersPageWorker } from "../actions/actionOrdersPage";
+import { ordersSearchPageWorker } from "../actions/actionOrdersSearchPage";
 import { orderUpdateWorker } from "../actions/actionOrderUpdate";
 import { pageStartWorker } from "../actions/actionPageStart";
+import { promisesClearWorker } from "../actions/actionPromisesClear";
+import { updateAvatarWorker } from "../actions/actionUpdateAvatar";
+import { uploadFilesWorker } from "../actions/actionUploadFiles";
+import { userPageWorker } from "../actions/actionUserPage";
+import { usersPageWorker } from "../actions/actionUsersPage";
+import { usersSearchPageWorker } from "../actions/actionUsersSearchPage";
+import { userUpdateWorker } from "../actions/actionUserUpdate";
 
 export function promiseReducer(state = {}, { type, name, status, payload, error }) {
     if (type === "PROMISE") {
@@ -55,4 +68,17 @@ export function* promiseWatcher() {
     yield takeLatest("GOODS_SEARCH_PAGE", goodsSearchPageWorker);
     yield takeLatest("CATEGORIES_PAGE", categoriesPageWorker);
     yield takeLatest("GOODS_PAGE", goodsPageWorker);
+    yield takeLatest("CATEGORY_PAGE", categoryPageWorker);
+    yield takeLatest("CATEGORY_UPDATE", categoryUpdateWorker);
+    yield takeLatest("GOOD_UPDATE", goodUpdateWorker);
+    yield takeLatest("ORDER_PAGE", orderPageWorker);
+    yield takeLatest("ORDERS_PAGE", ordersPageWorker);
+    yield takeLatest("ORDERS_SEARCH_PAGE", ordersSearchPageWorker);
+    yield takeLatest("UPDATE_AVATAR", updateAvatarWorker);
+    yield takeLatest("UPLOAD_FILES", uploadFilesWorker);
+    yield takeLatest("USER_PAGE", userPageWorker);
+    yield takeLatest("USERS_PAGE", usersPageWorker);
+    yield takeLatest("USERS_SEARCH_PAGE", usersSearchPageWorker);
+    yield takeLatest("USER_UPDATE", userUpdateWorker);
+    yield takeEvery("PROMISES_CLEAR", promisesClearWorker);
 }