浏览代码

fix good and category forms

ilya_shyian 2 年之前
父节点
当前提交
4979fa09ed

+ 1 - 0
package.json

@@ -1,6 +1,7 @@
 {
   "name": "diploma",
   "version": "0.1.0",
+  "proxy":"http://localhost:8000",
   "private": true,
   "dependencies": {
     "@dnd-kit/core": "^5.0.3",

+ 12 - 59
src/actions/actionCatAll.js

@@ -7,66 +7,19 @@ export const actionCatAll =
         dispatch(
             actionPromise(
                 promiseName,
-                new Promise((resolve) => {
-                    setTimeout(
-                        Math.random() > 0.01
-                            ? resolve({
-                                  data: [
-                                      {
-                                          _id: 1,
-                                          parent: null,
-                                          subcategories: [5, 6],
-                                          goods: [1, 2],
-                                          name: 'Category 1',
-                                      },
-                                      {
-                                          _id: 2,
-                                          parent: null,
-                                          subcategories: [],
-                                          goods: [],
-                                          name: 'Category 2',
-                                      },
-                                      {
-                                          _id: 3,
-                                          parent: null,
-                                          subcategories: [],
-                                          goods: [],
-                                          name: 'Category 3',
-                                      },
-                                      {
-                                          _id: 4,
-                                          parent: null,
-                                          subcategories: [],
-                                          goods: [],
-                                          name: 'Category 4',
-                                      },
-                                      {
-                                          _id: 5,
-                                          parent: 1,
-                                          subcategories: [],
-                                          goods: [],
-                                          name: 'Category 5',
-                                      },
-                                      {
-                                          _id: 6,
-                                          parent: 1,
-                                          subcategories: [],
-                                          goods: [],
-                                          name: 'Category 6',
-                                      },
-                                  ],
-                              })
-                            : resolve({
-                                  errors: [{ message: 'Error adsasdadas' }],
-                              }),
-                        400
-                    );
-                }).then((data) => {
-                    console.log(data);
-                    if (data.errors) {
-                        throw new Error(JSON.stringify(data.errors));
-                    } else return data.data;
+                fetch('/categories/', {
+                    method: 'GET',
+                    headers: {
+                        'Content-Type': 'application/json',
+                        ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
+                    },
                 })
+                    .then((res) => res.json())
+                    .then((data) => {
+                        if (data.errors) {
+                            throw new Error(JSON.stringify(data.errors));
+                        } else return data.data;
+                    })
             )
         );
     };

+ 17 - 126
src/actions/actionCatById.js

@@ -2,131 +2,22 @@ import { mock, query } from '../helpers';
 
 import { actionPromise } from '../reducers';
 
-export const actionCatById = (_id) => async (dispatch, getState) => {
-    dispatch(
-        actionPromise(
-            'catById',
-            new Promise((resolve) => {
-                setTimeout(
-                    Math.random() > 0.01
-                        ? resolve({
-                              data: {
-                                  _id: 1,
-                                  name: 'Category 1',
-                                  subcategories: [
-                                      { _id: 11, name: 'Category 1' },
-                                      { _id: 12, name: 'Category 1' },
-                                  ],
-                                  goods: [
-                                      {
-                                          _id: 1,
-                                          name: 'Good 1',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                      },
-                                      {
-                                          _id: 2,
-                                          name: 'Good 2',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                      },
-                                      {
-                                          _id: 3,
-                                          name: 'Good 3',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: null,
-                                      },
-                                      {
-                                          _id: 4,
-                                          name: 'Good 4',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                      },
-                                      {
-                                          _id: 5,
-                                          name: 'Good 5',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                      },
-                                      {
-                                          _id: 6,
-                                          name: 'Good 6',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                      },
-                                  ],
-                              },
-                          })
-                        : resolve({
-                              errors: [{ message: 'Error adsasdadas' }],
-                          }),
-                    400
-                );
+export const actionCatById = ({ _id, promiseName = 'catById' }) =>
+    actionPromise(
+        promiseName,
+        fetch(`/categories/${_id}/`, {
+            method: 'GET',
+            headers: {
+                'Content-Type': 'application/json',
+                Accept: 'application/json',
+
+                ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
+            },
+        })
+            .then((res) => res.json())
+            .then((data) => {
+                if (data.errors) {
+                    throw new Error(JSON.stringify(data.errors));
+                } else return data.data;
             })
-                // .then((res) => res.json())
-                .then((data) => {
-                    console.log(data);
-                    if (data.errors) {
-                        throw new Error(JSON.stringify(data.errors));
-                    } else return data.data;
-                })
-        )
     );
-};

+ 19 - 18
src/actions/actionCategoryUpsert.js

@@ -1,27 +1,28 @@
 import { actionPromise } from '../reducers';
 
-export const actionCategoryUpsert = (good) => async (dispatch) => {
+export const actionCategoryUpsert = (category) => async (dispatch) => {
+    const formData = new FormData();
+    category._id && formData.append('_id', category._id);
+    formData.append('name', category.name);
+    formData.append('goods', JSON.stringify(category.goods));
+    category.parent && formData.append('parent', JSON.stringify(category.parent));
+    formData.append('subcategories', JSON.stringify(category.subcategories));
     dispatch(
         actionPromise(
             'categoryUpsert',
-            new Promise((resolve) => {
-                setTimeout(
-                    Math.random() > 0.01
-                        ? resolve({
-                              data: {
-                                  _id: 6,
-                                  parent: 1,
-                                  subcategories: [],
-                                  goods: [],
-                                  name: 'Category 4',
-                              },
-                          })
-                        : resolve({
-                              errors: [{ message: 'Error adsasdadas' }],
-                          }),
-                    400
-                );
+            fetch(`/category/`, {
+                method: 'POST',
+                headers: {
+                    ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
+                },
+                body: formData,
             })
+                .then((res) => res.json())
+                .then((data) => {
+                    if (data.errors) {
+                        throw new Error(JSON.stringify(data.errors));
+                    } else return data.data;
+                })
         )
     );
 };

+ 20 - 52
src/actions/actionGoodById.js

@@ -1,55 +1,23 @@
-import { mock, query } from '../helpers';
+import { getQuery, mock, query } from '../helpers';
 
 import { actionPromise } from '../reducers';
 
-export const actionGoodById =
-    ({ _id, promiseName = 'goodById' } = {}) =>
-    async (dispatch, getState) => {
-        dispatch(
-            actionPromise(
-                promiseName,
-                new Promise((resolve) => {
-                    setTimeout(
-                        Math.random() > 0.01
-                            ? resolve({
-                                  data: {
-                                      _id: 6,
-                                      name: 'Good 6',
-                                      description: 'adaadasda asasd asd asd asd asd ',
-                                      price: '999',
-                                      images: [
-                                          {
-                                              _id: 1,
-                                              url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                          },
-                                          {
-                                              _id: 2,
-                                              url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                          },
-                                          {
-                                              _id: 3,
-                                              url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                          },
-                                          {
-                                              _id: 4,
-                                              url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                          },
-                                      ],
-                                  },
-                              })
-                            : resolve({
-                                  errors: [{ message: 'Error adsasdadas' }],
-                              }),
-                        400
-                    );
-                })
-                    // .then((res) => res.json())
-                    .then((data) => {
-                        console.log(data);
-                        if (data.errors) {
-                            throw new Error(JSON.stringify(data.errors));
-                        } else return data.data;
-                    })
-            )
-        );
-    };
+export const actionGoodById = ({ _id, promiseName = 'goodById' } = {}) =>
+    actionPromise(
+        promiseName,
+        fetch(`/goods/${_id}/`, {
+            method: 'GET',
+            headers: {
+                'Content-Type': 'application/json',
+                Accept: 'application/json',
+
+                ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
+            },
+        })
+            .then((res) => res.json())
+            .then((data) => {
+                if (data.errors) {
+                    throw new Error(JSON.stringify(data.errors));
+                } else return data.data;
+            })
+    );

+ 21 - 27
src/actions/actionGoodUpsert.js

@@ -1,37 +1,31 @@
 import { actionPromise } from '../reducers';
 
 export const actionGoodUpsert = (good) => async (dispatch) => {
+    const formData = new FormData();
+    console.log(JSON.stringify(good.images));
+    good._id && formData.append('_id', good._id);
+    formData.append('name', good.name);
+    formData.append('description', good.description);
+    formData.append('amount', good.amount);
+    formData.append('price', good.price);
+    formData.append('images', JSON.stringify(good.images));
+    formData.append('categories', JSON.stringify(good.categories));
     dispatch(
         actionPromise(
             'goodUpsert',
-            new Promise((resolve) => {
-                setTimeout(
-                    Math.random() > 0.01
-                        ? resolve({
-                              data: {
-                                  _id: 1,
-                                  name: 'Good 1',
-                                  description: 'adaadasda asasd asd asd asd asd ',
-                                  price: '999',
-                                  amount: 9999,
-                                  images: [
-                                      {
-                                          _id: 1,
-                                          url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                      },
-                                      {
-                                          _id: 2,
-                                          url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                      },
-                                  ],
-                              },
-                          })
-                        : resolve({
-                              errors: [{ message: 'Error adsasdadas' }],
-                          }),
-                    400
-                );
+            fetch(`/good/`, {
+                method: 'POST',
+                headers: {
+                    ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
+                },
+                body: formData,
             })
+                .then((res) => res.json())
+                .then((data) => {
+                    if (data.errors) {
+                        throw new Error(JSON.stringify(data.errors));
+                    } else return data.data;
+                })
         )
     );
 };

+ 13 - 119
src/actions/actionGoodsAll.js

@@ -1,3 +1,4 @@
+import { getQuery } from '../helpers';
 import { actionPromise } from '../reducers';
 
 export const actionGoodsAll =
@@ -6,126 +7,19 @@ export const actionGoodsAll =
         dispatch(
             actionPromise(
                 promiseName,
-                new Promise((resolve) => {
-                    setTimeout(
-                        Math.random() > 0.01
-                            ? resolve({
-                                  data: [
-                                      {
-                                          _id: 1,
-                                          name: 'Good 1',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                          categories: [{ _id: 1, name: 'Category 1' }],
-                                      },
-                                      {
-                                          _id: 2,
-                                          name: 'Good 2',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                          categories: [{ _id: 1, name: 'Category 1' }],
-                                      },
-                                      {
-                                          _id: 3,
-                                          name: 'Good 3',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: null,
-                                          categories: [{ _id: 1, name: 'Category 1' }],
-                                      },
-                                      {
-                                          _id: 4,
-                                          name: 'Good 4',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                          categories: [
-                                              { _id: 1, name: 'Category 1' },
-                                              { _id: 1, name: 'Category 2' },
-                                          ],
-                                      },
-                                      {
-                                          _id: 5,
-                                          name: 'Good 5',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                          categories: [{ _id: 1, name: 'Category 1' }],
-                                      },
-                                      {
-                                          _id: 6,
-                                          name: 'Good 6',
-                                          description: 'adaadasda asasd asd asd asd asd ',
-                                          price: '999',
-                                          amount: 9999,
-                                          images: [
-                                              {
-                                                  _id: 1,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                              {
-                                                  _id: 2,
-                                                  url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
-                                              },
-                                          ],
-                                          categories: [{ _id: 1, name: 'Category 1' }],
-                                      },
-                                  ],
-                              })
-                            : resolve({
-                                  errors: [{ message: 'Error adsasdadas' }],
-                              }),
-                        400
-                    );
-                }).then((data) => {
-                    console.log(data);
-                    if (data.errors) {
-                        throw new Error(JSON.stringify(data.errors));
-                    } else return data.data;
+                fetch('/goods/', {
+                    method: 'GET',
+                    headers: {
+                        'Content-Type': 'application/json',
+                        ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
+                    },
                 })
+                    .then((res) => res.json())
+                    .then((data) => {
+                        if (data.errors) {
+                            throw new Error(JSON.stringify(data.errors));
+                        } else return data.data;
+                    })
             )
         );
     };

+ 8 - 2
src/actions/actionUploadFile.js

@@ -5,10 +5,16 @@ export const actionUploadFile = (file) => {
     fd.append('photo', file);
     return actionPromise(
         'uploadFile',
-        fetch('/upload', {
+        fetch('/upload/', {
             method: 'POST',
             headers: localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {},
             body: fd,
-        }).then((res) => res.json())
+        })
+            .then((res) => res.json())
+            .then((data) => {
+                if (data.errors) {
+                    throw new Error(JSON.stringify(data.errors));
+                } else return data.data;
+            })
     );
 };

+ 1 - 1
src/actions/actionUploadFiles.js

@@ -4,5 +4,5 @@ import { actionPromise } from '../reducers';
 export const actionUploadFiles =
     (files = []) =>
     async (dispatch, getState) => {
-        actionPromise('uploadFiles', await Promise.all(files?.map((file) => dispatch(actionUploadFile(file)))));
+        dispatch(actionPromise('uploadFiles', Promise.all(files?.map((file) => dispatch(actionUploadFile(file))))));
     };

+ 3 - 2
src/components/LayoutPage/index.js

@@ -28,7 +28,8 @@ const GoodsPageContainer = () => {
 const GoodPageContainer = () => {
     const params = useParams();
     const dispatch = useDispatch();
-    dispatch(actionGoodById(params._id));
+
+    dispatch(actionGoodById({ _id: params._id }));
     return <GoodPage />;
 };
 
@@ -59,7 +60,7 @@ export const LayoutPage = () => (
                         <Route path="/search/:searchData/" element={<GoodsListContainer />} exact />
                         <Route path="/category/:_id" element={<GoodsPageContainer />} />
                         <Route path="/category/" element={<GoodsPageContainer />} />
-                        <Route path="/good/:id" element={<GoodPageContainer />} />
+                        <Route path="/good/:_id" element={<GoodPageContainer />} />
                         <Route
                             path="/admin/*"
                             element={

+ 40 - 12
src/components/admin/AdminCategoryPage/CategoryForm.js

@@ -3,7 +3,7 @@ import React, { useState, useEffect } from 'react';
 import Select from 'react-select';
 import { actionCategoryUpdate } from '../../../actions/actionCategoryUpdate';
 import { actionPromise, actionPromiseClear, store } from '../../../reducers';
-import { Box, Button, InputLabel, Stack, TextField, Typography } from '@mui/material';
+import { Alert, Box, Button, InputLabel, Snackbar, Stack, TextField, Typography } from '@mui/material';
 
 import { useFormik } from 'formik';
 import * as Yup from 'yup';
@@ -24,11 +24,12 @@ const CategoryForm = ({
     goodList = [],
     category = {},
 } = {}) => {
-    const [inputSubCategories, setInputSubCategories] = useState([]);
+    const [inputSubcategories, setInputSubcategories] = useState([]);
     const [inputGoods, setInputGoods] = useState([]);
     const [inputParent, setInputParent] = useState({});
     const [subCatList, setSubCatList] = useState([]);
     const [parentList, setParentList] = useState([]);
+    const [snackbar, setSnackbar] = useState({ isOpen: false, message: '', type: 'success' });
 
     const formik = useFormik({
         initialValues: {
@@ -43,29 +44,43 @@ const CategoryForm = ({
             inputGoods && (categoryToSave.goods = inputGoods);
             inputParent && (categoryToSave.parent = inputParent);
 
-            categoryToSave.subCategories = inputSubCategories;
+            categoryToSave.subcategories = inputSubcategories;
             onSaveClick && onSaveClick();
             onSave(categoryToSave);
         },
     });
 
     useEffect(() => {
+        formik.setFieldValue('name', category.name || '');
         setInputParent(category?.parent || null);
         setInputGoods(category?.goods || []);
-        setInputSubCategories(category?.subCategories || []);
-    }, []);
+        setInputSubcategories(category?.subcategories || []);
+    }, [category]);
+
+    useEffect(() => {
+        console.log(promiseStatus);
+        if (promiseStatus === 'FULFILLED') {
+            formik.setSubmitting(false);
+            setSnackbar({ ...snackbar, isOpen: true, message: 'Готово', severity: 'succes' });
+        }
+        if (promiseStatus === 'REJECTED') {
+            const errorMessage = serverErrors.reduce((prev, curr) => prev + '\n' + curr, '');
+            formik.setSubmitting(false);
+            setSnackbar({ ...snackbar, isOpen: true, message: errorMessage, severity: 'error' });
+        }
+    }, [promiseStatus]);
 
     useEffect(() => {
         let parentList = initialCatList.filter(
             ({ _id }) =>
                 !category?.subCatergories?.find((subCat) => _id === subCat._id) &&
                 _id !== category?._id &&
-                !inputSubCategories?.find((subCat) => _id === subCat._id)
+                !inputSubcategories?.find((subCat) => _id === subCat._id)
         );
         parentList = [...[{ _id: null, name: 'null' }], ...parentList];
 
         setParentList(parentList);
-    }, [inputSubCategories]);
+    }, [inputSubcategories]);
 
     useEffect(() => {
         let subCatList = initialCatList.filter(
@@ -115,14 +130,14 @@ const CategoryForm = ({
             <Box sx={{ mt: 3 }}>
                 <InputLabel className="form-label">Підкатегорії</InputLabel>
                 <Select
-                    value={inputSubCategories?.map(({ _id, name }) => ({ value: _id, label: name }))}
+                    value={inputSubcategories?.map(({ _id, name }) => ({ value: _id, label: name }))}
                     closeMenuOnSelect={false}
-                    onChange={(e) => setInputSubCategories(e.map(({ value, label }) => ({ _id: value, name: label })))}
+                    onChange={(e) => setInputSubcategories(e.map(({ value, label }) => ({ _id: value, name: label })))}
                     options={subCatList?.map(({ _id, name }) => ({ value: _id, label: name }))}
                     isMulti={true}
                 />
             </Box>
-            {goodsField && (
+            {
                 <Box sx={{ mt: 3 }}>
                     <InputLabel className="form-label">Товари</InputLabel>
                     <Select
@@ -133,8 +148,21 @@ const CategoryForm = ({
                         isMulti={true}
                     />
                 </Box>
-            )}
-
+            }
+            <Snackbar
+                severity={snackbar.type}
+                message={snackbar.message}
+                autoHideDuration={3000}
+                open={snackbar.isOpen}
+                onClose={() => setSnackbar({ ...snackbar, isOpen: false })}
+                sx={{
+                    width: 400,
+                }}
+            >
+                <Alert severity={snackbar.type} sx={{ width: '100%' }} open={snackbar.isOpen}>
+                    {snackbar.message}
+                </Alert>
+            </Snackbar>
             <Box direction="row" sx={{ mt: 3 }} justifyContent="flex-end">
                 <Button variant="contained" disabled={!formik.isValid || formik.isSubmitting} type="submit" fullWidth>
                     Зберегти

+ 3 - 3
src/components/admin/AdminCategoryPage/index.js

@@ -2,11 +2,11 @@ import { Box } from '@mui/material';
 import { connect } from 'react-redux';
 import { CCategoryForm } from './CategoryForm';
 
-export const AdminCategoryPage = ({ good }) => (
+export const AdminCategoryPage = ({ category }) => (
     <Box className="AdminCategoryPage">
-        <CCategoryForm good={good} />
+        <CCategoryForm category={category} />
     </Box>
 );
-export const CAdminCategoryPage = connect((state) => ({ good: state.promise?.adminCatById?.payload || {} }))(
+export const CAdminCategoryPage = connect((state) => ({ category: state.promise?.adminCatById?.payload || {} }))(
     AdminCategoryPage
 );

+ 50 - 21
src/components/admin/AdminGoodPage/GoodForm.js

@@ -6,6 +6,7 @@ import { actionGoodUpdate } from '../../../actions/actionGoodUpdate';
 import { EntityEditor } from '../../common/EntityEditor';
 import { actionUploadFiles } from '../../../actions/actionUploadFiles';
 import {
+    Alert,
     Box,
     Button,
     Chip,
@@ -13,6 +14,7 @@ import {
     InputLabel,
     MenuItem,
     OutlinedInput,
+    Snackbar,
     Stack,
     TextareaAutosize,
     TextField,
@@ -50,6 +52,7 @@ export const GoodForm = ({
 } = {}) => {
     const [inputCategories, setInputCategories] = useState([]);
     const [inputImages, setInputImages] = useState([]);
+    const [snackbar, setSnackbar] = useState({ isOpen: false, message: '', type: 'success' });
 
     const formik = useFormik({
         initialValues: {
@@ -69,12 +72,24 @@ export const GoodForm = ({
             goodToSave.amount = +formik.values.amount;
             goodToSave.categories = inputCategories;
             goodToSave.images = inputImages?.map(({ _id }) => ({ _id })) || [];
-
             onSaveClick && onSaveClick();
             onSave(goodToSave);
         },
     });
 
+    useEffect(() => {
+        console.log(promiseStatus);
+        if (promiseStatus === 'FULFILLED') {
+            formik.setSubmitting(false);
+            setSnackbar({ ...snackbar, isOpen: true, message: 'Готово', severity: 'succes' });
+        }
+        if (promiseStatus === 'REJECTED') {
+            const errorMessage = serverErrors.reduce((prev, curr) => prev + '\n' + curr, '');
+            formik.setSubmitting(false);
+            setSnackbar({ ...snackbar, isOpen: true, message: errorMessage, severity: 'error' });
+        }
+    }, [promiseStatus]);
+
     useEffect(() => {
         setInputCategories(good?.categories || []);
         setInputImages(good?.images || []);
@@ -82,7 +97,7 @@ export const GoodForm = ({
         formik.setFieldValue('description', good.description || '');
         formik.setFieldValue('amount', good.amount || 0);
         formik.setFieldValue('price', good.price || 0);
-    }, [good]);
+    }, [good.categories, good.name, good.description, good.amount, good.price]);
 
     useEffect(() => {
         return () => {
@@ -91,10 +106,6 @@ export const GoodForm = ({
     }, []);
     return (
         <Box className="GoodForm" component="form" onSubmit={formik.handleSubmit}>
-            {(serverErrors || []).map((error) => (
-                <Error>{error?.message}</Error>
-            ))}
-
             <TextField
                 id="name"
                 name="name"
@@ -150,6 +161,24 @@ export const GoodForm = ({
                 />
             </Box>
 
+            <Box sx={{ mt: 3 }}>
+                <TextField
+                    variant="outlined"
+                    id="amount"
+                    name="amount"
+                    label="Кількість"
+                    size="small"
+                    error={formik.touched.amount && Boolean(formik.errors.amount)}
+                    value={formik.values.amount}
+                    onBlur={formik.handleBlur}
+                    onChange={formik.handleChange}
+                    helperText={formik.touched.amount && formik.errors.amount}
+                    multiline
+                    fullWidth
+                    sx={{ mt: 2 }}
+                />
+            </Box>
+
             <Box sx={{ mt: 3 }}>
                 <InputLabel>Категорії</InputLabel>
                 <Select
@@ -160,21 +189,6 @@ export const GoodForm = ({
                     options={catList?.map(({ _id, name }) => ({ value: _id, label: name }))}
                     isMulti={true}
                 />
-                {/* <TextField
-                        classes={{ root: classes.root }}
-                        select
-                        name="userRoles"
-                        id="userRoles"
-                        variant="outlined"
-                        label="userRoles"
-                        SelectProps={{
-                            multiple: true,
-                            value: formState.userRoles,
-                            onChange: catList?.map(({ _id, name }) => ({ value: _id, label: name })),
-                        }}
-                    >
-                        {catList?.map(({ _id, name }) => ({ value: _id, label: name }))}
-                    </TextField> */}
             </Box>
 
             <Box direction="row" sx={{ mt: 3 }} justifyContent="flex-end">
@@ -182,6 +196,20 @@ export const GoodForm = ({
                     Зберегти
                 </Button>
             </Box>
+            <Snackbar
+                severity={snackbar.type}
+                message={snackbar.message}
+                autoHideDuration={3000}
+                open={snackbar.isOpen}
+                onClose={() => setSnackbar({ ...snackbar, isOpen: false })}
+                sx={{
+                    width: 400,
+                }}
+            >
+                <Alert severity={snackbar.type} sx={{ width: '100%' }} open={snackbar.isOpen}>
+                    {snackbar.message}
+                </Alert>
+            </Snackbar>
         </Box>
     );
 };
@@ -191,6 +219,7 @@ export const CGoodForm = connect(
         catList: state.promise.catAll?.payload || [],
         promiseStatus: state.promise.goodUpsert?.status || null,
         good: state.promise?.adminGoodById?.payload || {},
+        serverErrors: state.promise?.adminGoodById?.errors || [],
     }),
     {
         onSave: (good) => actionGoodUpdate(good),

+ 1 - 1
src/components/admin/AdminLayoutPage/index.js

@@ -20,7 +20,7 @@ const AdminCategoryPageContainer = ({}) => {
     const params = useParams();
     useEffect(() => {
         if (params._id) {
-            dispatch(actionCatById(params._id, 'adminCatById'));
+            dispatch(actionCatById({ _id: params._id, promiseName: 'adminCatById' }));
         } else {
             dispatch(actionPromiseClear('adminCatById'));
         }

+ 2 - 2
src/components/common/EntityEditor/index.js

@@ -21,11 +21,11 @@ export const EntityEditor = ({ entity = { images: [] }, onSave, onFileDrop, uplo
     }, [uploadFiles]);
 
     useEffect(() => {
-        console.log(entity.images);
         onImagesSave && onImagesSave(state.images?.filter((img) => img?._id && img?.url));
-    }, [state.images]);
+    }, [state]);
 
     const onSortEnd = ({ oldIndex, newIndex }) => {
+        console.log(arrayMoveImmutable(state.images, oldIndex, newIndex));
         setState({ ...state, images: arrayMoveImmutable(state.images, oldIndex, newIndex) });
     };
     const onItemRemove = (toRemoveId) => {

+ 1 - 17
src/helpers/getQuery.js

@@ -1,17 +1 @@
-export const getQuery =
-    () =>
-    (url, type = 'GET', body = {}) =>
-        fetch(url, {
-            method: type,
-            headers: {
-                'Content-Type': 'application/json',
-                ...(localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}),
-            },
-            body: body,
-        })
-            .then((res) => res.json())
-            .then((data) => {
-                if (data.errors) {
-                    throw new Error(JSON.stringify(data.errors));
-                } else return Object.values(data.data[0]);
-            });
+

+ 1 - 4
src/helpers/index.js

@@ -1,9 +1,6 @@
 import { jwtDecode } from './jwtDecode';
-import { getQuery } from './getQuery';
 import { mock } from './mock';
 import { delay } from './delay';
 import { statusNumber, statusOptions } from './orderStatus';
 
-export const query = getQuery('/');
-
-export { jwtDecode, getQuery, mock, delay, statusNumber, statusOptions };
+export { jwtDecode, mock, delay, statusNumber, statusOptions };

+ 2 - 0
src/reducers/promiseReducer.js

@@ -18,9 +18,11 @@ export const actionRejected = (name, error) => ({ type: 'PROMISE', name, status:
 export const actionPromiseClear = (name) => ({ type: 'PROMISE_CLEAR', name });
 export const actionPromise = (name, promise) => async (dispatch) => {
     dispatch(actionPending(name));
+
     try {
         let payload = await promise;
         dispatch(actionFulfilled(name, payload));
+
         return payload;
     } catch (error) {
         dispatch(actionRejected(name, JSON.parse(error.message)));