Browse Source

+AdminGoodsPAge

ilya_shyian 2 years ago
parent
commit
e95cf0a381

+ 72 - 0
src/actions/actionCatAll.js

@@ -0,0 +1,72 @@
+import { actionPromise } from '../reducers';
+import { gql } from '../helpers';
+
+export const actionCatAll =
+    ({ limit = 0, skip = 0, promiseName = 'catAll' } = {}) =>
+    async (dispatch, getState) => {
+        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 4',
+                                      },
+                                      {
+                                          _id: 6,
+                                          parent: 1,
+                                          subcategories: [],
+                                          goods: [],
+                                          name: 'Category 4',
+                                      },
+                                  ],
+                              })
+                            : 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;
+                })
+            )
+        );
+    };

+ 6 - 0
src/actions/actionCatById.js

@@ -23,6 +23,7 @@ export const actionCatById = (_id) => async (dispatch, getState) => {
                                           name: 'Good 1',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               {
                                                   url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
@@ -37,6 +38,7 @@ export const actionCatById = (_id) => async (dispatch, getState) => {
                                           name: 'Good 2',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               {
                                                   url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
@@ -51,6 +53,7 @@ export const actionCatById = (_id) => async (dispatch, getState) => {
                                           name: 'Good 3',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: null,
                                       },
                                       {
@@ -58,6 +61,7 @@ export const actionCatById = (_id) => async (dispatch, getState) => {
                                           name: 'Good 4',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               {
                                                   url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
@@ -72,6 +76,7 @@ export const actionCatById = (_id) => async (dispatch, getState) => {
                                           name: 'Good 5',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               {
                                                   url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',
@@ -86,6 +91,7 @@ export const actionCatById = (_id) => async (dispatch, getState) => {
                                           name: 'Good 6',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               {
                                                   url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg',

+ 101 - 0
src/actions/actionGoodsAll.js

@@ -0,0 +1,101 @@
+import { actionPromise } from '../reducers';
+
+export const actionGoodsAll =
+    ({ limit = 0, skip = 0, promiseName = 'goodsAll' } = {}) =>
+    async (dispatch, getState) => {
+        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: [
+                                              { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
+                                              { 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: [
+                                              { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
+                                              { 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: [
+                                              { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
+                                              { 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: [
+                                              { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
+                                              { 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: [
+                                              { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
+                                              { 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;
+                })
+            )
+        );
+    };

+ 8 - 2
src/actions/actionGoodsFind.js

@@ -16,6 +16,7 @@ export const actionGoodsFind =
                                           name: 'Good 1',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
@@ -26,6 +27,7 @@ export const actionGoodsFind =
                                           name: 'Good 2',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
@@ -36,6 +38,7 @@ export const actionGoodsFind =
                                           name: 'Good 3',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: null,
                                       },
                                       {
@@ -43,26 +46,29 @@ export const actionGoodsFind =
                                           name: 'Good 4',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           ],
                                       },
                                       {
-                                          _id: 6,
+                                          _id: 5,
                                           name: 'Good 5',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           ],
                                       },
                                       {
-                                          id: 6,
+                                          _id: 6,
                                           name: 'Good 6',
                                           description: 'adaadasda asasd asd asd asd asd ',
                                           price: '999',
+                                          amount: 9999,
                                           images: [
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                               { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },

+ 8 - 2
src/actions/actionGoodsPopular.js

@@ -16,6 +16,7 @@ export const actionGoodsPopular = () => async (dispatch, getState) => {
                                       name: 'Good 1',
                                       description: 'adaadasda asasd asd asd asd asd ',
                                       price: '999',
+                                      amount: 9999,
                                       images: [
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
@@ -26,6 +27,7 @@ export const actionGoodsPopular = () => async (dispatch, getState) => {
                                       name: 'Good 2',
                                       description: 'adaadasda asasd asd asd asd asd ',
                                       price: '999',
+                                      amount: 9999,
                                       images: [
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
@@ -36,6 +38,7 @@ export const actionGoodsPopular = () => async (dispatch, getState) => {
                                       name: 'Good 3',
                                       description: 'adaadasda asasd asd asd asd asd ',
                                       price: '999',
+                                      amount: 9999,
                                       images: null,
                                   },
                                   {
@@ -43,26 +46,29 @@ export const actionGoodsPopular = () => async (dispatch, getState) => {
                                       name: 'Good 4',
                                       description: 'adaadasda asasd asd asd asd asd ',
                                       price: '999',
+                                      amount: 9999,
                                       images: [
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                       ],
                                   },
                                   {
-                                      _id: 6,
+                                      _id: 5,
                                       name: 'Good 5',
                                       description: 'adaadasda asasd asd asd asd asd ',
                                       price: '999',
+                                      amount: 9999,
                                       images: [
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                       ],
                                   },
                                   {
-                                      id: 6,
+                                      _id: 6,
                                       name: 'Good 6',
                                       description: 'adaadasda asasd asd asd asd asd ',
                                       price: '999',
+                                      amount: 9999,
                                       images: [
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },
                                           { url: 'https://content2.rozetka.com.ua/goods/images/big/183546719.jpg' },

+ 3 - 0
src/components/AuthPage/index.js

@@ -1,4 +1,7 @@
 import { Box, Container } from '@mui/material';
+import { useEffect } from 'react';
+import { useSelector } from 'react-redux';
+import { useNavigate } from 'react-router-dom';
 import { AuthForm } from './AuthForm';
 
 export const AuthPage = () => {

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

@@ -61,7 +61,7 @@ export const LayoutPage = () => (
                         <Route path="/category/" element={<GoodsPageContainer />} />
                         <Route path="/good/:id" element={<GoodPageContainer />} />
                         <Route
-                            path="/admin"
+                            path="/admin/*"
                             element={
                                 <CProtectedRoute roles={['admin']} fallback="/auth">
                                     <AdminLayoutPage />

+ 9 - 1
src/components/Root/index.js

@@ -7,6 +7,7 @@ import { useDispatch, useSelector } from 'react-redux';
 
 import { AuthPage } from '../AuthPage';
 import { LayoutPage } from '../LayoutPage';
+import { CProtectedRoute } from '../common/ProtectedRoute';
 
 const Root = ({ user = {} }) => {
     const isSignIn = true;
@@ -16,7 +17,14 @@ const Root = ({ user = {} }) => {
     return (
         <Box className="Root">
             <Routes>
-                <Route path="/auth" element={<AuthPage />} />
+                <Route
+                    path="/auth"
+                    element={
+                        <CProtectedRoute roles={['anon']} fallback="/admin">
+                            <AuthPage />
+                        </CProtectedRoute>
+                    }
+                />
                 <Route path="/*" element={<LayoutPage />} />
             </Routes>
         </Box>

src/components/layout/Aside/CAdminCategories.js → src/components/admin/AdminGoodPage/index.js


+ 35 - 0
src/components/admin/AdminGoodsPage/AdminGoodItem.js

@@ -0,0 +1,35 @@
+import { actionPopupOpen } from '../../../reducers';
+import { connect } from 'react-redux';
+import { Link } from 'react-router-dom';
+import defaultGoodImage from '../../../images/default-good-image.png';
+import { FaEdit } from 'react-icons/fa';
+import { Box, Button, TableCell, TableRow } from '@mui/material';
+
+const AdminGoodItem = ({ good }) => (
+    <TableRow className="AdminGoodItem">
+        <TableCell scope="row">{good._id}</TableCell>
+        <TableCell>{good.name ? good.name : '-'}</TableCell>
+        <TableCell>
+            {
+                <Box
+                    component="img"
+                    src={good.images?.length ? `${good.images ? good.images[0]?.url : ''}` : defaultGoodImage}
+                />
+            }
+        </TableCell>
+        <TableCell>{good.price ? good.price : '-'}</TableCell>
+        <TableCell>{good.amount ? good.amount : '-'}</TableCell>
+        <TableCell>
+            {good.categories
+                ? (good.categories || []).map((category) => <div key={category._id}>{category?.name}</div>)
+                : '-'}
+        </TableCell>
+        <TableCell className="edit">
+            <Button component={Link} className="Link" to={`/admin/good/${good._id}/`}>
+                Редагувати
+            </Button>
+        </TableCell>
+    </TableRow>
+);
+
+export { AdminGoodItem };

+ 46 - 0
src/components/admin/AdminGoodsPage/AdminGoodList.js

@@ -0,0 +1,46 @@
+import { AdminGoodListHeader } from './AdminGoodListHeader';
+import { AdminGoodItem } from './AdminGoodItem';
+import { connect } from 'react-redux';
+import { useEffect, useState } from 'react';
+
+import { SearchBar, SearchResults } from '../../common/SearchBar';
+import { actionGoodsFind } from '../../../actions/actionGoodsFind';
+import { actionPromiseClear } from '../../../reducers';
+import { Box, Table, TableBody, TableHead } from '@mui/material';
+
+const CSearchBar = connect(null, {
+    onSearch: (text) => actionGoodsFind({ promiseName: 'adminGoodsFind', text, limit: 5 }),
+    onSearchButtonClick: () => actionPromiseClear('adminGoodsFind'),
+})(SearchBar);
+
+const CSearchResults = connect((state) => ({ items: state.promise.adminGoodsFind?.payload || [] }))(SearchResults);
+
+const AdminGoodList = ({ goods }) => {
+    const [isSortReverse, setSortReverse] = useState(false);
+
+    return (
+        <Box className="AdminGoodList">
+            <Box className="searchBarWrapper">
+                <CSearchBar
+                    render={CSearchResults}
+                    searchLink="/admin/goods/search/"
+                    renderParams={{ itemLink: '/admin/good/' }}
+                />
+            </Box>
+            <Table>
+                <TableHead>
+                    <AdminGoodListHeader />
+                </TableHead>
+                <TableBody>
+                    {(goods || []).map((good) => (
+                        <AdminGoodItem good={good} key={good._id} />
+                    ))}
+                </TableBody>
+            </Table>
+        </Box>
+    );
+};
+
+const CAdminGoodList = connect((state) => ({ goods: state.feed?.payload || [] }))(AdminGoodList);
+
+export { AdminGoodList, CAdminGoodList };

+ 28 - 0
src/components/admin/AdminGoodsPage/AdminGoodListHeader.js

@@ -0,0 +1,28 @@
+import { connect } from 'react-redux';
+
+import { AddButton } from '../../common/AddButton';
+import { TableCell, TableRow, TableSortLabel } from '@mui/material';
+import { useNavigate } from 'react-router-dom';
+
+const AdminGoodListHeader = ({ onSortChange, sort, sortReversed, onSortReverseChange }) => {
+    const navigate = useNavigate();
+    return (
+        <TableRow className="AdminGoodListHeader">
+            <TableCell scope="col">#</TableCell>
+            <TableCell scope="col">Назва</TableCell>
+            <TableCell scope="col">Зображення</TableCell>
+            <TableCell scope="col">Ціна</TableCell>
+            <TableCell scope="col">Кількість</TableCell>
+            <TableCell scope="col">Категорії</TableCell>
+            <TableCell scope="col">
+                <AddButton
+                    onClick={() => {
+                        navigate('/admin/good/');
+                    }}
+                />
+            </TableCell>
+        </TableRow>
+    );
+};
+
+export { AdminGoodListHeader };

+ 13 - 0
src/components/admin/AdminGoodsPage/index.js

@@ -0,0 +1,13 @@
+import { Box, Typography } from '@mui/material';
+import { AdminGoodList, CAdminGoodList } from './AdminGoodList';
+
+export const AdminGoodsPage = () => {
+    return (
+        <Box className="AdminGoodsPage">
+            <Typography variant="h5" sx={{ marginBottom: '10px', marginTop: '10px' }}>
+                Товари
+            </Typography>
+            <CAdminGoodList />
+        </Box>
+    );
+};

+ 43 - 2
src/components/admin/AdminLayoutPage/index.js

@@ -1,11 +1,52 @@
 import { Box, Container } from '@mui/material';
-import { Routes } from 'react-router-dom';
+import { useEffect } from 'react';
+import { connect, useDispatch, useSelector } from 'react-redux';
+import { Route, Routes } from 'react-router-dom';
+import { actionPromiseClear, store } from '../../../reducers';
+import { actionFeedAdd, actionFeedClear, actionFeedGoods } from '../../../reducers/feedReducer';
 import { CProtectedRoute } from '../../common/ProtectedRoute';
+import { AdminGoodsPage } from '../AdminGoodsPage';
+
+const AdminGoodsPageContainer = ({ goods }) => {
+    const dispatch = useDispatch();
+    useEffect(() => {
+        dispatch(actionFeedGoods());
+        window.onscroll = (e) => {
+            if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
+                const {
+                    feed,
+                    promise: { feedGoodsAll },
+                } = store.getState();
+
+                if (feedGoodsAll.status !== 'PENDING') {
+                    dispatch(actionFeedGoods(feed.payload?.length || 0));
+                }
+            }
+        };
+        return () => {
+            dispatch(actionFeedClear());
+            dispatch(actionPromiseClear('feedGoodsAll'));
+            dispatch(actionPromiseClear('goodUpsert'));
+            window.onscroll = null;
+        };
+    }, []);
+
+    useEffect(() => {
+        if (goods?.length) store.dispatch(actionFeedAdd(goods));
+    }, [goods]);
+    return <AdminGoodsPage />;
+};
+
+const CAdminGoodsPageContainer = connect((state) => ({ goods: state.promise?.feedGoodsAll?.payload || [] }))(
+    AdminGoodsPageContainer
+);
 
 const AdminLayoutPage = () => {
     return (
         <Box className="AdminLayoutPage">
-            <Routes></Routes>
+            <Routes>
+                <Route path="/goods/" element={<CAdminGoodsPageContainer />} />
+            </Routes>
         </Box>
     );
 };

+ 8 - 0
src/components/common/AddButton/index.js

@@ -0,0 +1,8 @@
+import { Button } from '@mui/material';
+import { AiOutlinePlus } from 'react-icons/ai';
+
+export const AddButton = ({ isDisable = false, onClick }) => (
+    <Button onClick={() => onClick()} className="AddButton" disable={isDisable.toString()}>
+        <AiOutlinePlus />
+    </Button>
+);

+ 2 - 2
src/components/common/Categories/Category.js

@@ -2,10 +2,10 @@ import { Divider, ListItem, ListItemButton, ListItemText } from '@mui/material';
 import { Fragment } from 'react';
 import { Link } from 'react-router-dom';
 
-export const Category = ({ category = {} }) => (
+export const Category = ({ category = {}, url = '' }) => (
     <Fragment>
         <ListItem disablePadding>
-            <ListItemButton component={Link} to={`/category/${category._id}`}>
+            <ListItemButton component={Link} to={`${url + category._id}`}>
                 <ListItemText primary={category.name || ''} />
             </ListItemButton>
         </ListItem>

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

@@ -2,13 +2,13 @@ import { Paper, List, ListItem, ListItemButton, ListItemText, Box } from '@mui/m
 import { useEffect } from 'react';
 import { Category } from './Category';
 
-const Categories = ({ categories = [] }) => {
+const Categories = ({ categories = [], url = '/category/' }) => {
     return (
         <Box className="Categories">
             <List>
                 {(categories || []).map((cat) => (
                     <Box key={cat._id}>
-                        <Category category={cat} />
+                        <Category category={cat} url={url} />
                     </Box>
                 ))}
             </List>

+ 2 - 2
src/components/common/SearchBar/SearchResults.js

@@ -43,7 +43,7 @@ export const SearchResults = ({ items, onItemClick, itemLink = '' }) => {
                         []
                     )
                 ) : (
-                    <Error>Ничего не знайдено</Error>
+                    <Error>Нічого не знайдено</Error>
                 )}
             </Stack>
         </Paper>
@@ -52,4 +52,4 @@ export const SearchResults = ({ items, onItemClick, itemLink = '' }) => {
 
 const CSearchResults = connect((state) => ({ items: state.promise.goodsFind?.payload || [] }))(SearchResults);
 
-export default CSearchResults;
+export { CSearchResults };

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

@@ -1,7 +1,7 @@
 import { SearchBar, CSearchBar } from './SearchBar';
 
-// import CSearchResults, { SearchResults } from './SearchResults';
+import { SearchResults, CSearchResults } from './SearchResults';
 // import SearchGoodResultItem from './SearchGoodResultItem';
 
 // export { SearchBar, SearchResults, CSearchResults, SearchGoodResultItem };
-export { SearchBar, CSearchBar };
+export { SearchBar, CSearchBar, SearchResults, CSearchResults };

+ 18 - 0
src/components/layout/Aside/AdminCategories.js

@@ -0,0 +1,18 @@
+import { Categories } from '../../common/Categories';
+
+const adminCategories = [
+    {
+        _id: 'goods/',
+        name: 'Товари',
+    },
+    {
+        _id: 'categories/',
+        name: 'Категорії',
+    },
+    {
+        _id: 'orders/',
+        name: 'Замовлення',
+    },
+];
+
+export const AdminCategories = () => <Categories categories={adminCategories} url="/admin/" />;

+ 2 - 1
src/components/layout/Aside/index.js

@@ -1,5 +1,6 @@
 import { Box } from '@mui/material';
 import { Route, Routes } from 'react-router-dom';
+import { AdminCategories } from './AdminCategories';
 
 import { CCategories } from './CCategories';
 
@@ -7,7 +8,7 @@ const Aside = ({ children }) => (
     <Box className="Aside">
         <Box className="body">
             <Routes>
-                {/* <Route path="/admin/" component={CAdminCategories} /> */}
+                <Route path="/admin/*" element={<AdminCategories />} />
                 <Route path="/*" element={<CCategories />} />
             </Routes>
             {children}

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

@@ -6,7 +6,7 @@ import { Link } from 'react-router-dom';
 import { ReactComponent as ShoppingLogo } from '../../../images/shopping-logo.svg';
 import { DrawerCart } from '../../common/DrawerCart/DrawerCart';
 import { CSearchBar, SearchBar } from '../../common/SearchBar';
-import CSearchResults from '../../common/SearchBar/SearchResults';
+import { CSearchResults } from '../../common/SearchBar/SearchResults';
 import { CCartIcon } from './CartIcon';
 
 const Header = () => {

+ 58 - 0
src/index.scss

@@ -164,6 +164,64 @@
     flex:1;
     border:1px solid #C9C5CA ;
 
+    & .AdminLayoutPage{
+      padding: 10px;
+      padding-bottom: 400px;
+
+
+      & .AdminGoodList{
+        width:90%;
+        display: flex;
+        justify-content: center;
+        flex-wrap: wrap;
+        margin-left: 5%;
+
+
+
+        & .AdminGoodItem{
+          & img{
+            width: 100px;
+          }
+        }
+      }
+      & .searchBarWrapper{
+        display: flex;
+        justify-content: center;
+        margin-bottom:10px ;
+
+        & .SearchBar{
+
+          position: relative;
+          & .SearchBarInput{
+            width: 100%;
+            max-width: 500px;
+            min-width: 500px;
+          }
+          & .SearchResults{
+            position: absolute;
+            width: 100%;
+            max-width: 480px;
+            background: white;
+            padding: 10px;
+            z-index: 2;
+
+            & .SearchGoodResultItem{
+              text-align: left;
+              & img{
+                width:100%;
+                max-height: 100px;
+              }
+              &:hover{
+                background: #F1F2F4;
+              }
+            }
+          }
+
+        }
+      }
+    }
+
+
     & .MainPage{
       padding: 10px;
       & .MainPageImage{

+ 49 - 48
src/reducers/feedReducer.js

@@ -1,55 +1,56 @@
-// import { actionPromise } from '.';
-// import { actionCatAll, actionGoodsFind } from '../actions';
-// import { actionCatsFind } from '../actions/actionCatsFind';
-// import { actionGoodsAll } from '../actions/actionGoodsAll';
-// import { gql } from '../helpers';
+import { actionPromise } from '.';
+import { actionCatAll } from '../actions/actionCatAll';
+import { actionGoodsFind } from '../actions/actionGoodsFind';
+import { actionCatsFind } from '../actions/actionCatsFind';
+import { actionGoodsAll } from '../actions/actionGoodsAll';
+import { gql } from '../helpers';
 
-// function feedReducer(state = { payload: [] }, { type, payload = [] }) {
-//     if (type === 'FEED_ADD') {
-//         return {
-//             ...state,
-//             payload: [...state['payload'], ...payload],
-//         };
-//     }
+function feedReducer(state = { payload: [] }, { type, payload = [] }) {
+    if (type === 'FEED_ADD') {
+        return {
+            ...state,
+            payload: [...state['payload'], ...payload],
+        };
+    }
 
-//     if (type === 'FEED_CLEAR') {
-//         return { payload: [] };
-//     }
-//     return state || { payload: [] };
-// }
+    if (type === 'FEED_CLEAR') {
+        return { payload: [] };
+    }
+    return state || { payload: [] };
+}
 
-// const actionFeedAdd = (payload) => ({ type: 'FEED_ADD', payload });
-// const actionFeedClear = () => ({ type: 'FEED_CLEAR' });
-// const actionFeedGoods =
-//     (skip = 0) =>
-//     async (dispatch, getState) => {
-//         await dispatch(actionGoodsAll({ skip, limit: 50, promiseName: 'feedGoodsAll' }));
-//     };
+const actionFeedAdd = (payload) => ({ type: 'FEED_ADD', payload });
+const actionFeedClear = () => ({ type: 'FEED_CLEAR' });
+const actionFeedGoods =
+    (skip = 0) =>
+    async (dispatch, getState) => {
+        await dispatch(actionGoodsAll({ skip, limit: 50, promiseName: 'feedGoodsAll' }));
+    };
 
-// const actionFeedGoodsFind =
-//     ({ skip = 0, text = '' }) =>
-//     async (dispatch, getState) => {
-//         await dispatch(actionGoodsFind({ skip, limit: 50, promiseName: 'feedGoodsFind', text }));
-//     };
+const actionFeedGoodsFind =
+    ({ skip = 0, text = '' }) =>
+    async (dispatch, getState) => {
+        await dispatch(actionGoodsFind({ skip, limit: 50, promiseName: 'feedGoodsFind', text }));
+    };
 
-// const actionFeedCatsFind =
-//     ({ skip = 0, text = '' }) =>
-//     async (dispatch, getState) => {
-//         await dispatch(actionCatsFind({ skip, promiseName: 'feedCatsFind', text, limit: 50 }));
-//     };
+const actionFeedCatsFind =
+    ({ skip = 0, text = '' }) =>
+    async (dispatch, getState) => {
+        await dispatch(actionCatsFind({ skip, promiseName: 'feedCatsFind', text, limit: 50 }));
+    };
 
-// const actionFeedCats =
-//     (skip = 0) =>
-//     async (dispatch, getState) => {
-//         await dispatch(actionCatAll({ promiseName: 'feedCatAll', skip, limit: 50 }));
-//     };
+const actionFeedCats =
+    (skip = 0) =>
+    async (dispatch, getState) => {
+        await dispatch(actionCatAll({ promiseName: 'feedCatAll', skip, limit: 50 }));
+    };
 
-// export {
-//     actionFeedCats,
-//     actionFeedCatsFind,
-//     actionFeedGoods,
-//     actionFeedClear,
-//     actionFeedAdd,
-//     actionFeedGoodsFind,
-//     feedReducer,
-// };
+export {
+    actionFeedCats,
+    actionFeedCatsFind,
+    actionFeedGoods,
+    actionFeedClear,
+    actionFeedAdd,
+    actionFeedGoodsFind,
+    feedReducer,
+};

+ 19 - 19
src/reducers/index.js

@@ -11,35 +11,35 @@ import {
     actionPromiseClear,
 } from './promiseReducer';
 import { cartReducer, actionCartAdd, actionCartChange, actionCartDelete, actionCartClear } from './cartReducer';
-// import {
-//     actionFeedCats,
-//     actionFeedCatsFind,
-//     actionFeedGoods,
-//     actionFeedGoodsFind,
-//     actionFeedClear,
-//     actionFeedAdd,
-//     feedReducer,
-// } from './feedReducer';
+import {
+    actionFeedCats,
+    actionFeedCatsFind,
+    actionFeedGoods,
+    actionFeedGoodsFind,
+    actionFeedClear,
+    actionFeedAdd,
+    feedReducer,
+} from './feedReducer';
 import { createStoreHook } from 'react-redux';
 
 export { cartReducer, actionCartAdd, actionCartChange, actionCartDelete, actionCartClear };
 export { authReducer, actionAuthLogin, actionAuthLogout };
 export { promiseReducer, actionPending, actionFulfilled, actionRejected, actionPromise, actionPromiseClear };
-// export {
-//     actionFeedCats,
-//     actionFeedCatsFind,
-//     actionFeedGoods,
-//     actionFeedGoodsFind,
-//     actionFeedClear,
-//     actionFeedAdd,
-//     feedReducer,
-// };
+export {
+    actionFeedCats,
+    actionFeedCatsFind,
+    actionFeedGoods,
+    actionFeedGoodsFind,
+    actionFeedClear,
+    actionFeedAdd,
+    feedReducer,
+};
 export const store = createStore(
     combineReducers({
         auth: authReducer,
         promise: promiseReducer,
         cart: cartReducer,
-        // feed: feedReducer,
+        feed: feedReducer,
     }),
     composeWithDevTools(applyMiddleware(thunk))
 );