2 Комити 2695e75a06 ... de04e6e9f5

Аутор SHA1 Порука Датум
  Gennadysht de04e6e9f5 rtk_tree_view_cls_trash пре 1 година
  Gennadysht 528a18b6e0 rtk_tree_view_beta1 пре 1 година

+ 122 - 53
package-lock.json

@@ -16,7 +16,8 @@
         "@fontsource/roboto": "^4.5.8",
         "@minoru/react-dnd-treeview": "^3.4.1",
         "@mui/icons-material": "^5.11.0",
-        "@mui/material": "^5.11.4",
+        "@mui/lab": "^5.0.0-alpha.118",
+        "@mui/material": "^5.11.7",
         "@mui/styled-engine-sc": "^5.11.0",
         "@reduxjs/toolkit": "^1.9.1",
         "@rtk-query/graphql-request-base-query": "^2.2.0",
@@ -3334,14 +3335,14 @@
       }
     },
     "node_modules/@mui/base": {
-      "version": "5.0.0-alpha.113",
-      "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.113.tgz",
-      "integrity": "sha512-XSjvyQWATM8uk+EJZvYna8D21kOXC42lwb3q4K70btuGieKlCIQLaHTTDV2OfD4+JfT4o3NJy3I4Td2co31RZA==",
+      "version": "5.0.0-alpha.116",
+      "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz",
+      "integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==",
       "dependencies": {
         "@babel/runtime": "^7.20.7",
         "@emotion/is-prop-valid": "^1.2.0",
         "@mui/types": "^7.2.3",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "@popperjs/core": "^2.11.6",
         "clsx": "^1.2.1",
         "prop-types": "^15.8.1",
@@ -3371,9 +3372,9 @@
       "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
     },
     "node_modules/@mui/core-downloads-tracker": {
-      "version": "5.11.4",
-      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.4.tgz",
-      "integrity": "sha512-jWVwGM3vG4O0sXcW0VcIl+njCWbGCBF5vvjRpuKJajrz51AD7D6+fP1SkInZXVk5pRHf6Bnk/Yj9Of9gXxb/hA==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz",
+      "integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/mui"
@@ -3404,17 +3405,63 @@
         }
       }
     },
