Browse Source

create files structure

Alex 2 years ago
parent
commit
17ef7abc71
87 changed files with 4520 additions and 2162 deletions
  1. 0 1
      .idea/inspectionProfiles/Project_Default.xml
  2. 2 0
      .idea/project.iml
  3. 906 22
      package-lock.json
  4. 4 0
      package.json
  5. 5 0
      public/index.html
  6. 21 21
      src/App.js
  7. 25 0
      src/actions/ActionCategory.js
  8. 1 1
      src/actions/ActionOrder.js
  9. 34 7
      src/actions/ActionOrderFind.js
  10. 18 6
      src/components/Breadcrumbs.jsx
  11. 2 1
      src/components/CPRoute.jsx
  12. 29 0
      src/components/Footer/Contact.jsx
  13. 51 47
      src/components/Footer.jsx
  14. 4 4
      src/components/GoogleMap.jsx
  15. 217 92
      src/components/Header.jsx
  16. 39 8
      src/components/MainButton.jsx
  17. 21 7
      src/components/NotFoundBlock.jsx
  18. 35 4
      src/components/SetCount.jsx
  19. 102 16
      src/components/TableLine.jsx
  20. 11 7
      src/components/Title.jsx
  21. 0 0
      src/img/our-team/1.jpg
  22. 0 0
      src/img/our-team/2.jpg
  23. 0 0
      src/img/our-team/3.jpg
  24. 0 0
      src/img/our-team/4.jpg
  25. 0 0
      src/img/our-team/romb.png
  26. 4 2
      src/index.css
  27. 13 52
      src/pages/AboutUsPage.jsx
  28. 18 0
      src/pages/AboutUsPage/BlockContentItem.jsx
  29. 27 0
      src/pages/AboutUsPage/BlockQualityItem.jsx
  30. 3 6
      src/pages/AdminPage/AdminPage.jsx
  31. 62 1
      src/pages/AdminPage/CateforyTab.jsx
  32. 1 1
      src/pages/AdminPage/ClientsTab.jsx
  33. 50 46
      src/pages/AdminPage/GoodTab.jsx
  34. 0 190
      src/pages/CartPage.jsx
  35. 72 0
      src/pages/CartPage/BlockTotal.jsx
  36. 49 0
      src/pages/CartPage/CartGoodLine.jsx
  37. 179 0
      src/pages/CartPage/CartPage.jsx
  38. 33 0
      src/pages/CartPage/TotalPriceLine.jsx
  39. 36 0
      src/pages/Catalog/CatalogPage.jsx
  40. 89 0
      src/pages/Catalog/CategoryAside.jsx
  41. 141 150
      src/pages/CatalogPage.jsx
  42. 88 0
      src/pages/Contact/AddressItem.jsx
  43. 51 81
      src/pages/ContactPage.jsx
  44. 0 78
      src/pages/FAQPage.jsx
  45. 43 0
      src/pages/FAQPage/AccordionsItem.jsx
  46. 59 0
      src/pages/FAQPage/FAQPage.jsx
  47. 0 153
      src/pages/MyAccountPage.jsx
  48. 87 0
      src/pages/MyAccountPage/Form.jsx
  49. 101 0
      src/pages/MyAccountPage/MyAccountPage.jsx
  50. 0 250
      src/pages/MyOrdersPage.jsx
  51. 24 0
      src/pages/MyOrdersPage/AccordionHeaderText.jsx
  52. 240 0
      src/pages/MyOrdersPage/AccordionItem.jsx
  53. 92 0
      src/pages/MyOrdersPage/MainOrders.jsx
  54. 26 0
      src/pages/MyOrdersPage/MyOrdersPage.jsx
  55. 0 182
      src/pages/OurTeamPage.jsx
  56. 100 0
      src/pages/OurTeamPage/ItemTeam.jsx
  57. 103 0
      src/pages/OurTeamPage/OurTeamPage.jsx
  58. 27 0
      src/pages/PrivacyPolicyPage/BlockPolicy.jsx
  59. 25 0
      src/pages/PrivacyPolicyPage/FullBlock.jsx
  60. 17 52
      src/pages/PrivacyPolicyPage.jsx
  61. 0 230
      src/pages/ProductPage.jsx
  62. 54 0
      src/pages/ProductPage/AddToCart.jsx
  63. 41 0
      src/pages/ProductPage/AddToWishList.jsx
  64. 30 0
      src/pages/ProductPage/BlockProduct.jsx
  65. 41 0
      src/pages/ProductPage/CarouselItem.jsx
  66. 104 0
      src/pages/ProductPage/Goods.jsx
  67. 11 0
      src/pages/ProductPage/ImageItem.jsx
  68. 15 0
      src/pages/ProductPage/ProductDescription.jsx
  69. 13 0
      src/pages/ProductPage/ProductPage.jsx
  70. 12 0
      src/pages/ProductPage/ProductPrice.jsx
  71. 24 0
      src/pages/ProductPage/ProductTags.jsx
  72. 13 0
      src/pages/ProductPage/ProductTitle.jsx
  73. 13 0
      src/pages/ProductPage/timeCalc.js
  74. 0 280
      src/pages/ProfilePage.jsx
  75. 79 0
      src/pages/ProfilePage/AccountDetails.jsx
  76. 104 0
      src/pages/ProfilePage/FormUpload.jsx
  77. 34 0
      src/pages/ProfilePage/ItemTabsAccountDefault.jsx
  78. 101 0
      src/pages/ProfilePage/MyDropzone.jsx
  79. 179 0
      src/pages/ProfilePage/ProfilePage.jsx
  80. 0 116
      src/pages/SearchPage.jsx
  81. 79 0
      src/pages/SearchPage/ItemFound.jsx
  82. 14 0
      src/pages/SearchPage/NotFound.jsx
  83. 89 0
      src/pages/SearchPage/SearchPage.jsx
  84. 0 47
      src/pages/WishListPage.jsx
  85. 71 0
      src/pages/WishListPage/MainWishList.jsx
  86. 11 0
      src/pages/WishListPage/WishListPage.jsx
  87. 1 1
      src/reducers/CategoryReducer.js

+ 0 - 1
.idea/inspectionProfiles/Project_Default.xml

@@ -6,7 +6,6 @@
         <language minSize="87" name="JavaScript" />
       </Languages>
     </inspection_tool>
-    <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
     <inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
       <option name="myValues">
         <value>

+ 2 - 0
.idea/project.iml

@@ -9,5 +9,7 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="material" level="application" />
+    <orderEntry type="library" name="systemjs" level="application" />
   </component>
 </module>

File diff suppressed because it is too large
+ 906 - 22
package-lock.json


+ 4 - 0
package.json

@@ -6,6 +6,7 @@
     "@emotion/react": "^11.7.1",
     "@emotion/styled": "^11.6.0",
     "@material-ui/icons": "^4.11.2",
+    "@minoru/react-dnd-treeview": "^1.6.1",
     "@mui/base": "^5.0.0-alpha.63",
     "@mui/icons-material": "^5.2.5",
     "@mui/lab": "^5.0.0-alpha.62",
@@ -13,11 +14,14 @@
     "@mui/styles": "^5.2.3",
     "@mui/system": "^5.2.6",
     "@mui/x-data-grid": "^5.2.2",
+    "@syncfusion/ej2-base": "^19.4.42",
+    "@syncfusion/ej2-react-navigations": "^19.4.41",
     "@testing-library/jest-dom": "^5.16.1",
     "@testing-library/react": "^12.1.2",
     "@testing-library/user-event": "^13.5.0",
     "array-move": "^4.0.0",
     "google-maps-react": "^2.0.6",
+    "mui-draggable-treeview": "^1.1.3",
     "node-sass": "^7.0.0",
     "prop-types": "^15.8.0",
     "react": "^17.0.2",

+ 5 - 0
public/index.html

@@ -19,6 +19,11 @@
             rel="stylesheet"
             href="https://fonts.googleapis.com/icon?family=Material+Icons"
     />
+    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
+    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
+    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
+    <link href="//cdn.syncfusion.com/ej2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
     <title>ABRAXAS</title>
   </head>
   <body>

+ 21 - 21
src/App.js

@@ -1,27 +1,27 @@
-import {Router} from 'react-router-dom';
+import { Router } from 'react-router-dom';
 import createHistory from "history/createBrowserHistory";
 import MainPage from "./pages/MainPage";
-import Page404 from "./pages/404Page";
-import ContactPage from "./pages/ContactPage";
-import Switch from "react-router-dom/es/Switch";
-import PrivacyPolicy from "./pages/PrivacyPolicyPage";
-import FAQPage from "./pages/FAQPage";
-import OurTeamPage from "./pages/OurTeamPage";
-import AboutUsPage from "./pages/AboutUsPage";
-import {Provider} from "react-redux";
-import MyAccountPage from "./pages/MyAccountPage";
+import { Switch } from "react-router-dom"
+import {AboutUsPage} from "./pages/AboutUsPage/AboutUsPage";
+import {OurTeamPage} from "./pages/OurTeamPage/OurTeamPage";
+import { Provider } from "react-redux";
 import {store} from "./reducers";
-import ProfilePage from "./pages/ProfilePage";
-import CatalogPage from "./pages/CatalogPage";
 import Header from "./components/Header";
-import {Footer} from "./components/Footer";
-import ProductPage from "./pages/ProductPage";
-import WishListPage from "./pages/WishListPage";
-import SearchPage from "./pages/SearchPage";
-import MyOrdersPage from "./pages/MyOrdersPage";
-import CartPage from "./pages/CartPage";
 import {CPRoute, CRRoute} from "./components/CPRoute";
 import AdminPage from "./pages/AdminPage/AdminPage";
+import Page404 from "./pages/404Page";
+import {FAQPage} from "./pages/FAQPage/FAQPage";
+import {CCatalogPage} from "./pages/Catalog/CatalogPage";
+import {ContactPage} from "./pages/Contact/ContactPage";
+import PrivacyPolicy from "./pages/PrivacyPolicyPage/PrivacyPolicyPage";
+import SearchPage from "./pages/SearchPage/SearchPage";
+import {CCartPage} from "./pages/CartPage/CartPage";
+import {MyOrdersPage} from "./pages/MyOrdersPage/MyOrdersPage";
+import {ProductPage} from "./pages/ProductPage/ProductPage";
+import {WishListPage} from "./pages/WishListPage/WishListPage";
+import MyAccountPage from "./pages/MyAccountPage/MyAccountPage";
+import {CProfilePage} from "./pages/ProfilePage/ProfilePage";
+import {Footer} from "./components/Footer/Footer";
 
 const history = createHistory();
 
