Browse Source

add adminGoodCard

Vika 2 years ago
parent
commit
78be0dc603
40 changed files with 771 additions and 206 deletions
  1. 1 0
      project/my-project/.gitignore
  2. 117 6
      project/my-project/package-lock.json
  3. 3 0
      project/my-project/package.json
  4. 18 3
      project/my-project/src/App.css
  5. 0 3
      project/my-project/src/App.js
  6. 2 2
      project/my-project/src/action/actionAddGoodToCat.js
  7. 21 0
      project/my-project/src/action/actionChangeArrImgGood.js
  8. 4 3
      project/my-project/src/action/actionChangeOneGood.js
  9. 6 0
      project/my-project/src/action/actionClearFirstImg.js
  10. 18 0
      project/my-project/src/action/actionImg.js
  11. 3 0
      project/my-project/src/action/actionImgClear.js
  12. 2 2
      project/my-project/src/action/actionUploadFile.js
  13. 18 0
      project/my-project/src/action/actionUploadFirstImg.js
  14. 28 0
      project/my-project/src/action/actionUploadImg.js
  15. 6 0
      project/my-project/src/action/index.js
  16. 97 0
      project/my-project/src/components/additionalImages.js
  17. 0 1
      project/my-project/src/components/cNewGoodInCat.js
  18. 8 4
      project/my-project/src/components/cartChangeGood.js
  19. 45 0
      project/my-project/src/components/cartGoodAdmin.js
  20. 9 23
      project/my-project/src/components/category.js
  21. 28 12
      project/my-project/src/components/changeOfGood.js
  22. 22 4
      project/my-project/src/components/goodCardCharacteristic.js
  23. 25 0
      project/my-project/src/components/imgGood.js
  24. 4 0
      project/my-project/src/components/index.js
  25. 1 1
      project/my-project/src/components/listOrders.js
  26. 7 2
      project/my-project/src/components/signIn.js
  27. 84 0
      project/my-project/src/components/sortTableComponent.js
  28. 21 21
      project/my-project/src/components/switchRoute.js
  29. 4 48
      project/my-project/src/pages/mainPage.js
  30. 2 2
      project/my-project/src/pages/pageAdmin.js
  31. 58 0
      project/my-project/src/pages/pageUser.js
  32. 3 1
      project/my-project/src/reducer/index.js
  33. 16 0
      project/my-project/src/reducer/promiseImg.js
  34. 17 0
      project/my-project/src/reducer/uploaderReducer.js
  35. 31 29
      project/my-project/src/route/cRoute.js
  36. 1 1
      project/my-project/src/route/index.js
  37. 16 15
      project/my-project/src/route/privateRoute.js
  38. 1 1
      project/my-project/src/route/routeSite.js
  39. 20 20
      project/my-project/src/route/useRoute.js
  40. 4 2
      project/my-project/src/store/index.js

+ 1 - 0
project/my-project/.gitignore

@@ -21,3 +21,4 @@
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
+/react2/

+ 117 - 6
project/my-project/package-lock.json

@@ -12,6 +12,8 @@
         "@testing-library/react": "^12.1.2",
         "@testing-library/user-event": "^13.5.0",
         "antd": "^4.18.2",
+        "antd-img-crop": "^4.1.0",
+        "array-move": "^4.0.0",
         "bootstrap": "^5.1.3",
         "react": "^17.0.2",
         "react-bootstrap": "^2.0.4",
@@ -20,6 +22,7 @@
         "react-redux": "^7.2.6",
         "react-router-dom": "^5.3.0",
         "react-scripts": "5.0.0",
+        "react-sortable-hoc": "^2.0.0",
         "redux-saga": "^1.1.3",
         "redux-thunk": "^2.4.1",
         "web-vitals": "^2.1.2"
@@ -1819,9 +1822,9 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.16.5",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-      "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
+      "version": "7.16.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
+      "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
       "dependencies": {
         "regenerator-runtime": "^0.13.4"
       },
@@ -4364,6 +4367,20 @@
         "react-dom": ">=16.9.0"
       }
     },
+    "node_modules/antd-img-crop": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/antd-img-crop/-/antd-img-crop-4.1.0.tgz",
+      "integrity": "sha512-41wH5kvn00fdWF1doN0MAXpTWjawUWbiOyDVuQGM8NIffs6YQ2ihgoVhaBMnbs9VCswrCAAHdo3nYL8B8Rg0tA==",
+      "dependencies": {
+        "@babel/runtime": "^7.16.7",
+        "react-easy-crop": "^4.0.1"
+      },
+      "peerDependencies": {
+        "antd": ">=4.0.0",
+        "react": ">=16.8.0",
+        "react-dom": ">=16.8.0"
+      }
+    },
     "node_modules/anymatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@@ -4424,6 +4441,17 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/array-move": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/array-move/-/array-move-4.0.0.tgz",
+      "integrity": "sha512-+RY54S8OuVvg94THpneQvFRmqWdAHeqtMzgMW6JNurHxe8rsS07cHQdfGkXnTUXiBcyZ0j3SiDIxxj0RPiqCkQ==",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/array-tree-filter": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
@@ -11565,6 +11593,11 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
+    },
     "node_modules/npm-run-path": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -14238,6 +14271,24 @@
         "react": ">= 16.8"
       }
     },
+    "node_modules/react-easy-crop": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-4.0.1.tgz",
+      "integrity": "sha512-cREis2557y/ZkvgiNaLlFrzjduUSUvEYYxbglwggpo2gnxCjBQZeRgAPoedvXX0e0BgyGAI0zD3motVucJGhzA==",
+      "dependencies": {
+        "normalize-wheel": "^1.0.1",
+        "tslib": "2.0.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.4.0",
+        "react-dom": ">=16.4.0"
+      }
+    },
+    "node_modules/react-easy-crop/node_modules/tslib": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz",
+      "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ=="
+    },
     "node_modules/react-error-overlay": {
       "version": "6.0.10",
       "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.10.tgz",
@@ -14412,6 +14463,21 @@
         }
       }
     },
+    "node_modules/react-sortable-hoc": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz",
+      "integrity": "sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==",
+      "dependencies": {
+        "@babel/runtime": "^7.2.0",
+        "invariant": "^2.2.4",
+        "prop-types": "^15.5.7"
+      },
+      "peerDependencies": {
+        "prop-types": "^15.5.7",
+        "react": "^16.3.0 || ^17.0.0",
+        "react-dom": "^16.3.0 || ^17.0.0"
+      }
+    },
     "node_modules/react-transition-group": {
       "version": "4.4.2",
       "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
@@ -18526,9 +18592,9 @@
       }
     },
     "@babel/runtime": {
-      "version": "7.16.5",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-      "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
+      "version": "7.16.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz",
+      "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==",
       "requires": {
         "regenerator-runtime": "^0.13.4"
       }
@@ -20445,6 +20511,15 @@
         "scroll-into-view-if-needed": "^2.2.25"
       }
     },