+    "node_modules/@mui/lab": {
+      "version": "5.0.0-alpha.118",
+      "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.118.tgz",
+      "integrity": "sha512-XedMEzYT6L9JawNV70mfMhDu4+2HNXSSn4+GPtFBE1Tefl8+djwK/FXdjPaG/qZzhwMyjO/RcwXzLPR0VWLpcw==",
+      "dependencies": {
+        "@babel/runtime": "^7.20.7",
+        "@mui/base": "5.0.0-alpha.116",
+        "@mui/system": "^5.11.7",
+        "@mui/types": "^7.2.3",
+        "@mui/utils": "^5.11.7",
+        "clsx": "^1.2.1",
+        "prop-types": "^15.8.1",
+        "react-is": "^18.2.0"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mui"
+      },
+      "peerDependencies": {
+        "@emotion/react": "^11.5.0",
+        "@emotion/styled": "^11.3.0",
+        "@mui/material": "^5.0.0",
+        "@types/react": "^17.0.0 || ^18.0.0",
+        "react": "^17.0.0 || ^18.0.0",
+        "react-dom": "^17.0.0 || ^18.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@emotion/react": {
+          "optional": true
+        },
+        "@emotion/styled": {
+          "optional": true
+        },
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@mui/lab/node_modules/react-is": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+      "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+    },
     "node_modules/@mui/material": {
-      "version": "5.11.4",
-      "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.4.tgz",
-      "integrity": "sha512-ZL/czK9ynrQJ6uyDwQgK+j7m1iKA1XKPON+rEPupwAu/bJ1XJxD+H/H2bkMM8UpOkzaucx/WuMbJJGQ60l7gBg==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz",
+      "integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==",
       "dependencies": {
         "@babel/runtime": "^7.20.7",
-        "@mui/base": "5.0.0-alpha.113",
-        "@mui/core-downloads-tracker": "^5.11.4",
-        "@mui/system": "^5.11.4",
+        "@mui/base": "5.0.0-alpha.116",
+        "@mui/core-downloads-tracker": "^5.11.7",
+        "@mui/system": "^5.11.7",
         "@mui/types": "^7.2.3",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "@types/react-transition-group": "^4.4.5",
         "clsx": "^1.2.1",
         "csstype": "^3.1.1",
@@ -3454,12 +3501,12 @@
       "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
     },
     "node_modules/@mui/private-theming": {
-      "version": "5.11.2",
-      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.2.tgz",
-      "integrity": "sha512-qZwMaqRFPwlYmqwVKblKBGKtIjJRAj3nsvX93pOmatsXyorW7N/0IPE/swPgz1VwChXhHO75DwBEx8tB+aRMNg==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
+      "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
       "dependencies": {
         "@babel/runtime": "^7.20.7",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -3536,15 +3583,15 @@
       }
     },
     "node_modules/@mui/system": {
-      "version": "5.11.4",
-      "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.4.tgz",
-      "integrity": "sha512-fE2Ts33V5zh7ouciwXgMm/a6sLvjIj9OMeojuHNYY7BStTxparC/Fp9CNUZNJwt76U6ZJC59aYScFSRQKbW08g==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz",
+      "integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==",
       "dependencies": {
         "@babel/runtime": "^7.20.7",
-        "@mui/private-theming": "^5.11.2",
+        "@mui/private-theming": "^5.11.7",
         "@mui/styled-engine": "^5.11.0",
         "@mui/types": "^7.2.3",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "clsx": "^1.2.1",
         "csstype": "^3.1.1",
         "prop-types": "^15.8.1"
@@ -3588,9 +3635,9 @@
       }
     },
     "node_modules/@mui/utils": {
-      "version": "5.11.2",
-      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.2.tgz",
-      "integrity": "sha512-AyizuHHlGdAtH5hOOXBW3kriuIwUIKUIgg0P7LzMvzf6jPhoQbENYqY6zJqfoZ7fAWMNNYT8mgN5EftNGzwE2w==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
+      "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
       "dependencies": {
         "@babel/runtime": "^7.20.7",
         "@types/prop-types": "^15.7.5",
@@ -23390,14 +23437,14 @@
       }
     },
     "@mui/base": {
-      "version": "5.0.0-alpha.113",
-      "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.113.tgz",
-      "integrity": "sha512-XSjvyQWATM8uk+EJZvYna8D21kOXC42lwb3q4K70btuGieKlCIQLaHTTDV2OfD4+JfT4o3NJy3I4Td2co31RZA==",
+      "version": "5.0.0-alpha.116",
+      "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz",
+      "integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==",
       "requires": {
         "@babel/runtime": "^7.20.7",
         "@emotion/is-prop-valid": "^1.2.0",
         "@mui/types": "^7.2.3",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "@popperjs/core": "^2.11.6",
         "clsx": "^1.2.1",
         "prop-types": "^15.8.1",
@@ -23412,9 +23459,9 @@
       }
     },
     "@mui/core-downloads-tracker": {
-      "version": "5.11.4",
-      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.4.tgz",
-      "integrity": "sha512-jWVwGM3vG4O0sXcW0VcIl+njCWbGCBF5vvjRpuKJajrz51AD7D6+fP1SkInZXVk5pRHf6Bnk/Yj9Of9gXxb/hA=="
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz",
+      "integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw=="
     },
     "@mui/icons-material": {
       "version": "5.11.0",
@@ -23424,17 +23471,39 @@
         "@babel/runtime": "^7.20.6"
       }
     },
+    "@mui/lab": {
+      "version": "5.0.0-alpha.118",
+      "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.118.tgz",
+      "integrity": "sha512-XedMEzYT6L9JawNV70mfMhDu4+2HNXSSn4+GPtFBE1Tefl8+djwK/FXdjPaG/qZzhwMyjO/RcwXzLPR0VWLpcw==",
+      "requires": {
+        "@babel/runtime": "^7.20.7",
+        "@mui/base": "5.0.0-alpha.116",
+        "@mui/system": "^5.11.7",
+        "@mui/types": "^7.2.3",
+        "@mui/utils": "^5.11.7",
+        "clsx": "^1.2.1",
+        "prop-types": "^15.8.1",
+        "react-is": "^18.2.0"
+      },
+      "dependencies": {
+        "react-is": {
+          "version": "18.2.0",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+          "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+        }
+      }
+    },
     "@mui/material": {
-      "version": "5.11.4",
-      "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.4.tgz",
-      "integrity": "sha512-ZL/czK9ynrQJ6uyDwQgK+j7m1iKA1XKPON+rEPupwAu/bJ1XJxD+H/H2bkMM8UpOkzaucx/WuMbJJGQ60l7gBg==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz",
+      "integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==",
       "requires": {
         "@babel/runtime": "^7.20.7",
-        "@mui/base": "5.0.0-alpha.113",
-        "@mui/core-downloads-tracker": "^5.11.4",
-        "@mui/system": "^5.11.4",
+        "@mui/base": "5.0.0-alpha.116",
+        "@mui/core-downloads-tracker": "^5.11.7",
+        "@mui/system": "^5.11.7",
         "@mui/types": "^7.2.3",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "@types/react-transition-group": "^4.4.5",
         "clsx": "^1.2.1",
         "csstype": "^3.1.1",
@@ -23451,12 +23520,12 @@
       }
     },
     "@mui/private-theming": {
-      "version": "5.11.2",
-      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.2.tgz",
-      "integrity": "sha512-qZwMaqRFPwlYmqwVKblKBGKtIjJRAj3nsvX93pOmatsXyorW7N/0IPE/swPgz1VwChXhHO75DwBEx8tB+aRMNg==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
+      "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
       "requires": {
         "@babel/runtime": "^7.20.7",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "prop-types": "^15.8.1"
       }
     },
@@ -23481,15 +23550,15 @@
       }
     },
     "@mui/system": {
-      "version": "5.11.4",
-      "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.4.tgz",
-      "integrity": "sha512-fE2Ts33V5zh7ouciwXgMm/a6sLvjIj9OMeojuHNYY7BStTxparC/Fp9CNUZNJwt76U6ZJC59aYScFSRQKbW08g==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz",
+      "integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==",
       "requires": {
         "@babel/runtime": "^7.20.7",
-        "@mui/private-theming": "^5.11.2",
+        "@mui/private-theming": "^5.11.7",
         "@mui/styled-engine": "^5.11.0",
         "@mui/types": "^7.2.3",
-        "@mui/utils": "^5.11.2",
+        "@mui/utils": "^5.11.7",
         "clsx": "^1.2.1",
         "csstype": "^3.1.1",
         "prop-types": "^15.8.1"
@@ -23502,9 +23571,9 @@
       "requires": {}
     },
     "@mui/utils": {
-      "version": "5.11.2",
-      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.2.tgz",
-      "integrity": "sha512-AyizuHHlGdAtH5hOOXBW3kriuIwUIKUIgg0P7LzMvzf6jPhoQbENYqY6zJqfoZ7fAWMNNYT8mgN5EftNGzwE2w==",
+      "version": "5.11.7",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
+      "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
       "requires": {
         "@babel/runtime": "^7.20.7",
         "@types/prop-types": "^15.7.5",

+ 2 - 1
package.json

@@ -11,7 +11,8 @@
     "@fontsource/roboto": "^4.5.8",
     "@minoru/react-dnd-treeview": "^3.4.1",
     "@mui/icons-material": "^5.11.0",
-    "@mui/material": "^5.11.4",
+    "@mui/lab": "^5.0.0-alpha.118",
+    "@mui/material": "^5.11.7",
     "@mui/styled-engine-sc": "^5.11.0",
     "@reduxjs/toolkit": "^1.9.1",
     "@rtk-query/graphql-request-base-query": "^2.2.0",

+ 4 - 10
src/App.js

@@ -1,7 +1,7 @@
 import { Router, Route, Switch } from 'react-router-dom';
 import { store, persistedStore } from './store';
 import { Provider } from 'react-redux';
-import { CCategoriesList, CEditableCategory, CEditableGood, CGood, CGoodsList, CLoginForm, CMainAppBar, COrder, COrdersList, CRegisterForm, CUser, CUsersList } from "./Components";
+import { CCategoriesList, CCategoryTree, CEditableCategory, CEditableGood, CGood, CGoodsList, CLoginForm, CMainAppBar, COrder, COrdersList, CRegisterForm, CUser, CUsersList } from "./Components";
 import { CLogout } from './Components';
 import { CSidebar } from './Components/Sidebar';
 import { CRootCats } from './Components';
@@ -10,18 +10,12 @@ import { CCategory } from './Components/Category';
 import { CCart } from './Components/Cart';
 import { createBrowserHistory } from "history";
 import { PersistGate } from 'redux-persist/integration/react';
-import { Box, Drawer, Paper, Typography } from '@mui/material';
+import { Box, Typography } from '@mui/material';
 import backImage from "./images/theme_main.png"
 
 export const history = createBrowserHistory();
 
 
-//import { cartReducer, actionRestoreCart } from './reducers';
-//store.dispatch(actionAuthLogin(localStorage.authToken));
-//store.dispatch(actionRootCats());
-//store.dispatch(actionRestoreCart());
-
-
 const NotFound = () =>
   <div>
     <h1>404 not found</h1>
@@ -33,7 +27,6 @@ const Main = () =>
     <h1>Main page</h1>
   </Box>
 
-//<EditPost onSave={post => console.log(post)}/>
 function App() {
   return (
     <>
@@ -61,7 +54,8 @@ function App() {
                 <Route path="/user/:_id" component={CUser} />
                 <Route path="/user" component={CUser} />
                 <Route path="/logout" component={CLogout} />
-                <Route path="/catree" component={CCategoriesList} />
+                <Route path="/catree" component={CCategoryTree} />
+                <Route path="/categories" component={CCategoriesList} />
                 <Route path="*" component={NotFound} />
               </Switch>
             </div>

+ 0 - 8
src/App.test.js

@@ -1,8 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
-  render(<App />);
-  const linkElement = screen.getByText(/learn react/i);
-  expect(linkElement).toBeInTheDocument();
-});

+ 0 - 2
src/Components/AvatarAnimated.js

@@ -17,8 +17,6 @@ export const AvatarAnimated = styled((props) => {
     const { selected, ...other } = props;
     return <AvatarImage {...other} />;
 })(({ theme, selected }) => ({
-    //width: theme.spacing(10),
-    //height: theme.spacing(10),
     transition: theme.transitions.create('transform', {
         duration: theme.transitions.duration.shortest,
     }),

+ 1 - 7
src/Components/Cart.js

@@ -19,13 +19,12 @@ const Cart = () => {
     let goods = useSelector(state => state.cart?.goods) ?? [];
     let { isLoading, data } = useGetGoodsByIdQuery({ goods });
     let goodsData = data?.GoodFind?.map(gd => ({ ...gd, count: mapCountToGood(gd, goods) })) ?? [];
-    let state = useSelector(state => state);
     let order = [];
     for (let good of Object.values(goods)) {
         order.push({ good: { _id: good._id }, count: good.count });
     }
     let currentUser = useSelector(state => getCurrentUser(state));
-    const [addOrderMutation, { isLoading: isOrderAdding, data: orderAddingData }] = useAddOrderMutation();
+    const [addOrderMutation, { isLoading: isOrderAdding }] = useAddOrderMutation();
     return !isLoading && (
         <>
             <Container>
@@ -53,11 +52,6 @@ const Cart = () => {
     )
 }
 const CCart = connect(state => ({
-    /*goods: state.cart.goods,
-    goodsData: state.goods?.goods?.payload,
-    uniqueId: state.cart.uniqueId,*/
-    //...getCart(state)
-    //cart: getCart(state) 
 }),
     {})(Cart);
 

+ 11 - 5
src/Components/Category.js

@@ -1,7 +1,6 @@
 import { List, ListItem, ListItemButton, ListItemText, Button } from "@mui/material"
 import { Typography } from "@mui/material"
 import { Box, Container } from "@mui/system"
-import { useState } from "react"
 import { useEffect } from "react"
 import { connect, useDispatch, useSelector } from "react-redux"
 import { useParams } from "react-router-dom"
@@ -24,7 +23,7 @@ const Category = () => {
     const dispatch = useDispatch();
     let state = useSelector(state => state);
     useEffect(() => {
-        if (getCurrentEntity(frontEndNames.category, state)?._id != _id)
+        if (getCurrentEntity(frontEndNames.category, state)?._id !== _id)
             dispatch(actionSetCurrentEntity(frontEndNames.category, { _id }));
         if (!isLoading)
             dispatch(actionSetCurrentEntity(frontEndNames.category, data.CategoryFindOne));
@@ -44,7 +43,7 @@ const Category = () => {
                             </MyLink>
                         )
                     }
-                    <Typography paragraph gutterBottom component={'h3'} variant={'h3'} sx={{marginTop: "1vh"} } >
+                    <Typography paragraph gutterBottom component={'h3'} variant={'h3'} sx={{ marginTop: "1vh" }} >
                         {cat.name}
                     </Typography>
                     {csubCats && <CSubCategories />}
@@ -53,8 +52,15 @@ const Category = () => {
                             {cat.subCategories.map(scat => (
                                 <ListItem key={scat._id} disablePadding>
                                     <ListItemButton>
-                                        <MyLink to={`/category/${scat._id}`}>
-                                            <ListItemText primary={scat.name} />
+                                        <MyLink to={`/category/${scat._id}`} >
+                                            <ListItemText
+                                                disableTypography
+                                                primary={
+                                                    <Typography paragraph gutterBottom component={'h4'} variant={'h4'} sx={{ marginTop: "1vh", marginLeft: "18vh" }} >
+                                                        {scat.name}
+                                                    </Typography>
+                                                }
+                                            />
                                         </MyLink>
                                     </ListItemButton>
                                 </ListItem>

+ 2 - 7
src/Components/CategoryList.js

@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react';
+import React from 'react';
 import { Container, Typography, Paper, Avatar, Button } from '@mui/material';
 import { Table, TableBody, TableContainer, TableHead, TableRow } from "@mui/material";
 import { StyledTableCell, StyledTableRow } from './StyledTableElements';
@@ -6,7 +6,7 @@ import { CPagination } from './Pagination';
 import { CSearchInput } from './SearchInput';
 import { MyLink, ReferenceLink } from '.';
 import { useSelector } from 'react-redux';
-import { frontEndNames, getCurrentUser, getEntitiesListShowParams, useGetCategoriesCountQuery, useGetCategoriesQuery, useGetOrdersCountQuery, useGetOrdersQuery } from '../reducers';
+import { frontEndNames, getCurrentUser, getEntitiesListShowParams, useGetCategoriesCountQuery, useGetCategoriesQuery } from '../reducers';
 import { UserEntity } from '../Entities';
 import { getFullImageUrl } from '../utills';
 
@@ -128,11 +128,6 @@ const CCategoriesList = () => {
     const categoriesCountResult = useGetCategoriesCountQuery({ searchStr, owner: currentUser }, { refetchOnMountOrArgChange: true });
     let isLoading = categoriesResult.isLoading || categoriesCountResult.isLoading;
 
-    /*useEffect(() => {
-        categoriesCountResult.refetch();
-    }, [searchStr]);*/
-
-
     let entities = !isLoading && categoriesResult.data?.CategoryFind;
     return !isLoading && <CategoriesList entities={entities} isAdmin={currentUser.isAdminRole} entitiesTypeName={entitiesTypeName} fromPage={fromPage} pageSize={pageSize} />
 }

+ 95 - 79
src/Components/CategoryTree.js

@@ -1,108 +1,107 @@
 import React, { useState } from "react";
-import { Typography } from "@mui/material"
 import { DndProvider } from "react-dnd";
 import {
     Tree,
     MultiBackend,
     getBackendOptions
 } from "@minoru/react-dnd-treeview";
-import { useGetRootCategoriesQuery } from "../reducers";
+import { useGetRootCategoriesQuery, useSaveCategoryMutation } from "../reducers";
+import { CategoryTreeItem } from "./CategoryTreeItem";
+import { ThemeProvider, CssBaseline } from "@mui/material";
+import { createTheme } from "@mui/material/styles";
+import styles from "./CategoryTree.module.css";
 
-const SampleData = [
-    {
-        "id": 1,
-        "parent": 0,
-        "droppable": true,
-        "text": "Folder 1"
-    },
-    {
-        "id": 2,
-        "parent": 1,
-        "droppable": false,
-        "text": "File 1-1"
-    },
-    {
-        "id": 3,
-        "parent": 1,
-        "droppable": false,
-        "text": "File 1-2"
-    },
-    {
-        "id": 4,
-        "parent": 0,
-        "droppable": true,
-        "text": "Folder 2"
-    },
-    {
-        "id": 5,
-        "parent": 4,
-        "droppable": true,
-        "text": "Folder 2-1"
-    },
-    {
-        "id": 6,
-        "parent": 5,
-        "droppable": false,
-        "text": "File 2-1-1"
-    },
-    {
-        "id": 7,
-        "parent": 0,
-        "droppable": false,
-        "text": "File 3"
+export const theme = createTheme({
+    components: {
+        MuiCssBaseline: {
+            styleOverrides: {
+                "*": {
+                    margin: 0,
+                    padding: 0
+                },
+                "html, body, #root": {
+                    height: "100%"
+                },
+                ul: {
+                    listStyle: "none"
+                }
+            }
+        },
+        MuiSvgIcon: {
+            styleOverrides: {
+                root: { verticalAlign: "middle" }
+            }
+        }
     }
-];
-
+});
 
 
-const logTree = (treeData) => {
-    console.log(treeData.map(el => { return { id: el.id, parent: el.parent, text: el.text } }));
-}
-
-const CategoryTree = ({ elements }) => {
+const CategoryTree = ({ elements, saveCategory }) => {
     console.log(elements);
     const [treeData, setTreeData] = useState(elements);
-    const handleDrop = (newTree) => {
-        let a = '';
-        setTreeData(newTree);
-        logTree(newTree)
-    }
 
+    const handleDrop = (newTree, params) => {
+        let targetCat = params.dropTarget?.cat;
+        let sourceCat = params.dragSource?.cat;
+        if (!sourceCat)
+            throw new Error("No source");
+
+        if (sourceCat.parent?._id !== targetCat?._id) {
+            sourceCat.parent = targetCat ? { _id: targetCat._id, name: targetCat.name } : null;
+            saveCategory(sourceCat);
+            setTreeData(newTree);
+        }
+    }
     return (
-        <div>
+        <ThemeProvider theme={theme}>
+            <CssBaseline />
             <DndProvider backend={MultiBackend} options={getBackendOptions()}>
-                <Tree
-                    tree={treeData}
-                    rootId={0}
-                    render={(node, { depth, isOpen, onToggle }) => (
-                        <div style={{ marginInlineStart: depth * 10 }}>
-                            {node.droppable && (
-                                <span onClick={onToggle}>{isOpen ? "[-]" : "[+]"}</span>
-                            )}
-                            {node.text}
-                        </div>
-                    )}
-                    dragPreviewRender={(monitorProps) => (
-                        <div>{monitorProps.item.text}</div>
-                    )}
-                    onDrop={handleDrop}
-                />
+                <div className={styles.app}>
+                    <Tree
+                        style={{ listStyleType: 'none', paddingLeft: '0px', height: 240, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
+                        tree={treeData}
+                        rootId={0}
+                        render={(node, { depth, isOpen, onToggle }) => (
+                            <CategoryTreeItem
+                                node={node}
+                                depth={depth}
+                                isOpen={isOpen}
+                                onToggle={onToggle}
+                                saveCategoryName={(node, name) => {
+                                    if (!node?.cat || node.cat.name === name)
+                                        return;
+                                    node.text = node.cat.name = name;
+                                    saveCategory(node.cat);
+                                }}
+                            />
+                        )}
+                        dragPreviewRender={(monitorProps) => (
+                            <div>{monitorProps.item.text}</div>
+                        )}
+                        onDrop={handleDrop}
+                        classes={{
+                            root: styles.treeRoot,
+                            draggingSource: styles.draggingSource,
+                            dropTarget: styles.dropTarget
+                        }}
+                    />
+                </div>
             </DndProvider>
-        </div>
+        </ThemeProvider>
     );
 }
 
-let index = 1;
-function wrapToTreeItems(cats, parentCat = undefined, catTreeItems = undefined) {
+let index = 2;
+function wrapToTreeItems(cats, parentCat = null, catTreeItems = undefined) {
     catTreeItems ??= [];
     if (cats) {
         for (let cat of cats) {
             let catTreeItem = {
                 "id": index++,
-                "parent": parentCat?.id ?? 0,
+                "parent": parentCat?.id ?? 1,
                 "droppable": true,
                 "text": cat.name,
-                "cat": cat
+                "cat": { _id: cat._id, name: cat.name, parent: parentCat?.cat ?? null }
             };
             catTreeItems.push(catTreeItem);
             wrapToTreeItems(cat.subCategories, catTreeItem, catTreeItems)
@@ -114,7 +113,24 @@ function wrapToTreeItems(cats, parentCat = undefined, catTreeItems = undefined)
 const CCategoryTree = () => {
     const { isLoading, data } = useGetRootCategoriesQuery(true);
     let cats = data?.CategoryFind;
-    return !isLoading && cats && <CategoryTree elements={wrapToTreeItems(cats)} />
+
+    let catTreeItems = [];
+    let rootCat = {
+        id: 1,
+        parent: 0,
+        droppable: true,
+        text: "...",
+        cat: null
+    }
+    catTreeItems.push(rootCat);
+
+    const [saveCategoryMutation] = useSaveCategoryMutation(true);
+
+    const saveCategory = async (category) => {
+        await saveCategoryMutation({ category });
+    }
+
+    return !isLoading && cats && <CategoryTree elements={wrapToTreeItems(cats, rootCat, catTreeItems)} saveCategory={saveCategory} />
 }
 
 export { CCategoryTree };

+ 15 - 0
src/Components/CategoryTree.module.css

@@ -0,0 +1,15 @@
+.app {
+    height: 100%;
+}
+
+.treeRoot {
+    height: 100%;
+}
+
+.draggingSource {
+    opacity: .3;
+}
+
+.dropTarget {
+    background-color: #e8f0fe;
+}

+ 60 - 0
src/Components/CategoryTreeItem.js

@@ -0,0 +1,60 @@
+import React from "react";
+import { TextField } from "@mui/material";
+import ArrowRightIcon from "@mui/icons-material/ArrowRight";
+import styles from "./CategoryTreeItem.module.css";
+import ListAltIcon from "@mui/icons-material/ListAlt";
+
+export const CategoryTreeItem = (props) => {
+    const { droppable, data } = props.node;
+    const indent = props.depth * 40;
+
+    const handleToggle = (e) => {
+        e.stopPropagation();
+        props.onToggle(props.node.id);
+    };
+
+    return (
+        <div
+            className={`tree-node ${styles.root}`}
+            style={{ paddingInlineStart: indent }}
+        >
+            <div
+                className={`${styles.expandIconWrapper} ${props.isOpen ? styles.isOpen : ""
+                    }`}
+            >
+                {props.node.droppable && (
+                    <div onClick={handleToggle}>
+                        <ArrowRightIcon color="secondary" />
+                    </div>
+                )}
+            </div>
+            <div>
+                <ListAltIcon color="secondary" droppable={droppable} fileType={data?.fileType} />
+            </div>
+            <div className={styles.labelGridItem}>
+                <TextField
+                    color="primary"
+                    InputProps={{
+                        sx: {
+                            "& input": {
+                                fontSize: "1.5em",
+                                display: 'flex',
+                                alignItems: 'center',
+                                color: 'darkBlue',
+                                fontWeight: 'bold',
+                            }
+                        },
+                    }}
+                    id="filled-basic" defaultValue={props.node.text} variant="filled" size="small"
+                    onBlur={e => props.saveCategoryName(props.node, e.target.value)}
+                    onKeyUp={(e) => {
+                        if (e.key === 'Escape') {
+                            e.target.value = e.target.defaultValue;
+                            console.log('Enter key pressed');
+                        }
+                    }}
+                />
+            </div>
+        </div>
+    );
+};

+ 30 - 0
src/Components/CategoryTreeItem.module.css

@@ -0,0 +1,30 @@
+.root {
+    align-items: center;
+    display: grid;
+    grid-template-columns: auto auto 1fr auto;
+    height: 62px;
+    padding-inline-end: 8px;
+  }
+  
+  .expandIconWrapper {
+    align-items: center;
+    font-size: 0;
+    cursor: pointer;
+    display: flex;
+    height: 50px;
+    justify-content: center;
+    width: 50px;
+    transition: transform linear .1s;
+    transform: rotate(0deg);
+  }
+  
+  .expandIconWrapper.isOpen {
+    transform: rotate(90deg);
+  }
+  
+  .labelGridItem {
+    padding-inline-start: 25px;
+    text-align:left;
+  }
+
+

+ 0 - 3
src/Components/DropDownList.js

@@ -130,9 +130,6 @@ export const CCategoryDropDownListUnstyled = ({ currentCat, onSetCategory, showC
     let cats = data?.CategoryFind;
     if (!isLoading && cats) {
         cats = wrapToTreeItems(cats);
-        if (cats[10].subCategories?.lenght > 1) {
-            let a = '';
-        }
         let selectedIndex = cats.findIndex(c => c.key == currentCat?._id);
         return <DropDownList elements={cats} selectedIndex={selectedIndex} onSetCategory={onSetCategory} showClearButton={showClearButton} />
     }

+ 1 - 4
src/Components/EditableCategory.js

@@ -1,10 +1,9 @@
 import { useSelector } from "react-redux"
 import { useParams } from "react-router-dom";
 import { Button, Card, CardActions, CardContent, CardMedia, Container, Grid, TextField, Typography } from "@mui/material";
-import { useEffect, useState } from "react";
+import { useState } from "react";
 import { getFullImageUrl, saveImage } from "../utills/utils";
 import { isCurrentUserAdmin, useGetCategoryByIdQuery, useSaveCategoryMutation } from "../reducers";
-import { DeleteOutline, UndoRounded } from "@mui/icons-material";
 import { CCategoryDropDownList } from "./DropDownList";
 
 const EditableCategory = ({ category: categoryExt, maxWidth = 'md', saveCategory }) => {
@@ -29,8 +28,6 @@ const EditableCategory = ({ category: categoryExt, maxWidth = 'md', saveCategory
     const uploadAvatar = async param => {
         let image = await saveImage({ data: param.target.files[0] }, false);
         setCategoryData({ image });
-        /*let categoryToSave = { _id: category._id, name: categoryExt.name || category.name, image: { _id: image._id } };
-        saveCategory({ category: categoryToSave });*/
     }
 
     return category && (

+ 0 - 16
src/Components/EditableGood.js

@@ -177,19 +177,3 @@ const CEditableGood = ({ maxWidth = 'md' }) => {
 
 
 export { CEditableGood }
-
-
-/*-good.categories.map(cat => (
-    <Grid item width="100%">
-        <TextField
-            required
-            id="outlined-required"
-            label="Categories"
-            value={cat.name}
-            onChange={event => setGoodData({ description: event.target.value })}
-            multiline={true}
-            rows={1}
-            fullWidth
-        />
-    </Grid>
-))*/

+ 1 - 1
src/Components/EditableUser.js

@@ -1,5 +1,5 @@
 import { useSelector } from "react-redux"
-import { frontEndNames, getCurrentEntity, getCurrentUser, useSaveUserMutation, useUserFindQuery } from "../reducers";
+import { getCurrentUser, useSaveUserMutation, useUserFindQuery } from "../reducers";
 import { useParams } from "react-router-dom";
 import { Button, Card, CardActions, CardContent, CardMedia, Checkbox, Container, FormControlLabel, FormGroup, Grid, InputAdornment, TextField, Typography } from "@mui/material";
 import { useEffect, useState } from "react";

+ 2 - 46
src/Components/FileDropZone.js

@@ -1,11 +1,10 @@
-import { Paper } from '@mui/material';
 import React, { useCallback, useState } from 'react'
 import { useDropzone } from 'react-dropzone'
 
 function FileDropZone({ onDropFiles }) {
   const [paths, setPaths] = useState([]);
   const onDrop = useCallback(acceptedFiles => {
-    // Do something with the files
+
     acceptedFiles = acceptedFiles.map(f => {
       let url = URL.createObjectURL(f)
       return { _id: null, name: f.path, url, data: f }
@@ -14,7 +13,7 @@ function FileDropZone({ onDropFiles }) {
     setPaths(acceptedFiles);
     onDropFiles(acceptedFiles);
   }, [setPaths])
-  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
+  const { getRootProps, getInputProps } = useDropzone({ onDrop })
   console.log(paths);
   return (
     <>
@@ -23,9 +22,6 @@ function FileDropZone({ onDropFiles }) {
         <div style={{backgroundColor: 'lightgrey', minHeight: '100px', margin:'auto', display: 'inline-block'}} >
           {
             <p>Drop the files here ...</p>
-            /*isDragActive ?
-              <p>Drop the files here ...</p> :
-              <p>Drag 'n' drop some files here, or click to select files</p>*/
         }
         </div>
       </div>
@@ -33,44 +29,4 @@ function FileDropZone({ onDropFiles }) {
   )
 }
 
-const DropZone = ({ isDragActive }) => {
-  <Paper>
-    {
-      isDragActive ?
-        <p>Drop the files here ...</p> :
-        <p>Drag 'n' drop some files here, or click to select files</p>
-    }
-  </Paper>
-
-}
-/*
-              {
-                paths.map(
-                    f => 
-                    <img key={f.name} src={f.url} />
-               )
-            }
-*/
-
-/*export function MyDropzone() {
-  const [paths, setPaths] = useState([]);
-
-  const onDrop = useCallback(acceptedFiles => {
-    setPaths(acceptedFiles.map(file => URL.createObjectURL(file)));
-  }, [setPaths]);
-  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
-
-  return (
-    <div>
-      <div {...getRootProps()}>
-        <input {...getInputProps()} />
-        <p>Drop the files here ...</p>
-      </div>
-      {paths.map(path => 
-        <img key={path} src={path} />
-       )}
-    </div>
-  );
-}*/
-
 export { FileDropZone }

+ 2 - 3
src/Components/Good.js

@@ -5,7 +5,7 @@ import { Container, Typography, Grid, CardActionArea, Card, CardContent, CardMed
 import { getFullImageUrl } from "./../utills";
 import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
 import { AvatarAnimated } from './AvatarAnimated';
-import { actionAddGoodToCart, actionSetCurrentEntity, frontEndNames, getCurrentUser, isCurrentUserAdmin } from '../reducers';
+import { actionAddGoodToCart, isCurrentUserAdmin } from '../reducers';
 import { useDispatch, useSelector } from 'react-redux';
 import { useGetGoodByIdQuery } from '../reducers';
 import { useParams } from 'react-router-dom';
@@ -38,7 +38,7 @@ export const AvatarGroupOriented = styled((props) => {
         marginLeft: 1,
         marginTop: theme.spacing(1),
     },
-    ".MuiAvatar-root": { /*width: 20, height: 20,*/ marginLeft: 1 }
+    ".MuiAvatar-root": { marginLeft: 1 }
 }));
 
 
@@ -157,5 +157,4 @@ const CGood = ({ good, maxWidth = 'md', showAddToCard = true, editable = true })
     let isAdmin = isCurrentUserAdmin(state);
     return isLoading ? <LoadingState /> : <Good good={good} isAdmin={isAdmin} maxWidth={maxWidth} showAddToCard={showAddToCard} editable={editable} actionAddGoodToCart={() => dispatch(actionAddGoodToCart(good))} />
 }
-let a = '';
 export { CGood };

+ 0 - 1
src/Components/LoginForm.js

@@ -1,6 +1,5 @@
 import React, { useState } from 'react';
 import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
-import Button from '@mui/material/Button';
 import { Container, CssBaseline, TextField, Avatar, Typography, FormControlLabel, Checkbox, Grid, Link } from '@mui/material';
 import { Box } from '@mui/system';
 import { connect, useDispatch } from 'react-redux';

+ 4 - 3
src/Components/MainAppBar.js

@@ -17,11 +17,11 @@ import LoginIcon from '@mui/icons-material/Login';
 import CategoryIcon from '@mui/icons-material/Category';
 import SupervisedUserCircleIcon from '@mui/icons-material/SupervisedUserCircle';
 import WorkHistoryIcon from '@mui/icons-material/WorkHistory';
-import { Badge, Paper, Tooltip } from '@mui/material';
+import { Badge, Tooltip } from '@mui/material';
 import logo from '../images/logo.jpg';
+import AccountTreeIcon from '@mui/icons-material/AccountTree';
 
 const MainAppBar = ({ token, openSidebar }) => {
-    const theme = useTheme();
     const cartItemsCount = useSelector(state => getCartItemsCount(state) ?? 0);
     let currentUser = useSelector(state => new UserEntity(state.auth?.currentUser ?? { _id: null }));
     let isAdmin = currentUser?.isAdminRole === true;
@@ -57,7 +57,8 @@ const MainAppBar = ({ token, openSidebar }) => {
                         <>
                             {isAdmin && (
                                 <>
-                                    <MyLink to="/catree"><Button sx={{ color: "white" }}><Tooltip title="Categories"><CategoryIcon /></Tooltip></Button></MyLink>
+                                    <MyLink to="/categories"><Button sx={{ color: "white" }}><Tooltip title="Categories"><CategoryIcon /></Tooltip></Button></MyLink>
+                                    <MyLink to="/catree"><Button sx={{ color: "white" }}><Tooltip title="Categories Tree"><AccountTreeIcon/></Tooltip></Button></MyLink>
                                     <MyLink to="/users"><Button sx={{ color: "white" }}><Tooltip title="Users"><SupervisedUserCircleIcon /></Tooltip></Button></MyLink>
                                 </>
                             )}

+ 1 - 1
src/Components/ModalContainer.js

@@ -33,7 +33,7 @@ const ModalContainer = ({ children, onCloseClick }) =>
   <ModalOverlay>
     <Modal>
       <ModalClose onClick={onCloseClick}>
-        &#10005; {/* HTML code for a multiplication sign */}
+        &#10005; {}
       </ModalClose>
       {children}
     </Modal>

+ 3 - 4
src/Components/Order.js

@@ -1,11 +1,10 @@
-import React, { useEffect } from 'react';
+import React from 'react';
 import { Typography } from "@mui/material"
 import { Box, Container } from "@mui/system"
-import { connect, useDispatch, useSelector } from "react-redux"
-import { actionOrderFindOne, getCurrentOrder, useGetOrderByIdQuery } from "../reducers/ordersReducer"
+import { useSelector } from "react-redux"
+import { useGetOrderByIdQuery } from "../reducers/ordersReducer"
 import { OrderGoodsList } from "./OrderGoodsList"
 import { useParams } from 'react-router-dom/cjs/react-router-dom';
-import { actionSetCurrentEntity, frontEndNames } from '../reducers/frontEndReducer';
 import { MyLink } from './MyLink';
 import { getCurrentUser } from '../reducers';
 import { UserEntity } from '../Entities';

+ 1 - 4
src/Components/OrderGood.js

@@ -1,8 +1,6 @@
-import { Paper, Avatar, Box, Container, Grid, Table, TableBody, TableContainer, TableHead, TableRow, TableCell, tableCellClasses, Typography } from "@mui/material";
-import { Good } from "./Good";
+import { Typography } from "@mui/material";
 import { getFullImageUrl } from "./../utills";
 import { AvatarImage } from "./AvatarAnimated";
-import { styled } from '@mui/material/styles';
 import { StyledTableCell, StyledTableRow } from "./StyledTableElements";
 import "./orderGood.css"
 import { MyLink } from "./MyLink";
@@ -51,7 +49,6 @@ const OrderGood = ({ orderGood, orderGoodNum }) => {
                     </Typography>
                 </StyledTableCell>
             </StyledTableRow>
-            {/*<Good good={{ ...orderGood.good, ...orderGood }} showAddToCard={false} />*/}
         </>
     )
 }

+ 2 - 2
src/Components/OrderList.js

@@ -1,8 +1,8 @@
 import React from 'react';
-import { Container, Typography, Paper, Link } from '@mui/material';
+import { Container, Typography, Paper } from '@mui/material';
 import { Table, TableBody, TableContainer, TableHead, TableRow } from "@mui/material";
 import { StyledTableCell, StyledTableRow } from './StyledTableElements';
-import { COrdersPagination, CPagination } from './Pagination';
+import { CPagination } from './Pagination';
 import { CSearchInput } from './SearchInput';
 import { MyLink, ReferenceLink } from '.';
 import { useSelector } from 'react-redux';

+ 3 - 5
src/Components/RegisterForm.js

@@ -1,15 +1,13 @@
 import React, { useState } from 'react';
 import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
-import { Container, CssBaseline, TextField, Avatar, Typography, FormControlLabel, Checkbox, Grid, Link } from '@mui/material';
+import { Container, CssBaseline, TextField, Avatar, Typography, FormControlLabel, Checkbox } from '@mui/material';
 import { Box } from '@mui/system';
 import { connect, useDispatch } from 'react-redux';
 import { MyLink } from './MyLink';
-import { actionAboutMe, useLoginMutation, useRegisterMutation, useSaveUserMutation } from '../reducers/authReducer';
-import { UserEntity } from '../Entities';
+import { actionAboutMe, useLoginMutation, useRegisterMutation } from '../reducers/authReducer';
 
 const RegisterForm = () => {
     const [onRegister, { isLoading: isLoadingReg }] = useRegisterMutation();
-    const [onSaveUser, { data, isLoading }] = useSaveUserMutation();
 
     const [onLogin, { }] = useLoginMutation();
     const dispatch = useDispatch()
@@ -19,7 +17,7 @@ const RegisterForm = () => {
     const [password, setPassword] = useState('');
     const [passwordRetype, setPasswordRetype] = useState('');
     const arePasswordsEqual = password === passwordRetype;
-    const isButtonActive = !isLoading && !isLoadingReg && arePasswordsEqual && login?.length > 3 && password?.length > 3;
+    const isButtonActive = !isLoadingReg && arePasswordsEqual && login?.length > 3 && password?.length > 3;
     return (
         <Container component="main" maxWidth="xs">
             <CssBaseline />

+ 1 - 18
src/Components/SortedFileDropZone.js

@@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
 import { CSS } from "@dnd-kit/utilities";
 import { FileDropZone } from "./FileDropZone";
 import { getFullImageUrl } from "../utills";
-import { Avatar, Box, CardMedia, Paper } from "@mui/material";
+import { CardMedia, Paper } from "@mui/material";
 
 const SortableItem = (props) => {
     const {
@@ -19,17 +19,7 @@ const SortableItem = (props) => {
     const itemStyle = {
         transform: CSS.Transform.toString(transform),
         transition,
-        //width: 110,
-        //height: 30,
-        //display: "flex",
-        //alignItems: "center",
-        //paddingLeft: 5,
-        //border: "1px solid gray",
-        //borderRadius: 5,
-        //marginBottom: 5,
-        //userSelect: "none",
         cursor: "grab",
-        //boxSizing: "border-box"
     };
 
     const Render = props.render
@@ -45,13 +35,6 @@ const SortableItem = (props) => {
 const Droppable = ({ id, items = [], itemProp, keyField, render }) => {
     const { setNodeRef } = useDroppable({ id });
 
-    const droppableStyle = {
-        //padding: "20px 10px",
-        //border: "1px solid black",
-        //borderRadius: "5px",
-        //minWidth: 110
-    };
-
     return (
         <SortableContext id={id} items={items} strategy={rectSortingStrategy}>
             {items.map((item) => (

+ 1 - 1
src/Components/UsersList.js

@@ -2,7 +2,7 @@ import React from 'react';
 import { Container, Typography, Paper, Link } from '@mui/material';
 import { Table, TableBody, TableContainer, TableHead, TableRow } from "@mui/material";
 import { StyledTableCell, StyledTableRow } from './StyledTableElements';
-import { CPagination, CUsersPagination } from './Pagination';
+import { CPagination } from './Pagination';
 import { CSearchInput } from './SearchInput';
 import { MyLink } from '.';
 import { useSelector } from 'react-redux';

+ 2 - 6
src/Entities/UserEntity.js

@@ -16,13 +16,10 @@ export class UserEntity {
     #fixRoles = () => {
         let _id = this._id;
         let acl = this.#acl;
-        if( this.login === 'berg'){
-            let a = '';
-        }
         let onlyAllowedAcls = acl.filter(a => a === this._id || a === "user" || a === "admin");
-        if (onlyAllowedAcls.length != acl.length) {
+        if (onlyAllowedAcls.length !== acl.length) {
             let uniqueRoles = new Set(onlyAllowedAcls);
-            if (uniqueRoles.length != acl.length) {
+            if (uniqueRoles.length !== acl.length) {
                 this.#acl = acl = [...uniqueRoles];
             }
         }
@@ -58,7 +55,6 @@ export class UserEntity {
     #isRole = (role) => this.#getRoleIdx(role) >= 0;
     get isAdminRole() { return this.#isRole("admin"); }
     get isUserRole() {
-        let a = '';
         return this.#isRole("user");
     }
     onSetRoleInt = () => {

+ 0 - 5
src/index.js

@@ -7,14 +7,9 @@ import reportWebVitals from './reportWebVitals';
 const root = ReactDOM.createRoot(document.getElementById('root'));
 
 
-{/*} <React.StrictMode>*/ }
-{/*} </React.StrictMode>*/ }
 root.render(
   <App />
 );
 
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
 reportWebVitals();
 

+ 2 - 14
src/reducers/authReducer.js

@@ -2,11 +2,10 @@ import { gql } from "graphql-request";
 import { createApi } from '@reduxjs/toolkit/query/react'
 import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query' //npm install
 import { jwtDecode } from "../utills";
-import { createSlice, current } from "@reduxjs/toolkit";
+import { createSlice } from "@reduxjs/toolkit";
 import { history } from "../App";
 import { UserEntity } from "../Entities";
 import { createFullQuery } from "../gql";
-//import { prepareHeaders } from "./index";
 
 const getUsersSearchParams = (searchStr, queryExt) => (
     {
@@ -115,8 +114,7 @@ const authSlice = createSlice({
     name: 'auth',
     initialState: {},
     reducers: {
-        logout(state) { //type - auth/logout
-            // state.token = undefined
+        logout(state) { 
             history.push('/');
             return {}
         }
@@ -138,16 +136,6 @@ const authSlice = createSlice({
                 if (retrievedUser?._id === state.currentUser?._id)
                     state.currentUser = retrievedUser;
             });
-        builder.addMatcher(authApi.endpoints.saveUser.matchFulfilled,
-            (state, { payload }) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(authApi.endpoints.saveUser.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
     }
 })
 

+ 7 - 8
src/reducers/cartReducer.js

@@ -1,17 +1,16 @@
-import { createSlice, current } from "@reduxjs/toolkit"
+import { createSlice } from "@reduxjs/toolkit"
 import { v4 } from "uuid";
 import { history } from "../App";
 import { findObjectIndexById } from "../utills";
 import { ordersApi } from "./ordersReducer";
-//import { clearCartData, getCartData } from "./cartGoodsReducer";
 
-const cartSlice = createSlice({ //promiseReducer
+const cartSlice = createSlice({ 
     name: 'cart', //префикс типа наподобие AUTH_
     initialState: {
         goods: []
     },
     reducers: {
-        restoreCart(state, action) {
+        restoreCart(state) {
             let goods = localStorage.cart?.goods ?? [];
             if (!goods) {
                 goods = [];
@@ -20,10 +19,10 @@ const cartSlice = createSlice({ //promiseReducer
             setStateData(state, goods, v4());
             return state;
         },
-        cleanCart(state, action) {
+        cleanCart(state) {
             return cleanCartInt(state);
         },
-        refreshCart(state, action) {
+        refreshCart(state) {
             state.uniqueId = v4();
             return state;
         },
@@ -110,8 +109,8 @@ const setStateData = (state, goods, uniqueId = undefined) => {
 
 
 export {
-    cartSlice, /*getCart,*/
+    cartSlice, 
     actionAddGoodToCart, actionDeleteGoodFromCart, actionRestoreCart,
-    actionClearCart/*, actionClearCartData*/,
+    actionClearCart,
     getCartItemsCount
 };

+ 9 - 15
src/reducers/categoryReducer.js

@@ -30,7 +30,7 @@ export const categoryApi = createApi({
                         }
                     }
                 `}),
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [...result.CategoryFind.map(obj => ({ type: 'Category', _id: obj._id })), 'Category']
                     : ['Category'];
@@ -52,7 +52,7 @@ export const categoryApi = createApi({
                     variables: params
                 }
             },
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [...result.CategoryFind.map(obj => ({ type: 'Category', _id: obj._id })), 'Category']
                     : ['Category'];
@@ -70,9 +70,6 @@ export const categoryApi = createApi({
             },
             providesTags: ['CategoryCount'],
         }),
-        /*forceRefetch(arg) {
-            return JSON.stringify(arg.currentArg) !== JSON.stringify(arg.previousArg);
-        },*/
         getCategoryById: builder.query({
             query: (_id) => ({
                 document: gql`
@@ -89,7 +86,7 @@ export const categoryApi = createApi({
                     `,
                 variables: { q: JSON.stringify([{ _id }]) }
             }),
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [{ type: 'Category', _id: result.CategoryFindOne._id }, 'Category']
                     : ['Category'];
@@ -110,6 +107,12 @@ export const categoryApi = createApi({
                     variables: { category: { ...category } }
                 }
             ),
+            transformResponse: (response) => {
+                return response;
+            },
+            transformErrorResponse: (response) => {
+                return response;
+            },
             invalidatesTags: (result, error, arg) => {
                 if (!error) {
                     let catInv = { type: 'Category', _id: arg.category._id };
@@ -120,14 +123,5 @@ export const categoryApi = createApi({
     }),
 })
 
-/*export const categoryApi = categoryApiInt.enhanceEndpoints({
-    endpoints: {
-        getCategoriesCount(endpoint) {
-            endpoint.refetchOnMountOrArgChange = true;
-        }
-    }
-})*/
-
-
 export const { useGetRootCategoriesQuery, useGetCategoryByIdQuery, useGetCategoriesQuery, useGetCategoriesCountQuery, useSaveCategoryMutation } = categoryApi;
 

+ 1 - 61
src/reducers/frontEndReducer.js

@@ -1,4 +1,4 @@
-import { createSlice, current } from "@reduxjs/toolkit"
+import { createSlice } from "@reduxjs/toolkit"
 import { categoryApi } from "./categoryReducer";
 import { goodsApi } from "./goodsReducer";
 import { ordersApi } from "./ordersReducer";
@@ -69,66 +69,6 @@ const frontEndSlice = createSlice({ //promiseReducer
             (state, { payload }) => {
                 setEntitiesCount(frontEndNames.category, state, payload.CategoryCount);
             });
-        builder.addMatcher(ordersApi.endpoints.getOrders.matchFulfilled,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(ordersApi.endpoints.getOrders.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(ordersApi.endpoints.getOrderById.matchFulfilled,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(ordersApi.endpoints.getOrderById.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(goodsApi.endpoints.saveGood.matchFulfilled,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(goodsApi.endpoints.saveGood.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(goodsApi.endpoints.getGoodById.matchFulfilled,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(goodsApi.endpoints.getGoodById.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(goodsApi.endpoints.getGoods.matchFulfilled,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(goodsApi.endpoints.getGoods.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(categoryApi.endpoints.saveCategory.matchFulfilled,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
-        builder.addMatcher(categoryApi.endpoints.saveCategory.matchRejected,
-            (state, data) => {
-                let a = '';
-                let b = '';
-            });
     }
 })
 

+ 3 - 4
src/reducers/goodsReducer.js

@@ -2,7 +2,6 @@ import { createApi } from '@reduxjs/toolkit/query/react'
 import { graphqlRequestBaseQuery } from "@rtk-query/graphql-request-base-query"
 import { gql } from "graphql-request";
 import { createFullQuery } from '../gql';
-//import { prepareHeaders } from "./index";
 
 export const prepareHeaders = (headers, { getState }) => {
     const token = getState().auth.token;
@@ -43,7 +42,7 @@ export const goodsApi = createApi({
                     variables: params
                 }
             },
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [...result.GoodFind.map(obj => ({ type: 'Good', _id: obj._id })), 'Good']
                     : ['Good'];
@@ -77,7 +76,7 @@ export const goodsApi = createApi({
                     variables: params
                 }
             },
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [{ type: 'Good', _id: result.GoodFindOne?._id }, 'Good']
                     : ['Good'];
@@ -98,7 +97,7 @@ export const goodsApi = createApi({
                     variables: params
                 }
             },
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [...result.GoodFind.map(obj => ({ type: 'Good', _id: obj._id })), 'Good']
                     : ['Good'];

+ 6 - 8
src/reducers/ordersReducer.js

@@ -1,8 +1,6 @@
 import { createApi } from '@reduxjs/toolkit/query/react'
 import { graphqlRequestBaseQuery } from "@rtk-query/graphql-request-base-query"
 import { gql } from "graphql-request";
-import { useSelector } from 'react-redux';
-import { frontEndNames, getCurrentEntity } from '.';
 import { createFullQuery } from '../gql';
 
 const getOrderSearchParams = (query, queryExt) => ({ searchStr: query, searchFieldNames: ["_id"], queryExt });
@@ -46,15 +44,15 @@ const ordersApi = createApi({
                     variables: params
                 }
             },
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [...result.OrderFind.map(obj => ({ type: 'Order', _id: obj._id })), 'Order']
                     : ['Order'];
             },
-            transformResponse: (response, meta, arg) => {
+            transformResponse: (response) => {
                 return response;
             },
-            transformErrorResponse: (response, meta, arg) => {
+            transformErrorResponse: (response, meta) => {
                 return {...response, ...meta.response?.data} ;
             },
         }),
@@ -97,15 +95,15 @@ const ordersApi = createApi({
                     variables: params
                 }
             },
-            providesTags: (result, error, arg) => {
+            providesTags: (result) => {
                 return result
                     ? [{ type: 'Order', _id: result.OrderFindOne._id }, 'Order']
                     : ['Order'];
             },
-            transformResponse: (response, meta, arg) => {
+            transformResponse: (response) => {
                 return response;
             },
-            transformErrorResponse: (response, meta, arg) => {
+            transformErrorResponse: (response, meta) => {
                 return {...response, ...meta.response?.data} ;
             },
         }),

+ 0 - 30
src/reducers/promiseReducer.js

@@ -42,33 +42,3 @@ let actionPending = promiseReducerSlice.actions.pending;
 let actionFulfilled = promiseReducerSlice.actions.fulfilled;
 let actionRejected = promiseReducerSlice.actions.rejected;
 export { promiseReducer, actionPending, actionFulfilled, actionRejected, actionPromise, createPromiseReducerSlice, actionPromiseGeneric };
-
-/*export function promiseReducer(state = {}, action) {                   // диспетчер обработки
-    if (action) {
-        if (action.type === 'PROMISE') {
-            let newState = { ...state };
-            newState[action.name] = { status: action.status, payload: action.payload, error: action.error };
-            return newState;
-        }
-    }
-    return state;
-}
-export const actionPending = (name) => ({ type: 'PROMISE', name: name, status: 'PENDING' });
-export const actionFulfilled = (name, payload) => ({ type: 'PROMISE', name: name, payload: payload, status: 'FULFILLED' });
-export const actionRejected = (name, error) => ({ type: 'PROMISE', name: name, error: error, status: 'REJECTED' });
-export const actionPromise = (name, promise) => {
-    return async (dispatch) => {
-        dispatch(actionPending(name)) //сигнализируем redux, что промис начался
-        try {
-            let payload = await promise //ожидаем промиса
-            if (payload && payload.data)
-                payload = Object.values(payload.data)[0];
-            dispatch(actionFulfilled(name, payload)) //сигнализируем redux, что промис успешно выполнен
-            return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
-        }
-        catch (error) {
-            console.log(error.message);
-            dispatch(actionRejected(name, error)) //в случае ошибки - сигнализируем redux, что промис несложился
-        }
-    }
-}*/

BIN
src/theme_main.png


+ 0 - 22
src/utills/gql.js

@@ -13,28 +13,6 @@ function jwtDecode(token) {                         // расщифровки т
         return undefined;
     }
 }
-/*function combineReducers(reducers) {
-    function totalReducer(totalState = {}, action) {
-        const newTotalState = {} //объект, который будет хранить только новые состояния дочерних редьюсеров
-
-        //цикл + квадратные скобочки позволяют написать код, который будет работать с любыми количеством дочерных редьюсеров
-        for (const [reducerName, childReducer] of Object.entries(reducers)) {
-            const newState = childReducer(totalState[reducerName], action) //запуск дочернего редьюсера
-            if (newState !== totalState[reducerName]) { //если он отреагировал на action
-                newTotalState[reducerName] = newState //добавляем его в newTotalState
-            }
-        }
-
-        //Универсальная проверка на то, что хотя бы один дочерний редьюсер создал новый стейт:
-        if (Object.values(newTotalState).length) {
-            return { ...totalState, ...newTotalState } //создаем новый общий стейт, накладывая новый стейты дочерних редьюсеров на старые
-        }
-
-        return totalState //если экшен не был понят ни одним из дочерних редьюсеров, возвращаем общий стейт как был.
-    }
-
-    return totalReducer
-}*/
 
 function getGql(url) {
     return function gql(query, vars = undefined) {