Gennadysht преди 2 години
родител
ревизия
ffa151f636

+ 8 - 7
src/Components/EditableGood.js

@@ -14,11 +14,11 @@ import { LackPermissions } from './LackPermissions';
 import { CCategoryDropDownList } from './DropDownList';
 
 
-const EditableGood = ({ good: goodExt, maxWidth = 'md', saveGood, uploadFile }) => {
-    const copyGood = goodExt => ({ ...goodExt, images: [ ...goodExt.images ] });
+const EditableGood = ({ good: goodExt, maxWidth = 'md', saveGood }) => {
+    const copyGood = goodExt => ({ ...goodExt, images: [ ...(goodExt.images ?? []) ] });
     let [good, setGood] = useState(copyGood(goodExt));
     let [showPreview, setShowPreview] = useState(false);
-    let [imagesContainer, setImagesContainer] = useState({ images: [...goodExt.images] });
+    let [imagesContainer, setImagesContainer] = useState({ images: [...(goodExt.images ?? [])] });
 
     const onSetCategory = (catItem) => {
         good.categories = catItem.cat ? [{ _id: catItem.cat._id }] : [];
@@ -152,8 +152,9 @@ const EditableGood = ({ good: goodExt, maxWidth = 'md', saveGood, uploadFile })
 
 const CEditableGood = ({ maxWidth = 'md' }) => {
     const { _id } = useParams();
-    const { isLoading, data } = useGetGoodByIdQuery(_id || 'fwkjelnfvkjwe');
-    let good = isLoading ? { name: 'loading', goods: [] } : data?.GoodFindOne;
+    let { isLoading, data } = useGetGoodByIdQuery(_id || 'fwkjelnfvkjwe');
+    isLoading = _id ? isLoading : false;
+    let good = isLoading ? { name: 'loading', categories: [] } : data?.GoodFindOne;
     const [saveGoodMutation, { }] = useSaveGoodMutation();
     const state = useSelector(state => state);
     let currentCategory = getCurrentEntity(frontEndNames.category, state)
@@ -162,10 +163,10 @@ const CEditableGood = ({ maxWidth = 'md' }) => {
 
     if (!isLoading && !good && isAdmin) {
         let categories = currentCategory ? [{ _id: currentCategory._id, name: currentCategory.name }] : [];
-        good = { _id: undefined, categories };
+        good = { _id: undefined, categories, images: [] };
     }
 
-    return !isLoading &&
+    return !isLoading && 
         (isAdmin ? <EditableGood good={good} saveGood={saveGoodMutation} maxWidth={maxWidth} /> : <LackPermissions name="good" />)
 }
 

+ 24 - 8
src/Components/MainAppBar.js

@@ -8,11 +8,20 @@ import MenuIcon from '@mui/icons-material/Menu';
 import { MyLink } from './MyLink';
 import { connect, useSelector } from 'react-redux';
 import { useTheme } from '@emotion/react';
-import { actionSetSidebar, getIsSideBarOpen } from '../reducers';
+import { actionSetSidebar, getCartItemsCount, getIsSideBarOpen } from '../reducers';
 import { UserEntity } from '../Entities';
+import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
+import { AccountCircle } from '@mui/icons-material';
+import LogoutIcon from '@mui/icons-material/Logout';
+import LoginIcon from '@mui/icons-material/Login';
+import CategoryIcon from '@mui/icons-material/Category';
+import SupervisedUserCircleIcon from '@mui/icons-material/SupervisedUserCircle';
+import WorkHistoryIcon from '@mui/icons-material/WorkHistory';
+import { Badge, Tooltip } from '@mui/material';
 
 const MainAppBar = ({ token, openSidebar }) => {
     const theme = useTheme();
+    const cartItemsCount = useSelector(state => getCartItemsCount(state) ?? 0);
     let currentUser = useSelector(state => new UserEntity(state.auth?.currentUser ?? { _id: null }));
     let isAdmin = currentUser?.isAdminRole === true;
     let isLoggedIn = token && true;
@@ -35,25 +44,32 @@ const MainAppBar = ({ token, openSidebar }) => {
                     {
                         !isLoggedIn &&
                         <>
-                            <MyLink to="/login"><Button sx={{ color: "white" }}>Login</Button></MyLink>
+                            <MyLink to="/login"><Button sx={{ color: "white" }}><Tooltip title="Login"><LoginIcon /></Tooltip></Button></MyLink>
                             <MyLink to="/register"><Button sx={{ color: "white" }}>Register</Button></MyLink>
                         </>
                     }
                     {
                         isLoggedIn &&
                         <>
-                            <MyLink to="/logout"><Button sx={{ color: "white" }}>Logout</Button></MyLink>
-                            <MyLink to="/orders"><Button sx={{ color: "white" }}>Orders</Button></MyLink>
                             {isAdmin && (
                                 <>
-                                    <MyLink to="/users"><Button sx={{ color: "white" }}>Users</Button></MyLink>
-                                    <MyLink to="/catree"><Button sx={{ color: "white" }}>Categories</Button></MyLink>
+                                    <MyLink to="/catree"><Button sx={{ color: "white" }}><Tooltip title="Categories"><CategoryIcon /></Tooltip></Button></MyLink>
+                                    <MyLink to="/users"><Button sx={{ color: "white" }}><Tooltip title="Users"><SupervisedUserCircleIcon /></Tooltip></Button></MyLink>
                                 </>
                             )}
-                            <MyLink to="/user"><Button sx={{ color: "white" }}>About Me</Button></MyLink>
+                            <MyLink to="/orders"><Button sx={{ color: "white" }}><Tooltip title="Orders"><WorkHistoryIcon /></Tooltip></Button></MyLink>
+                            <MyLink to="/user"><Button sx={{ color: "white" }}><Tooltip title="About Me"><AccountCircle /></Tooltip></Button></MyLink>
+                        </>
+                    }
+                    <Badge badgeContent={cartItemsCount} color="secondary">
+                        <MyLink to="/cart"><Button sx={{ color: "white" }}><Tooltip title="Cart"><ShoppingCartIcon /></Tooltip></Button></MyLink>
+                    </Badge>
+                    {
+                        isLoggedIn &&
+                        <>
+                            <MyLink to="/logout"><Button sx={{ color: "white" }}><Tooltip title="Logout"><LogoutIcon /></Tooltip></Button></MyLink>
                         </>
                     }
-                    <MyLink to="/cart"><Button sx={{ color: "white" }}>Cart</Button></MyLink>
                 </Toolbar>
             </AppBar>
         </Box>

+ 6 - 58
src/Components/Order.js

@@ -10,61 +10,8 @@ import { MyLink } from './MyLink';
 import { getCurrentUser } from '../reducers';
 import { UserEntity } from '../Entities';
 import { LackPermissions } from './LackPermissions';
+import { fixBackendDataError } from '../utills';
 
-let exampleOrder = {
-    "_id": "62cdc9b3b74e1f5f2ec1a0e9",
-    "total": 3383,
-    "createdAt": "1657653683000",
-    "orderGoods": [
-        {
-            "_id": "62cdc9b3b74e1f5f2ec1a0e6",
-            "price": 33,
-            "count": 1,
-            "total": 33,
-            "createdAt": "1657653683000",
-            "good": null
-        },
-        {
-            "_id": "62cdc9b3b74e1f5f2ec1a0e7",
-            "price": 1000,
-            "count": 2,
-            "total": 2000,
-            "createdAt": "1657653683000",
-            "good": {
-                "name": "iPhone 13",
-                "images": [
-                    {
-                        "url": "images/56c5d476685355221b1a3ba2c554ad91"
-                    },
-                    {
-                        "url": "images/29393a087c933d7caea010c98f4d2876"
-                    }
-                ]
-            }
-        },
-        {
-            "_id": "62cdc9b3b74e1f5f2ec1a0e8",
-            "price": 450,
-            "count": 3,
-            "total": 1350,
-            "createdAt": "1657653683000",
-            "good": {
-                "name": "Samsung Galaxy M52",
-                "images": [
-                    {
-                        "url": "images/e91a37b88f947e51586dfe87b2f4e13f"
-                    },
-                    {
-                        "url": "images/bf8fcf557844ba9bce1368e5bf52bb4d"
-                    },
-                    {
-                        "url": "images/fd419e96ffc2d21e880fc0efabe7ae5c"
-                    }
-                ]
-            }
-        }
-    ]
-}
 const Order = ({ order = {} }) => {
     return (
         <>
@@ -95,13 +42,14 @@ const Order = ({ order = {} }) => {
 const COrder = () => {
     const { _id } = useParams();
     let currentUser = useSelector(state => getCurrentUser(state));
-    const { isLoading, data } = useGetOrderByIdQuery({ _id, owner: new UserEntity(currentUser) });
-    let order = isLoading ? { name: 'loading', order: {} } : data?.OrderFindOne;
-    return !isLoading && 
+    
+    let getOrderById= useGetOrderByIdQuery({ _id, owner: new UserEntity(currentUser) });
+    let order = getOrderById.isLoading ? { name: 'loading', order: {} } : fixBackendDataError(getOrderById, "OrderFindOne");
+    return !getOrderById.isLoading && 
         order ?
         <Order order={order} />
         :
-        isLoading ? <Typography>Loading...</Typography> : <LackPermissions name="order"/>
+        getOrderById.isLoading ? <Typography>Loading...</Typography> : <LackPermissions name="order"/>
         ;
 }
 

+ 3 - 3
src/Components/OrderGoodsList.js

@@ -7,10 +7,10 @@ import { StyledTableCell } from './StyledTableElements';
 
 const OrderGoodsList = ({ orderGoods = [], tax_rate = 0 }) => {
     function ccyFormat(num) {
-        return `${num.toFixed(2)}`;
+        return `${(num ?? 0).toFixed(2)}`;
     }
     function subtotal(items) {
-        return items.map(({ price, count }) => price * count).reduce((sum, i) => sum + i, 0);
+        return items?.map(({ price, count }) => price * count).reduce((sum, i) => sum + i, 0) ?? 0;
     }
     const invoiceSubtotal = subtotal(orderGoods);
     const invoiceTaxes = tax_rate * invoiceSubtotal;
@@ -32,7 +32,7 @@ const OrderGoodsList = ({ orderGoods = [], tax_rate = 0 }) => {
                     </TableHead>
                     <TableBody>
                         {
-                            orderGoods.map((orderGood, index) => {
+                            orderGoods?.map((orderGood, index) => {
                                 return (
                                     <OrderGood key={orderGood._id} orderGood={orderGood} orderGoodNum={index} maxWidth='xs' />
                                 )

+ 4 - 1
src/Components/OrderList.js

@@ -8,6 +8,8 @@ import { MyLink, ReferenceLink } from '.';
 import { useSelector } from 'react-redux';
 import { frontEndNames, getCurrentUser, getEntitiesListShowParams, useGetOrdersCountQuery, useGetOrdersQuery } from '../reducers';
 import { UserEntity } from '../Entities';
+import { fixBackendDataError } from '../utills';
+
 
 const OrderList = ({ entities, entitiesTypeName, fromPage, pageSize }) => {
 
@@ -128,8 +130,9 @@ const COrdersList = () => {
     const ordersCountResult = useGetOrdersCountQuery({ searchStr, owner: currentUser });
     let isLoading = ordersResult.isLoading || ordersCountResult.isLoading;
 
-    let entities = !isLoading && ordersResult.data?.OrderFind;
+    let entities = !isLoading && fixBackendDataError(ordersResult, "OrderFind");
     return !isLoading && <OrderList entities={entities} entitiesTypeName={entitiesTypeName} fromPage={fromPage} pageSize={pageSize} />
 }
 
+
 export { COrdersList };

+ 7 - 1
src/reducers/cartReducer.js

@@ -69,6 +69,11 @@ const cartSlice = createSlice({ //promiseReducer
             });
     }
 })
+
+const getCartItemsCount = state => {
+    return state.cart?.goods?.reduce((sum, g) => sum + g.count, 0);
+}
+
 function cleanCartInt(state) {
     localStorage.cart = { goods: [] };
     setStateData(state, [], v4());
@@ -107,5 +112,6 @@ const setStateData = (state, goods, uniqueId = undefined) => {
 export {
     cartSlice, /*getCart,*/
     actionAddGoodToCart, actionDeleteGoodFromCart, actionRestoreCart,
-    actionClearCart/*, actionClearCartData*/
+    actionClearCart/*, actionClearCartData*/,
+    getCartItemsCount
 };

+ 1 - 1
src/reducers/goodsReducer.js

@@ -79,7 +79,7 @@ export const goodsApi = createApi({
             },
             providesTags: (result, error, arg) => {
                 return result
-                    ? [{ type: 'Good', _id: result.GoodFindOne._id }, 'Good']
+                    ? [{ type: 'Good', _id: result.GoodFindOne?._id }, 'Good']
                     : ['Good'];
             }
         }),

+ 1 - 1
src/reducers/index.js

@@ -1,6 +1,6 @@
 export { promiseReducer, actionPromise, actionFulfilled, actionPending, actionRejected } from "./promiseReducer";
 export { authApi, authSlice, authApi as loginApi, useUserFindQuery, actionAuthLogout, useGetUsersQuery, useGetUsersCountQuery, useSaveUserMutation, getCurrentUser, isCurrentUserAdmin } from './authReducer';
-export { cartSlice, actionAddGoodToCart, actionDeleteGoodFromCart, actionRestoreCart, actionClearCart } from "./cartReducer";
+export { cartSlice, actionAddGoodToCart, actionDeleteGoodFromCart, actionRestoreCart, actionClearCart, getCartItemsCount } from "./cartReducer";
 export { localStoredReducer, } from "./localStoredReducer";
 export { frontEndSlice, frontEndNames, actionSetSidebar, actionSetPaging, actionSetSearch, getEntitiesCount, getCurrentEntity, actionSetCurrentEntity, getEntitiesListShowParams, getEntitiesSearchStr, getEntitiesPaging, getIsSideBarOpen } from "./frontEndReducer";
 export { useGetRootCategoriesQuery, useGetCategoryByIdQuery, useGetCategoriesQuery, useGetCategoriesCountQuery, useSaveCategoryMutation } from './categoryReducer';

+ 14 - 2
src/reducers/ordersReducer.js

@@ -50,7 +50,13 @@ const ordersApi = createApi({
                 return result
                     ? [...result.OrderFind.map(obj => ({ type: 'Order', _id: obj._id })), 'Order']
                     : ['Order'];
-            }
+            },
+            transformResponse: (response, meta, arg) => {
+                return response;
+            },
+            transformErrorResponse: (response, meta, arg) => {
+                return {...response, ...meta.response?.data} ;
+            },
         }),
         getOrdersCount: builder.query({
             query: ({ owner, searchStr = '' }) => {
@@ -95,7 +101,13 @@ const ordersApi = createApi({
                 return result
                     ? [{ type: 'Order', _id: result.OrderFindOne._id }, 'Order']
                     : ['Order'];
-            }
+            },
+            transformResponse: (response, meta, arg) => {
+                return response;
+            },
+            transformErrorResponse: (response, meta, arg) => {
+                return {...response, ...meta.response?.data} ;
+            },
         }),
         addOrder: builder.mutation({
             query: ({ order, id = null }) => (

+ 1 - 1
src/utills/index.js

@@ -1,2 +1,2 @@
-export {getFullImageUrl, findObjectIndexById, capitalize} from './utils';
+export {getFullImageUrl, findObjectIndexById, capitalize, fixBackendDataError} from './utils';
 export {gql, jwtDecode} from './gql';

+ 8 - 1
src/utills/utils.js

@@ -19,7 +19,14 @@ function saveImage(image) {
 
 const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
 
+const fixBackendDataError = (result, propName) => {
+    if (result.error && result.error[propName])
+        return result.error[propName];
+    else if (result.data && result.data[propName])
+        return result.data[propName];
+    return undefined;
+}
 
-export { getFullImageUrl, findObjectIndexById, saveImage, capitalize };
+export { getFullImageUrl, findObjectIndexById, saveImage, capitalize, fixBackendDataError };