+    "antd-img-crop": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/antd-img-crop/-/antd-img-crop-4.1.0.tgz",
+      "integrity": "sha512-41wH5kvn00fdWF1doN0MAXpTWjawUWbiOyDVuQGM8NIffs6YQ2ihgoVhaBMnbs9VCswrCAAHdo3nYL8B8Rg0tA==",
+      "requires": {
+        "@babel/runtime": "^7.16.7",
+        "react-easy-crop": "^4.0.1"
+      }
+    },
     "anymatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@@ -20493,6 +20568,11 @@
         "is-string": "^1.0.7"
       }
     },
+    "array-move": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/array-move/-/array-move-4.0.0.tgz",
+      "integrity": "sha512-+RY54S8OuVvg94THpneQvFRmqWdAHeqtMzgMW6JNurHxe8rsS07cHQdfGkXnTUXiBcyZ0j3SiDIxxj0RPiqCkQ=="
+    },
     "array-tree-filter": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
@@ -25714,6 +25794,11 @@
       "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
       "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
     },
+    "normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
+    },
     "npm-run-path": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -27481,6 +27566,22 @@
         "prop-types": "^15.7.2"
       }
     },
+    "react-easy-crop": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-4.0.1.tgz",
+      "integrity": "sha512-cREis2557y/ZkvgiNaLlFrzjduUSUvEYYxbglwggpo2gnxCjBQZeRgAPoedvXX0e0BgyGAI0zD3motVucJGhzA==",
+      "requires": {
+        "normalize-wheel": "^1.0.1",
+        "tslib": "2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz",
+          "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ=="
+        }
+      }
+    },
     "react-error-overlay": {
       "version": "6.0.10",
       "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.10.tgz",
@@ -27620,6 +27721,16 @@
         "workbox-webpack-plugin": "^6.4.1"
       }
     },