@@ -32,7 +32,7 @@ export const App = () => {
               <Header/>
               <Switch>
                   <CRRoute path="/" component={MainPage} exact/>
-                  <CRRoute path="/catalog" component={CatalogPage} />
+                  <CRRoute path="/catalog" component={CCatalogPage} />
                   <CRRoute path="/good" component={ProductPage} />
                   <CRRoute path="/about-us" component={AboutUsPage} />
                   <CRRoute path="/our-team" component={OurTeamPage} />
@@ -41,10 +41,10 @@ export const App = () => {
                   <CRRoute path="/my-account" component={MyAccountPage} />
                   <CRRoute path="/privacy-policy" component={PrivacyPolicy} />
                   <CRRoute path="/search" component={SearchPage} />
-                  <CRRoute path="/basket" component={CartPage} />
+                  <CRRoute path="/basket" component={CCartPage} />
                   <CRRoute path="/wish-list" component={WishListPage} />
                   <CRRoute path="/my-orders" component={MyOrdersPage} />
-                  <CPRoute roles={["user", "admin"]} path="/profile" fallback='/my-account' component={ProfilePage} />
+                  <CPRoute roles={["user", "admin"]} path="/profile" fallback='/my-account' component={CProfilePage} />
                   <CPRoute roles={["admin"]} path="/admin" fallback='/my-account' component={AdminPage} />
                   <CRRoute path="*" component={Page404} />
               </Switch>

+ 25 - 0
src/actions/ActionCategory.js

@@ -93,3 +93,28 @@ export const actionCategoryUpsert = (category) => {
 //         )
 //     )
 // }
+
+export const actionAllCategory = () => {
+    return actionPromise('allCategory', gql(`query allCategory{
+          CategoryFind(query: "[{}]"){
+            _id
+            name
+            subCategories{
+              _id,
+              name,
+              subCategories{
+                _id,
+                name
+              }
+            }
+          }
+        }`)
+    )
+}
+export const actionFullAllCategory = () =>
+    async dispatch => {
+        let value = await dispatch(actionAllCategory())
+        if (value){
+            dispatch(actionCategoryCreate(value))
+        }
+    }

+ 1 - 1
src/actions/ActionOrder.js

@@ -1,6 +1,7 @@
 const {actionPromise} = require("../reducers/PromiseReducer");
 const {gql} = require("./PathDB");
 
+//OrderUpsert
 export const ActionOrder = (orderGoods) => {
     return actionPromise('order', gql(`
             mutation order($order:OrderInput){
@@ -9,7 +10,6 @@ export const ActionOrder = (orderGoods) => {
                  }
     `, {order: {orderGoods}}))
 }
-
 export const ActionFullOrder = (card) =>
     async (dispatch) => {
         let orderGoods = Object.entries(card).map(([_id, {count}]) => ({good: {_id}, count}))

+ 34 - 7
src/actions/ActionOrderFind.js

@@ -2,9 +2,10 @@ import {actionPromise} from "../reducers/PromiseReducer";
 import {gql} from "./PathDB";
 import {actionMyOrder} from "../reducers/MyOrdersReducer";
 
-const actionOrderFind = () => {
-    return actionPromise('orderFind', gql(`query orderFind {
-        OrderFind(query:"[{}]") {
+//OrderFind
+const actionOrderFind = (count, limit) => {
+    return actionPromise('orderFind', gql(`query orderFind($query: String!) {
+        OrderFind(query: $query) {
             _id total createdAt orderGoods{
                 _id count price good{
                     _id name description images{
@@ -13,15 +14,41 @@ const actionOrderFind = () => {
                 }
             }
         }
-    }`)
+    }`,
+            {
+                query: JSON.stringify([{}, { sort: [{ ["createdAt"]: -1 }], skip: [count || 0], limit: [limit] }])
+            }
+        )
     )
 }
-
-export const actionFullOrderFind = () =>
+export const actionFullOrderFind = (count=0, limit=100) =>
     async dispatch => {
-        let value = await dispatch(actionOrderFind())
+        let value = await dispatch(actionOrderFind(count, limit))
         if (value){
             dispatch(actionMyOrder(value))
         }
     }
 
+//OrderCount
+export const actionOrderCount = () => {
+    return actionPromise('orderCount', gql(`query orderCount{
+            OrderCount(query: "[{}]")
+        }`)
+    )
+}
+
+//OrderFindOne
+export const actionOrderFindOne = (_id) => {
+    return actionPromise('orderFindOne', gql(`query orderFindOne($q: String){
+            OrderFindOne(query: $q) {
+             _id createdAt total orderGoods {
+                    _id price count total good {
+                        _id createdAt name images {
+                            _id url
+                        }
+                    }
+                  }
+             }
+        }`,  {q: JSON.stringify([{_id}])})
+    )
+}

+ 18 - 6
src/components/Breadcrumbs.jsx

@@ -20,11 +20,19 @@ const Breadcrumb = ({links=['this page'], title}) => {
                     to={`/${link}`}> {i.toUpperCase()}
                 </Link>
     })
-    arr.unshift(<Link style={{
-        color: "#fff",
-        textDecoration: "none",
-        fontSize: "11px"
-    }} to="/" key={'homeBreadcrumbs'}> HOME </Link>)
+    arr.unshift(
+        <Link
+            style={{
+                color: "#fff",
+                textDecoration: "none",
+                fontSize: "11px"
+            }}
+            to="/"
+            key={'homeBreadcrumbs'}
+        >
+            HOME
+        </Link>
+    )
 
     return (
         <article
@@ -51,7 +59,11 @@ const Breadcrumb = ({links=['this page'], title}) => {
                 position="absolute"
                 bottom="40px"
             >
-                <Breadcrumbs color="#fff" separator="›" aria-label="breadcrumb">
+                <Breadcrumbs
+                    color="#fff"
+                    separator="›"
+                    aria-label="breadcrumb"
+                >
                     {arr}
                 </Breadcrumbs>
             </Stack>

+ 2 - 1
src/components/CPRoute.jsx

@@ -9,7 +9,8 @@ const RRoute = ({action, component: Component, ...routeProps}) => {
     }
     return <Route {...routeProps} component={WrapperComponent}/>
 }
-export const CRRoute = connect(null, {action: match => ({type: 'ROUTE', match})})(RRoute)
+export const CRRoute = connect(null,
+    {action: match => ({type: 'ROUTE', match})})(RRoute)
 
 const ProtectedRoute =({ fallback='/',
                          roles=['admin'],

+ 29 - 0
src/components/Footer/Contact.jsx

@@ -0,0 +1,29 @@
+import {Link, Typography} from "@mui/material";
+
+export const Contact = ({Icon, text, link}) => {
+    return (
+        <Typography
+            color="inherit"
+            variant="h6"
+            noWrap
+            component="div"
+        >
+            <Link
+                className='Footer__Contact'
+                display="flex"
+                flexDirection="row"
+                alignItems="center"
+                textAlign="left"
+                padding="10px 0"
+                component="a"
+                variant="body2"
+                color="#fff"
+                underline="none"
+                href={link}
+            >
+                <Icon />
+                {text}
+            </Link>
+        </Typography>
+    )
+}

+ 51 - 47
src/components/Footer.jsx

@@ -1,17 +1,17 @@
-import {Container, Typography, Link, Grid, Box, useMediaQuery, makeStyles} from "@mui/material";
-import LocalPhoneIcon from '@mui/icons-material/LocalPhone';
-import LocationOnIcon from '@mui/icons-material/LocationOn';
-import EmailIcon from '@mui/icons-material/Email';
-import WatchLaterIcon from '@mui/icons-material/WatchLater';
-import FacebookIcon from '@mui/icons-material/Facebook';
-import InstagramIcon from '@mui/icons-material/Instagram';
-import TwitterIcon from '@mui/icons-material/Twitter';
-import YouTubeIcon from '@mui/icons-material/YouTube';
+import LocalPhoneIcon from "@mui/icons-material/LocalPhone";
+import LocationOnIcon from "@mui/icons-material/LocationOn";
+import EmailIcon from "@mui/icons-material/Email";
+import WatchLaterIcon from "@mui/icons-material/WatchLater";
+import FacebookIcon from "@mui/icons-material/Facebook";
+import InstagramIcon from "@mui/icons-material/Instagram";
+import TwitterIcon from "@mui/icons-material/Twitter";
+import YouTubeIcon from "@mui/icons-material/YouTube";
+import {Box, Container, Grid, Typography, useMediaQuery} from "@mui/material";
+import background from "../../img/footer/bg-footer.png";
 import LinkRouter from "react-router-dom/es/Link";
-import background from "../img/footer/bg-footer.png"
-import "../scss/Footer.scss"
-import Social from "./SocialLink";
-
+import Social from "../SocialLink";
+import {Contact} from "./Contact";
+import '../../scss/Footer.scss';
 
 const contactDefault = [
     {'icon': LocalPhoneIcon, 'text': '+123 488 9652', 'url': '#'},
@@ -26,33 +26,6 @@ const linksSocialDefault = [
     {'icon': YouTubeIcon, 'url': 'https://www.youtube.com/'},
 ]
 
-const Contact = ({Icon, text, link}) => {
-    return (
-        <Typography
-            color="inherit"
-            variant="h6"
-            noWrap
-            component="div"
-        >
-            <Link
-                className='Footer__Contact'
-                display="flex"
-                flexDirection="row"
-                alignItems="center"
-                textAlign="left"
-                padding="10px 0"
-                component="a"
-                variant="body2"
-                color="#fff"
-                underline="none"
-                href={link}
-            >
-                <Icon />
-                {text}
-            </Link>
-        </Typography>
-    )
-}
 
 export const Footer = ({contact=contactDefault, linksSocial=linksSocialDefault}) => {
     const matches = useMediaQuery('(max-width:899px)');
@@ -60,17 +33,29 @@ export const Footer = ({contact=contactDefault, linksSocial=linksSocialDefault})
     return (
         <footer
             className="Footer"
-            style={{background: `url(${background}) center repeat`, padding: "40px 0"}}
+            style={{
+                background: `url(${background}) center repeat`,
+                padding: "40px 0"
+            }}
         >
             <Container maxWidth="lg">
-                <Grid container spacing={{ xs: 2, md: 3 }} columns={{ xs: 1, sm: 8, md: 12 }}>
+                <Grid
+                    container
+                    spacing={{ xs: 2, md: 3 }}
+                    columns={{ xs: 1, sm: 8, md: 12 }}
+                >
                     <Grid
                         item
                         sm={12} md={4}
                         width={matches ? "100%" : "auto"}
                     >
                         {(contact || []).map((item, index) =>
-                            <Contact key={index} Icon={item.icon} text={item.text} link={item.url}/>
+                            <Contact
+                                key={index}
+                                Icon={item.icon}
+                                text={item.text}
+                                link={item.url}
+                            />
                         )}
                     </Grid>
                     <Grid
@@ -87,11 +72,20 @@ export const Footer = ({contact=contactDefault, linksSocial=linksSocialDefault})
                             textAlign="center"
                             marginBottom="20px"
                         >
-                            <LinkRouter to='/' className="Footer__Logo"> ABRAXAS </LinkRouter>
+                            <LinkRouter
+                                to='/'
+                                className="Footer__Logo"
+                            >
+                                ABRAXAS
+                            </LinkRouter>
                         </Typography>
                         <Box>
                             {(linksSocial || []).map((item, index) =>
-                                <Social key={index} Icon={item.icon} link={item.url}/>
+                                <Social
+                                    key={index}
+                                    Icon={item.icon}
+                                    link={item.url}
+                                />
                             )}
                         </Box>
                     </Grid>
@@ -134,8 +128,18 @@ export const Footer = ({contact=contactDefault, linksSocial=linksSocialDefault})
                         variant="body2"
                         marginBottom={matches2 ? "10px" : "0"}
                     >
-                        <LinkRouter to='/privacy-policy' className="Footer__Bottom-link"> PRIVACY POLICY </LinkRouter>
-                        <LinkRouter to='/faq' className="Footer__Bottom-link"> FAQ </LinkRouter>
+                        <LinkRouter
+                            to='/privacy-policy'
+                            className="Footer__Bottom-link"
+                        >
+                            PRIVACY POLICY
+                        </LinkRouter>
+                        <LinkRouter
+                            to='/faq'
+                            className="Footer__Bottom-link"
+                        >
+                            FAQ
+                        </LinkRouter>
                     </Typography>
                 </Box>
             </Container>

+ 4 - 4
src/components/GoogleMap.jsx

@@ -7,12 +7,12 @@ export class MapContainer extends Component {
         activeMarker: {},
         selectedPlace: {},
         mapCenter: {
-            lat: this.props.lat,
-            lng: this.props.lng
+            lat: this.props['lat'],
+            lng: this.props['lng']
         }
     };
 
-    onMarkerClick = (props, marker, e) =>
+    onMarkerClick = (props, marker) =>
         this.setState({
             selectedPlace: props,
             activeMarker: marker,
@@ -22,7 +22,7 @@ export class MapContainer extends Component {
 
     render() {
         return (
-            <Map google={this.props.google}
+            <Map google={this.props['google']}
                  style={{width: '100%'}}
                  initialCenter={{
                      lat: this.state.mapCenter.lat,

+ 217 - 92
src/components/Header.jsx

@@ -36,7 +36,12 @@ const Header = ({user={}}) => {
 
     const LogoItem = () => {
         return (
-            <Link to='/' className="Header__Logo"> ABRAXAS </Link>
+            <Link
+                to='/'
+                className="Header__Logo"
+            >
+                ABRAXAS
+            </Link>
         )
     }
     const LinkItem = ({page, color='white'}) => {
@@ -44,7 +49,11 @@ const Header = ({user={}}) => {
             <Button
                 key={page.toString()}
                 onClick={handleCloseNavMenu}
-                sx={{ my: 2, color: color, display: 'block'}}
+                sx={{
+                    my: 2,
+                    color: color,
+                    display: 'block'
+                }}
             >
                 <Link
                     to={`/${Array.from(page.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}`}
@@ -53,21 +62,36 @@ const Header = ({user={}}) => {
             </Button>
         )
     }
-    const IconItems = ({cart={}, wishlist={}, size="large", color='default', valueWishList=0}) => {
+    const IconItems = ({cart={}, wishlist={}, size="large", color='default'}) => {
         return (
             <>
                 <Link to='/search'>
-                    <IconButton key={'search'} size={size} aria-label="search" color={color}>
+                    <IconButton
+                        key={'search'}
+                        size={size}
+                        aria-label="search"
+                        color={color}
+                    >
                         <SearchIcon />
                     </IconButton>
                 </Link>
                 <Link to='/my-orders'>
-                    <IconButton key={'my-orders'} size={size} aria-label="my-orders" color={color}>
+                    <IconButton
+                        key={'my-orders'}
+                        size={size}
+                        aria-label="my-orders"
+                        color={color}
+                    >
                         <ManageSearchIcon />
                     </IconButton>
                 </Link>
                 <Link to='/wish-list'>
-                    <IconButton key={'wish-list'} size={size} aria-label="wish-list" color={color}>
+                    <IconButton
+                        key={'wish-list'}
+                        size={size}
+                        aria-label="wish-list"
+                        color={color}
+                    >
                         <Badge
                             color="success"
                             badgeContent={+Object.entries(wishlist).length}
@@ -81,16 +105,21 @@ const Header = ({user={}}) => {
                     </IconButton>
                 </Link>
                 <Link to='/basket'>
-                    <IconButton key={'basket'} size={size} aria-label="basket" color={color}>
+                    <IconButton
+                        key={'basket'}
+                        size={size}
+                        aria-label="basket"
+                        color={color}
+                    >
                         <Badge
-                                color="success"
-                                badgeContent={+Object.entries(cart).reduce((a, b) => {
-                                    return a + b[1].count
-                                }, 0)}
-                                anchorOrigin={{
-                                    vertical: 'bottom',
-                                    horizontal: 'right',
-                                }}
+                            color="success"
+                            badgeContent={+Object.entries(cart).reduce((a, b) => {
+                                return a + b[1].count
+                            }, 0)}
+                            anchorOrigin={{
+                                vertical: 'bottom',
+                                horizontal: 'right',
+                            }}
                         >
                             <ShoppingCartIcon/>
                         </Badge>
@@ -103,9 +132,23 @@ const Header = ({user={}}) => {
 
     const ItemAuth = ({link, text}) => {
         return (
-            <Link style={{textDecoration: 'none', color: '#000'}} to={`/${link}`}>
-                <MenuItem key={text} onClick={handleCloseNavMenu}>
-                    <Typography textAlign="center" color='#fff'>{text}</Typography>
+            <Link
+                style={{
+                    textDecoration: 'none',
+                    color: '#000'
+                }}
+                to={`/${link}`}
+            >
+                <MenuItem
+                    key={text}
+                    onClick={handleCloseNavMenu}
+                >
+                    <Typography
+                        textAlign="center"
+                        color='#fff'
+                    >
+                        {text}
+                    </Typography>
                 </MenuItem>
             </Link>
         )
@@ -113,53 +156,76 @@ const Header = ({user={}}) => {
 
     const UserIcon = ({auth}) => {
         return (
-                Object.entries(auth).length === 0 ?
-                    <Link style={{textDecoration: 'none'}} to={'/my-account'}>
-                        <IconButton sx={{ p: 0 }}>
-                            <Avatar alt="User default" src={userDefault} />
+            Object.entries(auth).length === 0 ?
+                <Link
+                    style={{textDecoration: 'none'}}
+                    to={'/my-account'}
+                >
+                    <IconButton sx={{ p: 0 }}>
+                        <Avatar
+                            alt="User default"
+                            src={userDefault}
+                        />
+                    </IconButton>
+                </Link> :
+                <>
+                    <Tooltip title="Open settings">
+                        <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
+                            {!auth.avatar && auth.avatar === null ?
+                                <Avatar
+                                    alt="User"
+                                    src={userDefault}/>
+                                :
+                                <Avatar
+                                    alt="User"
+                                    src={user?.avatar?.url && backURL + '/' + user?.avatar?.url}
+                                />
+                            }
                         </IconButton>
-                    </Link> :
-                    <>
-                        <Tooltip title="Open settings">
-                            <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
-                                {!auth.avatar && auth.avatar === null ?
-                                    <Avatar alt="User" src={userDefault}/> :
-                                    <Avatar alt="User" src={user?.avatar?.url && backURL + '/' + user?.avatar?.url}/>
-                                }
-                            </IconButton>
-                        </Tooltip>
-                        <Menu
-                            sx={{ mt: '55px', ml: '90%'}}
-                            id="menu-appbar"
-                            anchorEl={anchorElUser}
-                            anchorOrigin={{
-                                vertical: 'top',
-                                horizontal: 'right',
-                            }}
-                            keepMounted
-                            transformOrigin={{
-                                vertical: 'top',
-                                horizontal: 'right',
-                            }}
-                            open={Boolean(anchorElUser)}
-                            onClose={handleCloseUserMenu}
-                        >
-                            {settingsDefaultUserAuth.map(item => {
-                                if (item === 'Logout') {
-                                    return <CButtonLogOut key={'Logout'}/>
-                                }
-                                else if(item === 'Dashboard'){
-                                    if (auth.payload?.sub?.acl[2]){
-                                        return <ItemAuth link={'admin'} text={'Dashboard'} key={'admin'}/>
-                                    }
-                                }
-                                else if(item !== 'Dashboard') {
-                                    return <ItemAuth key={item.toString()} text={item}
-                                                     link={Array.from(item.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}/>
+                    </Tooltip>
+                    <Menu
+                        sx={{ mt: '55px', ml: '90%'}}
+                        id="menu-appbar"
+                        anchorEl={anchorElUser}
+                        anchorOrigin={{
+                            vertical: 'top',
+                            horizontal: 'right',
+                        }}
+                        keepMounted
+                        transformOrigin={{
+                            vertical: 'top',
+                            horizontal: 'right',
+                        }}
+                        open={Boolean(anchorElUser)}
+                        onClose={handleCloseUserMenu}
+                    >
+                        {settingsDefaultUserAuth.map(item => {
+                            if (item === 'Logout') {
+                                return <CButtonLogOut key={'Logout'}/>
+                            }
+                            else if(item === 'Dashboard'){
+                                if (auth.payload?.sub?.acl[2]){
+                                    return (
+                                        <ItemAuth
+                                            link={'admin'}
+                                            text={'Dashboard'}
+                                            key={'admin'}
+                                        />
+                                    )
                                 }
-                            })}
-                        </Menu>
-                    </>
+                            }
+                            else if(item !== 'Dashboard') {
+                                return (
+                                    <ItemAuth
+                                        key={item.toString()}
+                                        text={item}
+                                        link={Array.from(item.toLowerCase()).map(i => i === ' ' ? '-' : i).join('')}
+                                    />
+                                )
+                            }
+                        })}
+                    </Menu>
+                </>
         )
     }
     const CUserIcon = connect(state => ({auth: state.auth}))(UserIcon)
@@ -167,29 +233,59 @@ const Header = ({user={}}) => {
     const ButtonLogOut = ({actionLogOut, actionUserRemove}) => {
         return (
             <Button
-                onClick={() => {actionLogOut(); actionUserRemove(); handleCloseNavMenu();}}
-                style={{textDecoration: 'none', textTransform: 'capitalize', fontWeight: '400', color: '#fff', textAlign: "center", width: '100%'}}
+                onClick={() => {
+                    actionLogOut();
+                    actionUserRemove();
+                    handleCloseNavMenu();
+                }}
+                style={{
+                    textDecoration: 'none',
+                    textTransform: 'capitalize',
+                    fontWeight: '400',
+                    color: '#fff',
+                    textAlign: "center",
+                    width: '100%'
+                }}
             >
                 Log out
             </Button>
         )
     }
-    const CButtonLogOut = connect(null, {actionLogOut: actionAuthLogout, actionUserRemove: actionUserRemove})(ButtonLogOut)
+    const CButtonLogOut = connect(null, {actionLogOut: actionAuthLogout,
+        actionUserRemove: actionUserRemove})(ButtonLogOut)
 
     return (
-        <AppBar sx={{padding: '10px 0', backgroundColor: 'rgb(131,179,175)'}} className='Header' position="fixed" enableColorOnDark={true}>
+        <AppBar
+            sx={{
+                padding: '10px 0',
+                backgroundColor: 'rgb(131,179,175)'
+            }}
+            className='Header'
+            position="fixed"
+            enableColorOnDark={true}
+        >
             <Container maxWidth="xl">
                 <Toolbar disableGutters>
                     <Typography
                         variant="h6"
                         noWrap
                         component="div"
-                        sx={{ mr: 2, display: { xs: 'none', md: 'flex' } }}
+                        sx={{ mr: 2,
+                            display: {
+                                xs: 'none',
+                                md: 'flex'
+                            }
+                        }}
                     >
                         <LogoItem/>
                     </Typography>
 
-                    <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
+                    <Box
+                        sx={{
+                            flexGrow: 1,
+                            display: { xs: 'flex', md: 'none' }
+                        }}
+                    >
                         <IconButton
                             size="large"
                             aria-label="account of current user"
@@ -201,30 +297,40 @@ const Header = ({user={}}) => {
                             <MenuIcon />
                         </IconButton>
                         <Menu className='Header__Burger'
-                            id="menu-appbar"
-                            anchorEl={anchorElNav}
-                            anchorOrigin={{
-                                vertical: 'bottom',
-                                horizontal: 'left',
-                            }}
-                            keepMounted
-                            transformOrigin={{
-                                vertical: 'top',
-                                horizontal: 'left',
-                            }}
-                            open={Boolean(anchorElNav)}
-                            onClose={handleCloseNavMenu}
-                            sx={{
-                                display: { xs: 'block', md: 'none' },
-                            }}
+                              id="menu-appbar"
+                              anchorEl={anchorElNav}
+                              anchorOrigin={{
+                                  vertical: 'bottom',
+                                  horizontal: 'left',
+                              }}
+                              keepMounted
+                              transformOrigin={{
+                                  vertical: 'top',
+                                  horizontal: 'left',
+                              }}
+                              open={Boolean(anchorElNav)}
+                              onClose={handleCloseNavMenu}
+                              sx={{
+                                  display: { xs: 'block', md: 'none' },
+                              }}
                         >
                             {pages.map((page) => (
-                                <MenuItem key={page.toString()} onClick={handleCloseNavMenu}>
-                                    <LinkItem key={page.toString()} page={page} color={'#fff'}/>
+                                <MenuItem
+                                    key={page.toString()}
+                                    onClick={handleCloseNavMenu}
+                                >
+                                    <LinkItem
+                                        key={page.toString()}
+                                        page={page}
+                                        color={'#fff'}
+                                    />
                                 </MenuItem>
                             ))}
                             <MenuItem onClick={handleCloseNavMenu}>
-                                <CIconItems size={'large'} color={'inherit'} />
+                                <CIconItems
+                                    size={'large'}
+                                    color={'inherit'}
+                                />
                             </MenuItem>
                         </Menu>
                     </Box>
@@ -233,18 +339,37 @@ const Header = ({user={}}) => {
                         variant="h6"
                         noWrap
                         component="div"
-                        sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}
+                        sx={{
+                            flexGrow: 1,
+                            display: { xs: 'flex', md: 'none' }
+                        }}
                     >
                         <LogoItem />
                     </Typography>
 
-                    <Box className='Header__Links' sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
+                    <Box
+                        className='Header__Links'
+                        sx={{
+                            flexGrow: 1,
+                            display: { xs: 'none', md: 'flex' }
+                        }}
+                    >
                         {pages.map((page) => (
-                            <LinkItem key={page.toString()} page={page} color={'#fff'}/>
+                            <LinkItem
+                                key={page.toString()}
+                                page={page}
+                                color={'#fff'}
+                            />
                         ))}
                     </Box>
 
-                    <Box className='Header__Icons' sx={{ flexGrow: 0, display: { xs: 'none', md: 'flex' } }}>
+                    <Box
+                        className='Header__Icons'
+                        sx={{
+                            flexGrow: 0,
+                            display: { xs: 'none', md: 'flex' }
+                        }}
+                    >
                         <CIconItems size={'large'} />
                     </Box>
                     <Box sx={{ flexGrow: 0 }}>

+ 39 - 8
src/components/MainButton.jsx

@@ -7,16 +7,34 @@ const ButtonRoot = React.forwardRef(function ButtonRoot(props, ref) {
     const { children, ...other } = props;
 
     return (
-        <svg width="150" height="50" {...other} ref={ref}>
-            <polygon points="0,50 0,0 150,0 150,50" className="bg" />
-            <polygon points="0,50 0,0 150,0 150,50" className="borderEffect" />
-            <foreignObject x="0" y="0" width="150" height="50">
-                <div className="content">{children}</div>
+        <svg
+            width="150"
+            height="50"
+            {...other}
+            ref={ref}
+        >
+            <polygon
+                points="0,50 0,0 150,0 150,50"
+                className="bg"
+            />
+            <polygon
+                points="0,50 0,0 150,0 150,50"
+                className="borderEffect"
+            />
+            <foreignObject
+                x="0" y="0"
+                width="150"
+                height="50"
+            >
+                <div
+                    className="content"
+                >
+                    {children}
+                </div>
             </foreignObject>
         </svg>
     );
 });
-
 ButtonRoot.propTypes = {
     children: PropTypes.node,
 };
@@ -105,9 +123,22 @@ const CustomButtonRoot = styled(ButtonRoot)(
 );
 
 const SvgButton = React.forwardRef(function SvgButton(props, ref) {
-    return <ButtonUnstyled {...props} component={CustomButtonRoot} ref={ref} />;
+    return (
+        <ButtonUnstyled
+            {...props}
+            component={CustomButtonRoot}
+            ref={ref}
+        />
+    )
 });
 
 export default function UnstyledButtonCustom({text, onClick, disabled}) {
-    return <SvgButton disabled={disabled} onClick={onClick}>{text}</SvgButton>;
+    return (
+        <SvgButton
+            disabled={disabled}
+            onClick={onClick}
+        >
+            {text}
+        </SvgButton>
+    )
 }

+ 21 - 7
src/components/NotFoundBlock.jsx

@@ -1,12 +1,22 @@
 import {Box, Container, Typography, useMediaQuery} from "@mui/material";
 import imgUrl from "../img/not-found/1.png";
 
-export const NotFoundBlock = ({img=imgUrl, headerText='OOPS! THAT PAGE CAN’T BE FOUND', text='The page you are trying to reach is not available.'}) => {
+export const NotFoundBlock = ({img=imgUrl,
+                                  headerText='OOPS! THAT PAGE CAN’T BE FOUND',
+                                  text='The page you are trying to reach is not available.',
+                                  marginTop='0px'}) => {
+
     const matches = useMediaQuery('(max-width:899px)');
     const matches2 = useMediaQuery('(max-width:450px)');
 
     return (
-        <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
+        <main
+            style={{
+                backgroundColor: "#f3f3f3",
+                padding: matches ? "20px 0" : "50px 0",
+                marginTop: marginTop
+            }}
+        >
             <Container maxWidth="lg">
                 <Box sx={{
                     backgroundColor: "#fff",
@@ -16,9 +26,13 @@ export const NotFoundBlock = ({img=imgUrl, headerText='OOPS! THAT PAGE CAN’T B
                     justifyContent: "center",
                     alignItems: "center"
                 }}>
-                    <img style={{
-                        maxWidth: matches2 ? "100px" : "150px"
-                    }} src={img} alt={headerText}/>
+                    <img
+                        style={{
+                            maxWidth: matches2 ? "100px" : "150px"
+                        }}
+                        src={ img }
+                        alt={ headerText }
+                    />
                     <Typography
                         variant={matches2 ? "h6" : "h5"}
                         fontFamily="sarif"
@@ -28,14 +42,14 @@ export const NotFoundBlock = ({img=imgUrl, headerText='OOPS! THAT PAGE CAN’T B
                         textAlign="center"
                         sx={{textTransform: 'uppercase'}}
                     >
-                        {headerText}
+                        { headerText }
                     </Typography>
                     <Typography
                         variant={matches2 ? "body1" : "h7"}
                         textAlign="center"
                         fontWeight="300"
                     >
-                        {text}
+                        { text }
                     </Typography>
                 </Box>
             </Container>

+ 35 - 4
src/components/SetCount.jsx

@@ -9,18 +9,49 @@ export const SetCount = ({onCount, defaultValue=1, height=55, width=50}) => {
     }, [count, onCount])
 
     return (
-        <Box sx={{display: 'flex', flexWrap: 'no-wrap'}}>
+        <Box
+            sx={{
+                display: 'flex',
+                flexWrap: 'no-wrap'
+            }}
+        >
             <Button
-                sx={{height: `${height}px`, width: `${width}px`, borderRadius: '0', color: '#000', borderColor: '#000', fontSize: '30px', fontWeight: '300'}}
+                sx={{height: `${height}px`,
+                    width: `${width}px`,
+                    borderRadius: '0',
+                    color: '#000',
+                    borderColor: '#000',
+                    fontSize: '30px',
+                    fontWeight: '300'
+                }}
                 variant="outlined"
                 color={"inherit"}
                 onClick={() => setCount(count === 1 ? count : count-1)}
             >
                 -
             </Button>
-            <input disabled value={count} style={{boxSizing: 'border-box', height: `${height}px`, width: `${width+10}px`, textAlign: 'center', border: '0', backgroundColor: '#eaeaea'}}/>
+            <input
+                disabled
+                value={count}
+                style={{
+                    boxSizing: 'border-box',
+                    height: `${height}px`,
+                    width: `${width+10}px`,
+                    textAlign: 'center',
+                    border: '0',
+                    backgroundColor: '#eaeaea'
+                }}
+            />
             <Button
-                sx={{height: `${height}px`, width: `${width}px`, borderRadius: '0', color: '#000', borderColor: '#000', fontSize: '30px', fontWeight: '300'}}
+                sx={{
+                    height: `${height}px`,
+                    width: `${width}px`,
+                    borderRadius: '0',
+                    color: '#000',
+                    borderColor: '#000',
+                    fontSize: '30px',
+                    fontWeight: '300'
+                }}
                 variant="outlined"
                 color={"inherit"}
                 onClick={() => setCount(count === 100 ? count : count+1)}

+ 102 - 16
src/components/TableLine.jsx

@@ -18,15 +18,48 @@ export const ItemHeaderLine = ({text, align='left'}) => {
 }
 export const LinkProductItem = ({item: [_id, name, images], children=''}) => {
     return (
-        <Link style={{textDecoration: 'none', display: 'flex', alignItems: 'center'}} to={`/good/${_id}`}>
-            <Box minWidth='60px' maxWidth='60px' height='60px' borderRadius='10px' overflow='hidden' marginRight='20px'>
-                <img style={{width: '100%', height: '100%', objectFit: 'cover'}} src={images[0]?.url ? backURL + '/' + images[0]?.url : imgNotFound} alt={name}/>
+        <Link
+            style={{
+                textDecoration: 'none',
+                display: 'flex',
+                alignItems: 'center'
+            }}
+            to={`/good/${_id}`}
+        >
+            <Box
+                minWidth='60px'
+                maxWidth='60px'
+                height='60px'
+                borderRadius='10px'
+                overflow='hidden'
+                marginRight='20px'
+            >
+                <img
+                    style={{
+                        width: '100%',
+                        height: '100%',
+                        objectFit: 'cover'
+                    }}
+                    src={
+                        Array.isArray(images) && images[0]?.url ?
+                            backURL + '/' + images[0]?.url
+                            :
+                            imgNotFound
+                    }
+                    alt={name}
+                />
             </Box>
             {children ?
-                <Box display='flex' flexDirection='column' height='50px' justifyContent='space-around'>
+                <Box
+                    display='flex'
+                    flexDirection='column'
+                    height='50px'
+                    justifyContent='space-around'
+                >
                     <ItemHeaderLine text={name}/>
                     <ItemHeaderLine text={children}/>
-                </Box> :
+                </Box>
+                :
                 <ItemHeaderLine text={name}/>
             }
         </Link>
@@ -36,7 +69,15 @@ export const LinkProductItem = ({item: [_id, name, images], children=''}) => {
 const AddToCart = ({good, addToCart}) => {
     return (
         <Button
-            sx={{height: '40px', width: '70%', borderRadius: '0', color: '#000', borderColor: '#000', fontSize: '16px', fontWeight: '300'}}
+            sx={{
+                height: '40px',
+                width: '70%',
+                borderRadius: '0',
+                color: '#000',
+                borderColor: '#000',
+                fontSize: '16px',
+                fontWeight: '300'
+            }}
             variant="outlined"
             color={"inherit"}
             onClick={() => addToCart(good)}
@@ -58,20 +99,65 @@ export const RemoveFromList = ({good, onRemove}) => {
     )
 }
 export const TableLine = ({columnName, role='header', customSizeCol}) => {
-    const good = {'_id': columnName[0][0], 'name': columnName[0][1], 'images': columnName[0][2], 'price': columnName[1]};
+    const good = {
+        '_id': columnName[0][0],
+        'name': columnName[0][1],
+        'images': columnName[0][2],
+        'price': columnName[1]
+    }
+
     return (
-        <Grid container justifyContent='space-between' marginBottom='20px' alignItems='center'>
-            <Grid item xs={3} md={customSizeCol ? customSizeCol[0] : 5}>
-                {role === 'header' ? <ItemHeaderLine text={columnName[0]}/> : <LinkProductItem item={columnName[0]}/>}
+        <Grid
+            container
+            justifyContent='space-between'
+            marginBottom='20px'
+            alignItems='center'
+        >
+            <Grid
+                item xs={3}
+                md={customSizeCol ? customSizeCol[0] : 5}
+            >
+                {
+                    role === 'header' ?
+                        <ItemHeaderLine text={columnName[0]}/>
+                        :
+                        <LinkProductItem item={columnName[0]}/>
+                }
             </Grid>
-            <Grid item xs={3} md={customSizeCol ? customSizeCol[1] : 2}>
-                <ItemHeaderLine text={role === 'header' ? columnName[1] : '$'+columnName[1]} align={'center'}/>
+            <Grid
+                item xs={3}
+                md={customSizeCol ? customSizeCol[1] : 2}
+            >
+                <ItemHeaderLine
+                    text={role === 'header' ? columnName[1] : '$'+columnName[1]}
+                    align={'center'}
+                />
             </Grid>
-            <Grid item xs={3} md={customSizeCol ? customSizeCol[2] : 3} display='flex' justifyContent='center'>
-                {role === 'header' ? <ItemHeaderLine text={columnName[3]} align={'center'}/> : <AddToCart good={good} addToCart={columnName[3]}/>}
+            <Grid
+                item xs={3}
+                md={customSizeCol ? customSizeCol[2] : 3}
+                display='flex'
+                justifyContent='center'
+            >
+                {
+                    role === 'header' ?
+                        <ItemHeaderLine text={columnName[3]} align={'center'}/>
+                        :
+                        <AddToCart good={good} addToCart={columnName[3]}/>
+                }
             </Grid>
-            <Grid item xs={3} md={customSizeCol ? customSizeCol[3] : 1} display='flex' justifyContent='center'>
-                {role === 'header' ? <ItemHeaderLine text={columnName[2]} align={'center'}/> : <RemoveFromList good={good} onRemove={columnName[2]}/>}
+            <Grid
+                item xs={3}
+                md={customSizeCol ? customSizeCol[3] : 1}
+                display='flex'
+                justifyContent='center'
+            >
+                {
+                    role === 'header' ?
+                        <ItemHeaderLine text={columnName[2]} align={'center'}/>
+                        :
+                        <RemoveFromList good={good} onRemove={columnName[2]}/>
+                }
             </Grid>
         </Grid>
     )

+ 11 - 7
src/components/Title.jsx

@@ -1,5 +1,5 @@
 import {Box, Typography} from "@mui/material";
-import rom from "../img/our team/romb.png";
+import rom from "../img/our-team/romb.png";
 
 const Title = ({subtitle, title}) => {
     return (
@@ -18,12 +18,16 @@ const Title = ({subtitle, title}) => {
                 marginLeft='5px'
                 marginBottom='10px'
             >
-                {subtitle}
+                {subtitle || 'subtitle'}
             </Typography>
-            <img style={{
-                width: '7px',
-                maxHeight: '7px',
-            }} src={rom} alt='item'/>
+            <img
+                style={{
+                    width: '7px',
+                    maxHeight: '7px',
+                }}
+                src={rom}
+                alt='item'
+            />
             <Typography
                 variant='h4'
                 color='#000'
@@ -32,7 +36,7 @@ const Title = ({subtitle, title}) => {
                 marginLeft='5px'
                 marginTop='10px'
             >
-                {title}
+                {title || 'title'}
             </Typography>
         </Box>
     )

src/img/our team/1.jpg → src/img/our-team/1.jpg


src/img/our team/2.jpg → src/img/our-team/2.jpg


src/img/our team/3.jpg → src/img/our-team/3.jpg


src/img/our team/4.jpg → src/img/our-team/4.jpg


src/img/our team/romb.png → src/img/our-team/romb.png


+ 4 - 2
src/index.css

@@ -8,6 +8,8 @@ body {
 }
 
 code {
-  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
-    monospace;
+  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
+ul, li{
+  list-style: none;
 }

+ 13 - 52
src/pages/AboutUsPage.jsx

@@ -1,54 +1,15 @@
-import Breadcrumb from "../components/Breadcrumbs";
 import {Box, Container, Grid, Typography, useMediaQuery} from "@mui/material";
-import Title from "../components/Title";
-import image1 from "../img/about-us/1.jpg";
-import SavingsIcon from '@mui/icons-material/Savings';
-import AlarmIcon from '@mui/icons-material/Alarm';
-import AutoGraphIcon from '@mui/icons-material/AutoGraph';
-import imgNotFound from "../img/catalog/imgNotFound.png";
+import Breadcrumb from "../../components/Breadcrumbs";
+import Title from "../../components/Title";
+import imageGirl from "../../img/about-us/1.jpg";
+import imgNotFound from "../../img/catalog/imgNotFound.png";
+import SavingsIcon from "@mui/icons-material/Savings";
+import AlarmIcon from "@mui/icons-material/Alarm";
+import AutoGraphIcon from "@mui/icons-material/AutoGraph";
+import {BlockContentItem} from "./BlockContentItem";
+import {BlockQualityItem} from "./BlockQualityItem";
 
-const BlockContentItem = ({content}) => {
-    return (
-        <Grid item xs={12} sm={5}>
-            <Typography
-                variant='body1'
-                fontWeight='300'
-                lineHeight='1.8em'
-                color='#616161'
-                marginBottom='10px'
-                textAlign='justify'
-            >
-                {content || 'default text'}
-            </Typography>
-        </Grid>
-    )
-}
-const BlockQualityItem = ({Icon, title, content}) => {
-    return (
-        <Grid sx={{padding: '0 20px'}} item xs={12} md={4}>
-            <Box
-                display='flex'
-                justifyContent='center'
-                marginBottom='20px'
-            >
-                {Icon && <Icon/>}
-            </Box>
-            <Title subtitle={title || 'default title'} />
-            <Typography
-                variant='body1'
-                fontWeight='300'
-                lineHeight='1.8em'
-                color='#616161'
-                marginBottom='10px'
-                textAlign='center'
-            >
-                {content || 'default content'}
-            </Typography>
-        </Grid>
-    )
-}
-
-const AboutUsPage = () => {
+export const AboutUsPage = () => {
     const matches = useMediaQuery('(max-width:768px)');
 
     return (
@@ -57,7 +18,8 @@ const AboutUsPage = () => {
             <main
                 style={{
                     backgroundColor: "#f3f3f3",
-                    padding: matches ? "20px 0" : "50px 0"
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight:'300px'
                 }}
             >
                 <Container maxWidth="lg">
@@ -87,7 +49,7 @@ const AboutUsPage = () => {
                                     objectFit: 'cover',
                                     objectPosition: 'center top'
                                 }}
-                                src={image1 || imgNotFound}
+                                src={imageGirl || imgNotFound}
                                 alt='background'
                             />
                         </Grid>
@@ -157,4 +119,3 @@ const AboutUsPage = () => {
         </>
     )
 }
-export default AboutUsPage

+ 18 - 0
src/pages/AboutUsPage/BlockContentItem.jsx

@@ -0,0 +1,18 @@
+import {Grid, Typography} from "@mui/material";
+
+export const BlockContentItem = ({content}) => {
+    return (
+        <Grid item xs={12} sm={5}>
+            <Typography
+                variant='body1'
+                fontWeight='300'
+                lineHeight='1.8em'
+                color='#616161'
+                marginBottom='10px'
+                textAlign='justify'
+            >
+                {content || 'default text'}
+            </Typography>
+        </Grid>
+    )
+}

+ 27 - 0
src/pages/AboutUsPage/BlockQualityItem.jsx

@@ -0,0 +1,27 @@
+import {Box, Grid, Typography} from "@mui/material";
+import Title from "../../components/Title";
+
+export const BlockQualityItem = ({Icon, title, content}) => {
+    return (
+        <Grid sx={{padding: '0 20px'}} item xs={12} md={4}>
+            <Box
+                display='flex'
+                justifyContent='center'
+                marginBottom='20px'
+            >
+                {Icon && <Icon/>}
+            </Box>
+            <Title subtitle={title || 'default title'} />
+            <Typography
+                variant='body1'
+                fontWeight='300'
+                lineHeight='1.8em'
+                color='#616161'
+                marginBottom='10px'
+                textAlign='center'
+            >
+                {content || 'default content'}
+            </Typography>
+        </Grid>
+    )
+}

+ 3 - 6
src/pages/AdminPage/AdminPage.jsx

@@ -25,12 +25,9 @@ import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
 import BottomNavigation from '@mui/material/BottomNavigation';
 import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
 import EditIcon from '@mui/icons-material/Edit';
-import {CategoryAside} from "../CatalogPage";
-import {CFindGoodEdit, CGoodEdit, CSearchPage, FindGoodEdit} from "./GoodTab";
-import MyOrdersPage from "../MyOrdersPage";
-import {Route} from "react-router-dom";
+import {CFindGoodEdit, CGoodEdit, FindGoodEdit} from "./GoodTab";
 import {CClients} from "./ClientsTab";
-import {CCategoryEdit} from "./CateforyTab";
+import {CCategoryEdit, CCategoryEditTree} from "./CateforyTab";
 
 const defaultTabs = [{icon: PersonIcon, text: 'clients'}, {icon: CategoryIcon, text: 'categories'}, {icon: AutoAwesomeIcon, text: 'products'}]
 
@@ -130,7 +127,7 @@ const FullWidthTabs = () => {
                     <CClients/>
                 </TabPanel>
                 <TabPanel value={value} index={1} dir={theme.direction}>
-                    <SelectBlock Block={CCategoryEdit} FindBlock={CFindGoodEdit}/>
+                    <SelectBlock Block={CCategoryEdit} FindBlock={CCategoryEditTree}/>
                 </TabPanel>
                 <TabPanel value={value} index={2} dir={theme.direction}>
                     <SelectBlock Block={CGoodEdit} FindBlock={CFindGoodEdit}/>

+ 62 - 1
src/pages/AdminPage/CateforyTab.jsx

@@ -1,4 +1,4 @@
-import {useEffect, useState} from "react";
+import * as React from 'react';
 import {Button, Checkbox, Grid, Switch, TextField} from "@mui/material";
 import Autocomplete from "@mui/material/Autocomplete";
 import Box from "@mui/material/Box";
@@ -7,6 +7,10 @@ import {SetCount} from "../../components/SetCount";
 import {connect} from "react-redux";
 import {actionCategoryCount, actionCategoryUpsert, actionFullRootCats} from "../../actions/ActionCategory";
 import {actionAllGoodFind} from "../../actions/ActionGoodFind";
+import { enableRipple } from '@syncfusion/ej2-base';
+import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
+import {useEffect, useState} from "react";
+enableRipple(true);
 
 const InputCategory = ({goods, setArray, countSubCat}) => {
     const [name, setName] = useState('');
@@ -167,3 +171,60 @@ const CategoryEdit = ({category, categoryCount, goods, variant='create', actionR
     )
 }
 export const CCategoryEdit = connect(state => ({category: state.category, categoryCount: state.promise['categoryCount'], goods: state.promise['goodAllFind'] }), {actionRootCat: actionFullRootCats, getCountCategory: actionCategoryCount, getGoodFind: actionAllGoodFind, onCreateCategory: actionCategoryUpsert})(CategoryEdit)
+
+
+export class CCategoryEditTree extends React.Component {
+    constructor() {
+        super(...arguments);
+        this.productTeam = [
+            {
+                id: 1, name: 'ASP.NET MVC Team', expanded: true,
+                child: [
+                    { id: 2, pid: 1, name: 'Smith', isSelected: true },
+                    { id: 3, pid: 1, name: 'Johnson', isSelected: true },
+                    { id: 4, pid: 1, name: 'Anderson' },
+                ]
+            },
+            {
+                id: 5, name: 'Windows Team',
+                child: [
+                    { id: 6, pid: 5, name: 'Clark' },
+                    { id: 7, pid: 5, name: 'Wright' },
+                    { id: 8, pid: 5, name: 'Lopez' },
+                ]
+            },
+            {
+                id: 9, name: 'Web Team',
+                child: [
+                    { id: 11, pid: 9, name: 'Joshua' },
+                    { id: 12, pid: 9, name: 'Matthew' },
+                    { id: 13, pid: 9, name: 'David' },
+                ]
+            },
+            {
+                id: 14, name: 'Build Team',
+                child: [
+                    { id: 15, pid: 14, name: 'Ryan' },
+                    { id: 16, pid: 14, name: 'Justin' },
+                    { id: 17, pid: 14, name: 'Robert' },
+                ]
+            },
+            {
+                id: 18, name: 'WPF Team',
+                child: [
+                    { id: 19, pid: 18, name: 'Brown' },
+                    { id: 20, pid: 18, name: 'Johnson' },
+                    { id: 21, pid: 18, name: 'Miller' },
+                ]
+            }
+        ];
+        this.fields = { dataSource: this.productTeam, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild', selected: 'isSelected' };
+        this.allowDragAndDrop = true;
+        this.allowMultiSelection = true;
+    }
+    render() {
+        return (
+            <TreeViewComponent fields={this.fields} allowMultiSelection={this.allowMultiSelection} allowDragAndDrop={this.allowDragAndDrop}/>
+        );
+    }
+}

+ 1 - 1
src/pages/AdminPage/ClientsTab.jsx

@@ -14,10 +14,10 @@ import {
 import Box from "@mui/material/Box";
 import {backURL} from "../../actions/PathDB";
 import userDefault from "../../img/header/userDefault.png";
-import {timeCalc} from "../ProductPage";
 import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
 import {connect} from "react-redux";
 import {actionUserCount, actionUserFind} from "../../actions/ActionUserFind";
+import {timeCalc} from "../ProductPage/timeCalc";
 
 const ClientsCart = ({_id, login, nick, avatar, createdAt, acl}) => {
     const ItemAccordion = ({text, size='h6'}) => {

+ 50 - 46
src/pages/AdminPage/GoodTab.jsx

@@ -12,7 +12,7 @@ import {
     TextField
 } from "@mui/material";
 import {connect} from "react-redux";
-import {actionFullRootCats} from "../../actions/ActionCategory";
+import {actionAllCategory} from "../../actions/ActionCategory";
 import {actionGoodUpsert} from "../../actions/ActionCreateGood";
 import Autocomplete from "@mui/material/Autocomplete";
 import {actionFullGoodFind, actionGoodCount} from "../../actions/ActionGoodFind";
@@ -37,10 +37,11 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
     const SortableItem = sortableElement(({value}) => {
         return (
             <Box key={value?._id} sx={{display: 'flex', justifyContent: 'center',  borderRadius: 2, border: '1px solid #eaeaea', marginBottom: 2, width: 200, height: 200, padding: '5px', boxSizing: 'border-box'}}>
-                <Box sx={{display: 'flex', justifyContent: 'center', minWidth: 0, overflow: 'hidden'}}>
+                <Box sx={{display: 'flex', justifyContent: 'center', minWidth: 0, overflow: 'hidden', position: 'relative'}}>
                     {value?.url ?
-                        <img src={backURL+ '/' + value.url} style={{display: 'block', width: 'auto', height: '100%', objectFit: 'cover', objectPosition: 'center center'}} alt={value.name}/>
-                        :
+                        <>
+                            <img src={backURL+ '/' + value.url} style={{display: 'block', width: 'auto', height: '100%', objectFit: 'cover', objectPosition: 'center center'}} alt={value.name}/>
+                        </> :
                         <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center'}}>
                             <CircularProgress />
                         </Box>
@@ -78,8 +79,9 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
         actionClear('goodUpsert')
         actionClear('uploadFile')
     }
+
     useEffect(() => {
-        if(!categoryState || Object.entries(categoryState).length === 0) actionRootCat()
+        if(!categoryState) actionRootCat()
         if(!goods) goodCount()
         if(fileStatus?.status === 'RESOLVED'){
             state.images?.length > 0 ?
@@ -87,7 +89,6 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
                 setState({...state, images: [fileStatus?.payload]})
         }
     },[categoryState, goods, fileStatus])
-
     return (
         <>
             {!result ?
@@ -110,45 +111,48 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
                             <TextField fullWidth id="filled-basic" label="Title product" variant="standard" value={state?.name || ''} onChange={e => setState({...state, name: e.target.value})}/>
                         </Grid>
                         <Grid item xs={5.5}>
-                            {categoryState &&
-                                state.categories?.length > 0 ?
-                                <Autocomplete
-                                    multiple
-                                    id="tags-standard"
-                                    options={Object.values(categoryState)}
-                                    defaultValue={state.categories}
-                                    onChange={(event, newValue) => {
-                                        setState({...state, categories: [...newValue]})
-                                    }}
-                                    getOptionLabel={(option) => option?.name || 'no name'}
-                                    key={option => option?.id}
-                                    renderInput={(params) => (
-                                        <TextField
-                                            {...params}
-                                            variant="standard"
-                                            label="Select categories"
-                                            placeholder="categories"
-                                        />
-                                    )}
-                                />:
-                                <Autocomplete
-                                    multiple
-                                    id="tags-standard"
-                                    options={Object.values(categoryState)}
-                                    onChange={(event, newValue) => {
-                                        setState({...state, categories: [...newValue]})
-                                    }}
-                                    getOptionLabel={(option) => option?.name || 'no name'}
-                                    key={option => option?.id}
-                                    renderInput={(params) => (
-                                        <TextField
-                                            {...params}
-                                            variant="standard"
-                                            label="Select categories"
-                                            placeholder="categories"
+                            {categoryState && categoryState?.payload && categoryState.payload?.length > 0 &&
+                                <>
+                                    {state.categories?.length > 0 ?
+                                        <Autocomplete
+                                            multiple
+                                            id="tags-standard"
+                                            options={Object.values(categoryState.payload)}
+                                            defaultValue={state.categories}
+                                            onChange={(event, newValue) => {
+                                                setState({...state, categories: [...newValue]})
+                                            }}
+                                            getOptionLabel={(option) => option?.name || 'no name'}
+                                            key={option => option?.id}
+                                            renderInput={(params) => (
+                                                <TextField
+                                                    {...params}
+                                                    variant="standard"
+                                                    label="Select categories"
+                                                    placeholder="categories"
+                                                />
+                                            )}
+                                        /> :
+                                        <Autocomplete
+                                            multiple
+                                            id="tags-standard"
+                                            options={Object.values(categoryState.payload)}
+                                            onChange={(event, newValue) => {
+                                                setState({...state, categories: [...newValue]})
+                                            }}
+                                            getOptionLabel={(option) => option?.name || 'no name'}
+                                            key={option => option?.id}
+                                            renderInput={(params) => (
+                                                <TextField
+                                                    {...params}
+                                                    variant="standard"
+                                                    label="Select categories"
+                                                    placeholder="categories"
+                                                />
+                                            )}
                                         />
-                                    )}
-                                />
+                                    }
+                                </>
                             }
                         </Grid>
                     </Grid>
@@ -223,8 +227,8 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
 }
 
 export const CGoodEdit = connect(state => ({fileStatus: state.promise['uploadFile'],
-    categoryState: state.category, goods: state.promise['goodCount'], result: state.promise['goodUpsert']}),
-    {actionRootCat: actionFullRootCats, onSave: actionGoodUpsert, goodCount:  actionGoodCount,
+    categoryState: state.promise['allCategory'], goods: state.promise['goodCount'], result: state.promise['goodUpsert']}),
+    {actionRootCat: actionAllCategory, onSave: actionGoodUpsert, goodCount:  actionGoodCount,
         onFileDrop: actionUploadFile, actionClear: actionClearPromise})(GoodEdit)
 
 const ItemFound = ({item:{_id, name, price, images, description, categories}}) => {

+ 0 - 190
src/pages/CartPage.jsx

@@ -1,190 +0,0 @@
-import Breadcrumb from "../components/Breadcrumbs";
-import {connect} from "react-redux";
-import {actionCardChange, actionCardClear, actionCardRemove} from "../reducers/CartReducer";
-import {ActionFullOrder} from "../actions/ActionOrder";
-import {Box, Button, Container, Divider, Grid, Typography, useMediaQuery} from "@mui/material";
-import {ItemHeaderLine, LinkProductItem, RemoveFromList, TableLine} from "../components/TableLine";
-import {NotFoundBlock} from "../components/NotFoundBlock";
-import imgUrl from "../img/not-found/3.png";
-import AddShoppingCartIcon from "@mui/icons-material/AddShoppingCart";
-import {SetCount} from "../components/SetCount";
-import {useEffect, useState} from "react";
-import {actionClearPromise} from "../reducers/PromiseReducer";
-import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
-
-const CartGoodLine = ({item, onCartRemove, onCardChange}) => {
-    let [count, setCount] = useState(item?.count)
-    useEffect(() => {
-        onCardChange(item?.good, count)
-    }, [count])
-    return(
-        <Grid container alignItems='center' marginBottom='20px'>
-            <Grid item xs={6}>
-                <LinkProductItem item={[item?.good?._id, item?.good?.name, item?.good?.images]} children={<Typography>${item?.good?.price}</Typography>}/>
-            </Grid>
-            <Grid item xs={3} display='flex' justifyContent="center">
-                <SetCount height={40} width={40} defaultValue={item?.count} onCount={value => setCount(value)}/>
-            </Grid>
-            <Grid item xs={2}>
-                <ItemHeaderLine align={'center'} text={(`$${parseFloat(item?.good?.price * count).toFixed(2)}`) || 'NaN'}/>
-            </Grid>
-            <Grid item xs={1}>
-                <RemoveFromList good={item?.good} onRemove={onCartRemove}/>
-            </Grid>
-        </Grid>
-    )
-}
-
-const TotalPriceLine = ({title, subtitle, sizeSubtitle='body2'}) => {
-    return (
-        <Grid container display='flex' flexDirection='row' justifyContent='space-between' alignItems='center' padding='20px'>
-            <Grid item xs={6}>
-                <Typography
-                    variant='body2'
-                    color='#616161'
-                    textAlign='left'
-                >
-                    {title}
-                </Typography>
-            </Grid>
-            <Grid item xs={6}>
-                <Typography
-                    variant={sizeSubtitle}
-                    color='#000'
-                    textAlign='right'
-                >
-                    {subtitle}
-                </Typography>
-            </Grid>
-        </Grid>
-    )
-}
-
-const BlockTotal = ({auth ,cart, rows, onOrderUpsert, onCartClear}) => {
-    return (
-        <>
-            <Typography
-                padding='20px'
-                variant='h4'
-                fontFamily='sarif'
-                letterSpacing='2px'
-                textAlign='center'
-            >
-                TOTAL
-            </Typography>
-            <Divider/>
-            <TotalPriceLine title={`${rows.length || 1} goods for the amount`} subtitle={`$${rows.reduce((a, i) => a + (i.good.price * i.count), 0)}`}/>
-            <TotalPriceLine title={'Cost of delivery'} subtitle={'according to the carrier\'s tariffs'}/>
-            <Divider/>
-            <TotalPriceLine title={'To pay'} subtitle={`$${rows.reduce((a, i) => a + (i.good.price * i.count), 0)}`} sizeSubtitle={'h6'}/>
-            <Divider sx={{marginBottom: '20px'}}/>
-            <Box display='flex' justifyContent='center' flexDirection='column' alignItems='center'>
-                <Button sx={{borderRadius: '0', width:'80%', padding: '10px 20px', marginBottom: '20px'}}
-                        color='success'
-                        variant="outlined"
-                        onClick={() => {onOrderUpsert(cart); onCartClear()}}
-                        disabled={Object.entries(auth).length === 0}
-                >
-                    {Object.entries(auth).length === 0 ? 'you need to log in' : 'confirm the order'}
-                </Button>
-                <Button sx={{borderRadius: '0', width:'80%', padding: '10px 20px'}}
-                        color='warning'
-                        variant="outlined"
-                        onClick={() => onCartClear()}
-                >
-                    cart clear
-                </Button>
-            </Box>
-        </>
-    )
-}
-const CBlockTotal = connect(state=>({auth: state.auth}))(BlockTotal)
-
-const CartPage = ({order, cart, onCardChange, onCartClear, onCartRemove, onOrderUpsert, actionClearOrder}) => {
-    const matches = useMediaQuery('(max-width:768px)')
-    let rows = []
-    for (const key of Object.values(cart)) {
-        rows.push(key)
-    }
-    useEffect(() => {
-        if (order && Object.entries(order).length > 0) {
-            actionClearOrder('order')
-        }
-    },[cart])
-
-
-    return (
-        <>
-            <Breadcrumb links={['cart']}/>
-            {Object.values(cart).length > 0 || order ?
-                <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0", minHeight:'300px'}}>
-                        <Container maxWidth="lg">
-                            {order && Object.entries(order).length > 0 ?
-                                <Box display='flex' height='300px' flexDirection='column' alignItems='center' justifyContent='space-around'>
-                                    {order.error ?
-                                        <Typography variant='h5' textAlign='center'>Error, try again</Typography> :
-                                        <>
-                                            <Typography
-                                                variant='h5'
-                                                textAlign='center'
-                                            >
-                                                Order successfully completed
-                                            </Typography>
-                                            <CheckCircleOutlineIcon/>
-                                            <Typography
-                                                variant='h4'
-                                                textAlign='center'
-                                                fontFamily='sarif'
-                                                letterSpacing='2px'
-                                                sx={{textTransform: 'uppercase'}}
-                                            >
-                                                Thanks for your order!
-                                            </Typography>
-                                            <Typography
-                                                variant='body1'
-                                                textAlign='center'
-                                                color="#616161"
-                                            >
-                                                Attention! Shipping is paid separately upon receipt of the goods.
-                                            </Typography>
-                                            <Typography
-                                                variant='body1'
-                                                textAlign='center'
-                                                color="#616161"
-                                            >
-                                                Your order number: {order.payload?._id || 1}
-                                            </Typography>
-                                            <Typography
-                                                variant='body1'
-                                                textAlign='center'
-                                                color="#616161"
-                                            >
-                                                For the amount: ${+order.payload?.total || 0}
-                                            </Typography>
-                                        </>
-                                    }
-                                </Box>:
-                                <Grid container justifyContent='space-between'>
-                                    <Grid item xs={8.5}>
-                                        <TableLine columnName={['PRODUCT', 'QUANTITY', 'REMOVE', 'SUBTOTAL']}
-                                                   customSizeCol={[6, 3, 2, 1]}/>
-                                        <Divider sx={{marginBottom: '20px'}}/>
-                                        {rows.map(item => <CartGoodLine item={item} onCartRemove={onCartRemove}
-                                                                        onCardChange={onCardChange}/>)}
-                                        <Divider/>
-                                    </Grid>
-                                    <Grid item xs={3} sx={{backgroundColor: '#fff'}} height='100%' paddingBottom='20px'>
-                                        <CBlockTotal cart={cart} rows={rows} onCartClear={onCartClear}
-                                                     onOrderUpsert={onOrderUpsert}/>
-                                    </Grid>
-                                </Grid>
-                            }
-                        </Container>
-                </main>:
-                <NotFoundBlock img={imgUrl} headerText={'YOUR CART IS CURRENTLY EMPTY'} text={<Box display='flex' alignItems='center'><Typography component='span'>Click the</Typography><AddShoppingCartIcon sx={{margin: '0 10px'}}/><Typography component='span'>icons to add products</Typography></Box>}/>
-            }
-        </>
-    )
-}
-const CCartPage = connect(state=>({cart: state.cart, order: state.promise?.order}), {onCardChange: actionCardChange, onCartClear: actionCardClear, onCartRemove: actionCardRemove, onOrderUpsert: ActionFullOrder, actionClearOrder: actionClearPromise})(CartPage)
-export default CCartPage

+ 72 - 0
src/pages/CartPage/BlockTotal.jsx

@@ -0,0 +1,72 @@
+import {Box, Button, Divider, Typography} from "@mui/material";
+import {connect} from "react-redux";
+import {TotalPriceLine} from "./TotalPriceLine";
+
+const BlockTotal = ({auth ,cart, rows, onOrderUpsert, onCartClear}) => {
+    return (
+        <>
+            <Typography
+                padding='20px'
+                variant='h4'
+                fontFamily='sarif'
+                letterSpacing='2px'
+                textAlign='center'
+            >
+                TOTAL
+            </Typography>
+            <Divider/>
+            <TotalPriceLine
+                title={`${rows.length || 1} goods for the amount`}
+                subtitle={`$${rows.reduce((a, i) => a + (i.good.price * i.count), 0)}`}
+            />
+            <TotalPriceLine
+                title={'Cost of delivery'}
+                subtitle={'according to the carrier\'s tariffs'}
+            />
+            <Divider/>
+            <TotalPriceLine
+                title={'To pay'}
+                subtitle={`$${rows.reduce((a, i) => a + (i.good.price * i.count), 0)}`} sizeSubtitle={'h6'}
+            />
+            <Divider sx={{marginBottom: '20px'}}/>
+            <Box
+                display='flex'
+                justifyContent='center'
+                flexDirection='column'
+                alignItems='center'
+            >
+                <Button
+                    sx={{
+                        borderRadius: '0',
+                        width:'80%',
+                        padding: '10px 20px',
+                        marginBottom: '20px'
+                    }}
+                    color='success'
+                    variant="outlined"
+                    onClick={() => {onOrderUpsert(cart); onCartClear()}}
+                    disabled={Object.entries(auth).length === 0}
+                >
+                    {
+                        Object.entries(auth).length === 0 ?
+                            'you need to log in'
+                            : 'confirm the order'
+                    }
+                </Button>
+                <Button
+                    sx={{
+                        borderRadius: '0',
+                        width:'80%',
+                        padding: '10px 20px'
+                    }}
+                    color='warning'
+                    variant="outlined"
+                    onClick={() => onCartClear()}
+                >
+                    cart clear
+                </Button>
+            </Box>
+        </>
+    )
+}
+export const CBlockTotal = connect(state=>({auth: state.auth}))(BlockTotal)

+ 49 - 0
src/pages/CartPage/CartGoodLine.jsx

@@ -0,0 +1,49 @@
+import {useEffect, useState} from "react";
+import {Grid, Typography} from "@mui/material";
+import {ItemHeaderLine, LinkProductItem, RemoveFromList} from "../../components/TableLine";
+import {SetCount} from "../../components/SetCount";
+
+export const CartGoodLine = ({item, onCartRemove, onCardChange}) => {
+    let [count, setCount] = useState(item?.count)
+    useEffect(() => {
+        onCardChange(item?.good, count)
+    }, [count])
+
+    return(
+        <Grid
+            container
+            alignItems='center'
+            marginBottom='20px'
+        >
+            <Grid item xs={6}>
+                <LinkProductItem
+                    item={[item?.good?._id, item?.good?.name, item?.good?.images]}
+                    children={`$${ item?.good?.price }`}
+                />
+            </Grid>
+            <Grid item xs={3}
+                  display='flex'
+                  justifyContent="center"
+            >
+                <SetCount
+                    height={40}
+                    width={40}
+                    defaultValue={item?.count}
+                    onCount={value => setCount(value)}
+                />
+            </Grid>
+            <Grid item xs={2}>
+                <ItemHeaderLine
+                    align={'center'}
+                    text={(`$${parseFloat(item?.good?.price * count).toFixed(2)}`) || 'NaN'}
+                />
+            </Grid>
+            <Grid item xs={1}>
+                <RemoveFromList
+                    good={item?.good}
+                    onRemove={onCartRemove}
+                />
+            </Grid>
+        </Grid>
+    )
+}

+ 179 - 0
src/pages/CartPage/CartPage.jsx

@@ -0,0 +1,179 @@
+import {Box, Button, Container, Divider, Grid, Typography, useMediaQuery} from "@mui/material";
+import {useEffect, useState} from "react";
+import Breadcrumb from "../../components/Breadcrumbs";
+import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
+import {TableLine} from "../../components/TableLine";
+import {NotFoundBlock} from "../../components/NotFoundBlock";
+import imgUrl from "../../img/not-found/3.png";
+import AddShoppingCartIcon from "@mui/icons-material/AddShoppingCart";
+import {connect} from "react-redux";
+import {actionCardChange, actionCardClear, actionCardRemove} from "../../reducers/CartReducer";
+import {ActionFullOrder} from "../../actions/ActionOrder";
+import {actionClearPromise} from "../../reducers/PromiseReducer";
+import {CartGoodLine} from "./CartGoodLine";
+import {CBlockTotal} from "./BlockTotal";
+import {AccordionItem} from "../MyOrdersPage/AccordionItem";
+import {actionOrderFindOne} from "../../actions/ActionOrderFind";
+
+const CartPage = ({order, cart, finalOrder, onCardChange, onCartClear, onCartRemove, onOrderUpsert, actionClearOrder, onOrderFind}) => {
+    const matches = useMediaQuery('(max-width:768px)')
+    const [showDetails, setShowDetails] = useState(false)
+
+    let rows = []
+    for (const key of Object.values(cart)) {
+        rows.push(key)
+    }
+    useEffect(() => {
+        if (order && Object.entries(order).length > 0) {
+            actionClearOrder('order')
+            actionClearOrder('orderFindOne')
+        }
+    },[cart])
+
+    return (
+        <>
+            <Breadcrumb links={['cart']}/>
+            {Object.values(cart).length > 0 || order ?
+                <main
+                    style={{
+                        backgroundColor: "#f3f3f3",
+                        padding: matches ? "20px 0" : "50px 0",
+                        minHeight:'300px'
+                    }}
+                >
+                    <Container maxWidth="lg">
+                        {order && Object.entries(order).length > 0 ?
+                            <Box
+                                display='flex'
+                                minHeight='500px'
+                                height='100%'
+                                flexDirection='column'
+                                alignItems='center'
+                                justifyContent='space-around'
+                            >
+                                {order.error ?
+                                    <Typography
+                                        variant='h5'
+                                        textAlign='center'
+                                        marginBottom='20px'
+                                    >
+                                        Error, try again
+                                    </Typography>
+                                    :
+                                    <>
+                                        <Typography
+                                            variant='h5'
+                                            textAlign='center'
+                                            marginBottom='20px'
+                                        >
+                                            Order successfully completed
+                                        </Typography>
+                                        <CheckCircleOutlineIcon/>
+                                        <Typography
+                                            variant='h4'
+                                            textAlign='center'
+                                            fontFamily='sarif'
+                                            letterSpacing='2px'
+                                            marginBottom='20px'
+                                            sx={{textTransform: 'uppercase'}}
+                                        >
+                                            Thanks for your order!
+                                        </Typography>
+                                        <Typography
+                                            variant='body1'
+                                            textAlign='center'
+                                            color="#616161"
+                                            marginBottom='20px'
+                                        >
+                                            Attention! Shipping is paid separately upon receipt of the goods.
+                                        </Typography>
+                                        <Typography
+                                            variant='body1'
+                                            textAlign='center'
+                                            color="#616161"
+                                            marginBottom='20px'
+                                        >
+                                            Your order number: {order.payload?._id || 1}
+                                        </Typography>
+                                        <Typography
+                                            variant='body1'
+                                            textAlign='center'
+                                            color="#616161"
+                                            marginBottom='20px'
+                                        >
+                                            For the amount: ${+order.payload?.total || 0}
+                                        </Typography>
+                                        <Button
+                                            variant='outlined'
+                                            onClick={() => {setShowDetails(!showDetails); onOrderFind(order.payload?._id)}}
+                                        >
+                                            Show Details
+                                        </Button>
+                                        {showDetails && finalOrder?.payload &&
+                                            <Box
+                                                marginTop='40px'
+                                                marginBottom='40px'
+                                                width='100%'
+                                            >
+                                                <AccordionItem key={finalOrder.payload._id} data={finalOrder.payload}/>
+                                            </Box>
+                                        }
+                                    </>
+                                }
+                            </Box>:
+                            <Grid
+                                container
+                                justifyContent='space-between'
+                            >
+                                <Grid item xs={8.5}>
+                                    <TableLine
+                                        columnName={['PRODUCT', 'QUANTITY', 'REMOVE', 'SUBTOTAL']}
+                                        customSizeCol={[6, 3, 2, 1]}
+                                    />
+                                    <Divider sx={{marginBottom: '20px'}}/>
+                                    {rows.map((item, index) =>
+                                        <CartGoodLine
+                                            key={index}
+                                            item={item}
+                                            onCartRemove={onCartRemove}
+                                            onCardChange={onCardChange}
+                                        />)
+                                    }
+                                    <Divider/>
+                                </Grid>
+                                <Grid item xs={3}
+                                      sx={{backgroundColor: '#fff'}}
+                                      height='100%'
+                                      paddingBottom='20px'
+                                >
+                                    <CBlockTotal
+                                        cart={cart}
+                                        rows={rows}
+                                        onCartClear={onCartClear}
+                                        onOrderUpsert={onOrderUpsert}
+                                    />
+                                </Grid>
+                            </Grid>
+                        }
+                    </Container>
+                </main>
+                :
+                <NotFoundBlock
+                    img={imgUrl}
+                    headerText={'YOUR CART IS CURRENTLY EMPTY'}
+                    text={
+                        <Box display='flex' alignItems='center'>
+                            <Typography component='span'>Click the</Typography>
+                            <AddShoppingCartIcon sx={{margin: '0 10px'}}/>
+                            <Typography component='span'>icons to add products</Typography>
+                        </Box>
+                    }
+                />
+            }
+        </>
+    )
+}
+export const CCartPage = connect(state => ({cart: state.cart, order: state.promise?.order,
+        finalOrder: state.promise['orderFindOne']}),
+    {onCardChange: actionCardChange, onCartClear: actionCardClear, onCartRemove: actionCardRemove,
+        onOrderUpsert: ActionFullOrder, actionClearOrder: actionClearPromise, onOrderFind: actionOrderFindOne})(CartPage)

+ 33 - 0
src/pages/CartPage/TotalPriceLine.jsx

@@ -0,0 +1,33 @@
+import {Grid, Typography} from "@mui/material";
+
+export const TotalPriceLine = ({title, subtitle, sizeSubtitle='body2'}) => {
+    return (
+        <Grid
+            container
+            display='flex'
+            flexDirection='row'
+            justifyContent='space-between'
+            alignItems='center'
+            padding='20px'
+        >
+            <Grid item xs={6}>
+                <Typography
+                    variant='body2'
+                    color='#616161'
+                    textAlign='left'
+                >
+                    { title || 'title' }
+                </Typography>
+            </Grid>
+            <Grid item xs={6}>
+                <Typography
+                    variant={sizeSubtitle}
+                    color='#000'
+                    textAlign='right'
+                >
+                    { subtitle || 'subtitle' }
+                </Typography>
+            </Grid>
+        </Grid>
+    )
+}

+ 36 - 0
src/pages/Catalog/CatalogPage.jsx

@@ -0,0 +1,36 @@
+import {Container, Grid, useMediaQuery} from "@mui/material";
+import {useEffect} from "react";
+import Breadcrumb from "../../components/Breadcrumbs";
+import {connect} from "react-redux";
+import {actionFullAllCategory} from "../../actions/ActionCategory";
+import {CategoryAside} from "./CategoryAside";
+import {Products} from "./Goods";
+
+const CatalogPage = ({category, actionRootCat}) => {
+    const matches = useMediaQuery('(max-width:899px)')
+    useEffect(() => {
+        if(!category) actionRootCat()
+    }, [category])
+
+    return (
+        <>
+            <Breadcrumb links={['catalog']}/>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: '300px'
+                }}
+            >
+                <Container maxWidth="lg">
+                    <Grid container justifyContent='space-between'>
+                        {category?.payload && <CategoryAside category={category.payload}/>}
+                        <Products/>
+                    </Grid>
+                </Container>
+            </main>
+        </>
+    )
+}
+export const CCatalogPage = connect(state => ({category: state.promise['allCategory']}),
+    {actionRootCat: actionFullAllCategory})(CatalogPage)

+ 89 - 0
src/pages/Catalog/CategoryAside.jsx

@@ -0,0 +1,89 @@
+import {useState} from "react";
+import Link from "react-router-dom/es/Link";
+import {Accordion, AccordionDetails, AccordionSummary, Grid, Typography} from "@mui/material";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+
+const CategoryItem = ({object: {_id, name, subCategories}={}}) => {
+    const [expanded, setExpanded] = useState(false);
+
+    const handleChange = (panel) => (event, isExpanded) => {
+        setExpanded(isExpanded ? panel : false);
+    };
+
+    return (
+        <>
+            {subCategories === null || !subCategories ?
+                <li>
+                    <Link style={{textDecoration: 'none'}} to={`/catalog/category/${_id}`}>
+                        <Typography
+                            variant='body1'
+                            color='#616161'
+                            marginBottom='10px'
+                        >
+                            {name || 'no name'}
+                        </Typography>
+                    </Link>
+                </li>
+                :
+                <li>
+                    <Accordion
+                        style={{border: 'none', borderRadius: '0',marginTop: '-10px', boxShadow: 'none'}}
+                        expanded={expanded === 'panel1'}
+                        onChange={handleChange('panel1')}
+                    >
+                        <AccordionSummary
+                            sx={{padding: '0'}}
+                            expandIcon={<ExpandMoreIcon />}
+                            aria-controls="panel1bh-content"
+                            id="panel1bh-header"
+                        >
+                            <Link
+                                style={{textDecoration: 'none'}}
+                                to={`/catalog/category/${_id}`}
+                            >
+                                <Typography
+                                    variant='body1'
+                                    color='#616161'
+                                    padding='0'
+                                >
+                                    {name || 'no name'}
+                                </Typography>
+                            </Link>
+                        </AccordionSummary>
+                        <AccordionDetails>
+                            <ul style={{listStyle: 'none', padding: '0 0 0 10px', marginBottom: '10px'}}>
+                                {subCategories && Object.values(subCategories).map(item =>
+                                    <CategoryItem key={item['_id']} object={item}/>
+                                )}
+                            </ul>
+                        </AccordionDetails>
+                    </Accordion>
+                </li>
+            }
+        </>
+    )
+}
+export const CategoryAside = ({category}) => {
+    return (
+        <Grid
+            sx={{
+                backgroundColor: '#fff', padding: '30px'
+            }}
+            xs={12} lg={3} item
+        >
+            <Typography
+                variant='h6'
+                letterSpacing='3px'
+                lineHeight='1.3em'
+                marginBottom='20px'
+            >
+                PRODUCT CATEGORIES
+            </Typography>
+            <ul style={{listStyle: 'none', padding: '0'}}>
+                {category && Object.values(category).map(item =>
+                    <CategoryItem key={item['_id']} object={item}/>
+                )}
+            </ul>
+        </Grid>
+    )
+}

+ 141 - 150
src/pages/CatalogPage.jsx

@@ -1,118 +1,76 @@
-import Breadcrumb from "../components/Breadcrumbs";
 import {
-    Accordion,
-    AccordionDetails,
-    AccordionSummary, Box, Button,
-    Card, CardActionArea, CardActions, CardContent, CardMedia,
-    Container, Divider, FormControl,
-    Grid, MenuItem, Select,
-    Typography,
-    useMediaQuery
+    Box,
+    Button,
+    Card,
+    CardActionArea,
+    CardActions,
+    CardContent,
+    CardMedia, Divider,
+    FormControl,
+    Grid, MenuItem, Pagination, Select,
+    Typography
 } from "@mui/material";
-import {connect} from "react-redux";
-import {actionFullCatById, actionFullRootCats} from "../actions/ActionCategory";
 import Link from "react-router-dom/es/Link";
-import Route from "react-router-dom/es/Route";
-import Switch from "react-router-dom/es/Switch";
-import {useEffect, useState} from "react";
-import {backURL} from "../actions/PathDB";
-import {actionCardRemove, actionCartAdd} from "../reducers/CartReducer";
-import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
+import {backURL} from "../../actions/PathDB";
+import imgNotFound from "../../img/catalog/imgNotFound.png";
+import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
+import AddShoppingCartIcon from "@mui/icons-material/AddShoppingCart";
+import FavoriteIcon from "@mui/icons-material/Favorite";
 import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
-import AddShoppingCartIcon from '@mui/icons-material/AddShoppingCart';
-import {Pagination} from "@mui/material";
-import {actionWishListAdd, actionWishListRemove} from "../reducers/WishListReducer";
-import FavoriteIcon from '@mui/icons-material/Favorite';
-import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
-import imgNotFound from "../img/catalog/imgNotFound.png";
-import {NotFoundBlock} from "../components/NotFoundBlock";
-
-const CategoryItem = ({object: {_id, name, subCategories}={}}) => {
-    const [expanded, setExpanded] = useState(false);
-
-    const handleChange = (panel) => (event, isExpanded) => {
-        setExpanded(isExpanded ? panel : false);
-    };
-
-    return (
-        <>
-            {subCategories === null || !subCategories ?
-                <li>
-                    <Link style={{textDecoration: 'none'}} to={`/catalog/category/${_id}`}>
-                        <Typography
-                            variant='body1'
-                            color='#616161'
-                            marginBottom='10px'
-                        >
-                            {name}
-                        </Typography>
-                    </Link>
-                </li>
-                :
-                <li>
-                    <Accordion style={{border: 'none', borderRadius: '0',marginTop: '-10px', boxShadow: 'none'}} expanded={expanded === 'panel1'} onChange={handleChange('panel1')}>
-                        <AccordionSummary
-                            sx={{padding: '0'}}
-                            expandIcon={<ExpandMoreIcon />}
-                            aria-controls="panel1bh-content"
-                            id="panel1bh-header"
-                        >
-                            <Link style={{textDecoration: 'none'}} to={`/catalog/category/${_id}`}>
-                                <Typography
-                                    variant='body1'
-                                    color='#616161'
-                                    padding='0'
-                                >
-                                    {name}
-                                </Typography>
-                            </Link>
-                        </AccordionSummary>
-                        <AccordionDetails>
-                            <ul style={{listStyle: 'none', padding: '0 0 0 10px', marginBottom: '10px'}}>
-                                {subCategories && Object.values(subCategories).map(item =>
-                                    <CategoryItem key={item['_id']} object={item}/>
-                                )}
-                            </ul>
-                        </AccordionDetails>
-                    </Accordion>
-                </li>
-            }
-        </>
-    )
-}
-const CategoryAside = ({category}) => {
-    return (
-        <Grid sx={{backgroundColor: '#fff', padding: '30px'}} xs={12} lg={3} item>
-            <Typography
-                variant='h6'
-                letterSpacing='3px'
-                lineHeight='1.3em'
-                marginBottom='20px'
-            >
-                PRODUCT CATEGORIES
-            </Typography>
-            <ul style={{listStyle: 'none', padding: '0'}}>
-                {category && Object.values(category).map(item =>
-                    <CategoryItem key={item['_id']} object={item}/>
-                )}
-            </ul>
-        </Grid>
-    )
-}
+import {connect} from "react-redux";
+import {actionCardRemove, actionCartAdd} from "../../reducers/CartReducer";
+import {actionWishListAdd, actionWishListRemove} from "../../reducers/WishListReducer";
+import {useEffect, useState} from "react";
+import {NotFoundBlock} from "../../components/NotFoundBlock";
+import {actionFullCatById} from "../../actions/ActionCategory";
+import Switch from "react-router-dom/es/Switch";
+import Route from "react-router-dom/es/Route";
+import {CRRoute} from "../../components/CPRoute";
 
-const GoodCard = ({good:{_id, name, description, price, images}={}, wishlist={}, cart={}, onCartAdd, onWishListAdd, onCartRemove, onWishListRemove}) => {
+const GoodCard = ({good:{_id, name, description, price, images}={},
+                      wishlist={},
+                      cart={},
+                      onCartAdd,
+                      onWishListAdd,
+                      onCartRemove,
+                      onWishListRemove}) => {
     return (
         <Grid xs={12} lg={4} item margin='20px 0'>
-            <Card sx={{ maxWidth: 345, height: '100%', display: 'flex', flexDirection: 'column', margin: 'auto 20px'}}>
-                <CardActionArea sx={{padding: '0', flexGrow: '1', position: 'relative'}}>
-                    <Link  to={`/good/${_id}`} style={{position: 'relative', textDecoration: 'none'}}>
-                        <CardMedia sx={{marginBottom: '20px', marginTop: '20px'}}
+            <Card
+                sx={{
+                    maxWidth: 345,
+                    height: '100%',
+                    display: 'flex',
+                    flexDirection: 'column',
+                    margin: 'auto 20px'
+                }}
+            >
+                <CardActionArea
+                    sx={{
+                        padding: '0',
+                        flexGrow: '1',
+                        position: 'relative'
+                    }}
+                >
+                    <Link
+                        to={`/good/${_id}`}
+                        style={{position: 'relative', textDecoration: 'none'}}
+                    >
+                        <CardMedia
+                            sx={{marginBottom: '20px', marginTop: '20px'}}
                             component="img"
                             height="230"
                             image={images && images[0]?.url ? `${backURL}/${images[0]?.url}` : imgNotFound}
                             alt="Good title image"
                         />
-                        <CardContent sx={{display: 'flex', flexDirection: 'column', height: '200px', justifyContent: 'space-between'}}>
+                        <CardContent
+                            sx={{
+                                display: 'flex',
+                                flexDirection: 'column',
+                                height: '200px',
+                                justifyContent: 'space-between'
+                            }}
+                        >
                             <Typography
                                 textAlign='center'
                                 fontFamily='sarif'
@@ -122,26 +80,58 @@ const GoodCard = ({good:{_id, name, description, price, images}={}, wishlist={},
                                 sx={{textTransform: 'uppercase', flexGrow: '1'}}
                                 color='#000'
                             >
-                               {name.length > 30 ? name.split(' ').splice(0, 6).join(' ') : name}
+                                {name.length > 30 ? name.split(' ').splice(0, 6).join(' ') : name}
                             </Typography>
-                            <Typography textAlign='center' variant="body2" color='#616161' marginBottom='20px' sx={{ flexGrow: '0'}}>
+                            <Typography
+                                textAlign='center'
+                                variant="body2"
+                                color='#616161'
+                                marginBottom='20px'
+                                sx={{ flexGrow: '0'}}
+                            >
                                 {description && description.length > 60 ?
                                     'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' :
                                     description
                                 }
                             </Typography>
-                            <Typography textAlign='center' variant="h5" color="#000" sx={{ flexGrow: '0'}}>
-                                $ {parseFloat(price).toFixed(2)}
+                            <Typography
+                                textAlign='center'
+                                variant="h5"
+                                color="#000"
+                                sx={{ flexGrow: '0'}}>
+                                $ {parseFloat(price || 0).toFixed(2)}
                             </Typography>
                         </CardContent>
                     </Link>
                 </CardActionArea>
                 <CardActions sx={{flexGrow: '0', justifyContent: 'space-between'}}>
-                    <Button onClick={() => {_id in cart ? onCartRemove({_id, name, price, images}) : onCartAdd({_id, name, price, images})}} size="small" color="primary">
-                        {_id in cart ? <ShoppingCartIcon/> : <AddShoppingCartIcon />}
+                    <Button
+                        onClick={() => {
+                            _id in cart ?
+                                onCartRemove({_id, name, price, images})
+                                : onCartAdd({_id, name, price, images})}
+                        }
+                        size="small"
+                        color="primary"
+                    >
+                        {_id in cart ?
+                            <ShoppingCartIcon/>
+                            : <AddShoppingCartIcon />
+                        }
                     </Button>
-                    <Button onClick={() => {_id in wishlist ? onWishListRemove({_id, name, price, images}) : onWishListAdd({_id, name, price, images})}} size="small" color="primary">
-                        {_id in wishlist ? <FavoriteIcon/> : <FavoriteBorderIcon />}
+                    <Button
+                        onClick={() => {
+                            _id in wishlist ?
+                                onWishListRemove({_id, name, price, images})
+                                : onWishListAdd({_id, name, price, images})}
+                        }
+                        size="small"
+                        color="primary"
+                    >
+                        {_id in wishlist ?
+                            <FavoriteIcon/>
+                            : <FavoriteBorderIcon />
+                        }
                     </Button>
                 </CardActions>
             </Card>
@@ -149,10 +139,11 @@ const GoodCard = ({good:{_id, name, description, price, images}={}, wishlist={},
     )
 }
 const CGoodCard = connect(state => ({wishlist: state.wishlist, cart: state.cart}),
-    {onCartAdd: actionCartAdd, onWishListAdd: actionWishListAdd, onCartRemove: actionCardRemove, onWishListRemove: actionWishListRemove})(GoodCard)
+    {onCartAdd: actionCartAdd, onWishListAdd: actionWishListAdd, onCartRemove: actionCardRemove,
+        onWishListRemove: actionWishListRemove})(GoodCard)
 
 const Goods = ({_id, category={}}) => {
-    const itemsPerPage = 6
+    const itemsPerPage = 9
     const [page, setPage] = useState(1)
     const [count, setCount] = useState(1)
     const [goods, setGoods] = useState([])
@@ -224,20 +215,34 @@ const Goods = ({_id, category={}}) => {
         }).filter(item => item)
         setGoods(arr)
     }, [_id, category])
-
     return (
         <>
             {(goods.length > 0 ?
-                <Box sx={{height:'100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
-                    <Box display='flex' alignItems='center' justifyContent='space-between' padding='0 20px'>
+                <Box
+                    sx={{height:'100%',
+                        display: 'flex',
+                        flexDirection: 'column',
+                        justifyContent: 'space-between'
+                    }}
+                >
+                    <Box
+                        display='flex'
+                        alignItems='center'
+                        justifyContent='space-between'
+                        padding='0 20px'
+                    >
                         <Typography
                             variant='body1'
                             color='#616161'
                             letterSpacing='1px'
                         >
-                            SHOWING {goods[0].length > itemsPerPage ? `${((page-1) * itemsPerPage)+1}-${page * itemsPerPage > goods[0].length ? goods[0].length : page * itemsPerPage}` : goods[0].length} OF {goods[0].length} RESULTS
+                            SHOWING {goods[0].length > itemsPerPage ? `${((page-1) * itemsPerPage)+1}-
+                            ${page * itemsPerPage > goods[0].length ? goods[0].length : page * itemsPerPage}` :
+                            goods[0].length} OF {goods[0].length} RESULTS
                         </Typography>
-                        <FormControl variant="standard">
+                        <FormControl
+                            variant="standard"
+                        >
                             <Select
                                 labelId="demo-simple-select-label"
                                 id="demo-simple-select"
@@ -253,15 +258,25 @@ const Goods = ({_id, category={}}) => {
                             </Select>
                         </FormControl>
                     </Box>
-                    <Box flexGrow='1'>
-                        <Grid container justifyContent='space-between'>
+                    <Box
+                        flexGrow='1'
+                    >
+                        <Grid
+                            container
+                            justifyContent='space-between'
+                        >
                             {[...goods[0]].slice((page - 1) * itemsPerPage, page * itemsPerPage)
-                                     .map(good => <CGoodCard key={good['_id']} good={good}/>)}
+                                .map(good => <CGoodCard key={good['_id']} good={good}/>)
+                            }
                         </Grid>
                     </Box>
                     <Box width='100%' flexGrow='0'>
                         <Divider sx={{margin: '20px'}}/>
-                        <Box display='flex' justifyContent='center' width='100%'>
+                        <Box
+                            display='flex'
+                            justifyContent='center'
+                            width='100%'
+                        >
                             <Pagination
                                 count={count}
                                 page={page}
@@ -275,7 +290,7 @@ const Goods = ({_id, category={}}) => {
                         </Box>
                     </Box>
                 </Box>
-                : <NotFoundBlock/>)
+                : <NotFoundBlock marginTop={'-50px'}/>)
             }
         </>
     )
@@ -292,37 +307,13 @@ const BlockGood = ({match:{params:{_id}}, getData}) => {
 }
 const CBlockGood= connect(null, {getData: actionFullCatById})(BlockGood)
 
-const Products = () => {
+export const Products = () => {
     return (
         <Grid xs={12} lg={9} item>
             <Switch>
-                <Route path="/catalog/category/:_id" component={CBlockGood} />
-                <Route path="*" component={NotFoundBlock} />
+                <CRRoute path="/catalog/category/:_id" component={CBlockGood} />
+                <CRRoute path="*" component={NotFoundBlock} />
             </Switch>
         </Grid>
     )
 }
-
-const CatalogPage = ({category={}, actionRootCat}) => {
-    const matches = useMediaQuery('(max-width:899px)')
-    if(Object.entries(category).length === 0) actionRootCat()
-
-    return (
-        <>
-            <Breadcrumb links={['catalog']}/>
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
-                <Container maxWidth="lg">
-                    <Grid container justifyContent='space-between'>
-                        <CategoryAside category={category}/>
-                        <Products/>
-                    </Grid>
-                </Container>
-            </main>
-        </>
-    )
-}
-const CCatalogPage = connect(state => ({category: state.category}), {actionRootCat: actionFullRootCats})(CatalogPage)
-
-export default CCatalogPage
-
-//TODO MOBILE VERSION

+ 88 - 0
src/pages/Contact/AddressItem.jsx

@@ -0,0 +1,88 @@
+import {Grid} from "@mui/material";
+import Typography from "@mui/material/Typography";
+import Social from "../../components/SocialLink";
+import * as React from "react";
+
+export const AddressItem = ({item}) => {
+    return (
+        <>
+            <Grid padding='50px 40px !important' item xs={12} md={6}>
+                <Typography
+                    variant="h5"
+                    letterSpacing="2px"
+                    marginBottom='40px'
+                >
+                    {item[0].toString() || 'no name'}
+                </Typography>
+                <Grid color="#616161" container spacing={2}>
+                    <Grid marginBottom='30px' item xs={12} sm={6}>
+                        <Typography
+                            fontSize='13px'
+                            fontWeight='300'
+                            marginBottom='15px'
+                        >
+                            PHONES
+                        </Typography>
+                        {Array.isArray(item) && item.length > 0 && item[1]?.phones.map((i, index) =>
+                            <Typography
+                                key={index}
+                                lineHeight='1.7em'
+                                fontWeight='400'
+                                variant="body1"
+                            >
+                                {i.toString() || 'phones'}
+                            </Typography>
+                        )}
+                    </Grid>
+                    <Grid marginBottom='30px' item xs={12} sm={6}>
+                        <Typography
+                            fontSize='13px'
+                            fontWeight='300'
+                            marginBottom='15px'
+                        >
+                            ADDRESS
+                        </Typography>
+                        <Typography
+                            lineHeight='1.7em'
+                            fontWeight='400'
+                            variant='body1'
+                        >
+                            {Array.isArray(item) && item.length > 0 ? item[1]?.address : 'address'}
+                        </Typography>
+                    </Grid>
+                    <Grid marginBottom='30px' item xs={12} sm={6}>
+                        <Typography
+                            fontSize='13px'
+                            fontWeight='300'
+                            marginBottom='15px'
+                        >
+                            EMAIL
+                        </Typography>
+                        {Array.isArray(item) && item.length > 0  &&item[1]?.email.map(i =>
+                            <Typography
+                                key={i.toString()}
+                                lineHeight='1.7em'
+                                fontWeight='400'
+                                variant="body1"
+                            >
+                                { i.toString() || 'email' }
+                            </Typography>)
+                        }
+                    </Grid>
+                    <Grid marginBottom='30px' item xs={12} sm={6}>
+                        <Typography
+                            fontSize='13px'
+                            fontWeight='300'
+                            marginBottom='15px'
+                        >
+                            SOCIAL NETWORKS
+                        </Typography>
+                        {(item[1]["social networks"] || []).map(item =>
+                            <Social key={item.url} Icon={item.icon} link={item.url}/>
+                        )}
+                    </Grid>
+                </Grid>
+            </Grid>
+        </>
+    )
+}

+ 51 - 81
src/pages/ContactPage.jsx

@@ -1,18 +1,17 @@
-import * as React from 'react';
-import PropTypes from 'prop-types';
-import Tabs from '@mui/material/Tabs';
-import Tab from '@mui/material/Tab';
-import Typography from '@mui/material/Typography';
-import Box from '@mui/material/Box';
-import Breadcrumbs from "../components/Breadcrumbs";
-import {useState} from "react";
-import {Container, Grid, useMediaQuery} from "@mui/material";
 import FacebookIcon from "@mui/icons-material/Facebook";
 import InstagramIcon from "@mui/icons-material/Instagram";
 import TwitterIcon from "@mui/icons-material/Twitter";
 import YouTubeIcon from "@mui/icons-material/YouTube";
-import Social from "../components/SocialLink";
-import GoogleMap from "../components/GoogleMap";
+import Box from "@mui/material/Box";
+import PropTypes from "prop-types";
+import {Container, Grid, useMediaQuery} from "@mui/material";
+import {useState} from "react";
+import Breadcrumbs from "../../components/Breadcrumbs";
+import Tabs from "@mui/material/Tabs";
+import Tab from "@mui/material/Tab";
+import GoogleMap from "../../components/GoogleMap";
+import * as React from "react";
+import {AddressItem} from "./AddressItem";
 
 const defaultAddress = {
     'NEW YORK': {
@@ -108,67 +107,7 @@ function a11yProps(index) {
     };
 }
 
-const AddressItem = ({item}) => {
-    return (
-        <>
-            <Grid padding='50px 40px !important' item xs={12} md={6}>
-                <Typography
-                    variant="h5"
-                    letterSpacing="2px"
-                    marginBottom='40px'
-                >
-                    {item[0].toString()}
-                </Typography>
-                <Grid color="#616161" container spacing={2}>
-                    <Grid marginBottom='30px' item xs={12} sm={6}>
-                        <Typography
-                            fontSize='13px'
-                            fontWeight='300'
-                            marginBottom='15px'
-                        >
-                            PHONES
-                        </Typography>
-                        {item[1].phones.map((i, index) => <Typography key={index} lineHeight='1.7em' fontWeight='400' variant="body1">{i.toString()}</Typography>)}
-                    </Grid>
-                    <Grid marginBottom='30px' item xs={12} sm={6}>
-                        <Typography
-                            fontSize='13px'
-                            fontWeight='300'
-                            marginBottom='15px'
-                        >
-                            ADDRESS
-                        </Typography>
-                        <Typography lineHeight='1.7em' fontWeight='400' variant="body1">{item[1].address}</Typography>
-                    </Grid>
-                    <Grid marginBottom='30px' item xs={12} sm={6}>
-                        <Typography
-                            fontSize='13px'
-                            fontWeight='300'
-                            marginBottom='15px'
-                        >
-                            EMAIL
-                        </Typography>
-                        {item[1].email.map(i => <Typography key={i.toString()} lineHeight='1.7em' fontWeight='400' variant="body1">{i.toString()}</Typography>)}
-                    </Grid>
-                    <Grid marginBottom='30px' item xs={12} sm={6}>
-                        <Typography
-                            fontSize='13px'
-                            fontWeight='300'
-                            marginBottom='15px'
-                        >
-                            SOCIAL NETWORKS
-                        </Typography>
-                        {(item[1]["social networks"] || []).map(item =>
-                            <Social key={item.url} Icon={item.icon} link={item.url}/>
-                        )}
-                    </Grid>
-                </Grid>
-            </Grid>
-        </>
-    )
-}
-
-const Contact = ({address=defaultAddress}) => {
+export const ContactPage = ({address=defaultAddress}) => {
     const matches = useMediaQuery('(max-width:768px)');
     const matches2 = useMediaQuery('(max-width:420px)');
     const [value, setValue] = useState(0);
@@ -178,7 +117,13 @@ const Contact = ({address=defaultAddress}) => {
     return (
         <>
             <Breadcrumbs links={['contact']}/>
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: '300px'
+                }}
+            >
                 <Container maxWidth="lg">
                     <Box sx={{ width: '100%' }}>
                         <Box sx={{ color: "#616161" }}>
@@ -192,18 +137,44 @@ const Contact = ({address=defaultAddress}) => {
                                 sx={{fontWeight: 300, marginBottom: '30px'}}
                                 centered
                             >
-                                {Object.keys(address).map((value, index) => {
-                                    return <Tab key={index} sx={{borderBottom: '1px solid #dedede'}} label={value.toString()} {...a11yProps(index)} />
-                                })}
+                                {Object.keys(address).map((value, index) =>
+                                    <Tab
+                                        key={index}
+                                        sx={{borderBottom: '1px solid #dedede'}}
+                                        label={value.toString() || 'value'}
+                                        {...a11yProps(index)}
+                                    />
+                                )}
                             </Tabs>
                         </Box>
                         {Object.entries(address).map((item, index) => {
                             return (
-                                <TabPanel key={index} value={value} index={index}>
-                                    <Grid sx={{backgroundColor: '#fff', padding: '0px 0px', marginLeft: '-10px'}} container spacing={2}>
+                                <TabPanel
+                                    key={index}
+                                    value={value}
+                                    index={index}
+                                >
+                                    <Grid
+                                        sx={{backgroundColor: '#fff',
+                                            padding: '0px 0px',
+                                            marginLeft: '-10px'
+                                        }}
+                                        container
+                                        spacing={2}
+                                    >
                                         <AddressItem key={index} item={item} />
-                                        <Grid sx={{padding: '0px 0px !important', position: 'relative', height: matches ? '300px': '500px'}} item xs={12} md={6}>
-                                            <GoogleMap lat={item[1].coordinates.lat} lng={item[1].coordinates.lng} key={index} />
+                                        <Grid
+                                            sx={{
+                                                padding: '0px 0px !important',
+                                                position: 'relative',
+                                                height: matches ? '300px': '500px'
+                                            }} item xs={12} md={6}
+                                        >
+                                            <GoogleMap
+                                                lat={item[1].coordinates.lat}
+                                                lng={item[1].coordinates.lng}
+                                                key={index}
+                                            />
                                         </Grid>
                                     </Grid>
                                 </TabPanel>
@@ -215,4 +186,3 @@ const Contact = ({address=defaultAddress}) => {
         </>
     )
 }
-export default Contact

+ 0 - 78
src/pages/FAQPage.jsx

@@ -1,78 +0,0 @@
-import Breadcrumbs from "../components/Breadcrumbs";
-import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
-import {Accordion, AccordionDetails, AccordionSummary, Container, Typography, useMediaQuery} from "@mui/material";
-import {useState} from "react";
-
-const AccordionsItem = ({id, title, content}) => {
-    const matches = useMediaQuery('(max-width:768px)');
-    const [expanded, setExpanded] = useState(false)
-
-    const handleChange = (panel) => (event, isExpanded) => {
-        setExpanded(isExpanded ? panel : false)
-    }
-
-    return (
-        <Accordion
-            expanded={expanded === id}
-            onChange={handleChange(id)}
-            sx={{padding: matches ? '10px' : "20px"}}
-        >
-            <AccordionSummary
-                expandIcon={<ExpandMoreIcon />}
-                aria-controls="panel1a-content"
-                id="panel1a-header"
-            >
-                <Typography
-                    variant={matches ? 'body1' : 'h5'}
-                    letterSpacing='3px'
-                >
-                    {title.toUpperCase()}
-                </Typography>
-            </AccordionSummary>
-            <AccordionDetails>
-                <Typography
-                    variant='body1'
-                    color='#616161'
-                    lineHeight='1.7em'
-                    fontWeight='300'
-                >
-                    {content}
-                </Typography>
-            </AccordionDetails>
-        </Accordion>
-    )
-}
-
-const FAQPage = () => {
-    const matches = useMediaQuery('(max-width:768px)');
-    return (
-        <>
-            <Breadcrumbs links={['faq']}/>
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
-                <Container maxWidth="lg">
-                   <AccordionsItem
-                       id={'panel1'}
-                       title={'PAYMENT METHODS'}
-                       content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus labore quos rerum sed suscipit voluptatibus.'}
-                   />
-                    <AccordionsItem
-                        id={'panel2'}
-                        title={'INTERNATIONAL SHIPPING'}
-                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus labore quos rerum sed suscipit voluptatibus.'}
-                    />
-                    <AccordionsItem
-                        id={'panel3'}
-                        title={'CASHBACK PROGRAM'}
-                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus labore quos rerum sed suscipit voluptatibus.'}
-                    />
-                    <AccordionsItem
-                        id={'panel4'}
-                        title={'MONEY BACK WARRANTY'}
-                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus labore quos rerum sed suscipit voluptatibus.'}
-                    />
-                </Container>
-            </main>
-        </>
-    )
-}
-export default FAQPage

+ 43 - 0
src/pages/FAQPage/AccordionsItem.jsx

@@ -0,0 +1,43 @@
+import {Accordion, AccordionDetails, AccordionSummary, Typography, useMediaQuery} from "@mui/material";
+import {useState} from "react";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+
+export const AccordionsItem = ({id, title, content}) => {
+    const matches = useMediaQuery('(max-width:768px)')
+    const [expanded, setExpanded] = useState(false)
+
+    const handleChange = (panel) => (event, isExpanded) => {
+        setExpanded(isExpanded ? panel : false)
+    }
+
+    return (
+        <Accordion
+            expanded={expanded === id}
+            onChange={handleChange(id)}
+            sx={{padding: matches ? '10px' : "20px"}}
+        >
+            <AccordionSummary
+                expandIcon={<ExpandMoreIcon />}
+                aria-controls="panel1a-content"
+                id="panel1a-header"
+            >
+                <Typography
+                    variant={matches ? 'body1' : 'h5'}
+                    letterSpacing='3px'
+                >
+                    { title.toUpperCase() || 'title' }
+                </Typography>
+            </AccordionSummary>
+            <AccordionDetails>
+                <Typography
+                    variant='body1'
+                    color='#616161'
+                    lineHeight='1.7em'
+                    fontWeight='300'
+                >
+                    { content || 'content' }
+                </Typography>
+            </AccordionDetails>
+        </Accordion>
+    )
+}

+ 59 - 0
src/pages/FAQPage/FAQPage.jsx

@@ -0,0 +1,59 @@
+import {Container, useMediaQuery} from "@mui/material";
+import Breadcrumbs from "../../components/Breadcrumbs";
+import {AccordionsItem} from "./AccordionsItem";
+
+export const FAQPage = () => {
+    const matches = useMediaQuery('(max-width:768px)')
+
+    return (
+        <>
+            <Breadcrumbs links={['faq']}/>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: '300px'
+                }}
+            >
+                <Container maxWidth="lg">
+                    <AccordionsItem
+                        id={'panel1'}
+                        title={'PAYMENT METHODS'}
+                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, ' +
+                            'blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, ' +
+                            'possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem' +
+                            'fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus ' +
+                            ' labore quos rerum sed suscipit voluptatibus.'}
+                    />
+                    <AccordionsItem
+                        id={'panel2'}
+                        title={'INTERNATIONAL SHIPPING'}
+                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, ' +
+                            'blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, ' +
+                            'possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem' +
+                            ' fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus ' +
+                            'labore quos rerum sed suscipit voluptatibus.'}
+                    />
+                    <AccordionsItem
+                        id={'panel3'}
+                        title={'CASHBACK PROGRAM'}
+                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, ' +
+                            'blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, ' +
+                            'possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem' +
+                            ' fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus ' +
+                            'labore quos rerum sed suscipit voluptatibus.'}
+                    />
+                    <AccordionsItem
+                        id={'panel4'}
+                        title={'MONEY BACK WARRANTY'}
+                        content={'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam amet autem, ' +
+                            'blanditiis cupiditate dolore eum facilis fuga magni, molestias mollitia odio placeat, ' +
+                            'possimus sit ut vel. Architecto cumque dignissimos distinctio dolorum eos exercitationem' +
+                            ' fuga molestiae odio optio placeat porro, possimus, repellendus. Accusamus ad ducimus ' +
+                            'labore quos rerum sed suscipit voluptatibus.'}
+                    />
+                </Container>
+            </main>
+        </>
+    )
+}

+ 0 - 153
src/pages/MyAccountPage.jsx

@@ -1,153 +0,0 @@
-import Breadcrumb from "../components/Breadcrumbs";
-import {
-    Box,
-    Button,
-    Container,
-    TextField,
-    Typography,
-    useMediaQuery
-} from "@mui/material";
-import UnstyledButtonCustom from "../components/MainButton";
-import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
-import {useState} from "react";
-import Link from "react-router-dom/es/Link";
-import {connect} from 'react-redux';
-import {actionFullLogin, actionFullRegister} from "../actions/ActionLogin";
-import Redirect from "react-router-dom/es/Redirect";
-import {actionClearPromise} from "../reducers/PromiseReducer";
-
-const MyAccountPage = ({auth, promise, user, onLogin, onRegister, onClear}) => {
-    const matches = useMediaQuery('(max-width:899px)')
-    const [status, setStatus] = useState('login')
-    if (auth?.payload && Object.keys(user).length !== 0){
-        onClear('login'); onClear('register');
-    }
-    const Form = ({title, target, onClickEvent, children}) => {
-        const matches2 = useMediaQuery('(max-width:450px)')
-
-        const [valueLogin, setValueLogin] = useState('')
-        const [valuePassword, setValuePassword] = useState('')
-        const [flagLogin, setFlagLog] = useState(false)
-        const [flagPassword, setFlagPass] = useState(false)
-
-        return (
-            <Box
-                sx={{
-                    backgroundColor: "#fff",
-                    display: "flex",
-                    flexDirection: "column",
-                    justifyContent: "center",
-                    alignItems: "center",
-                    padding: matches2 ? "30px 20px" : "40px 60px"
-                }}
-            >
-                <Typography
-                    variant='h4'
-                    letterSpacing='10px'
-                    marginBottom='30px'
-                >
-                    {title}
-                </Typography>
-                <TextField
-                    id="login"
-                    label="Login"
-                    variant="standard"
-                    type="text"
-                    required
-                    fullWidth
-                    value={valueLogin}
-                    onChange={e => {setValueLogin(e.target.value); setFlagLog(true)}}
-                    error={flagLogin && (valueLogin.length < 3 || valueLogin.length > 20)}
-                    sx={{marginBottom: '20px'}}
-                />
-                <TextField
-                    id="password"
-                    label="Password"
-                    variant="standard"
-                    type="password"
-                    required
-                    fullWidth
-                    value={valuePassword}
-                    onChange={e => {setValuePassword(e.target.value); setFlagPass(true)}}
-                    error={flagPassword && (valuePassword.length < 3 || valuePassword.length > 20)}
-                    sx={{marginBottom: '30px'}}
-                />
-                {children}
-                <UnstyledButtonCustom
-                    onClick={() => {
-                        if(valuePassword.length >= 3 && valuePassword.length <= 20 &&
-                            valueLogin.length >= 3 && valueLogin.length <= 20) {
-                            onClickEvent(valueLogin, valuePassword)
-                        }
-                    }}
-                    text={title}
-                />
-                <Box
-                    width='100%'
-                    display='flex'
-                    justifyContent='flex-end'
-                    marginTop='20px'
-                >
-                    <Button
-                        onClick={() => setStatus(target)}
-                    >
-                        {target}
-                        <ArrowForwardIosIcon/>
-                    </Button>
-                </Box>
-            </Box>
-        )
-    }
-
-    return (
-        <>
-            <Breadcrumb links={['my account']}/>
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
-                <Container maxWidth="sm">
-                    {(auth?.payload && Object.keys(user).length !== 0) ? <Redirect to={'/profile'}/>:
-                        status === 'login' ?
-                            <Form title={'LOGIN'} target={'register'} onClickEvent={onLogin} children={
-                                <>
-                                    {promise?.login?.status === "RESOLVED" &&
-                                        <Typography
-                                            variant='body2'
-                                            color='red'
-                                            marginBottom='20px'
-                                        >
-                                            This user does not exist
-                                        </Typography>
-                                    }
-                                </>
-                            }/> :
-                            <Form title={'REGISTER'} target={'login'} onClickEvent={onRegister} children={
-                                <>
-                                    <Typography
-                                        variant='body2'
-                                        color='#616161'
-                                        textAlign='justify'
-                                        marginBottom='40px'
-                                    >
-                                        Your personal data will be used to support your experience throughout this website, to manage access to your account, and for other purposes described in our
-                                        <Link style={{textDecoration: 'none'}} to='/privacy-policy'> privacy policy</Link>
-                                        .
-                                    </Typography>
-                                    {promise?.register?.status === "RESOLVED" &&
-                                        <Typography
-                                            variant='body2'
-                                            color='red'
-                                            marginBottom='20px'
-                                        >
-                                            Such user already exists
-                                        </Typography>
-                                    }
-                                </>
-                            }/>
-                    }
-                </Container>
-            </main>
-        </>
-    )
-}
-const CLoginForm = connect(state => ({auth: state.auth, promise: state.promise, user: state.user}), {onLogin: actionFullLogin, onRegister: actionFullRegister, onClear: actionClearPromise})(MyAccountPage)
-
-export default CLoginForm

+ 87 - 0
src/pages/MyAccountPage/Form.jsx

@@ -0,0 +1,87 @@
+import {Box, Button, TextField, Typography, useMediaQuery} from "@mui/material";
+import {useState} from "react";
+import UnstyledButtonCustom from "../../components/MainButton";
+import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos";
+
+export const Form = ({title, target, onClickEvent, children, setStatus}) => {
+    const matches2 = useMediaQuery('(max-width:450px)')
+
+    const [valueLogin, setValueLogin] = useState('')
+    const [valuePassword, setValuePassword] = useState('')
+    const [flagLogin, setFlagLog] = useState(false)
+    const [flagPassword, setFlagPass] = useState(false)
+
+    return (
+        <Box
+            sx={{
+                backgroundColor: "#fff",
+                display: "flex",
+                flexDirection: "column",
+                justifyContent: "center",
+                alignItems: "center",
+                padding: matches2 ? "30px 20px" : "40px 60px"
+            }}
+        >
+            <Typography
+                variant='h4'
+                letterSpacing='10px'
+                marginBottom='30px'
+            >
+                { title || 'title' }
+            </Typography>
+            <TextField
+                id="login"
+                label="Login"
+                variant="standard"
+                type="text"
+                required
+                fullWidth
+                value={valueLogin}
+                onChange={e => {
+                    setValueLogin(e.target.value);
+                    setFlagLog(true)
+                }}
+                error={flagLogin && (valueLogin.length < 3 || valueLogin.length > 20)}
+                sx={{marginBottom: '20px'}}
+            />
+            <TextField
+                id="password"
+                label="Password"
+                variant="standard"
+                type="password"
+                required
+                fullWidth
+                value={valuePassword}
+                onChange={e => {
+                    setValuePassword(e.target.value);
+                    setFlagPass(true)
+                }}
+                error={flagPassword && (valuePassword.length < 3 || valuePassword.length > 20)}
+                sx={{marginBottom: '30px'}}
+            />
+            {children}
+            <UnstyledButtonCustom
+                onClick={() => {
+                    if(valuePassword.length >= 3 && valuePassword.length <= 20 &&
+                        valueLogin.length >= 3 && valueLogin.length <= 20) {
+                        onClickEvent(valueLogin, valuePassword)
+                    }
+                }}
+                text={title || 'title'}
+            />
+            <Box
+                width='100%'
+                display='flex'
+                justifyContent='flex-end'
+                marginTop='20px'
+            >
+                <Button
+                    onClick={() => setStatus(target)}
+                >
+                    { target }
+                    <ArrowForwardIosIcon/>
+                </Button>
+            </Box>
+        </Box>
+    )
+}

+ 101 - 0
src/pages/MyAccountPage/MyAccountPage.jsx

@@ -0,0 +1,101 @@
+import {Container, Typography, useMediaQuery} from "@mui/material";
+import {useState} from "react";
+import Breadcrumb from "../../components/Breadcrumbs";
+import Redirect from "react-router-dom/es/Redirect";
+import Link from "react-router-dom/es/Link";
+import {connect} from "react-redux";
+import {actionFullLogin, actionFullRegister} from "../../actions/ActionLogin";
+import {actionClearPromise} from "../../reducers/PromiseReducer";
+import {Form} from "./Form";
+
+const MyAccountPage = ({auth, promise, user, onLogin, onRegister, onClear}) => {
+    const matches = useMediaQuery('(max-width:899px)')
+    const [status, setStatus] = useState('login')
+
+    if (auth?.payload && Object.keys(user).length !== 0){
+        onClear('login');
+        onClear('register');
+    }
+
+    return (
+        <>
+            <Breadcrumb links={['my account']}/>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight:'300px'
+                }}
+            >
+                <Container maxWidth="sm">
+                    {(auth?.payload && Object.keys(user).length !== 0) ?
+                        <Redirect to={'/profile'}/>
+                        :
+                        status === 'login' ?
+                            <Form
+                                title={'LOGIN'}
+                                target={'register'}
+                                onClickEvent={onLogin}
+                                setStatus={value => setStatus(value)}
+                                children={
+                                    <>
+                                        {promise?.login?.status === "RESOLVED" &&
+                                            <Typography
+                                                variant='body2'
+                                                color='red'
+                                                marginBottom='20px'
+                                            >
+                                                This user does not exist
+                                            </Typography>
+                                        }
+                                    </>
+                                }
+                            />
+                            :
+                            <Form
+                                title={'REGISTER'}
+                                target={'login'}
+                                onClickEvent={onRegister}
+                                setStatus={value => setStatus(value)}
+                                children={
+                                    <>
+                                        <Typography
+                                            variant='body2'
+                                            color='#616161'
+                                            textAlign='justify'
+                                            marginBottom='40px'
+                                        >
+                                            Your personal data will be used to support your experience throughout
+                                            this website, to manage access to your account, and for other purposes
+                                            described in our
+                                            <Link
+                                                style={{textDecoration: 'none'}}
+                                                to='/privacy-policy'
+                                            >
+                                                {' privacy policy'}
+                                            </Link>
+                                            .
+                                        </Typography>
+                                        {promise?.register?.status === "RESOLVED" &&
+                                            <Typography
+                                                variant='body2'
+                                                color='red'
+                                                marginBottom='20px'
+                                            >
+                                                Such user already exists
+                                            </Typography>
+                                        }
+                                    </>
+                                }
+                            />
+                    }
+                </Container>
+            </main>
+        </>
+    )
+}
+const CLoginForm = connect(state => ({auth: state.auth, promise: state.promise, user: state.user}),
+    {onLogin: actionFullLogin, onRegister: actionFullRegister,
+        onClear: actionClearPromise})(MyAccountPage)
+
+export default CLoginForm

+ 0 - 250
src/pages/MyOrdersPage.jsx

@@ -1,250 +0,0 @@
-import Breadcrumb from "../components/Breadcrumbs";
-import {
-    Accordion,
-    AccordionDetails,
-    AccordionSummary, Box,
-    CircularProgress,
-    Container, Divider, Grid, Pagination,
-    Typography,
-    useMediaQuery
-} from "@mui/material";
-import {connect} from "react-redux";
-import {actionFullOrderFind} from "../actions/ActionOrderFind";
-import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
-import {timeCalc} from "./ProductPage";
-import {backURL} from "../actions/PathDB";
-import {actionMyOrderClear} from "../reducers/MyOrdersReducer";
-import {useEffect, useState} from "react";
-import imgNotFound from "../img/catalog/imgNotFound.png";
-import Link from "react-router-dom/es/Link";
-import {NotFoundBlock} from "../components/NotFoundBlock";
-
-const AccordionHeaderText = ({columnText, content}) => {
-    return (
-        <Box display='flex' flexDirection='column' justifyContent='space-between'>
-            <Typography
-                variant='body2'
-                color='#616161'
-                marginBottom='20px'
-            >
-                {columnText}
-            </Typography>
-            <Typography
-                variant='body1'
-            >
-                {content}
-            </Typography>
-        </Box>
-    )
-}
-const AccordionItem = ({data}) => {
-    const time = timeCalc(+data['createdAt'])
-    const [status, setStatus] = useState(false);
-
-    return (
-        <Accordion onChange={() => setStatus(!status)}>
-            <AccordionSummary
-                expandIcon={<ExpandMoreIcon />}
-            >
-                <Divider orientation="vertical" flexItem sx={{backgroundColor: data['total'] ? '#7cd545': '#ad2222', width:'5px', borderRadius: '3px', boxShadow: 'none'}}/>
-                <Box sx={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%', padding: '10px 20px'}}>
-                    <AccordionHeaderText columnText={`№ ${data['_id']} from ${time}`} content={data['total'] ? 'Completed' : 'Canceled'}/>
-                    {!status && <AccordionHeaderText columnText={'Order price'} content={data['total'] ? `$${data['total']}` : 'null'}/>}
-                    {!status && <Box sx={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '200px'}}>
-                        {data['orderGoods'] && data['orderGoods'].map((item, index, array) => {
-                            if (index < 2) {
-                                return <Box minWidth='60px' maxWidth='60px' height='60px' borderRadius='10px' overflow='hidden' marginRight='20px'>
-                                            <img style={{width: '100%', height: '100%', objectFit: 'cover'}}
-                                                 src={item?.good?.images && item.good.images[0].url ? backURL + '/' + item.good.images[0].url : imgNotFound}
-                                                 alt={'image'}/>
-                                        </Box>
-                            }
-                            else if (index === 2) {
-                                return <Box sx={{width:'60px', height:'60px', border:'1px solid #616161', display: 'flex', justifyContent: 'center', alignItems: 'center', color: '#616161', borderRadius: '10px'}}>
-                                            +{array.length - 2}
-                                       </Box>}
-                            })
-                        }
-                    </Box>}
-                </Box>
-            </AccordionSummary>
-            <AccordionDetails sx={{padding: '20px'}}>
-                {data['orderGoods'] && data['orderGoods'].length > 0 ?
-                    <>
-                        <Grid container>
-                            <Grid item md={7}>
-                                <Typography
-                                    color='#616161'
-                                    variant='body1'
-                                    letterSpacing='1px'
-                                    textAlign='left'
-                                >
-                                    Product
-                                </Typography>
-                            </Grid>
-                            <Grid item md={2}>
-                                <Typography
-                                    color='#616161'
-                                    variant='body1'
-                                    letterSpacing='1px'
-                                    textAlign='center'
-                                >
-                                    Price
-                                </Typography>
-                            </Grid>
-                            <Grid item md={1}>
-                                <Typography
-                                    color='#616161'
-                                    variant='body1'
-                                    letterSpacing='1px'
-                                    textAlign='center'
-                                >
-                                    Count
-                                </Typography>
-                            </Grid>
-                            <Grid item md={2}>
-                                <Typography
-                                    color='#616161'
-                                    variant='body1'
-                                    letterSpacing='1px'
-                                    textAlign='right'
-                                >
-                                    Sum
-                                </Typography>
-                            </Grid>
-                        </Grid>
-                        <Divider sx={{margin: '10px 0'}}/>
-                        {data['orderGoods'].map(item => {
-                            return <Grid container alignItems='center' marginBottom='20px'>
-                                <Grid item md={7}>
-                                    <Link style={{textDecoration: 'none', display: 'flex', alignItems: 'center', color: '#616161'}} to={`/good/${item?.good?._id}`}>
-                                        <Box minWidth='60px' maxWidth='60px' height='60px' borderRadius='10px' overflow='hidden' marginRight='20px'>
-                                            <img style={{width: '100%', height: '100%', objectFit: 'cover'}}
-                                                 src={item?.good?.images && item.good.images[0].url ? backURL + '/' + item.good.images[0].url : imgNotFound}
-                                                 alt={'image'}/>
-                                        </Box>
-                                        <Typography
-                                            variant='body1'
-                                        >
-                                            {item.good?.name || 'product name'}
-                                        </Typography>
-                                    </Link>
-                                </Grid>
-                                <Grid item md={2}>
-                                    <Typography
-                                        color='#616161'
-                                        variant='body1'
-                                        letterSpacing='1px'
-                                        textAlign='center'
-                                    >
-                                        {item?.price ? '$' + parseFloat(item.price).toFixed(2) : 'NaN'}
-                                    </Typography>
-                                </Grid>
-                                <Grid item md={1}>
-                                    <Typography
-                                        color='#616161'
-                                        variant='body1'
-                                        letterSpacing='1px'
-                                        textAlign='center'
-                                    >
-                                        {item?.count || '1'}
-                                    </Typography>
-                                </Grid>
-                                <Grid item md={2}>
-                                    <Typography
-                                        color='#616161'
-                                        variant='body1'
-                                        letterSpacing='1px'
-                                        textAlign='right'
-                                    >
-                                        {item?.price && item?.count ? '$'+parseFloat(item.price * item.count).toFixed(2) : 'NaN'}
-                                    </Typography>
-                                </Grid>
-                            </Grid>
-                        })}
-                        <Divider sx={{margin: '-10px 0 10px 0'}}/>
-                        <Box display='flex' justifyContent='space-between'>
-                            <Typography
-                                variant='body1'
-                                color='#616161'
-                            >
-                                Total
-                            </Typography>
-                            <Typography
-                                variant='body1'
-                                color='#616161'
-                            >
-                                {data?.total ? '$'+parseFloat(data.total).toFixed(2) : 'NaN'}
-                            </Typography>
-                        </Box>
-                    </> :
-                    <Typography>Error</Typography>
-                }
-            </AccordionDetails>
-        </Accordion>
-    )
-}
-
-const MainOrders = ({itemsPerPage=10, orders, onFindOrders, onOrdersClear}) => {
-    const [page, setPage] = useState(1)
-    const [count, setCount] = useState(1)
-    const handleChange = (event, value) => {
-        setPage(value);
-    }
-
-    useEffect(() => {
-        onOrdersClear()
-    }, [onOrdersClear])
-
-    useEffect(() => {
-        if(orders?.orderResult && Object.entries(orders.orderResult).length > 0) {
-            setCount(Math.ceil(Object.entries(orders.orderResult).length / itemsPerPage))
-        }
-    }, [orders])
-
-    if(Object.entries(orders).length === 0) onFindOrders()
-
-    return (
-        <>
-            {Object.entries(orders).length === 0 ?
-                <Box sx={{height: '100%', width: '100%', display: 'flex', justifyContent:'center', alignItems:'center'}}><CircularProgress color="inherit"/></Box> :
-                Object.entries(orders?.orderResult).length > 0 ?
-                    <Box>
-                        {Object.values(orders.orderResult).slice((page - 1) * itemsPerPage, page * itemsPerPage).map(item => <AccordionItem data={item}/>)}
-                        <Divider sx={{margin: '20px'}}/>
-                        <Box display='flex' justifyContent='center' width='100%'>
-                            <Pagination
-                                count={count}
-                                page={page}
-                                onChange={handleChange}
-                                defaultPage={1}
-                                color="primary"
-                                size="large"
-                                showFirstButton
-                                showLastButton
-                            />
-                        </Box>
-                    </Box>
-                    :
-                    <NotFoundBlock headerText={'OOPS! ORDERS CAN’T BE FOUND'} text={'No order has been made yet.'}/>
-            }
-        </>
-    )
-}
-export const CMainOrders = connect(state=>({orders: state.myorders}), {onFindOrders: actionFullOrderFind, onOrdersClear: actionMyOrderClear})(MainOrders)
-
-const MyOrdersPage = () => {
-    const matches = useMediaQuery('(max-width:768px)')
-    return (
-        <>
-            <Breadcrumb links={['My orders']} />
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0", minHeight:'300px'}}>
-                <Container maxWidth="lg" sx={{position:'relative'}}>
-                    <CMainOrders />
-                </Container>
-            </main>
-        </>
-    )
-}
-
-export default MyOrdersPage

+ 24 - 0
src/pages/MyOrdersPage/AccordionHeaderText.jsx

@@ -0,0 +1,24 @@
+import {Box, Typography} from "@mui/material";
+
+export const AccordionHeaderText = ({columnText, content}) => {
+    return (
+        <Box
+            display='flex'
+            flexDirection='column'
+            justifyContent='space-between'
+        >
+            <Typography
+                variant='body2'
+                color='#616161'
+                marginBottom='20px'
+            >
+                {columnText || 'columnText'}
+            </Typography>
+            <Typography
+                variant='body1'
+            >
+                {content || 'content'}
+            </Typography>
+        </Box>
+    )
+}

+ 240 - 0
src/pages/MyOrdersPage/AccordionItem.jsx

@@ -0,0 +1,240 @@
+import {useState} from "react";
+import {Accordion, AccordionDetails, AccordionSummary, Box, Divider, Grid, Typography} from "@mui/material";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+import {backURL} from "../../actions/PathDB";
+import imgNotFound from "../../img/catalog/imgNotFound.png";
+import Link from "react-router-dom/es/Link";
+import {AccordionHeaderText} from "./AccordionHeaderText";
+import {timeCalc} from "../ProductPage/timeCalc";
+
+export const AccordionItem = ({data}) => {
+    const time = timeCalc(+data['createdAt'])
+    const [status, setStatus] = useState(false);
+
+    return (
+        <Accordion onChange={() => setStatus(!status)}>
+            <AccordionSummary
+                expandIcon={<ExpandMoreIcon />}
+            >
+                <Divider
+                    orientation="vertical"
+                    flexItem
+                    sx={{
+                        backgroundColor: data['total'] ? '#7cd545': '#ad2222',
+                        width:'5px',
+                        borderRadius: '3px',
+                        boxShadow: 'none'
+                    }}
+                />
+                <Box
+                    sx={{
+                        display: 'flex',
+                        justifyContent: 'space-between',
+                        alignItems: 'center',
+                        width: '100%',
+                        padding: '10px 20px'
+                    }}
+                >
+                    <AccordionHeaderText
+                        columnText={`№ ${data['_id']} from ${time}`}
+                        content={data['total'] ? 'Completed' : 'Canceled'}
+                    />
+                    {!status &&
+                        <AccordionHeaderText
+                            columnText={'Order price'}
+                            content={data['total'] ? `$${data['total']}` : 'null'}
+                        />
+                    }
+                    {!status &&
+                        <Box
+                            sx={{
+                                display: 'flex',
+                                justifyContent: 'space-between',
+                                alignItems: 'center',
+                                width: '200px'
+                            }}
+                        >
+                            {data['orderGoods'] && data['orderGoods'].map((item, index, array) => {
+                                if (index < 2) {
+                                    return (
+                                        <Box
+                                            key={index}
+                                            maxWidth='60px'
+                                            height='60px'
+                                            borderRadius='10px'
+                                            overflow='hidden'
+                                            marginRight='20px'
+                                        >
+                                            <img style={{width: '100%', height: '100%', objectFit: 'cover'}}
+                                                 src={item?.good?.images && item.good.images[0].url ?
+                                                     backURL + '/' + item.good.images[0].url : imgNotFound}
+                                                 alt={'image'}/>
+                                        </Box>
+                                    )
+                                }
+                                else if (index === 2) {
+                                    return (
+                                        <Box
+                                            key={index}
+                                            sx={{
+                                                width:'60px',
+                                                height:'60px',
+                                                border:'1px solid #616161',
+                                                display: 'flex',
+                                                justifyContent: 'center',
+                                                alignItems: 'center',
+                                                color: '#616161',
+                                                borderRadius: '10px'}}
+                                        >
+                                            +{array.length - 2}
+                                        </Box>
+                                    )
+                                }})
+                            }
+                        </Box>}
+                </Box>
+            </AccordionSummary>
+            <AccordionDetails sx={{padding: '20px'}}>
+                {data['orderGoods'] && data['orderGoods'].length > 0 ?
+                    <>
+                        <Grid container>
+                            <Grid item md={7}>
+                                <Typography
+                                    color='#616161'
+                                    variant='body1'
+                                    letterSpacing='1px'
+                                    textAlign='left'
+                                >
+                                    Product
+                                </Typography>
+                            </Grid>
+                            <Grid item md={2}>
+                                <Typography
+                                    color='#616161'
+                                    variant='body1'
+                                    letterSpacing='1px'
+                                    textAlign='center'
+                                >
+                                    Price
+                                </Typography>
+                            </Grid>
+                            <Grid item md={1}>
+                                <Typography
+                                    color='#616161'
+                                    variant='body1'
+                                    letterSpacing='1px'
+                                    textAlign='center'
+                                >
+                                    Count
+                                </Typography>
+                            </Grid>
+                            <Grid item md={2}>
+                                <Typography
+                                    color='#616161'
+                                    variant='body1'
+                                    letterSpacing='1px'
+                                    textAlign='right'
+                                >
+                                    Sum
+                                </Typography>
+                            </Grid>
+                        </Grid>
+                        <Divider sx={{margin: '10px 0'}}/>
+                        {data['orderGoods'].map((item, index) => {
+                            return (
+                                <Grid
+                                    key={index}
+                                    container
+                                    alignItems='center'
+                                    marginBottom='20px'
+                                >
+                                    <Grid item md={7}>
+                                        <Link
+                                            style={{
+                                                textDecoration: 'none',
+                                                display: 'flex',
+                                                alignItems: 'center',
+                                                color: '#616161'
+                                            }}
+                                            to={`/good/${item?.good?._id}`}
+                                        >
+                                            <Box
+                                                minWidth='60px'
+                                                maxWidth='60px'
+                                                height='60px'
+                                                borderRadius='10px'
+                                                overflow='hidden'
+                                                marginRight='20px'
+                                            >
+                                                <img style={{width: '100%', height: '100%', objectFit: 'cover'}}
+                                                     src={item?.good?.images && item.good.images[0].url ?
+                                                         backURL + '/' + item.good.images[0].url : imgNotFound}
+                                                     alt={'image'}/>
+                                            </Box>
+                                            <Typography
+                                                variant='body1'
+                                            >
+                                                {item.good?.name || 'product name'}
+                                            </Typography>
+                                        </Link>
+                                    </Grid>
+                                    <Grid item md={2}>
+                                        <Typography
+                                            color='#616161'
+                                            variant='body1'
+                                            letterSpacing='1px'
+                                            textAlign='center'
+                                        >
+                                            {item?.price ? '$' + parseFloat(item.price).toFixed(2) : 'NaN'}
+                                        </Typography>
+                                    </Grid>
+                                    <Grid item md={1}>
+                                        <Typography
+                                            color='#616161'
+                                            variant='body1'
+                                            letterSpacing='1px'
+                                            textAlign='center'
+                                        >
+                                            {item?.count || '1'}
+                                        </Typography>
+                                    </Grid>
+                                    <Grid item md={2}>
+                                        <Typography
+                                            color='#616161'
+                                            variant='body1'
+                                            letterSpacing='1px'
+                                            textAlign='right'
+                                        >
+                                            {item?.price && item?.count ? '$'+parseFloat(item.price * item.count)
+                                                .toFixed(2) : 'NaN'
+                                            }
+                                        </Typography>
+                                    </Grid>
+                                </Grid>
+                            )
+                        })}
+                        <Divider sx={{margin: '-10px 0 10px 0'}}/>
+                        <Box
+                            display='flex'
+                            justifyContent='space-between'
+                        >
+                            <Typography
+                                variant='body1'
+                                color='#616161'
+                            >
+                                Total
+                            </Typography>
+                            <Typography
+                                variant='body1'
+                                color='#616161'
+                            >
+                                {data?.total ? '$'+parseFloat(data.total).toFixed(2) : 'NaN'}
+                            </Typography>
+                        </Box>
+                    </> :
+                    <Typography>Error</Typography>
+                }
+            </AccordionDetails>
+        </Accordion>
+    )
+}

+ 92 - 0
src/pages/MyOrdersPage/MainOrders.jsx

@@ -0,0 +1,92 @@
+import {useEffect, useState} from "react";
+import {Box, CircularProgress, Divider, Pagination, Typography} from "@mui/material";
+import {NotFoundBlock} from "../../components/NotFoundBlock";
+import {connect} from "react-redux";
+import {actionFullOrderFind, actionOrderCount} from "../../actions/ActionOrderFind";
+import {actionMyOrderClear} from "../../reducers/MyOrdersReducer";
+import {AccordionItem} from "./AccordionItem";
+
+const MainOrders = ({itemsPerPage=100,
+                        orders,
+                        ordersPreload,
+                        orderCount,
+                        onFindOrders,
+                        onOrdersClear,
+                        onGetCountOrder}) => {
+    const [page, setPage] = useState(1)
+    const [count, setCount] = useState(1)
+    const handleChange = (event, value) => {
+        onOrdersClear()
+        setPage(value);
+        onFindOrders((itemsPerPage * value)-itemsPerPage, itemsPerPage);
+    }
+
+    useEffect(() => {
+        if (Object.entries(orders).length === 0 && page === 1) onFindOrders(null, itemsPerPage)
+        if (!orderCount) onGetCountOrder()
+        else {
+            setCount(Math.ceil(+orderCount?.payload / itemsPerPage))
+        }
+    }, [orders, orderCount])
+
+
+    return (
+        <>
+            {ordersPreload?.status === "PENDING" || Object.entries(orders).length === 0 ?
+                <Box
+                    sx={{
+                        height: '100%',
+                        width: '100%',
+                        display: 'flex',
+                        justifyContent:'center',
+                        alignItems:'center'
+                    }}
+                >
+                    <CircularProgress color="inherit"/>
+                </Box>
+                :
+                Object.entries(orders?.orderResult).length > 0 ?
+                    <Box>
+                        {orderCount?.payload &&
+                            <Typography
+                                variant='h5'
+                                marginBottom='30px'
+                                letterSpacing='3px'
+                            >
+                                Total orders: {orderCount.payload || 0}
+                            </Typography>
+                        }
+                        {Object.values(orders.orderResult)
+                            .map(item => <AccordionItem key={item._id} data={item}/>)
+                        }
+                        <Divider sx={{margin: '20px'}}/>
+                        <Box
+                            display='flex'
+                            justifyContent='center'
+                            width='100%'
+                        >
+                            <Pagination
+                                count={count}
+                                page={page}
+                                onChange={handleChange}
+                                defaultPage={1}
+                                color="primary"
+                                size="large"
+                                showFirstButton
+                                showLastButton
+                            />
+                        </Box>
+                    </Box>
+                    :
+                    <NotFoundBlock
+                        headerText={'OOPS! ORDERS CAN’T BE FOUND'}
+                        text={'No order has been made yet.'}
+                    />
+            }
+        </>
+    )
+}
+export const CMainOrders = connect(state => ({orders: state.myorders,
+        ordersPreload: state.promise['orderFind'], orderCount: state.promise['orderCount']}),
+    {onFindOrders: actionFullOrderFind, onOrdersClear: actionMyOrderClear,
+        onGetCountOrder: actionOrderCount})(MainOrders)

+ 26 - 0
src/pages/MyOrdersPage/MyOrdersPage.jsx

@@ -0,0 +1,26 @@
+import {Container, useMediaQuery} from "@mui/material";
+import Breadcrumb from "../../components/Breadcrumbs";
+import {CMainOrders} from "./MainOrders";
+
+export const MyOrdersPage = () => {
+    const matches = useMediaQuery('(max-width:768px)')
+    return (
+        <>
+            <Breadcrumb links={['My orders']} />
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: '300px'
+                }}
+            >
+                <Container
+                    maxWidth="lg"
+                    sx={{position:'relative'}}
+                >
+                    <CMainOrders />
+                </Container>
+            </main>
+        </>
+    )
+}

+ 0 - 182
src/pages/OurTeamPage.jsx

@@ -1,182 +0,0 @@
-import Breadcrumb from "../components/Breadcrumbs";
-import {Box, Container, Grid, Typography, useMediaQuery} from "@mui/material";
-import FacebookIcon from "@mui/icons-material/Facebook";
-import InstagramIcon from "@mui/icons-material/Instagram";
-import TwitterIcon from "@mui/icons-material/Twitter";
-import YouTubeIcon from "@mui/icons-material/YouTube";
-import Social from "../components/SocialLink";
-import LocalPhoneIcon from '@mui/icons-material/LocalPhone';
-import EmailIcon from '@mui/icons-material/Email';
-import rom from "../img/our team/romb.png"
-import one from "../img/our team/1.jpg"
-import two from "../img/our team/2.jpg"
-import three from "../img/our team/3.jpg"
-import four from "../img/our team/4.jpg"
-
-let defaultTeam = [
-    {
-        img: one,
-        name: 'MARIA CULHANE',
-        spec: 'online seller',
-        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum mollitia nisi nostrum nulla omnis quia, veniam!',
-        links: [
-            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
-            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
-            {icon: TwitterIcon, url: 'https://twitter.com/home'},
-            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
-        ],
-        phone: '+123 456 77 88',
-        email: 'chmoleg@gmail.com'
-    },
-    {
-        img: two,
-        name: 'EMERY HERWITZ',
-        spec: 'online seller',
-        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum mollitia nisi nostrum nulla omnis quia, veniam!',
-        links: [
-            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
-            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
-            {icon: TwitterIcon, url: 'https://twitter.com/home'},
-            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
-        ],
-        phone: '+123 456 77 88',
-        email: 'info@gmail.com'
-    },
-    {
-        img: three,
-        name: 'ALLISON WORKMAN',
-        spec: 'online seller',
-        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum mollitia nisi nostrum nulla omnis quia, veniam!',
-        links: [
-            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
-            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
-            {icon: TwitterIcon, url: 'https://twitter.com/home'},
-            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
-        ],
-        phone: '+123 456 77 88',
-        email: 'info@gmail.com'
-    },
-    {
-        img: four,
-        name: 'MADELYN BATOR',
-        spec: 'online seller',
-        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum mollitia nisi nostrum nulla omnis quia, veniam!',
-        links: [
-            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
-            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
-            {icon: TwitterIcon, url: 'https://twitter.com/home'},
-            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
-        ],
-        phone: '+123 456 77 88',
-        email: 'info@gmail.com'
-    }
-]
-
-const ItemTeam = ({item: {img, name, spec, desc, links, phone, email}, breakpoint}) => {
-    return (
-        <Grid sx={{
-            backgroundColor: '#fff',
-            marginBottom: '50px'
-        }}
-              item xs={12} sm={5.5}
-        >
-            <Box>
-                <img style={{maxWidth: '100%'}} src={img} alt='face'/>
-            </Box>
-            <Box
-                display='flex'
-                flexDirection='column'
-                justifyContent='center'
-                alignItems='center'
-                padding='50px'
-            >
-                <Typography
-                    textAlign="center"
-                    variant='h5'
-                    fontFamily='sarif'
-                    letterSpacing='7px'
-                    marginBottom='10px'
-                >
-                    {name}
-                </Typography>
-                <img style={{
-                    width: '7px',
-                    maxHeight: '7px',
-                }} src={rom} alt='item'/>
-                <Typography
-                    textAlign="center"
-                    variant='body1'
-                    letterSpacing='5px'
-                    marginBottom='10px'
-                    marginTop='8px'
-                    color="#616161"
-                >
-                    {spec}
-                </Typography>
-                <Typography
-                    textAlign="center"
-                    variant='body2'
-                    marginBottom='30px'
-                    fontWeight='300'
-                    color="#616161"
-                    lineHeight='1.7em'
-                >
-                    {desc}
-                </Typography>
-                <Box marginBottom='30px'>
-                    {links.map(item => <Social key={item.url} Icon={item.icon} link={item.url}/>)}
-                </Box>
-                <Box
-                    display='flex'
-                    flexDirection={breakpoint? 'column': 'row'}
-                    justifyContent='space-between'
-                    alignItems='center'
-                    width='100%'
-                >
-                    <Typography
-                        variant='body2'
-                        fontWeight='400'
-                        color="#616161"
-                        display='flex'
-                        flexDirection='row'
-                        justifyContent='space-between'
-                        alignItems='center'
-                        marginBottom={breakpoint ? '15px': '0'}
-                    >
-                        <LocalPhoneIcon sx={{width: '15px', marginRight: '5px'}}/>
-                        {phone}
-                    </Typography>
-                    <Typography
-                        variant='body2'
-                        fontWeight='400'
-                        color="#616161"
-                        display='flex'
-                        flexDirection='row'
-                        justifyContent='space-between'
-                        alignItems='center'
-                    >
-                        <EmailIcon sx={{maxWidth: '15px', marginRight: '5px'}}/>
-                        {email}
-                    </Typography>
-                </Box>
-            </Box>
-        </Grid>
-    )
-}
-
-const OurTeamPage = ({specialist=defaultTeam}) => {
-    const matches = useMediaQuery('(max-width:768px)');
-    return (
-        <>
-            <Breadcrumb links={['our team']}/>
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
-                <Container maxWidth="lg">
-                    <Grid sx={{padding: '0px 0px'}} container justifyContent='space-between'>
-                        {(specialist).map(item => <ItemTeam key={item?.name} item={item} breakpoint={matches}/>)}
-                    </Grid>
-                </Container>
-            </main>
-        </>
-    )
-}
-export default OurTeamPage

+ 100 - 0
src/pages/OurTeamPage/ItemTeam.jsx

@@ -0,0 +1,100 @@
+import {Box, Grid, Typography} from "@mui/material";
+import imgNotFound from "../../img/catalog/imgNotFound.png";
+import romb from "../../img/our-team/romb.png";
+import Social from "../../components/SocialLink";
+import LocalPhoneIcon from "@mui/icons-material/LocalPhone";
+import EmailIcon from "@mui/icons-material/Email";
+
+export const ItemTeam = ({item: {img, name, spec, desc, links, phone, email}, breakpoint}) => {
+    return (
+        <Grid sx={{
+            backgroundColor: '#fff',
+            marginBottom: '50px'
+        }}
+              item xs={12} sm={5.5}
+        >
+            <Box>
+                <img style={{maxWidth: '100%'}} src={img || imgNotFound} alt='face'/>
+            </Box>
+            <Box
+                display='flex'
+                flexDirection='column'
+                justifyContent='center'
+                alignItems='center'
+                padding='50px'
+            >
+                <Typography
+                    textAlign='center'
+                    variant='h5'
+                    fontFamily='sarif'
+                    letterSpacing='7px'
+                    marginBottom='10px'
+                >
+                    { name || 'no name' }
+                </Typography>
+                <img style={{
+                    width: '7px',
+                    maxHeight: '7px',
+                }} src={romb} alt='item'/>
+                <Typography
+                    textAlign='center'
+                    variant='body1'
+                    letterSpacing='5px'
+                    marginBottom='10px'
+                    marginTop='8px'
+                    color='#616161'
+                >
+                    { spec || 'text' }
+                </Typography>
+                <Typography
+                    textAlign='center'
+                    variant='body2'
+                    marginBottom='30px'
+                    fontWeight='300'
+                    color='#616161'
+                    lineHeight='1.7em'
+                >
+                    { desc || 'description' }
+                </Typography>
+                <Box marginBottom='30px'>
+                    {
+                        links.map(item => <Social key={item.url} Icon={item.icon} link={item.url}/>)
+                    }
+                </Box>
+                <Box
+                    display='flex'
+                    flexDirection={breakpoint ? 'column': 'row'}
+                    justifyContent='space-between'
+                    alignItems='center'
+                    width='100%'
+                >
+                    <Typography
+                        variant='body2'
+                        fontWeight='400'
+                        color='#616161'
+                        display='flex'
+                        flexDirection='row'
+                        justifyContent='space-between'
+                        alignItems='center'
+                        marginBottom={breakpoint ? '15px': '0'}
+                    >
+                        <LocalPhoneIcon sx={{width: '15px', marginRight: '5px'}}/>
+                        { phone || 'phone' }
+                    </Typography>
+                    <Typography
+                        variant='body2'
+                        fontWeight='400'
+                        color="#616161"
+                        display='flex'
+                        flexDirection='row'
+                        justifyContent='space-between'
+                        alignItems='center'
+                    >
+                        <EmailIcon sx={{maxWidth: '15px', marginRight: '5px'}}/>
+                        { email || 'email' }
+                    </Typography>
+                </Box>
+            </Box>
+        </Grid>
+    )
+}

+ 103 - 0
src/pages/OurTeamPage/OurTeamPage.jsx

@@ -0,0 +1,103 @@
+import FacebookIcon from "@mui/icons-material/Facebook";
+import InstagramIcon from "@mui/icons-material/Instagram";
+import TwitterIcon from "@mui/icons-material/Twitter";
+import YouTubeIcon from "@mui/icons-material/YouTube";
+import one from "../../img/our-team/1.jpg";
+import two from "../../img/our-team/2.jpg";
+import three from "../../img/our-team/3.jpg";
+import four from "../../img/our-team/4.jpg";
+import {Container, Grid, useMediaQuery} from "@mui/material";
+import Breadcrumb from "../../components/Breadcrumbs";
+import {ItemTeam} from "./ItemTeam";
+
+let defaultTeam = [
+    {
+        img: one,
+        name: 'MARIA CULHANE',
+        spec: 'online seller',
+        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum ' +
+            'mollitia nisi nostrum nulla omnis quia, veniam!',
+        links: [
+            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
+            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
+            {icon: TwitterIcon, url: 'https://twitter.com/home'},
+            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
+        ],
+        phone: '+123 456 77 88',
+        email: 'chmoleg@gmail.com'
+    },
+    {
+        img: two,
+        name: 'EMERY HERWITZ',
+        spec: 'online seller',
+        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum ' +
+            'mollitia nisi nostrum nulla omnis quia, veniam!',
+        links: [
+            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
+            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
+            {icon: TwitterIcon, url: 'https://twitter.com/home'},
+            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
+        ],
+        phone: '+123 456 77 88',
+        email: 'info@gmail.com'
+    },
+    {
+        img: three,
+        name: 'ALLISON WORKMAN',
+        spec: 'online seller',
+        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum ' +
+            'mollitia nisi nostrum nulla omnis quia, veniam!',
+        links: [
+            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
+            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
+            {icon: TwitterIcon, url: 'https://twitter.com/home'},
+            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
+        ],
+        phone: '+123 456 77 88',
+        email: 'info@gmail.com'
+    },
+    {
+        img: four,
+        name: 'MADELYN BATOR',
+        spec: 'online seller',
+        desc: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusamus blanditiis distinctio eum ' +
+            'mollitia nisi nostrum nulla omnis quia, veniam!',
+        links: [
+            {icon: FacebookIcon, url: 'https://www.facebook.com/'},
+            {icon: InstagramIcon, url: 'https://www.instagram.com/'},
+            {icon: TwitterIcon, url: 'https://twitter.com/home'},
+            {icon: YouTubeIcon, url: 'https://www.youtube.com/'},
+        ],
+        phone: '+123 456 77 88',
+        email: 'info@gmail.com'
+    }
+]
+
+export const OurTeamPage = ({specialist=defaultTeam}) => {
+    const matches = useMediaQuery('(max-width:768px)')
+
+    return (
+        <>
+            <Breadcrumb links={['our-team']}/>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: '300px'
+                }}
+            >
+                <Container maxWidth="lg">
+                    <Grid
+                        sx={{padding: '0px 0px'}}
+                        container
+                        justifyContent='space-between'
+                    >
+                        {
+                            (specialist || []).map((item, index) => <ItemTeam key={item?.name || index} item={item || index} breakpoint={matches}/>)
+                        }
+                    </Grid>
+                </Container>
+            </main>
+        </>
+    )
+}

+ 27 - 0
src/pages/PrivacyPolicyPage/BlockPolicy.jsx

@@ -0,0 +1,27 @@
+import {Box, Typography} from "@mui/material";
+
+export const BlockPolicy = ({title, children, breakpoint}) => {
+    return (
+        <Box marginTop='30px'>
+            <Typography
+                variant={breakpoint ? 'h6':'h5'}
+                fontWeight='500'
+                letterSpacing='5px'
+                textAlign='left'
+                marginBottom={breakpoint ? '10px':'25px'}
+            >
+                {title || 'title'}
+            </Typography>
+            <Typography
+                variant='body1'
+                fontWeight='300'
+                marginBottom='40px'
+                color='#616161'
+                textAlign='left'
+                lineHeight='1.7em'
+            >
+                {children || 'children'}
+            </Typography>
+        </Box>
+    )
+}

+ 25 - 0
src/pages/PrivacyPolicyPage/FullBlock.jsx

@@ -0,0 +1,25 @@
+import {Box, Typography} from "@mui/material";
+
+export const FullBlock = ({title, children, breakpoint}) => {
+    return (
+        <Box>
+            <Typography
+                variant={breakpoint ? 'h5': 'h4'}
+                textAlign='center'
+                fontWeight='300'
+                marginBottom='20px'
+                letterSpacing='7px'
+            >
+                {title || 'title'}
+            </Typography>
+            <Typography
+                variant='body1'
+                fontWeight='300'
+                marginBottom='40px'
+                color='#616161'
+            >
+                {children || 'children'}
+            </Typography>
+        </Box>
+    )
+}

+ 17 - 52
src/pages/PrivacyPolicyPage.jsx

@@ -1,63 +1,28 @@
-import Breadcrumbs from "../components/Breadcrumbs";
 import {Box, Container, Link, Typography, useMediaQuery} from "@mui/material";
-
-const FullBlock = ({title, children, breakpoint}) => {
-    return (
-        <Box>
-            <Typography
-                variant={breakpoint ? 'h5': 'h4'}
-                textAlign='center'
-                fontWeight='300'
-                marginBottom='20px'
-                letterSpacing='7px'
-            >
-                {title}
-            </Typography>
-            <Typography
-                variant='body1'
-                fontWeight='300'
-                marginBottom='40px'
-                color='#616161'
-            >
-                {children}
-            </Typography>
-        </Box>
-    )
-}
-const BlockPolicy = ({title, children, breakpoint}) => {
-    return (
-        <Box marginTop='30px'>
-            <Typography
-                variant={breakpoint ? 'h6':'h5'}
-                fontWeight='500'
-                letterSpacing='5px'
-                textAlign='left'
-                marginBottom={breakpoint ? '10px':'25px'}
-            >
-                {title}
-            </Typography>
-            <Typography
-                variant='body1'
-                fontWeight='300'
-                marginBottom='40px'
-                color='#616161'
-                textAlign='left'
-                lineHeight='1.7em'
-            >
-                {children}
-            </Typography>
-        </Box>
-    )
-}
+import Breadcrumbs from "../../components/Breadcrumbs";
+import {FullBlock} from "./FullBlock";
+import {BlockPolicy} from "./BlockPolicy";
 
 const PrivacyPolicy = () => {
     const matches = useMediaQuery('(max-width:768px)');
     return (
         <>
             <Breadcrumbs links={['privacy policy']}/>
-            <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: '300px'
+                }}
+            >
                 <Container maxWidth="lg">
-                    <Box sx={{width: '100%', backgroundColor: '#fff', padding: matches ? '40px 0 20px 0' : '50px 0px'}}>
+                    <Box
+                        sx={{
+                            width: '100%',
+                            backgroundColor: '#fff',
+                            padding: matches ? '40px 0 20px 0' : '50px 0px'
+                        }}
+                    >
                         <Container maxWidth="md">
                             <Typography
                                 variant={matches ? 'h4': 'h3'}

+ 0 - 230
src/pages/ProductPage.jsx

@@ -1,230 +0,0 @@
-import {useEffect, useState} from "react";
-import {connect} from "react-redux";
-import {Box, Button, CircularProgress, Container, Divider, Grid, Paper, Typography, useMediaQuery} from "@mui/material";
-import {actionGoodFindOne} from "../actions/ActionGoodFind";
-import Switch from "react-router-dom/es/Switch";
-import Route from "react-router-dom/es/Route";
-import Page404 from "./404Page";
-import Breadcrumb from "../components/Breadcrumbs";
-import {SetCount} from "../components/SetCount";
-import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
-import Link from "react-router-dom/es/Link";
-import {actionCardChange} from "../reducers/CartReducer";
-import {actionWishListAdd, actionWishListRemove} from "../reducers/WishListReducer";
-import FavoriteIcon from "@mui/icons-material/Favorite";
-import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
-import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
-import Carousel from 'react-material-ui-carousel'
-import {backURL} from "../actions/PathDB";
-import imgNotFound from "../img/catalog/imgNotFound.png";
-
-export const timeCalc = (createdAt) => {
-    let formattedTime;
-    let date = new Date(+createdAt);
-    let year = date.getFullYear();
-    let month = "0" + (date.getMonth()+1);
-    let day = "0" + date.getDate();
-    let hours = "0" + date.getHours();
-    let minutes = "0" + date.getMinutes();
-    let seconds = "0" + date.getSeconds();
-    formattedTime = day.substr(-2) + '.' + month.substr(-2) + '.' + year +
-        ' ' + hours.substr(-2) + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
-    return formattedTime;
-}
-
-const ImageItem = ({images}) => {
-    return (
-        <img src={images && images.url ? backURL + '/' + images.url : imgNotFound} alt={images?.originalFileName ? images.originalFileName.split('.')[0] : 'image'}/>
-    )
-}
-const CarouselItem = ({images}) => {
-    return (
-        <Carousel
-            navButtonsProps={{
-                style: {
-                    backgroundColor: 'transparent',
-                    color: '#000',
-                    borderRadius: 0
-                }
-            }}
-            NextIcon={<ArrowForwardIosIcon/>}
-            PrevIcon={<ArrowBackIosNewIcon/>}
-            fullHeightHover={true}
-        >
-            {
-                images.map((item, index) => <Box key={index} sx={{width: '100%', display: 'flex', justifyContent: 'center', height: '340px'}}><ImageItem key={item._id} images={item} /></Box>)
-            }
-        </Carousel>
-    )
-}
-
-const ProductTitle = ({title}) => {
-    return (
-        <Typography
-            variant='h4'
-            fontFamily='sarif'
-            letterSpacing='4px'
-        >
-            {title || 'PRODUCT TITLE'}
-        </Typography>
-    )
-}
-const ProductPrice = ({price}) => {
-    return (
-        <Typography
-            variant='h5'
-            margin='30px 0'
-        >
-            ${price ? parseFloat(price).toFixed(2) : 0 }
-        </Typography>
-    )
-}
-const ProductDescription = ({description}) => {
-    return (
-        <Typography
-            fontSize='17px'
-            letterSpacing='1px'
-            lineHeight='1.7em'
-            color='#616161'
-            fontWeight='300'
-        >
-            {description || 'PRODUCT DESCRIPTION'}
-        </Typography>
-    )
-}
-const ProductTags = ({title, subtitle}) => {
-    return (
-        <Typography
-            variant='body2'
-            color='#616161'
-            fontWeight='300'
-            marginBottom='10px'
-        >
-            {title}: {Array.isArray(subtitle) ? subtitle.map((item, index) => <span key={index}>{item}{subtitle.length-1 !== index && ", " } </span>) : subtitle}
-        </Typography>
-    )
-}
-
-const AddToCart = ({cart, good, addToCart}) => {
-    let [count, setCount] = useState(cart[good?._id]?.count || 1)
-
-    useEffect(() => {
-        setCount(cart[good?._id]?.count || 1)
-    },[cart])
-
-    console.log(count)
-    return (
-        <Box width='100%' backgroundColor='#fff' padding='30px'>
-            <Grid container justifyContent='space-between'>
-                <Grid xs={5} item>
-                   <SetCount defaultValue={count} onCount={value => setCount(value)}/>
-                </Grid>
-                <Grid xs={5} item>
-                    <Button
-                        sx={{height: '55px', width: '100%', borderRadius: '0', color: '#000', borderColor: '#000', fontSize: '20px', fontWeight: '300'}}
-                        variant="outlined"
-                        color={"inherit"}
-                        onClick={() => addToCart(good, count)}
-                    >
-                        {good._id in cart ? 'CHANGE CART' : 'ADD TO CART'}
-                    </Button>
-                </Grid>
-            </Grid>
-        </Box>
-    )
-}
-const CAddToCart = connect(state=>({cart: state.cart}), {addToCart: actionCardChange})(AddToCart)
-
-const AddToWishList = ({good={}, wishlist ,onAddToWishList, onWishListRemove}) => {
-    const flag = good?._id in wishlist
-    return (
-        <Button size="small"
-                color="inherit"
-                sx={{paddingLeft: '0', margin: '30px 0'}}
-                onClick={() => {flag ? onWishListRemove(good) : onAddToWishList(good)}}
-        >
-            <Typography
-                color='#000'
-                display='flex'
-                alignItems='center'
-                fontSize='13px'
-                fontWeight='600'
-                letterSpacing='2px'
-            >
-                {flag ?
-                    <><FavoriteIcon sx={{marginRight: '10px'}}/> REMOVE FROM WISHLIST</>:
-                    <><FavoriteBorderIcon sx={{marginRight: '10px'}}/> ADD TO WISHLIST</>
-                }
-            </Typography>
-        </Button>
-    )
-}
-const CAddToWishList = connect(state => ({wishlist: state.wishlist}), {onAddToWishList: actionWishListAdd, onWishListRemove: actionWishListRemove})(AddToWishList)
-
-const Goods = ({good}) => {
-    const matches = useMediaQuery('(max-width:768px)');
-
-    return (
-        good && Object.values(good).length > 0  ?
-            <Grid container justifyContent='space-around' padding={matches ? "20px 0" : "50px 0"}>
-                <Grid xs={12} md={6} item padding='5px 70px 5px 10px'>
-                    {Array.isArray(good?.images) && good?.images.length > 1 ? <CarouselItem images={good?.images}/> :
-                        <Box sx={{width: '100%', display: 'flex', justifyContent: 'center', height: '340px'}}>
-                            <ImageItem images={Array.isArray(good?.images) && good?.images[0]}/>
-                        </Box>}
-                    <Divider sx={{margin: '20px 0'}}/>
-                    <ProductDescription description={good?.description}/>
-                </Grid>
-                <Grid xs={12} md={6} item padding='5px 110px 5px 10px'>
-                    <ProductTitle title={good?.name}/>
-                    <ProductPrice price={good?.price}/>
-                    <CAddToCart good={good}/>
-                    <CAddToWishList good={good}/>
-                    <Box>
-                        {good?._id && <ProductTags key={'SKU'} title={'SKU'} subtitle={good?._id}/>}
-                        {Array.isArray(good?.categories) &&
-                            <ProductTags key={'CATEGORY'} title={'CATEGORY'} subtitle={good?.categories.map(item => {
-                                return <Link key={item?._id} style={{color: "#000", textDecoration: 'none'}}
-                                             to={`/catalog/category/${item?._id}`}>{item?.name}</Link>
-                            })}/>
-                        }
-                        {good?.createdAt && <ProductTags key={'TIMEOFCREATION'} title={'TIME OF CREATION'}
-                                                         subtitle={timeCalc(good?.createdAt)}/>}
-                    </Box>
-                </Grid>
-            </Grid>:
-            <Box sx={{height: '100%', width: '100%', display: 'flex', justifyContent:'center', alignItems:'center'}}><CircularProgress color="inherit"/></Box>
-    )
-}
-const CGoods = connect(state => ({good: state.promise['goodFindOne']?.payload}))(Goods)
-
-const BlockProduct = ({match:{params:{_id}}, getData}) => {
-    useEffect(() => {
-        getData(_id)
-    },[_id, getData])
-
-    return(
-        <>
-            <main style={{backgroundColor: "#f3f3f3", minHeight:'300px'}}>
-                <Breadcrumb links={['good']}/>
-                <Container maxWidth="lg">
-                    <CGoods key={_id} />
-                </Container>
-            </main>
-        </>
-    )
-}
-const CBlockProduct = connect(null, {getData: actionGoodFindOne})(BlockProduct)
-
-const ProductPage = () => {
-    return (
-        <Switch>
-            <Route path="/good/:_id" component={CBlockProduct} />
-            <Route path="*" component={Page404} />
-        </Switch>
-    )
-}
-
-export default ProductPage
-
-//TODO MOBILE VERSION

+ 54 - 0
src/pages/ProductPage/AddToCart.jsx

@@ -0,0 +1,54 @@
+import {useEffect, useState} from "react";
+import {Box, Button, Grid} from "@mui/material";
+import {SetCount} from "../../components/SetCount";
+import {connect} from "react-redux";
+import {actionCardChange} from "../../reducers/CartReducer";
+
+const AddToCart = ({cart, good, addToCart}) => {
+    let [count, setCount] = useState(cart[good?._id]?.count || 1)
+
+    useEffect(() => {
+        setCount(cart[good?._id]?.count || 1)
+    },[cart])
+
+    console.log(count)
+    return (
+        <Box
+            width='100%'
+            backgroundColor='#fff'
+            padding='30px'
+        >
+            <Grid
+                container
+                justifyContent='space-between'
+            >
+                <Grid xs={5} item>
+                    <SetCount
+                        defaultValue={count}
+                        onCount={value => setCount(value)}
+                    />
+                </Grid>
+                <Grid xs={5} item>
+                    <Button
+                        sx={{
+                            height: '55px',
+                            width: '100%',
+                            borderRadius: '0',
+                            color: '#000',
+                            borderColor: '#000',
+                            fontSize: '20px',
+                            fontWeight: '300'
+                        }}
+                        variant="outlined"
+                        color={"inherit"}
+                        onClick={() => addToCart(good, count)}
+                    >
+                        {good._id in cart ? 'CHANGE CART' : 'ADD TO CART'}
+                    </Button>
+                </Grid>
+            </Grid>
+        </Box>
+    )
+}
+export const CAddToCart = connect(state=>({cart: state.cart}),
+    {addToCart: actionCardChange})(AddToCart)

+ 41 - 0
src/pages/ProductPage/AddToWishList.jsx

@@ -0,0 +1,41 @@
+import {Button, Typography} from "@mui/material";
+import FavoriteIcon from "@mui/icons-material/Favorite";
+import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
+import {connect} from "react-redux";
+import {actionWishListAdd, actionWishListRemove} from "../../reducers/WishListReducer";
+
+const AddToWishList = ({good={}, wishlist ,onAddToWishList, onWishListRemove}) => {
+    const flag = good?._id in wishlist
+
+    return (
+        <Button
+            size="small"
+            color="inherit"
+            sx={{paddingLeft: '0', margin: '30px 0'}}
+            onClick={() => {flag ? onWishListRemove(good) : onAddToWishList(good)}}
+        >
+            <Typography
+                color='#000'
+                display='flex'
+                alignItems='center'
+                fontSize='13px'
+                fontWeight='600'
+                letterSpacing='2px'
+            >
+                {flag ?
+                    <>
+                        <FavoriteIcon sx={{marginRight: '10px'}}/>
+                        REMOVE FROM WISHLIST
+                    </>
+                    :
+                    <>
+                        <FavoriteBorderIcon sx={{marginRight: '10px'}}/>
+                        ADD TO WISHLIST
+                    </>
+                }
+            </Typography>
+        </Button>
+    )
+}
+export const CAddToWishList = connect(state => ({wishlist: state.wishlist}),
+    {onAddToWishList: actionWishListAdd, onWishListRemove: actionWishListRemove})(AddToWishList)

+ 30 - 0
src/pages/ProductPage/BlockProduct.jsx

@@ -0,0 +1,30 @@
+import {useEffect} from "react";
+import Breadcrumb from "../../components/Breadcrumbs";
+import {Container} from "@mui/material";
+import {connect} from "react-redux";
+import {actionGoodFindOne} from "../../actions/ActionGoodFind";
+import {CGoods} from "./Goods";
+
+const BlockProduct = ({match:{params:{_id}}, getData}) => {
+    useEffect(() => {
+        getData(_id)
+    },[_id, getData])
+
+    return(
+        <>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    minHeight:'300px'
+                }}
+            >
+                <Breadcrumb links={['good']}/>
+                <Container maxWidth="lg">
+                    <CGoods key={_id} />
+                </Container>
+            </main>
+        </>
+    )
+}
+export const CBlockProduct = connect(null,
+    {getData: actionGoodFindOne})(BlockProduct)

+ 41 - 0
src/pages/ProductPage/CarouselItem.jsx

@@ -0,0 +1,41 @@
+import Carousel from "react-material-ui-carousel";
+import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos";
+import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
+import {Box} from "@mui/material";
+import {ImageItem} from "./ImageItem";
+
+export const CarouselItem = ({images}) => {
+    return (
+        <Carousel
+            navButtonsProps={{
+                style: {
+                    backgroundColor: 'transparent',
+                    color: '#000',
+                    borderRadius: 0
+                }
+            }}
+            NextIcon={<ArrowForwardIosIcon/>}
+            PrevIcon={<ArrowBackIosNewIcon/>}
+            fullHeightHover={true}
+        >
+            {
+                images.map((item, index) =>
+                    <Box
+                        key={index}
+                        sx={{
+                            width: '100%',
+                            display: 'flex',
+                            justifyContent: 'center',
+                            height: '340px'
+                        }}
+                    >
+                        <ImageItem
+                            key={item._id}
+                            images={item}
+                        />
+                    </Box>
+                )
+            }
+        </Carousel>
+    )
+}

+ 104 - 0
src/pages/ProductPage/Goods.jsx

@@ -0,0 +1,104 @@
+import {Box, CircularProgress, Divider, Grid, useMediaQuery} from "@mui/material";
+import Link from "react-router-dom/es/Link";
+import {connect} from "react-redux";
+import {CarouselItem} from "./CarouselItem";
+import {ImageItem} from "./ImageItem";
+import {ProductDescription} from "./ProductDescription";
+import {ProductTitle} from "./ProductTitle";
+import {ProductPrice} from "./ProductPrice";
+import {CAddToCart} from "./AddToCart";
+import {CAddToWishList} from "./AddToWishList";
+import {ProductTags} from "./ProductTags";
+import {timeCalc} from "./timeCalc";
+
+const Goods = ({good}) => {
+    const matches = useMediaQuery('(max-width:768px)')
+
+    return (
+        good && Object.values(good).length > 0  ?
+            <Grid
+                container
+                justifyContent='space-around'
+                padding={matches ? "20px 0" : "50px 0"}
+            >
+                <Grid xs={12} md={6}
+                      item
+                      padding='5px 70px 5px 10px'
+                >
+                    {Array.isArray(good?.images) && good?.images.length > 1 ?
+                        <CarouselItem images={good?.images}/>
+                        :
+                        <Box
+                            sx={{
+                                width: '100%',
+                                display: 'flex',
+                                justifyContent: 'center',
+                                height: '340px'
+                            }}
+                        >
+                            <ImageItem images={Array.isArray(good?.images) && good?.images[0]}/>
+                        </Box>
+                    }
+                    <Divider sx={{margin: '20px 0'}}/>
+                    <ProductDescription description={good?.description}/>
+                </Grid>
+                <Grid xs={12} md={6}
+                      item
+                      padding='5px 110px 5px 10px'
+                >
+                    <ProductTitle title={good?.name}/>
+                    <ProductPrice price={good?.price}/>
+                    <CAddToCart good={good}/>
+                    <CAddToWishList good={good}/>
+                    <Box>
+                        {good?._id &&
+                            <ProductTags
+                                key={'SKU'}
+                                title={'SKU'}
+                                subtitle={good?._id}
+                            />
+                        }
+                        {Array.isArray(good?.categories) &&
+                            <ProductTags
+                                key={'CATEGORY'}
+                                title={'CATEGORY'}
+                                subtitle={good?.categories.map(item => {
+                                    return (
+                                        <Link
+                                            key={item?._id}
+                                            style={{
+                                                color: "#000",
+                                                textDecoration: 'none'
+                                            }}
+                                            to={`/catalog/category/${item?._id}`}
+                                        >
+                                            {item?.name}
+                                        </Link>
+                                    )
+                                })}
+                            />
+                        }
+                        {good?.createdAt &&
+                            <ProductTags
+                                key={'TIMEOFCREATION'}
+                                title={'TIME OF CREATION'}
+                                subtitle={timeCalc(good?.createdAt)}
+                            />
+                        }
+                    </Box>
+                </Grid>
+            </Grid>:
+            <Box
+                sx={{
+                    height: '100%',
+                    width: '100%',
+                    display: 'flex',
+                    justifyContent:'center',
+                    alignItems:'center'
+                }}
+            >
+                <CircularProgress color="inherit"/>
+            </Box>
+    )
+}
+export const CGoods = connect(state => ({good: state.promise['goodFindOne']?.payload}))(Goods)

+ 11 - 0
src/pages/ProductPage/ImageItem.jsx

@@ -0,0 +1,11 @@
+import {backURL} from "../../actions/PathDB";
+import imgNotFound from "../../img/catalog/imgNotFound.png";
+
+export const ImageItem = ({images}) => {
+    return (
+        <img
+            src={images && images.url ? backURL + '/' + images.url : imgNotFound}
+            alt={images['originalFileName'] ? images['originalFileName'].split('.')[0] : 'image'}
+        />
+    )
+}

+ 15 - 0
src/pages/ProductPage/ProductDescription.jsx

@@ -0,0 +1,15 @@
+import {Typography} from "@mui/material";
+
+export const ProductDescription = ({description}) => {
+    return (
+        <Typography
+            fontSize='17px'
+            letterSpacing='1px'
+            lineHeight='1.7em'
+            color='#616161'
+            fontWeight='300'
+        >
+            {description || 'PRODUCT DESCRIPTION'}
+        </Typography>
+    )
+}

+ 13 - 0
src/pages/ProductPage/ProductPage.jsx

@@ -0,0 +1,13 @@
+import Switch from "react-router-dom/es/Switch";
+import Route from "react-router-dom/es/Route";
+import Page404 from "../404Page";
+import {CBlockProduct} from "./BlockProduct";
+
+export const ProductPage = () => {
+    return (
+        <Switch>
+            <Route path="/good/:_id" component={CBlockProduct} />
+            <Route path="*" component={Page404} />
+        </Switch>
+    )
+}

+ 12 - 0
src/pages/ProductPage/ProductPrice.jsx

@@ -0,0 +1,12 @@
+import {Typography} from "@mui/material";
+
+export const ProductPrice = ({price}) => {
+    return (
+        <Typography
+            variant='h5'
+            margin='30px 0'
+        >
+            ${ price ? parseFloat(price).toFixed(2) : 0 }
+        </Typography>
+    )
+}

+ 24 - 0
src/pages/ProductPage/ProductTags.jsx

@@ -0,0 +1,24 @@
+import {Typography} from "@mui/material";
+
+export const ProductTags = ({title, subtitle}) => {
+    return (
+        <Typography
+            variant='body2'
+            color='#616161'
+            fontWeight='300'
+            marginBottom='10px'
+        >
+            {title}: {
+                Array.isArray(subtitle) ?
+                    subtitle.map((item, index) =>
+                        <span
+                            key={index}
+                        >
+                            { item }
+                            { subtitle.length-1 !== index && ", " }
+                        </span>)
+                    : subtitle
+            }
+        </Typography>
+    )
+}

+ 13 - 0
src/pages/ProductPage/ProductTitle.jsx

@@ -0,0 +1,13 @@
+import {Typography} from "@mui/material";
+
+export const ProductTitle = ({title}) => {
+    return (
+        <Typography
+            variant='h4'
+            fontFamily='sarif'
+            letterSpacing='4px'
+        >
+            {title || 'PRODUCT TITLE'}
+        </Typography>
+    )
+}

+ 13 - 0
src/pages/ProductPage/timeCalc.js

@@ -0,0 +1,13 @@
+export const timeCalc = (createdAt) => {
+    let formattedTime;
+    let date = new Date(+createdAt);
+    let year = date.getFullYear();
+    let month = "0" + (date.getMonth()+1);
+    let day = "0" + date.getDate();
+    let hours = "0" + date.getHours();
+    let minutes = "0" + date.getMinutes();
+    let seconds = "0" + date.getSeconds();
+    formattedTime = day.substr(-2) + '.' + month.substr(-2) + '.' + year +
+        ' ' + hours.substr(-2) + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
+    return formattedTime;
+}

+ 0 - 280
src/pages/ProfilePage.jsx

@@ -1,280 +0,0 @@
-import Breadcrumb from "../components/Breadcrumbs";
-import {connect} from "react-redux";
-import {Avatar, Box, Button, Container, Grid, TextField, Typography, useMediaQuery} from "@mui/material";
-import Redirect from "react-router-dom/es/Redirect";
-import Tabs from "@mui/material/Tabs";
-import Tab from "@mui/material/Tab";
-import {createRef, useCallback, useEffect, useState} from "react";
-import PropTypes from "prop-types";
-import ManageAccountsIcon from '@mui/icons-material/ManageAccounts';
-import CancelIcon from '@mui/icons-material/Cancel';
-import SendAndArchiveIcon from '@mui/icons-material/SendAndArchive';
-import {actionAuthLogout} from "../reducers/AuthReducer";
-import {actionUserRemove} from "../reducers/UserReducer";
-import {backURL} from "../actions/PathDB";
-import {CMainOrders} from "./MyOrdersPage";
-import {CMainWishList} from "./WishListPage";
-import Dropzone, {useDropzone} from 'react-dropzone';
-import {
-    actionFullUserUpdate,
-    actionSetAvatar,
-    actionSetLogin,
-    actionSetNick, actionSetPassword,
-    actionUploadFile
-} from "../actions/ActionUploadFile";
-import {actionFullUserFindOne} from "../actions/ActionUserFind";
-
-function TabPanel(props) {
-    const { children, value, index, ...other } = props;
-
-    return (
-        <div
-            role="tabpanel"
-            hidden={value !== index}
-            id={`vertical-tabpanel-${index}`}
-            aria-labelledby={`vertical-tab-${index}`}
-            style={{width: '100%'}}
-            {...other}
-        >
-            {value === index && (
-                <Box sx={{ p: 3}}>
-                    <Typography>{children}</Typography>
-                </Box>
-            )}
-        </div>
-    );
-}
-TabPanel.propTypes = {
-    children: PropTypes.node,
-    index: PropTypes.number.isRequired,
-    value: PropTypes.number.isRequired,
-};
-function a11yProps(index) {
-    return {
-        id: `vertical-tab-${index}`,
-        'aria-controls': `vertical-tabpanel-${index}`,
-    };
-}
-
-const ItemTabsAccountDefault = ({title, content}) => {
-    const matches = useMediaQuery('(max-width:899px)')
-
-    return(
-        <Grid item xs={6} sm={4} marginBottom='20px'>
-            <Typography
-                color='#616161'
-                fontWeight='300'
-                marginBottom='5px'
-                fontSize={matches ? '13px' : '16px'}
-            >
-                {title}
-            </Typography>
-            <Typography
-                color='#000'
-                fontWeight='400'
-                fontSize={matches ? '16px' : '22px'}
-            >
-                {content}
-            </Typography>
-        </Grid>
-    )
-}
-const MyDropzone = ({onLoad}) => {
-    const [files, setFiles] = useState([]);
-
-    const {getRootProps, getInputProps, isDragActive} = useDropzone({accept: 'image/*', onDrop: acceptedFiles => {
-            setFiles(acceptedFiles.map(file => Object.assign(file, {
-                preview: URL.createObjectURL(file)
-            })));
-        }})
-
-    const thumbs = files.map(file => (
-        <div key={file.name} style={{display: 'inline-flex', borderRadius: 2,border: '1px solid #eaeaea',marginBottom: 8, marginRight: 8, width: 500, height: 500, padding: 4, boxSizing: 'border-box'}}>
-            <div style={{display: 'flex', minWidth: 0, overflow: 'hidden'}}>
-                <img src={file.preview} style={{display: 'block', width: 'auto', height: '100%', objectFit: 'cover', objectPosition: 'center center'}} alt={'avatar'}/>
-            </div>
-        </div>
-    ));
-
-    useEffect(() => {
-        files.forEach(file => URL.revokeObjectURL(file.preview));
-        onLoad(files)
-    }, [files]);
-
-    return (
-        <section style={{display: 'flex', flexDirection: 'column', justifyContent: 'space-between', alignItems: 'center', width:"100%", borderRadius: '20px', padding: '20px'}}>
-            <div style={{width:"100%", height: "100%", border: '1px dashed #616161', borderRadius: '20px', padding: '20px'}} {...getRootProps()}>
-                <input {...getInputProps()} />
-                {isDragActive ?
-                    <Typography variant='body1' color='#616161'>Drop the file here ...</Typography> :
-                    <Typography variant='body1' color='#616161'>Drag 'n' drop image files here, or click to select file</Typography>
-                }
-                <aside>
-                    {thumbs}
-                </aside>
-            </div>
-        </section>
-    )
-}
-
-const FormUpload = ({user, setStatus, setLogin, setNick, setPassword, setImage}) => {
-    const [loginValue, setLoginValue] = useState(user?.login || '')
-    const [nickValue, setNickValue] = useState(user?.nick || '')
-    const [passwordValue, setPasswordValue] = useState('')
-    const [fileValue, setFileValue] = useState('')
-    return (
-            <Grid container spacing={2} justifyContent={'center'} textAlign='center' flexDirection='column'>
-                <Grid item xs={12} display='flex' justifyContent='space-between' alignItems='center' marginBottom='30px'>
-                    <TextField sx={{color: '#000'}} label={'Login'} variant="outlined" placeholder={user?.login || ''} onChange={e => setLoginValue(e.target.value)}/>
-                    <TextField sx={{color: '#000'}} label={'Nick'} variant="outlined" placeholder={user?.nick || ''} onChange={e => setNickValue(e.target.value)}/>
-                    <TextField sx={{color: '#000'}} label={'Password'} type='password' variant="outlined" onChange={e => setPasswordValue(e.target.value)}/>
-                </Grid>
-                <Grid item xs={12} display='flex' justifyContent='space-between' alignItems='center' marginBottom='30px'>
-                    <MyDropzone onLoad={value => setFileValue(value)}/>
-                </Grid>
-                <Grid item xs={12} display='flex' justifyContent='center' alignItems='center'>
-                    <Button
-                        style={{ color: '#1976d2'}}
-                        fullWidth
-                        type='submit'
-                        onClick={() => {
-                            if (loginValue !== user?.login) {
-                                setLogin(loginValue)
-                            }
-                            if (nickValue !== user?.nick) {
-                                setNick(nickValue)
-                            }
-                            if (passwordValue){
-                                setPassword(passwordValue)
-                            }
-                            if (Array.isArray(fileValue) && fileValue[0]) {
-                                setImage(fileValue[0]);
-                            }
-                            setStatus(false)
-                        }}
-                    >
-                        <SendAndArchiveIcon style={{marginRight: '5px'}}/>
-                        Save
-                    </Button>
-                    <Button
-                        style={{ color: '#1976d2'}}
-                        fullWidth
-                        onClick={() => setStatus(false)}
-                    >
-                        <CancelIcon style={{marginRight: '5px'}}/>
-                        Cancel
-                    </Button>
-                </Grid>
-            </Grid>
-    )
-}
-const CFormUpload = connect(null, {setLogin: actionSetLogin, setNick: actionSetNick, setPassword: actionSetPassword, setImage: actionSetAvatar, userUpdate: actionFullUserFindOne})(FormUpload)
-
-const AccountDetails = ({promise, user, time}) => {
-    const [status, setStatus] = useState(false)
-
-    return (
-        !status ?
-            <Grid container spacing={2} justifyContent={'space-between'} alignItems={'center'} textAlign={'center'}>
-                <ItemTabsAccountDefault title={'Login'} content={user?.login}/>
-                <ItemTabsAccountDefault title={'Nick'} content={user?.nick}/>
-                <ItemTabsAccountDefault title={'Status account'} content={user?.acl[2] || user?.acl[1]}/>
-                <ItemTabsAccountDefault title={'Account creation date'} content={time}/>
-                <ItemTabsAccountDefault title={'Avatar'}
-                                 content={
-                                     (user?.avatar?.url ? <Avatar style={{margin: '0 auto'}} alt="User" src={backURL + '/' + user?.avatar?.url}/> : 'Not installed')
-                                 }
-                />
-                <Grid item xs={12} md={4}>
-                    <Typography
-                        sx={{cursor: 'pointer'}}
-                        color={'#1976d2'}
-                        display='flex'
-                        justifyContent='center'
-                        alignItems='center'
-                        variant='h6'
-                        onClick={() => setStatus(true)}
-                    >
-                        <ManageAccountsIcon style={{marginRight: '10px'}}/>
-                        Edit data
-                    </Typography>
-                </Grid>
-                {!promise.setNewLogin?.payload && promise.setNewLogin?.status === 'RESOLVED' && <Typography width='100%' textAlign='center' color='red'>this login already exists</Typography>}
-            </Grid> :
-            <CFormUpload user={user} setStatus={value => setStatus(value)}/>
-    )
-}
-
-const ProfilePage = ({user = {}, promise, authLogOut, userLogOut}) => {
-    const matches = useMediaQuery('(max-width:899px)')
-    const matches2 = useMediaQuery('(max-width:768px)')
-    const [value, setValue] = useState(0)
-
-    const handleChange = (event, newValue) => {
-        setValue(newValue);
-    };
-
-    let formattedTime = 0;
-    if (Object.keys(user).length !== 0) {
-        let date = new Date(+user.createdAt);
-        let year = date.getFullYear();
-        let month = "0" + (date.getMonth()+1);
-        let day = "0" + date.getDate();
-        let hours = "0" + date.getHours();
-        let minutes = "0" + date.getMinutes();
-        let seconds = "0" + date.getSeconds();
-        formattedTime = day.substr(-2) + '.' + month.substr(-2) + '.' + year +
-            ' ' + hours.substr(-2) + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
-    }
-
-    return (
-        Object.keys(user).length > 1 &&
-            <>
-                <Breadcrumb links={['Profile']}/>
-                <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
-                    <Container maxWidth="lg">
-                        <Box>
-                            <Typography
-                                variant='h5'
-                                textAlign='center'
-                                fontFamily='sarif'
-                                marginBottom={matches ? '20px':'40px'}
-                            >
-                                LOGGED IN AS <strong>{user.login.toUpperCase()}</strong>
-                            </Typography>
-                        </Box>
-                        <Box
-                            sx={{ flexGrow: 1, bgcolor: '#fff', display: 'flex', height: '100%', alignItems: 'center'}}
-                            flexDirection={matches2 ? 'column': "row"}
-                        >
-                            <Tabs
-                                orientation={matches2 ? 'horizontal': "vertical"}
-                                variant="scrollable"
-                                value={value}
-                                onChange={handleChange}
-                                aria-label="Profile settings"
-                                sx={{ borderRight: 1, borderColor: 'divider', padding: '50px 0', height: '100%'}}
-                            >
-                                <Tab sx={{padding: '0 50px', textAlign: 'center'}} label={'ACCOUNT DETAILS'} {...a11yProps(0)} />
-                                <Tab sx={{padding: '0 50px', textAlign: 'center'}} label={'my orders'} {...a11yProps(1)} />
-                                <Tab sx={{padding: '0 50px', textAlign: 'center'}} label={'wish list'} {...a11yProps(2)} />
-                                <Button onClick={() => {authLogOut(); userLogOut()}}>Logout</Button>
-                            </Tabs>
-                            <TabPanel value={value} index={0}>
-                                <AccountDetails user={user} promise={promise} time={formattedTime}/>
-                            </TabPanel>
-                            <TabPanel value={value} index={1}>
-                                <CMainOrders itemsPerPage={5}/>
-                            </TabPanel>
-                            <TabPanel value={value} index={2}>
-                                <CMainWishList color={'#fff'}/>
-                            </TabPanel>
-                        </Box>
-                    </Container>
-                </main>
-            </>
-    )
-}
-const CProfilePage = connect(state => ({user: state.user, promise: state.promise}), {authLogOut: actionAuthLogout, userLogOut: actionUserRemove})(ProfilePage)
-
-export default CProfilePage

+ 79 - 0
src/pages/ProfilePage/AccountDetails.jsx

@@ -0,0 +1,79 @@
+import {useState} from "react";
+import {Avatar, Grid, Typography} from "@mui/material";
+import {backURL} from "../../actions/PathDB";
+import ManageAccountsIcon from "@mui/icons-material/ManageAccounts";
+import {ItemTabsAccountDefault} from "./ItemTabsAccountDefault";
+import {CFormUpload} from "./FormUpload";
+
+export const AccountDetails = ({promise, user, time}) => {
+    const [status, setStatus] = useState(false)
+
+    return (
+        !status ?
+            <Grid
+                container
+                spacing={2}
+                justifyContent='space-between'
+                alignItems='center'
+                textAlign='center'
+            >
+                <ItemTabsAccountDefault
+                    title={'Login'}
+                    content={user?.login}
+                />
+                <ItemTabsAccountDefault
+                    title={'Nick'}
+                    content={user?.nick}
+                />
+                <ItemTabsAccountDefault
+                    title={'Status account'}
+                    content={user?.acl[2] || user?.acl[1]}
+                />
+                <ItemTabsAccountDefault
+                    title={'Account creation date'}
+                    content={time}
+                />
+                <ItemTabsAccountDefault
+                    title={'Avatar'}
+                    content={
+                        (user?.avatar?.url ?
+                                <Avatar
+                                    style={{margin: '0 auto'}}
+                                    alt="User"
+                                    src={backURL + '/' + user?.avatar?.url}
+                                />
+                                : 'Not installed'
+                        )
+                    }
+                />
+                <Grid item xs={12} md={4}>
+                    <Typography
+                        sx={{cursor: 'pointer'}}
+                        color={'#1976d2'}
+                        display='flex'
+                        justifyContent='center'
+                        alignItems='center'
+                        variant='h6'
+                        onClick={() => setStatus(true)}
+                    >
+                        <ManageAccountsIcon style={{marginRight: '10px'}}/>
+                        Edit data
+                    </Typography>
+                </Grid>
+                {!promise['setNewLogin']?.payload && promise['setNewLogin']?.status === 'RESOLVED' &&
+                    <Typography
+                        width='100%'
+                        textAlign='center'
+                        color='red'
+                    >
+                        this login already exists
+                    </Typography>
+                }
+            </Grid>
+            :
+            <CFormUpload
+                user={user}
+                setStatus={value => setStatus(value)}
+            />
+    )
+}

+ 104 - 0
src/pages/ProfilePage/FormUpload.jsx

@@ -0,0 +1,104 @@
+import {useState} from "react";
+import {Button, Grid, TextField} from "@mui/material";
+import SendAndArchiveIcon from "@mui/icons-material/SendAndArchive";
+import CancelIcon from "@mui/icons-material/Cancel";
+import {connect} from "react-redux";
+import {actionSetAvatar, actionSetLogin, actionSetNick, actionSetPassword} from "../../actions/ActionUploadFile";
+import {actionFullUserFindOne} from "../../actions/ActionUserFind";
+import {MyDropzone} from "./MyDropzone";
+
+const FormUpload = ({user, setStatus, setLogin, setNick, setPassword, setImage}) => {
+    const [loginValue, setLoginValue] = useState(user?.login || '')
+    const [nickValue, setNickValue] = useState(user?.nick || '')
+    const [passwordValue, setPasswordValue] = useState('')
+    const [fileValue, setFileValue] = useState('')
+    return (
+        <Grid
+            container
+            spacing={2}
+            justifyContent='center'
+            textAlign='center'
+            flexDirection='column'
+        >
+            <Grid
+                item xs={12}
+                display='flex'
+                justifyContent='space-between'
+                alignItems='center'
+                marginBottom='30px'
+            >
+                <TextField
+                    sx={{color: '#000'}}
+                    label={'Login'}
+                    variant="outlined"
+                    placeholder={user?.login || ''}
+                    onChange={e => setLoginValue(e.target.value)}
+                />
+                <TextField
+                    sx={{color: '#000'}}
+                    label={'Nick'}
+                    variant="outlined"
+                    placeholder={user?.nick || ''}
+                    onChange={e => setNickValue(e.target.value)}
+                />
+                <TextField
+                    sx={{color: '#000'}}
+                    label={'Password'}
+                    type='password'
+                    variant="outlined"
+                    onChange={e => setPasswordValue(e.target.value)}
+                />
+            </Grid>
+            <Grid
+                item xs={12}
+                display='flex'
+                justifyContent='space-between'
+                alignItems='center'
+                marginBottom='30px'
+            >
+                <MyDropzone onLoad={value => setFileValue(value)}/>
+            </Grid>
+            <Grid
+                item xs={12}
+                display='flex'
+                justifyContent='center'
+                alignItems='center'
+            >
+                <Button
+                    style={{ color: '#1976d2'}}
+                    fullWidth
+                    type='submit'
+                    onClick={() => {
+                        if (loginValue !== user?.login) {
+                            setLogin(loginValue)
+                        }
+                        if (nickValue !== user?.nick) {
+                            setNick(nickValue)
+                        }
+                        if (passwordValue){
+                            setPassword(passwordValue)
+                        }
+                        if (Array.isArray(fileValue) && fileValue[0]) {
+                            setImage(fileValue[0]);
+                        }
+                        setStatus(false)
+                    }}
+                >
+                    <SendAndArchiveIcon style={{marginRight: '5px'}}/>
+                    Save
+                </Button>
+                <Button
+                    style={{ color: '#1976d2'}}
+                    fullWidth
+                    onClick={() => setStatus(false)}
+                >
+                    <CancelIcon style={{marginRight: '5px'}}/>
+                    Cancel
+                </Button>
+            </Grid>
+        </Grid>
+    )
+}
+export const CFormUpload = connect(null, {setLogin: actionSetLogin,
+    setNick: actionSetNick, setPassword: actionSetPassword, setImage: actionSetAvatar,
+    userUpdate: actionFullUserFindOne})(FormUpload)

+ 34 - 0
src/pages/ProfilePage/ItemTabsAccountDefault.jsx

@@ -0,0 +1,34 @@
+import {Box, Grid, Typography, useMediaQuery} from "@mui/material";
+
+export const ItemTabsAccountDefault = ({title, content}) => {
+    const matches = useMediaQuery('(max-width:899px)')
+
+    return(
+        <Grid
+            item xs={6} sm={4}
+            marginBottom='20px'
+        >
+            <Typography
+                color='#616161'
+                fontWeight='300'
+                marginBottom='5px'
+                fontSize={matches ? '13px' : '16px'}
+            >
+                {title || 'title'}
+            </Typography>
+            {typeof content === "string" ?
+                <Typography
+                    color='#000'
+                    fontWeight='400'
+                    fontSize={matches ? '16px' : '22px'}
+                >
+                    {content || 'content'}
+                </Typography>
+                :
+                <Box>
+                    {content}
+                </Box>
+            }
+        </Grid>
+    )
+}

+ 101 - 0
src/pages/ProfilePage/MyDropzone.jsx

@@ -0,0 +1,101 @@
+import {useEffect, useState} from "react";
+import {useDropzone} from "react-dropzone";
+import {Box, Typography} from "@mui/material";
+
+export const MyDropzone = ({onLoad}) => {
+    const [files, setFiles] = useState([]);
+
+    const {getRootProps, getInputProps, isDragActive} = useDropzone({
+        accept: 'image/*', onDrop: acceptedFiles => {
+            setFiles(acceptedFiles.map(file => Object.assign(file, {
+                preview: URL.createObjectURL(file)
+            })));
+        }})
+
+    const thumbs = files.map(file => (
+        <Box
+            key={ file.name }
+            style={{
+                display: 'inline-flex',
+                borderRadius: 2,
+                border: '1px solid #eaeaea',
+                marginBottom: 8,
+                marginRight: 8,
+                width: 500,
+                height: 500,
+                padding: 4,
+                boxSizing: 'border-box'
+            }}
+        >
+            <Box
+                style={{
+                    display: 'flex',
+                    minWidth: 0,
+                    overflow: 'hidden'
+                }}
+            >
+                <img
+                    src={file.preview}
+                    style={{
+                        display: 'block',
+                        width: 'auto',
+                        height: '100%',
+                        objectFit: 'cover',
+                        objectPosition: 'center center'
+                    }}
+                    alt={file.name}
+                />
+            </Box>
+        </Box>
+    ));
+
+    useEffect(() => {
+        files.forEach(file => URL.revokeObjectURL(file.preview));
+        onLoad(files)
+    }, [files]);
+
+    return (
+        <section
+            style={{
+                display: 'flex',
+                flexDirection: 'column',
+                justifyContent: 'space-between',
+                alignItems: 'center',
+                width:"100%",
+                borderRadius: '20px',
+                padding: '20px'
+            }}
+        >
+            <Box
+                style={{
+                    width:"100%",
+                    height: "100%",
+                    border: '1px dashed #616161',
+                    borderRadius: '20px',
+                    padding: '20px'
+                }}
+                {...getRootProps()}
+            >
+                <input {...getInputProps()} />
+                {isDragActive ?
+                    <Typography
+                        variant='body1'
+                        color='#616161'
+                    >
+                        Drop the file here ...
+                    </Typography>
+                    :
+                    <Typography
+                        variant='body1'
+                        color='#616161'
+                    >
+                        Drag 'n' drop image files here, or click to select file
+                    </Typography>
+                }
+                <aside>
+                    {thumbs}
+                </aside>
+            </Box>
+        </section>
+    )
+}

+ 179 - 0
src/pages/ProfilePage/ProfilePage.jsx

@@ -0,0 +1,179 @@
+import {Box, Container, Typography, useMediaQuery} from "@mui/material";
+import PropTypes from "prop-types";
+import {useState} from "react";
+import {timeCalc} from "../ProductPage/timeCalc";
+import Breadcrumb from "../../components/Breadcrumbs";
+import Tabs from "@mui/material/Tabs";
+import Tab from "@mui/material/Tab";
+import {CMainOrders} from "../MyOrdersPage/MainOrders";
+import {CMainWishList} from "../WishListPage/MainWishList";
+import {connect} from "react-redux";
+import {actionAuthLogout} from "../../reducers/AuthReducer";
+import {actionUserRemove} from "../../reducers/UserReducer";
+import {AccountDetails} from "./AccountDetails";
+
+function TabPanel(props) {
+    const { children, value, index, ...other } = props;
+
+    return (
+        <div
+            role="tabpanel"
+            hidden={value !== index}
+            id={`vertical-tabpanel-${index}`}
+            aria-labelledby={`vertical-tab-${index}`}
+            style={{width: '100%'}}
+            {...other}
+        >
+            {value === index && (
+                <Box sx={{ p: 3}}>
+                    <Box>
+                        {children}
+                    </Box>
+                </Box>
+            )}
+        </div>
+    );
+}
+TabPanel.propTypes = {
+    children: PropTypes.node,
+    index: PropTypes.number.isRequired,
+    value: PropTypes.number.isRequired,
+};
+function a11yProps(index) {
+    return {
+        id: `vertical-tab-${index}`,
+        'aria-controls': `vertical-tabpanel-${index}`,
+    };
+}
+
+const ProfilePage = ({user = {}, promise, authLogOut, userLogOut}) => {
+    const matches = useMediaQuery('(max-width:899px)')
+    const matches2 = useMediaQuery('(max-width:768px)')
+    const [value, setValue] = useState(0)
+
+    const handleChange = (event, newValue) => {
+        setValue(newValue);
+    };
+
+    let formattedTime = 0;
+    if (Object.keys(user).length !== 0) {
+        formattedTime = timeCalc(+user.createdAt);
+    }
+
+    const handleLogOut = () => {
+        authLogOut();
+        userLogOut();
+    }
+    return (
+        Object.keys(user).length > 1 &&
+        <>
+            <Breadcrumb links={['Profile']}/>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight:'300px'
+                }}
+            >
+                <Container maxWidth="lg">
+                    <Box>
+                        <Typography
+                            variant='h5'
+                            textAlign='center'
+                            fontFamily='sarif'
+                            marginBottom={matches ? '20px':'40px'}
+                        >
+                            LOGGED IN AS
+                            <strong>
+                                { ` ${user?.login.toUpperCase()}` || 'login' }
+                            </strong>
+                        </Typography>
+                    </Box>
+                    <Box
+                        sx={{
+                            flexGrow: 1,
+                            bgcolor: '#fff',
+                            display: 'flex',
+                            height: '100%',
+                            alignItems: 'center'
+                        }}
+                        flexDirection={matches2 ? 'column': "row"}
+                    >
+                        <Tabs
+                            orientation={matches2 ? 'horizontal': "vertical"}
+                            variant="scrollable"
+                            value={value}
+                            onChange={handleChange}
+                            aria-label="Profile settings"
+                            sx={{
+                                borderRight: 1,
+                                borderColor: 'divider',
+                                padding: '50px 0',
+                                height: '100%'
+                            }}
+                        >
+                            <Tab
+                                sx={{
+                                    padding: '0 50px',
+                                    textAlign: 'center'
+                                }}
+                                label={'ACCOUNT DETAILS'}
+                                {...a11yProps(0)}
+                            />
+                            <Tab
+                                sx={{
+                                    padding: '0 50px',
+                                    textAlign: 'center'
+                                }}
+                                label={'my orders'}
+                                {...a11yProps(1)}
+                            />
+                            <Tab
+                                sx={{
+                                    padding: '0 50px',
+                                    textAlign: 'center'
+                                }}
+                                label={'wish list'}
+                                {...a11yProps(2)}
+                            />
+                            <Tab
+                                sx={{
+                                    padding: '0 50px',
+                                    textAlign: 'center'
+                                }}
+                                label={'Logout'}
+                                onClick={handleLogOut}
+                                {...a11yProps(2)}
+                            />
+                        </Tabs>
+                        <TabPanel
+                            value={value}
+                            index={0}
+                        >
+                            <AccountDetails
+                                user={user}
+                                promise={promise}
+                                time={formattedTime}
+                            />
+                        </TabPanel>
+                        <TabPanel
+                            value={value}
+                            index={1}
+                        >
+                            <CMainOrders itemsPerPage={5} />
+                        </TabPanel>
+                        <TabPanel
+                            value={value}
+                            index={2}
+                        >
+                            <CMainWishList color={'#fff'}/>
+                        </TabPanel>
+                    </Box>
+                </Container>
+            </main>
+        </>
+    )
+}
+export const CProfilePage = connect(state => ({user: state.user, promise: state.promise}),
+    {authLogOut: actionAuthLogout, userLogOut: actionUserRemove})(ProfilePage)
+

+ 0 - 116
src/pages/SearchPage.jsx

@@ -1,116 +0,0 @@
-import {
-    Box,
-    CircularProgress,
-    Container,
-    IconButton,
-    InputAdornment,
-    TextField,
-    Typography,
-    useMediaQuery
-} from "@mui/material";
-import SearchIcon from "@material-ui/icons/Search";
-import {connect} from "react-redux";
-import {actionFullGoodFind} from "../actions/ActionGoodFind";
-import {useState} from "react";
-import {backURL} from "../actions/PathDB";
-import imgNotFound from "../img/catalog/imgNotFound.png";
-import Link from "react-router-dom/es/Link";
-import {actionSearchRemove} from "../reducers/SearchReducer";
-
-const NotFound = () => {
-    return (
-        <Typography
-            textAlign='center'
-            color='#000'
-            letterSpacing='1px'
-            variant='body1'
-        >
-            No results found
-        </Typography>
-    )
-}
-const ItemFound = ({item:{_id, name, price, images, description}}) => {
-    return (
-        <Link style={{textDecoration: 'none', display: 'flex', alignItems: 'center', marginBottom: '30px'}} to={`/good/${_id}`}>
-            <Box width='60px' height='60px' borderRadius='10px' overflow='hidden' marginRight='60px' position='relative'>
-                <img style={{position: 'absolute',top: '0', left: '0', width: '100%', height: '100%', objectFit: 'cover'}} src={images[0]?.url ? backURL + '/' + images[0]?.url : imgNotFound} alt={name}/>
-            </Box>
-            <Box sx={{display: 'flex', flexDirection:'column', justifyContent: 'space-between', alignItems:'flex-start'}}>
-                <Typography
-                    color='#000'
-                    letterSpacing='1px'
-                    fontFamily='sarif'
-                    fontWeight='600'
-                    variant='h6'
-                >
-                    {name}
-                </Typography>
-                <Typography
-                    letterSpacing='1px'
-                    variant='body1'
-                    fontWeight='300'
-                    color='#616161'
-                    margin='10px 0'
-                >
-                    {description.length > 60 ? 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' : description}
-                </Typography>
-                <Typography
-                    color='#000'
-                    letterSpacing='1px'
-                    variant='body1'
-                    fontWeight='600'
-                >
-                    ${parseFloat(price).toFixed(2)}
-                </Typography>
-            </Box>
-        </Link>
-    )
-}
-
-const SearchPage = ({searchResult, onSearch, onSearchRemove}) => {
-    const matches = useMediaQuery('(max-width:899px)')
-    const [value, setValue] = useState('')
-    const [click, setClick] = useState(false)
-    return(
-        <>
-            <main style={{backgroundColor: "#f3f3f3", marginTop: '85px', padding: matches ? "20px 0" : "50px 0", minHeight: 'calc(100vh - (185px + 290px))'}}>
-                <Container maxWidth="sm">
-                    <Typography
-                        variant='h5'
-                        fontFamily='sarif'
-                        letterSpacing='3px'
-                        marginBottom='30px'
-                    >
-                        WHAT YOU ARE LOOKING FOR?
-                    </Typography>
-                    <TextField
-                        color={'primary'}
-                        fullWidth
-                        variant="standard"
-                        value={value}
-                        placeholder="Start typing..."
-                        onChange={(event) => {setClick(false); setValue(event.target.value); onSearchRemove()}}
-                        InputProps={{
-                            sx: {padding: '10px', outline:'none', color: '#616161', fontWeight: '300', letterSpacing: '1px', marginBottom: '50px'},
-                            endAdornment: (
-                                <InputAdornment position="end">
-                                    <IconButton onClick={() => {setClick(true); onSearchRemove(); onSearch(value)}}>
-                                        <SearchIcon />
-                                    </IconButton>
-                                </InputAdornment>
-                            )
-                        }}
-                    />
-                    {(value !== '' && click) && (searchResult?.searchResult ?
-                        Object.values(searchResult.searchResult).length > 0  ?
-                            Object.values(searchResult.searchResult).map(item => <ItemFound item={item}/>) : <NotFound/> :
-                        <CircularProgress color="inherit"/>
-                    )}
-                </Container>
-            </main>
-        </>
-    )
-}
-const CSearchPage = connect(state=>({searchResult: state.search}), {onSearch: actionFullGoodFind, onSearchRemove: actionSearchRemove})(SearchPage)
-export default CSearchPage
-// TODO MOBILE VERSION

+ 79 - 0
src/pages/SearchPage/ItemFound.jsx

@@ -0,0 +1,79 @@
+import Link from "react-router-dom/es/Link";
+import {Box, Typography} from "@mui/material";
+import {backURL} from "../../actions/PathDB";
+import imgNotFound from "../../img/catalog/imgNotFound.png";
+
+export const ItemFound = ({item:{_id, name, price, images, description}}) => {
+    return (
+        <Link
+            style={{
+                textDecoration: 'none',
+                display: 'flex',
+                alignItems: 'center',
+                marginBottom: '30px'
+            }}
+            to={`/good/${_id}`}
+        >
+            <Box
+                width='60px'
+                height='60px'
+                borderRadius='10px'
+                overflow='hidden'
+                marginRight='60px'
+                position='relative'
+            >
+                <img
+                    style={{
+                        position: 'absolute',
+                        top: '0',
+                        left: '0',
+                        width: '100%',
+                        height: '100%',
+                        objectFit: 'cover'
+                    }}
+                    src={Array.isArray(images) && images[0]?.url ? backURL + '/' + images[0]?.url : imgNotFound}
+                    alt={name}
+                />
+            </Box>
+            <Box
+                sx={{
+                    display: 'flex',
+                    flexDirection:'column',
+                    justifyContent: 'space-between',
+                    alignItems:'flex-start'
+                }}
+            >
+                <Typography
+                    color='#000'
+                    letterSpacing='1px'
+                    fontFamily='sarif'
+                    fontWeight='600'
+                    variant='h6'
+                >
+                    {name || 'name'}
+                </Typography>
+                <Typography
+                    letterSpacing='1px'
+                    variant='body1'
+                    fontWeight='300'
+                    color='#616161'
+                    margin='10px 0'
+                >
+                    {
+                        description.length > 60 ?
+                            'Lorem ipsum dolor sit amet, consectetur adipisicing elit.'
+                            : description
+                    }
+                </Typography>
+                <Typography
+                    color='#000'
+                    letterSpacing='1px'
+                    variant='body1'
+                    fontWeight='600'
+                >
+                    ${parseFloat(price || 0).toFixed(2)}
+                </Typography>
+            </Box>
+        </Link>
+    )
+}

+ 14 - 0
src/pages/SearchPage/NotFound.jsx

@@ -0,0 +1,14 @@
+import {Typography} from "@mui/material";
+
+export const NotFound = () => {
+    return (
+        <Typography
+            textAlign='center'
+            color='#000'
+            letterSpacing='1px'
+            variant='body1'
+        >
+            No results found
+        </Typography>
+    )
+}

+ 89 - 0
src/pages/SearchPage/SearchPage.jsx

@@ -0,0 +1,89 @@
+import {
+    CircularProgress,
+    Container,
+    IconButton,
+    InputAdornment,
+    TextField,
+    Typography,
+    useMediaQuery
+} from "@mui/material";
+import {useState} from "react";
+import SearchIcon from "@material-ui/icons/Search";
+import {connect} from "react-redux";
+import {actionFullGoodFind} from "../../actions/ActionGoodFind";
+import {actionSearchRemove} from "../../reducers/SearchReducer";
+import {ItemFound} from "./ItemFound";
+import {NotFound} from "./NotFound";
+
+const SearchPage = ({searchResult, onSearch, onSearchRemove}) => {
+    const matches = useMediaQuery('(max-width:899px)')
+    const [value, setValue] = useState('')
+    const [click, setClick] = useState(false)
+
+    return(
+        <>
+            <main
+                style={{
+                    backgroundColor: "#f3f3f3",
+                    marginTop: '85px',
+                    padding: matches ? "20px 0" : "50px 0",
+                    minHeight: 'calc(100vh - (185px + 290px))'
+                }}
+            >
+                <Container maxWidth="sm">
+                    <Typography
+                        variant='h5'
+                        fontFamily='sarif'
+                        letterSpacing='3px'
+                        marginBottom='30px'
+                    >
+                        WHAT YOU ARE LOOKING FOR?
+                    </Typography>
+                    <TextField
+                        color={'primary'}
+                        fullWidth
+                        variant="standard"
+                        value={value}
+                        placeholder="Start typing..."
+                        onChange={(event) => {
+                            setClick(false);
+                            setValue(event.target.value);
+                            onSearchRemove()}
+                        }
+                        InputProps={{
+                            sx: {
+                                padding: '10px',
+                                outline:'none',
+                                color: '#616161',
+                                fontWeight: '300',
+                                letterSpacing: '1px',
+                                marginBottom: '50px'},
+                            endAdornment: (
+                                <InputAdornment position="end">
+                                    <IconButton onClick={() => {
+                                        setClick(true);
+                                        onSearchRemove();
+                                        onSearch(value)}
+                                    }>
+                                        <SearchIcon />
+                                    </IconButton>
+                                </InputAdornment>
+                            )
+                        }}
+                    />
+                    {(value !== '' && click) && (searchResult?.searchResult ?
+                            Object.values(searchResult.searchResult).length > 0  ?
+                                Object.values(searchResult.searchResult).map((item, index) =>
+                                    <ItemFound key={index} item={item}/>
+                                )
+                                : <NotFound/>
+                            : <CircularProgress color="inherit"/>
+                    )}
+                </Container>
+            </main>
+        </>
+    )
+}
+const CSearchPage = connect(state => ({searchResult: state.search}),
+    {onSearch: actionFullGoodFind, onSearchRemove: actionSearchRemove})(SearchPage)
+export default CSearchPage

+ 0 - 47
src/pages/WishListPage.jsx

@@ -1,47 +0,0 @@
-import Breadcrumb from "../components/Breadcrumbs";
-import {Box, Container, Divider, Typography, useMediaQuery} from "@mui/material";
-import {connect} from 'react-redux';
-import {actionWishListRemove} from "../reducers/WishListReducer";
-import {actionCardChange} from "../reducers/CartReducer";
-import {NotFoundBlock} from "../components/NotFoundBlock";
-import imgUrl from "../img/not-found/2.png"
-import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
-import {TableLine} from "../components/TableLine";
-
-const MainWishList = ({wishlist, addToCart, onWishListRemove, color='#f3f3f3'}) => {
-    const matches = useMediaQuery('(max-width:899px)')
-    let rows = []
-    for (const key of Object.values(wishlist)) {
-        for (const item in key) {
-            rows.push(key[item])
-        }
-    }
-    return (
-        <>
-            {Object.values(wishlist).length > 0 ?
-                    <main style={{backgroundColor: {color}, padding: matches ? "20px 0" : "50px 0"}}>
-                        <Container maxWidth="lg">
-                            <TableLine columnName={['PRODUCT', 'PRICE', 'REMOVE', 'ADD TO CART']}/>
-                            <Divider sx={{marginBottom: '20px'}}/>
-                            {rows.map(item => <TableLine columnName={[[item?._id, item?.name, item?.images], item?.price, onWishListRemove, addToCart]} role={'item'}/>)}
-                            <Divider/>
-                        </Container>
-                    </main> :
-                    <NotFoundBlock img={imgUrl} headerText={'YOUR WISHLIST IS CURRENTLY EMPTY'} text={<Box display='flex' alignItems='center'><Typography component='span'>Click the</Typography><FavoriteBorderIcon sx={{margin: '0 10px'}}/><Typography component='span'>icons to add products</Typography></Box>}/>
-            }
-        </>
-    )
-}
-export const CMainWishList = connect(state => ({wishlist: state.wishlist}), {addToCart: actionCardChange, onWishListRemove: actionWishListRemove})(MainWishList)
-
-const WishListPage = () => {
-    return (
-        <>
-            <Breadcrumb links={['wish list']}/>
-            <CMainWishList/>
-        </>
-    )
-}
-
-export default WishListPage
-// TODO MOBILE VERSION

+ 71 - 0
src/pages/WishListPage/MainWishList.jsx

@@ -0,0 +1,71 @@
+import {Box, Container, Divider, Typography, useMediaQuery} from "@mui/material";
+import {TableLine} from "../../components/TableLine";
+import {NotFoundBlock} from "../../components/NotFoundBlock";
+import imgUrl from "../../img/not-found/2.png";
+import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
+import {connect} from "react-redux";
+import {actionCardChange} from "../../reducers/CartReducer";
+import {actionWishListRemove} from "../../reducers/WishListReducer";
+
+const MainWishList = ({wishlist, addToCart, onWishListRemove, color='#f3f3f3'}) => {
+    const matches = useMediaQuery('(max-width:899px)')
+    let rows = []
+    for (const key of Object.values(wishlist)) {
+        for (const item in key) {
+            rows.push(key[item])
+        }
+    }
+
+    return (
+        <>
+            {Object.values(wishlist).length > 0 ?
+                <main
+                    style={{
+                        backgroundColor: {color},
+                        padding: matches ? "20px 0" : "50px 0",
+                        minHeight:'300px'
+                    }}
+                >
+                    <Container maxWidth="lg">
+                        <TableLine columnName={['PRODUCT', 'PRICE', 'REMOVE', 'ADD TO CART']}/>
+                        <Divider sx={{marginBottom: '20px'}}/>
+                        {rows.map(item =>
+                            <TableLine
+                                key={item?._id}
+                                columnName={[[item?._id, item?.name, item?.images], item?.price,
+                                    onWishListRemove, addToCart]}
+                                role={'item'}
+                            />)
+                        }
+                        <Divider/>
+                    </Container>
+                </main>
+                :
+                <NotFoundBlock
+                    img={imgUrl}
+                    headerText={'YOUR WISHLIST IS CURRENTLY EMPTY'}
+                    text={
+                        <Box
+                            display='flex'
+                            alignItems='center'
+                        >
+                            <Typography
+                                component='span'
+                            >
+                                Click the
+                            </Typography>
+                            <FavoriteBorderIcon sx={{margin: '0 10px'}}/>
+                            <Typography
+                                component='span'
+                            >
+                                icons to add products
+                            </Typography>
+                        </Box>
+                    }
+                />
+            }
+        </>
+    )
+}
+export const CMainWishList = connect(state => ({wishlist: state.wishlist}),
+    {addToCart: actionCardChange, onWishListRemove: actionWishListRemove})(MainWishList)

+ 11 - 0
src/pages/WishListPage/WishListPage.jsx

@@ -0,0 +1,11 @@
+import Breadcrumb from "../../components/Breadcrumbs";
+import {CMainWishList} from "./MainWishList";
+
+export const WishListPage = () => {
+    return (
+        <>
+            <Breadcrumb links={['wish list']}/>
+            <CMainWishList/>
+        </>
+    )
+}

+ 1 - 1
src/reducers/CategoryReducer.js

@@ -35,7 +35,7 @@ export const CategoryReducer = (state={}, { type, value={} }) => {
             }
         }
         else
-            return state
+            return {...state}
     }
     if (type === 'CATEGORY_REMOVE') {
         return {}