+    "react-sortable-hoc": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz",
+      "integrity": "sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==",
+      "requires": {
+        "@babel/runtime": "^7.2.0",
+        "invariant": "^2.2.4",
+        "prop-types": "^15.5.7"
+      }
+    },
     "react-transition-group": {
       "version": "4.4.2",
       "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",

+ 3 - 0
project/my-project/package.json

@@ -7,6 +7,8 @@
     "@testing-library/react": "^12.1.2",
     "@testing-library/user-event": "^13.5.0",
     "antd": "^4.18.2",
+    "antd-img-crop": "^4.1.0",
+    "array-move": "^4.0.0",
     "bootstrap": "^5.1.3",
     "react": "^17.0.2",
     "react-bootstrap": "^2.0.4",
@@ -15,6 +17,7 @@
     "react-redux": "^7.2.6",
     "react-router-dom": "^5.3.0",
     "react-scripts": "5.0.0",
+    "react-sortable-hoc": "^2.0.0",
     "redux-saga": "^1.1.3",
     "redux-thunk": "^2.4.1",
     "web-vitals": "^2.1.2"

+ 18 - 3
project/my-project/src/App.css

@@ -27,9 +27,9 @@
 a:link, a:visited {
   color: black;
 }
-
-/* .ant-menu-vertical>.ant-menu-item {
-  background-color: #e6f7ff;
+/* 
+.ant-menu-vertical>.ant-menu-item {
+  background-color: #a11952;
 }  */
 
 .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
@@ -80,3 +80,18 @@ a:link, a:visited {
   border-radius: 4px;
 }
 
+.additionalImg {
+  outline: 2px solid rgb(117, 9, 103);;
+  display: inline-block;
+  margin-left: 3px;
+}
+
+.sortTablelist {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+}
+
+.liSortTable {
+  display: block;
+}

+ 0 - 3
project/my-project/src/App.js

@@ -18,9 +18,6 @@ function App() {
           <MainPage></MainPage>
       </div>
       </Provider>
-
-<InputUpLoadFile/>
-
     </Router>
 
     

+ 2 - 2
project/my-project/src/action/actionAddGoodToCat.js

@@ -2,8 +2,8 @@ import { actionCatById, actionPromise } from ".";
 import gql from "../api";
 
 const actionAddGoodToCat = (_idCat, nameCat, nameGood) => 
-  (dispatch) => {
-    dispatch(actionPromise('addGoodToCat', gql(` mutation addGood($good:GoodInput){
+ async (dispatch) => {
+  await  dispatch(actionPromise('addGoodToCat', gql(` mutation addGood($good:GoodInput){
       GoodUpsert(good:$good){
         _id name 
       }

+ 21 - 0
project/my-project/src/action/actionChangeArrImgGood.js

@@ -0,0 +1,21 @@
+import { actionPromise } from "."
+import { actionGoodById } from "./index";
+import gql from "../api"
+
+const actionChangeArrInGood = (_id, arr) => 
+  async (dispatch) => {
+    await dispatch(actionPromise('changeArrInGood', gql(`mutation changeArrImgInGood ($good:GoodInput){
+      GoodUpsert(good:$good){
+        _id name
+      }
+    }`, {
+      "good": {
+        "_id": _id,
+        "images": arr,
+      }
+    })));
+
+    dispatch(actionGoodById(_id));
+  }
+
+export default actionChangeArrInGood; 

+ 4 - 3
project/my-project/src/action/actionChangeOneGood.js

@@ -1,7 +1,7 @@
 import { actionPromise, actionCatById } from ".";
 import gql from "../api";
 
-const actionChangeOneGood = (_id, name, description, price, idImg) =>
+const actionChangeOneGood = (_id, _idCat, name, description, price, idImg) =>
   async (dispatch) => {
     await dispatch(actionPromise('changeGood', gql(`mutation changeGood($good:GoodInput){
       GoodUpsert(good:$good){
@@ -13,11 +13,12 @@ const actionChangeOneGood = (_id, name, description, price, idImg) =>
           "description": description,
           "name": name, 
           "price": +price,
-          "images": [{"_id": idImg}]
+          // "images": [{"_id": idImg}]
+          "images": idImg,
         } 
     })))
 
-    dispatch(actionCatById())
+    dispatch(actionCatById(_idCat)); console.log('_idCattttttt', _idCat)
 }
 
 export default actionChangeOneGood; 

+ 6 - 0
project/my-project/src/action/actionClearFirstImg.js

@@ -0,0 +1,6 @@
+const actionClearFirstImg = () => {
+  console.log('ACTION ON DELETE UPLOAD')
+   return {type: 'UPLOAD_IMG_CLEAR'}
+};
+
+export default actionClearFirstImg;

+ 18 - 0
project/my-project/src/action/actionImg.js

@@ -0,0 +1,18 @@
+const actionPend  = name => ({type: 'IMG', status: 'PENDING', name})
+const actionResolv = (name, payload) => ({type: 'IMG', status: 'RESOLVED', name, payload})
+const actionReject = (name, error) => ({type: 'IMG', status: 'REJECTED', name,  error})
+
+const actionImg = (name, promise) =>
+  async (dispatch) => {
+      dispatch(actionPend(name)) 
+      try{
+          let payload = await promise
+          dispatch(actionResolv(name, payload))
+          return payload;
+      }
+      catch(error){
+          dispatch(actionReject(name, error))
+      }
+  }
+
+ export default actionImg; 

+ 3 - 0
project/my-project/src/action/actionImgClear.js

@@ -0,0 +1,3 @@
+const actionImgClear = () => ({type:'IMG_CLEAR'});
+
+export default actionImgClear;

+ 2 - 2
project/my-project/src/action/actionUploadFile.js

@@ -1,5 +1,5 @@
 import { connect } from "react-redux";
-import { actionPromise } from "./";
+import { actionUploadFirstImg  } from "./";
 import { backURL } from '../api';
 import { Upload, message, Button } from 'antd';
 import { UploadOutlined } from '@ant-design/icons';
@@ -9,7 +9,7 @@ const actionUploadFile = (file) => {
   const formData = new FormData();
   formData.append("photo", file[0]);
   
-   return actionPromise('upLoad',  fetch(`${backURL}/upload`, {
+   return actionUploadFirstImg ('upLoad',  fetch(`${backURL}/upload`, {
     method: "POST",
     headers: localStorage.authToken ? {Authorization: 'Bearer ' + localStorage.authToken} : {},
     body: formData

+ 18 - 0
project/my-project/src/action/actionUploadFirstImg.js

@@ -0,0 +1,18 @@
+const actionPend  = name => ({type: 'UPLOAD', status: 'PENDING', name})
+const actionResolv = (name, payload) => ({type: 'UPLOAD', status: 'RESOLVED', name, payload})
+const actionReject = (name, error) => ({type: 'UPLOAD', status: 'REJECTED', name,  error})
+
+const actionUploadFirstImg = (name, promise) =>
+  async (dispatch) => {
+      dispatch(actionPend(name)) 
+      try{
+          let payload = await promise
+          dispatch(actionResolv(name, payload))
+          return payload;
+      }
+      catch(error){
+          dispatch(actionReject(name, error))
+      }
+  }
+
+ export default actionUploadFirstImg; 

+ 28 - 0
project/my-project/src/action/actionUploadImg.js

@@ -0,0 +1,28 @@
+import { connect } from "react-redux";
+import { actionImg } from "./";
+import { backURL } from '../api';
+import { Upload, message, Button } from 'antd';
+import { UploadOutlined } from '@ant-design/icons';
+
+const actionUploadImg = (file, name) => {
+  const fileJson = JSON.stringify(file[0]);
+  const formData = new FormData();
+  formData.append("photo", file[0]);
+  
+   return actionImg(name,  fetch(`${backURL}/upload`, {
+    method: "POST",
+    headers: localStorage.authToken ? {Authorization: 'Bearer ' + localStorage.authToken} : {},
+    body: formData
+  })
+  .then(res => {
+    console.log('file', res)
+    return res.json();
+  }). then (data => {
+        if (data.errors && !data._id)
+            throw new Error(JSON.stringify(data.errors))
+        return data;
+})
+  )
+}
+
+export default actionUploadImg;

+ 6 - 0
project/my-project/src/action/index.js

@@ -14,4 +14,10 @@ export { default as actionChangeOneGood } from './actionChangeOneGood';
 export { default as actionSearchGood } from './actionSearchGood';
 export { default as actionChangeGoodsInCat } from './actionChangeGoodsInCat';
 export { default as actionAddGoodToCat } from './actionAddGoodToCat';
+export { default as actionImg } from './actionImg';
+export { default as actionUploadImg } from './actionUploadImg';
+export { default as actionChangeArrInGood } from './actionChangeArrImgGood';
+export { default as actionImgClear } from './actionImgClear';
+export { default as actionUploadFirstImg } from './actionUploadFirstImg';
+export {default as actionClearFirstImg } from './actionClearFirstImg';
 

+ 97 - 0
project/my-project/src/components/additionalImages.js

@@ -0,0 +1,97 @@
+import React, { useEffect, useState } from 'react';
+import { Upload, Button, Space } from 'antd';
+import ImgCrop from 'antd-img-crop'; 
+import { connect } from 'react-redux'; 
+import { backURL } from '../api'; 
+import { actionUploadImg, actionGoodById , actionChangeArrInGood, actionImgClear } from '../action';
+import { Link } from 'react-router-dom';
+
+
+const Additional = ({imgs, upload, _id, goodById, good, saveImg, imgClear}) => { 
+  const [fileList, setFileList] = useState([]);
+  //const [selectGood, setSelectGood] = useState(good);
+  
+  useEffect(() => {
+    goodById(_id);
+                               
+  }, [_id])
+                                                            console.log('gooood', good);
+  const onChange = ({ fileList: newFileList }) => {
+    setFileList(newFileList); console.log('newFileList', newFileList)
+  };
+
+  const onPreview = async file => {
+    let src = file.url; console.log('file', file)
+    if (!src) {
+      src = await new Promise(resolve => {
+        const reader = new FileReader();
+        reader.readAsDataURL(file.originFileObj);
+        reader.onload = () => resolve(reader.result);
+      });
+    }
+    const image = new Image();
+    image.src = src;
+    const imgWindow = window.open(src);
+    imgWindow.document.write(image.outerHTML);
+  };
+  const onChangeArrImg = () => {
+    
+    const newArrImg = [... good.images].map((item) => ({"_id": item._id}));        
+    for (let i = 0; i < Object.keys(imgs).length; i++) {
+      const newImgId = imgs[`${i}`].payload._id;
+      
+      newArrImg.push({"_id":newImgId});           
+      saveImg(good._id, newArrImg);
+    }
+  }
+
+  const onSave = async () => {
+    const newF = [...fileList].map((item) => [item.originFileObj]); 
+    const newFF = await  newF.map((item, index) => [upload(item, index)]); 
+    // await onChangeArrImg();
+    setFileList([]);
+    // imgClear(); 
+    
+  }
+
+  return (
+    <div>
+      <ImgCrop rotate>
+        <Upload
+          action=""
+          listType="picture-card"
+          fileList={fileList}
+          onChange={onChange}
+          onPreview={onPreview}
+        >
+          {fileList.length < 4 && '+ Добавить фото'}
+        </Upload>
+      </ImgCrop>
+     
+      <Space direction="vertical">
+        <Button type="primary" onClick={onSave}>Закачать</Button>
+        <Button type="primary" onClick={() => {onChangeArrImg(); imgClear()}}>Сохранить</Button>
+        <Link to={`/goodAdmin/${_id}`}>
+          <Button type="primary" >Просмотреть карточку товара</Button> 
+        </Link> 
+      </Space>
+      
+    </div>  
+  );
+};
+
+const mapStateToProps = (state) => ({
+  imgs: state.img || [],
+  good: state.promise.goodById?.payload || {},
+})
+
+const mapDispatchToProps = {
+  upload: actionUploadImg,
+  goodById: actionGoodById,
+  saveImg: actionChangeArrInGood, 
+  imgClear: actionImgClear,
+}
+
+const AdditionalImages = connect(mapStateToProps, mapDispatchToProps)(Additional);
+
+export default AdditionalImages;

+ 0 - 1
project/my-project/src/components/cNewGoodInCat.js

@@ -20,7 +20,6 @@ const NewGoodInCat = ({cat, add}) => {
     setNameGood('');
   }
 
-  console.log('_idCat', _idCat, nameCat, nameGood)  ;
   return (
     < >
       <Card type="inner" title="Добавить товар в категорию">

+ 8 - 4
project/my-project/src/components/cartChangeGood.js

@@ -2,11 +2,11 @@ import { Select,Card } from 'antd';
 import { useEffect, useState } from 'react';
 import { connect } from 'react-redux';
 import { СhangeOfGood } from '.';
-import { actionChangeOneGood, actionChangeGoodsInCat } from '../action';
+import { actionChangeOneGood, actionChangeGoodsInCat, actionImgClear, actionClearFirstImg } from '../action';
 
 const { Option } = Select;
 
-const SelectGood = ({goods, changeGood, changeGoodsInCat}) => { console.log('ggggg',goods)
+const SelectGood = ({goods, changeGood, changeGoodsInCat, imgClear, firstImgClear, _idCat}) => { console.log('_idCat',_idCat)
   
   const [goodsCat, setGoodsCat] = useState([]); 
   const [_id, setId] = useState('');
@@ -39,11 +39,13 @@ const SelectGood = ({goods, changeGood, changeGoodsInCat}) => { console.log('ggg
         return good._id === value}); 
       setSelectGood(...good);
       setId(value);
+      imgClear(); 
+      firstImgClear();
     }
 
     function changeGoodInSer (name, description, price, imgId) {
-      console.log("----", typeof name, typeof description, typeof price, typeof imgId )
-      changeGood(_id, name, description,price, imgId);
+                                                               
+      changeGood(_id, _idCat, name, description,price, imgId);
     }
     function changeIndexGoodInSer (number) {              
       if (numbSelectGood !== number && number > 0 ){                  
@@ -81,6 +83,8 @@ const mapStateToProps = (state) => ({
 const mapDispatchToProps = {
   changeGood : actionChangeOneGood,
   changeGoodsInCat: actionChangeGoodsInCat, 
+  imgClear: actionImgClear,
+  firstImgClear: actionClearFirstImg,
 }
 
 

+ 45 - 0
project/my-project/src/components/cartGoodAdmin.js

@@ -0,0 +1,45 @@
+import { connect } from 'react-redux';
+import { useState, useEffect } from 'react';
+import { GoodCardCharacteristic, SortableComponent  } from './index';
+import { Card } from 'antd';
+import { actionClearFirstImg, actionChangeArrInGood } from '../action';
+
+
+const CartGoodAdmin = ({good:{_id, images}, upLoad, clearUpLoad, onChangeArrInGood}) => {
+  const [arrImages, setArrImages] = useState(images);  
+  const [upl, setUpl] = useState(upLoad);
+
+  // useEffect(() => {
+  //    setArrImages(images);                       
+  // }, [images])
+    
+  // useEffect(() => {
+  //   setUpl(upLoad);
+  // }, [upLoad])
+    console.log('upLoad===========', upLoad)
+   return (
+    <Card>
+      <GoodCardCharacteristic/>
+      <div style={{textAlign:"center"}}>
+        <strong >Фото можно поменять местами</strong>
+      </div>
+      <div>
+      <SortableComponent images={images} idGood={_id} upLoad={upLoad} clearUpLoad={clearUpLoad} onChangeArrInGood={onChangeArrInGood} />
+      </div>
+    </Card>
+  )
+}
+
+const mapStateToProps = (state) => ({
+  good: state.promise.goodById?.payload || [],  
+  upLoad: state.upLoad.upLoad?.payload || '',
+});
+
+const mapDispatchToProps = {
+  clearUpLoad: actionClearFirstImg,
+  onChangeArrInGood: actionChangeArrInGood,
+};
+
+const CCartGoodAdmin = connect(mapStateToProps, mapDispatchToProps)(CartGoodAdmin);
+
+export default CCartGoodAdmin;

+ 9 - 23
project/my-project/src/components/category.js

@@ -9,28 +9,11 @@ import { jwtDecode } from "../utils";
 
 const { SubMenu } = Menu;
 
-const CategoryListItem = ({_id, name}) => {
-  const [userName, setUserName] = useState('user');
-  
-  useEffect( () => {
-    const token = localStorage.getItem('authToken'); 
-    //
-    if (token) { 
-      const name = jwtDecode(token)['sub']['acl']; 
-      name.includes('admin') ? setUserName('admin'):  setUserName('user'); 
-     
-    }
-  }, [localStorage.getItem('authToken')]);  
-  
+const CategoryListItem = ({_id, name, auth}) => {
+
   return (
     < > 
-
-
-      { userName === 'user' ? 
-        <Menu.Item icon={<PieChartOutlined />}><Link to={`/category/${_id}`}>{name} </Link></Menu.Item>
-        :
-        <Menu.Item><Link to={`/admin/${_id}`}>{name} </Link></Menu.Item>
-      } 
+      <Menu.Item icon={<PieChartOutlined />}><Link to={`/category/${_id}`}>{name} </Link></Menu.Item>
     </>
     
      
@@ -39,18 +22,21 @@ const CategoryListItem = ({_id, name}) => {
 
 }
 
-const CategoryList = ({cats}) =>{console.log('cats', cats)
+const CategoryList = ({cats, auth}) =>{console.log('cats', cats)
  
   return (
     <div >
      
-        {cats.map((item) => <CategoryListItem key={item._id} {...item} />)}
+        {cats.map((item) => <CategoryListItem key={item._id} {...item} auth={auth} />)}
      
     </div>
   ) 
 }
 
-const mapStateToProps = state => ({cats:state.promise.rootCats?.payload || []})
+const mapStateToProps = state => ({
+  cats:state.promise.rootCats?.payload || [],
+  auth: state.auth,
+})
 
 const CCategoryList = connect(mapStateToProps)(CategoryList)
 

+ 28 - 12
project/my-project/src/components/changeOfGood.js

@@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from 'react';
 import { connect } from 'react-redux';
 import { InputUpLoadFile } from '.';
 import { backURL } from '../api'; 
+import { AdditionalImages } from './index';
 
 const { TextArea } = Input;
 
@@ -18,16 +19,16 @@ const CharacterfGood =({ good, good:{ _id, name, description, images, price }, u
       setInputName(name);
       setInputDescrip(description);
 
-      if (images && images[0].url) {
+      if (images && images.length >=1 &&images[0].url) {
         setImag(images[0].url); 
         setInputIdImg(images[0]._id);
       }
 
-      if (Object.keys(good).length === 0) { console.log('gfergergrthetrhrthyrty')
+      if (Object.keys(good).length === 0) { 
         setImag(''); 
         setInputIdImg('');
       }
-      if(images && !images[0].url) {
+      if(images && images.length >=1 &&!images[0].url) {
         setImag(''); 
         setInputIdImg(''); 
       }
@@ -36,9 +37,9 @@ const CharacterfGood =({ good, good:{ _id, name, description, images, price }, u
       setInputNumber(number); 
           
 
-    }, [good])
+    }, [good]);                                       console.log('good',good)
 
-    
+                                                      
 
     useEffect(() => {
       if(upLoad && upLoad.status === 'RESOLVED' ) { 
@@ -62,11 +63,25 @@ const CharacterfGood =({ good, good:{ _id, name, description, images, price }, u
     }
 
     const saveChange = () => {
-      changeGood(inputName, inputDescrip, cost, inputIdImg );
+       let goodImages = [{"_id": inputIdImg}];
+
+      if (good.images && good.images.length > 1) {
+        goodImages = [...good.images].map((state) => ({"_id": state._id})); 
+        goodImages.shift();
+        goodImages.unshift({"_id": inputIdImg}); 
+      }
+      // if (!good.images) {
+      //   goodImages = [{"_id": inputIdImg}]
+      // }          
+      changeGood(inputName, inputDescrip, cost, goodImages);
       changeIndexGoodInSer(inputNumber);
       clearInput();
     }
-                                                                        console.log('imag', imag); console.log('good',good)
+                                       console.log('inputIdImg', inputIdImg)  ;           
+                                       console.log('good',good); console.log('iinputIdImg.length === 0',  inputIdImg.length === 0 );
+                                       console.log('Object.keys(good).length === 0',Object.keys(good).length === 0);
+                                       console.log('good.images == null',good.images == null);
+
   return (
     <div >
         <div>№ в категории</div>
@@ -94,8 +109,8 @@ const CharacterfGood =({ good, good:{ _id, name, description, images, price }, u
         <Space size={12} direction="vertical">
           
             {/* <div  className="imgWrapper"> */}
-              <div>Фото</div>
-            {Object.keys(good).length === 0 ?
+              <div>Фото основное</div>
+            {(Object.keys(good).length === 0 && good.images == null )|| inputIdImg.length === 0   ?
               <div style={{height:"150px", width:"150px"}}> </div>
               :
               <Image width={150} height={150} src={`${backURL}/${imag}`} style={{ objectFit: 'cover' }}/>}
@@ -105,16 +120,17 @@ const CharacterfGood =({ good, good:{ _id, name, description, images, price }, u
         <Space size={2}></Space>
         <Button type="primary" block onClick={saveChange}>
           Сохранить изменения
-        </Button>     
+        </Button>  
+        <div> Загрузить дополнительные фото</div>
+        <AdditionalImages imag={imag} _id={_id}/>   
   </div>
   )
 }
 
 const mapStateToProps = ((state) => ({
-  upLoad: state.promise?.upLoad
+  upLoad: state.upLoad.upLoad
 }))
 const СhangeOfGood = connect(mapStateToProps)(CharacterfGood);
 
 export default СhangeOfGood;
 
-//{images && images[0] && images[0].url && (src={backURL + '/' + `${img || images[0].url }`})}

+ 22 - 4
project/my-project/src/components/goodCardCharacteristic.js

@@ -1,13 +1,31 @@
-import { Card, Image, Button  } from 'antd';
+import { Card, Image, Button, Space  } from 'antd';
+import { useEffect, useState } from 'react';
 import { connect } from 'react-redux';
 import { actionCartAdd } from '../action';
 
 const backendURL = 'http://shop-roles.asmer.fs.a-level.com.ua';
 
-const Good = ({good: {name, images, description, price, _id}, onAdd}) => { console.log(name)
+const Good = ({good: {name, images, description, price, _id}, onAdd}) => { 
+  const [dopImg, setDopImg] = useState([]);
+  
+  useEffect(() => {
+    if (images && images.length > 1) {         
+      const newImages = [...images]; 
+      newImages.shift();                    
+      setDopImg(newImages);
+    }
+  }, [images])
+                                             
   return (
-    <Card title={name} style={{ width: 350 }} hoverable>
-    {images && images[0] && images[0].url && <Image width={300} src={backendURL + '/' + images[0].url} />}
+    <Card title={name} style={{ width: 400}} hoverable>
+    {images && images[0] && images[0].url && <Image width={350} src={backendURL + '/' + images[0].url} />}
+    {(dopImg.length >= 1) &&  dopImg.map((item) =>
+      
+        <div key={item._id} className='additionalImg'> 
+          <Image width={110} height={110} src={backendURL + '/' + item.url} />
+        </div>
+     
+        )}
     <p>{description}</p>
     <p>{price} грн</p>
     <Button onClick={() => onAdd({_id, name, price, images})}>Купить</Button>

+ 25 - 0
project/my-project/src/components/imgGood.js

@@ -0,0 +1,25 @@
+import { upload } from '@testing-library/user-event/dist/upload';
+import { Image , Card, Button} from 'antd';
+import { useEffect, useState } from 'react';
+import { connect } from 'react-redux';
+import { backURL } from '../api';
+import { InputUpLoadFile } from './index';
+
+
+const ImgGood = ({url, _id}) => {
+
+  return (
+    < > 
+      <Image height={200} style={{objectFit: 'cover'}}
+        width={200}
+        src={backURL + '/' + url}
+      />
+      <InputUpLoadFile/>
+      {/* <Button onClick={() => onSave()}>Сохранить</Button> */}
+    </>
+
+  )
+}
+
+export default ImgGood;
+

+ 4 - 0
project/my-project/src/components/index.js

@@ -18,5 +18,9 @@ export { default as InputSearchGood } from './inputSearchGood';
 export { default as CNewGoodInCat } from './cNewGoodInCat';
 export { default as EmptyContent } from './emptyContent';
 export { default as GoodSearch } from './goodSearch';
+export { default as AdditionalImages } from './additionalImages';
+export { default as CCartGoodAdmin } from './cartGoodAdmin';
+export { default as SortableComponent } from './sortTableComponent';
+export { default as ImgGood } from './imgGood';
 
 

+ 1 - 1
project/my-project/src/components/listOrders.js

@@ -17,7 +17,7 @@ const Orders = ({allOrders, status}) => {
 
       <Card title="История заказов">
 
-      { ord.length0 === 0 && status['status'] &&  <Card>Вы не совершали покупки</Card>}
+      { ord.length === 0 && status['status'] === 'RESOLVD' &&  <Card>Вы не совершали покупки</Card>}
         { ord.map( (item, index) => 
             <Card  key={index} type="inner" title={`Заказ №  ${index + 1}`} style={{ marginTop: 16 }} >
               <Row>

+ 7 - 2
project/my-project/src/components/signIn.js

@@ -8,7 +8,7 @@ import {Router, Route, Link, Redirect, Switch, useHistory} from 'react-router-do
 
 import { useEffect, useState } from 'react';
 
-const Sign = ({getState, auth, logStatus}) => { console.log('auth', auth); 
+const Sign = ({getState, auth, logStatus, user}) => { console.log('auth', auth); 
 
   const  [logMessage, setLogMessage] = useState(false);
   
@@ -20,8 +20,12 @@ const Sign = ({getState, auth, logStatus}) => { console.log('auth', auth);
     () => {
       
       if((auth).length !== 0) { 
-        history.push('/')
+        history.push('/');             
       } 
+
+      if(user.payload && user.payload.sub && user.payload.sub.acl.includes('admin') ) {
+        history.push('/admin'); 
+      }
     } , [auth]) 
 
 
@@ -94,6 +98,7 @@ const Sign = ({getState, auth, logStatus}) => { console.log('auth', auth);
 const mapStateToProps = state => ({
   auth: state.auth?.token || '',
   logStatus: state.promise.login?.status || '', 
+  user: state.auth || '',
  
 })
 

+ 84 - 0
project/my-project/src/components/sortTableComponent.js

@@ -0,0 +1,84 @@
+import React, {Component} from 'react';
+import {render} from 'react-dom';
+import { SortableContainer, SortableElement } from 'react-sortable-hoc';
+import { arrayMoveImmutable } from 'array-move';
+import { Image , Card, Button} from 'antd';
+// import { arrayMove } from 'react-sortable-hoc';
+import { ImgGood } from '.';
+
+const SortableItem = SortableElement(({value:{_id, url, onSave}}) =>  
+  <li className='liSortTable'>
+    <Card>    {console.log('onSave',onSave)}
+      <ImgGood url={url} />
+      <Button onClick={onSave}>Сохранить</Button>
+    </Card>  
+  </li>);
+
+const SortableList = SortableContainer(({items, idGood, onSave, onChangeImagesOnSer}) => {
+  
+  return (
+    <>
+      <ul className='sortTablelist' > 
+        {items.map((value, index) => (
+          <SortableItem  key={`item-${index}`} index={index} value={
+            {"_id": value._id, 
+            "url":value.url, 
+            "onSave": () => onSave(value._id)
+            }
+        } />
+        ))}
+      </ul>
+      <Button type="primary" block onClick={onChangeImagesOnSer}>Сохранить на сервере</Button>
+    </>
+  );
+});
+
+class SortableComponent extends Component {
+  state = {
+    items: this.props.images,
+    idGood: this.props.idGood,   
+    clearUpLoad: this.props.clearUpLoad,
+  };
+
+  getState =() => console.log('this.state',this.state)
+
+  onSortEnd = ({oldIndex, newIndex}) => {
+    this.setState(({items}) => ({
+      items: arrayMoveImmutable(items, oldIndex, newIndex),
+    }));
+    this.getState();  
+  };
+
+  onChangeImagesOnSer = () => {
+    const arrImagesForSave = this.state.items.map((item) => ({_id: item._id}));
+    this.props.onChangeArrInGood(this.state.idGood, arrImagesForSave);
+                
+  } 
+
+  onSave = (idImg) => {
+    const newArrImgs = this.state.items.map((item) => {    
+
+      if (idImg === item._id) {
+        return {
+          _id: this.props.upLoad._id,
+          url: this.props.upLoad.url,
+        }
+      };
+      return item;
+    });                               
+                                                    //console.log('newArrImgs ', newArrImgs )
+    this.setState(() => ({items: newArrImgs}));
+    
+    this.state.clearUpLoad();     
+
+  }
+
+  render() {
+    return <SortableList axis="xy" items={this.state.items} idGood={this.state.idGood} onSortEnd={this.onSortEnd} onSave={this.onSave} 
+      onChangeImagesOnSer={this.onChangeImagesOnSer}
+    />;
+  }
+}
+
+export default SortableComponent;
+

+ 21 - 21
project/my-project/src/components/switchRoute.js

@@ -1,26 +1,26 @@
-// import { useEffect, useState } from "react";
-// import { UseRoute } from "../route";
-// import { jwtDecode } from "../utils";
-// import { PrivateRoute } from "../route";
+import { useEffect, useState } from "react";
+import { UseRoute } from "../route";
+import { jwtDecode } from "../utils";
+import { PrivateRoute } from "../route";
 
-// const SwitchRoute = () => {
-//   const [userName, setUserName] = useState('user');
+const SwitchRoute = () => {
+  const [userName, setUserName] = useState('user');
 
-//   useEffect( () => {
-//     const token = localStorage.getItem('authToken'); 
-//     //
-//     if (token) { 
-//       const name = jwtDecode(token)['sub']['acl']; //console.log('name', jwtDecode(token)['sub']);
-//       name.includes('admin') ? setUserName(name ):  setUserName('user'); 
+  useEffect( () => {
+    const token = localStorage.getItem('authToken'); 
+    //
+    if (token) { 
+      const name = jwtDecode(token)['sub']['acl']; //console.log('name', jwtDecode(token)['sub']);
+      name.includes('admin') ? setUserName(name ):  setUserName('user'); 
      
-//     }
-//   }, [localStorage.getItem('authToken')])
+    }
+  }, [localStorage.getItem('authToken')])
 
-//   return ( 
-//     < >
-//     {userName === 'user' ? <UseRoute/>: <PrivateRoute/>}
-//     </>
-//   )
-// }
+  return ( 
+    < >
+    {userName === 'user' ? <UseRoute/>: <PrivateRoute/>}
+    </>
+  )
+}
 
-// export default SwitchRoute; 
+export default SwitchRoute; 

+ 4 - 48
project/my-project/src/pages/mainPage.js

@@ -1,22 +1,10 @@
 import { Layout, Menu, Breadcrumb, Row, Col, Avatar  } from 'antd';
-import { UserOutlined, LaptopOutlined, NotificationOutlined, createFromIconfontCN  } from '@ant-design/icons';
+import { createFromIconfontCN } from '@ant-design/icons';
 import '../App.css';
 import 'antd/dist/antd.min.css';
-import {Router, Route, Link, Redirect, Switch} from 'react-router-dom';
-import { actionRootCats } from "../action";
-
-
-
-import {SignIn, ListOrders, Page404} from '../components';
+import {Switch} from 'react-router-dom';
 import { CCategoryList, SwitchRoute } from '../components';
-import { useEffect } from 'react';
-import CPageCategory from './cpageCategory';
-import CreatePageGood from './pageGood';
 import { HeaderSite } from '../components';
-import PageBasket from './pageBasket';
-import { RegisterIn } from '../components';
-import { UseRoute, RouteSite } from '../route'
-
 
 const { SubMenu } = Menu;
 const { Header, Content, Footer, Sider } = Layout;
@@ -44,45 +32,13 @@ function MainPage () {
         </Sider>
         <Content style={{ padding: '0 24px', minHeight: 280 }}>Content
           <Switch>
-            <RouteSite/>
+            <SwitchRoute/>
           </Switch>
         </Content>  
       </Layout>
     </Content>
-    <Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
+    <Footer style={{ textAlign: 'center' }}>Viktoriia Yurchenko 2022</Footer>
   </Layout>
-
-
-
-    // <>
-    //  <Layout>
-    //   <HeaderSite/>
-    // <Content style={{ padding: '0 50px' }}>
-    //   <Layout className="site-layout-background" style={{ padding: '24px 0' }}>
-    //     <Sider >
-         
-    //         <CCategoryList/>
-      
-    //     </Sider>
-    //     <Content style={{ padding: '0 24px', minHeight: 280 }}>Content
-          // <Switch>
-          //   {/* <SwitchRoute/> */}
-          //   <RouteSite/>
-          // </Switch>
-
-          
-
-
-    //     </Content>
-    //   </Layout>
-    // </Content>
-    // <Footer style={{ textAlign: 'center' }}><div className="icons-list">
-    //   <IconFont type="icon-facebook"  style={{color: 'black', fontSize:'30px'}}/>
-    //   <IconFont type="icon-twitter" style={{fontSize:'30px', marginLeft:'10px'}} />
-    // </div>
-    // </Footer>
-    // </Layout> 
-    // </>
   )
   
 }

+ 2 - 2
project/my-project/src/pages/pageAdmin.js

@@ -8,7 +8,7 @@ import { CPromisePreloader } from '../reducer';
 const PCategoryAdmin = ({match, match: {params: {_id}}, getData}) => { console.log('match', match)
   useEffect( () => {
     getData(_id);
-  }, [_id])
+  }, [_id]);                            console.log('======id', _id)
 
   return (
     <> 
@@ -27,7 +27,7 @@ const PCategoryAdmin = ({match, match: {params: {_id}}, getData}) => { console.l
         </div>  
         {/* Изменить товар */}
         <div>
-          <CartChangeGood/>
+          <CartChangeGood _idCat={_id}/>
         </div>
       </CPromisePreloader>
     </> 

+ 58 - 0
project/my-project/src/pages/pageUser.js

@@ -0,0 +1,58 @@
+import { Layout, Menu, Breadcrumb, Row, Col, Avatar  } from 'antd';
+import { UserOutlined, LaptopOutlined, NotificationOutlined, createFromIconfontCN  } from '@ant-design/icons';
+import '../App.css';
+import 'antd/dist/antd.min.css';
+import {Router, Route, Link, Redirect, Switch} from 'react-router-dom';
+import { actionRootCats } from "../action";
+
+
+
+import {SignIn, ListOrders, Page404} from '../components';
+import { CCategoryList, SwitchRoute } from '../components';
+import { useEffect } from 'react';
+import CPageCategory from './cpageCategory';
+import CreatePageGood from './pageGood';
+import { HeaderSite } from '../components';
+import PageBasket from './pageBasket';
+import { RegisterIn } from '../components';
+import { UseRoute, RouteSite } from '../route'
+
+
+const { SubMenu } = Menu;
+const { Header, Content, Footer, Sider } = Layout;
+const IconFont = createFromIconfontCN({
+  scriptUrl: '//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js',
+});
+
+function PageUser () {
+
+  return (
+    <Layout>
+     <HeaderSite/>
+    <Content style={{ padding: '0 50px' }}>
+      <Breadcrumb style={{ margin: '16px 0' }}/>
+      <Layout className="site-layout-background" style={{ marginTop: '-2px 0' }}>
+        <Sider className="site-layout-background" width={230}>
+          <Menu
+            mode="inline"
+            defaultSelectedKeys={['1']}
+            defaultOpenKeys={['sub1']}
+            style={{ height: '100%' }}
+          >
+            <CCategoryList/>
+          </Menu>
+        </Sider>
+        <Content style={{ padding: '0 24px', minHeight: 280 }}>Content
+          <Switch>
+            <RouteSite/>
+          </Switch>
+        </Content>  
+      </Layout>
+    </Content>
+    <Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
+  </Layout>
+  )
+  
+}
+
+export default PageUser;

+ 3 - 1
project/my-project/src/reducer/index.js

@@ -1,4 +1,6 @@
 export { default as authReducer } from './authReducer';
 export { default as promiseReducer } from './promiseReducer';
 export { default as cartReducer} from './cartReducer';
-export { default as CPromisePreloader } from './promisePreloader'; 
+export { default as CPromisePreloader } from './promisePreloader';
+export { default as promiseImg } from './promiseImg'; 
+export { default as upLoaderReducer } from './uploaderReducer';

+ 16 - 0
project/my-project/src/reducer/promiseImg.js

@@ -0,0 +1,16 @@
+function promiseImg(state={}, {type, name, status, payload, error}){
+  if (type === 'IMG_CLEAR') {
+    return {}
+  }
+  if (type === 'IMG'){
+      return {
+        ...state,
+        [name]:{status, payload: (status === 'PENDING' && state[name] && state[name].payload) || payload, error}
+      }
+  }
+  return state
+}
+
+
+
+export default promiseImg;

+ 17 - 0
project/my-project/src/reducer/uploaderReducer.js

@@ -0,0 +1,17 @@
+function upLoaderReducer(state={}, {type, name, status, payload, error}){
+  if (type === 'UPLOAD_IMG_CLEAR') {
+    return {}
+  }
+  if (type === 'UPLOAD'){
+      return {
+        ...state,
+        [name]:{status, payload: (status === 'PENDING' && state[name] && state[name].payload) || payload, error}
+      }
+  }
+  return state
+}
+
+
+
+export default upLoaderReducer;
+

+ 31 - 29
project/my-project/src/route/cRoute.js

@@ -1,37 +1,39 @@
-import { useEffect, useState } from "react";
-import { useHistory, Route, Redirect}  from 'react-router-dom';
-import { connect } from "react-redux";
+// import { useEffect, useState } from "react";
+// import { useHistory, Route, Redirect}  from 'react-router-dom';
+// import { connect } from "react-redux";
 
 
-const ProtectedRoute = ({fallback='/', 
-                      roles=["admin"], 
-                      auth,
-                      ...routeProps}) => {
+// const ProtectedRoute = ({fallback='/', 
+//                       roles=["admin"], 
+//                       auth,
+//                       path, component}) => {
  
-    const [acl, setAcl] = useState([]);
-    const [access, setAccess] = useState(false);    
-    let history = useHistory();
+//     const [acl, setAcl] = useState([]);
+//     const [access, setAccess] = useState(false);    
+    // let history = useHistory();
 
-    useEffect(() => {
-      if (auth && auth.payload && auth.payload.sub.acl.length !== 0) {            
-        setAcl(auth.payload.sub.acl);                                                    
-      } else setAcl('anon');                                                             
-                                                                                        
-      const newAcl = roles.filter((item) => acl.includes(item));                     
-      if (newAcl.length) {
-        setAccess(true);
-      }
-    })
-
-    return (
-      < >
-        { access? <Route {...routeProps}/> : <Redirect to='/'/>}
-      </>
-    )  
-}
+//     useEffect(() => {
+//       if (auth && auth.payload && auth.payload.sub.acl.length !== 0) {            
+//         setAcl(auth.payload.sub.acl);                                                    
+//       } else {
+//         setAcl('anon'); 
+//         setAccess(false);                                                            
+//       }                                                                                
+//       const newAcl = roles.filter((item) => acl.includes(item));                  
+//       if (newAcl.length) {
+//         setAccess(true); console.log('access24', access)
+//       }
+//     }, [auth])
+//                                console.log('acl', acl); console.log('roles', roles) ;  
+//     return (
+//       < >
+//         { access? <Route path={path} component={component}/> : <Redirect to={fallback}/>}
+//       </>
+//     )  
+// }
 //<CRoute roles={["anon", "user", "admin"]} path="/category/:_id" component={PageCategory} />
 //<CRoute roles={["admin"]} path="/good/:_id" component={PageGood} />
 
-const CRoute = connect(state => ({auth: state.auth}))(ProtectedRoute);
+// const CRoute = connect(state => ({auth: state.auth.payload}))(ProtectedRoute);
 
-export default CRoute; 
+// export default CRoute; 

+ 1 - 1
project/my-project/src/route/index.js

@@ -1,4 +1,4 @@
 export { default as UseRoute } from './useRoute';
 export { default as PrivateRoute } from './privateRoute';
 export { default as RouteSite } from './routeSite';
-export { default as CRoute } from './cRoute';
+export { default as CRoute } from './cRoute';

+ 16 - 15
project/my-project/src/route/privateRoute.js

@@ -1,19 +1,20 @@
-// import { Route, Switch } from "react-router-dom";
-// import { SignIn } from "../components";
-// import { PageCategoryAdmin } from "../pages";
+import { Route, Switch } from "react-router-dom";
+import { SignIn, CCartGoodAdmin  } from "../components";
+import { PageCategoryAdmin, CreatePageGood, PageSearch } from "../pages";
 
 
 
-// const PrivateRoute = () => {
-//   return (
-//     <>
-//       <Route path = "/login" component = {SignIn}/>
-//       <Route path = "/category/:_id" component = {PageCategoryAdmin}/>
-//       {/* <Route path = "/good/:_id" component = {CreatePageGood}/>
-//       <Route path = "/basket" component={PageBasket}/> 
-//       <Route path = "/listOrders" component={ListOrders}/> */}
-//     </>
-//   )
-// }
+const PrivateRoute = () => {
+  return (
+    <>
+      <Route path = "/login" component = {SignIn}/>
+      <Route path = "/category/:_id" component = {PageCategoryAdmin}/>
+      <Route path = "/goodAdmin/:_id" component = {CCartGoodAdmin}/>
+      <Route path = "/search/:value" component = {PageSearch}/>
+      {/* <Route path = "/basket" component={PageBasket}/> 
+      <Route path = "/listOrders" component={ListOrders}/>  */}
+    </>
+  )
+}
 
-// export default PrivateRoute;
+export default PrivateRoute;

+ 1 - 1
project/my-project/src/route/routeSite.js

@@ -9,7 +9,7 @@ const RouteSite = () => {
      
       {/* <Redirect from="/main" to='/' /> */}
       <CRoute roles={["anon", "user", "admin"]} path="/" component={EmptyContent} exact />
-      <CRoute roles={["anon", "user", "admin"]} path = "/login" component = {SignIn}/>
+      <CRoute roles={["anon", "user", "admin"]} path ="/login" component = {SignIn}/>
       <CRoute roles={["anon"]} path = "/registration" component = {RegisterIn} />
       <CRoute roles={["anon", "user", "admin"]} path = "/category/:_id" component = {CPageCategory}/>
       <CRoute roles={["anon", "user", "admin"]} path = "/good/:_id" component = {CreatePageGood}/>

+ 20 - 20
project/my-project/src/route/useRoute.js

@@ -1,25 +1,25 @@
-// import {Router, Route, Link, Redirect, Switch} from 'react-router-dom';
-// import { SignIn, RegisterIn, ListOrders, EmptyContent, Page404} from '../components';
-// import { PageBasket, CPageCategory, CreatePageGood, PageSearch}  from '../pages';
+import {Router, Route, Link, Redirect, Switch} from 'react-router-dom';
+import { SignIn, RegisterIn, ListOrders, EmptyContent, Page404} from '../components';
+import { PageBasket, CPageCategory, CreatePageGood, PageSearch}  from '../pages';
 
 
 
 
-// const UseRoute = () => {
-//   return (
-//     <>
-//       {/* <Redirect from="/main" to='/' /> */}
-//       <Route path="/" component={EmptyContent} exact />
-//       <Route path = "/login" component = {SignIn}/>
-//       <Route path = "/registration" component = {RegisterIn} />
-//       <Route path = "/category/:_id" component = {CPageCategory}/>
-//       <Route path = "/good/:_id" component = {CreatePageGood}/>
-//       <Route path = "/basket" component={PageBasket}/> 
-//       <Route path = "/listOrders" component={ListOrders}/>
-//       <Route path = "/search/:value" component = {PageSearch}/>
-//       {/* <Route path = "*" component={Page404}/> */}
-//     </>
-//   )
-// }
+const UseRoute = () => {
+  return (
+    <>
+      {/* <Redirect from="/main" to='/' /> */}
+      <Route path="/" component={EmptyContent} exact />
+      <Route path = "/login" component = {SignIn}/>
+      <Route path = "/registration" component = {RegisterIn} />
+      <Route path = "/category/:_id" component = {CPageCategory}/>
+      <Route path = "/good/:_id" component = {CreatePageGood}/>
+      <Route path = "/basket" component={PageBasket}/> 
+      <Route path = "/listOrders" component={ListOrders}/>
+      <Route path = "/search/:value" component = {PageSearch}/>
+      {/* <Route path = "*" component={Page404}/> */}
+    </>
+  )
+}
 
-// export default UseRoute;
+export default UseRoute;

+ 4 - 2
project/my-project/src/store/index.js

@@ -1,7 +1,7 @@
 
 import thunk from 'redux-thunk';
 import { createStore, combineReducers, applyMiddleware } from 'redux';
-import { authReducer, promiseReducer, cartReducer } from '../reducer';
+import { authReducer, promiseReducer, cartReducer, promiseImg, upLoaderReducer } from '../reducer';
 import { actionRootCats, actionSearchGood } from "../action";
 
 // export const store = createStore(combineReducers({
@@ -40,7 +40,9 @@ const localStoredReducer = (reducer, localStorageName) =>
   export const store = createStore(combineReducers({
     promise: localStoredReducer(promiseReducer, 'promise'), 
     auth: localStoredReducer(authReducer, 'auth'), 
-    cart: localStoredReducer(cartReducer, 'cart')
+    cart: localStoredReducer(cartReducer, 'cart'),
+    img: localStoredReducer(promiseImg, 'img'),
+    upLoad: localStoredReducer(upLoaderReducer, 'upLoad'),
   }), applyMiddleware(thunk));