Gennadysht 2 gadi atpakaļ
vecāks
revīzija
b23a92b397

+ 3 - 1
src/App.js

@@ -4,7 +4,7 @@ import { Router, Route, Switch } from 'react-router-dom';
 import { createBrowserHistory } from "history";
 import { Provider } from 'react-redux';
 import { promiseReducer, frontEndReducer, cartReducer, actionRestoreCart, goodsApi, cartGoodsApi } from './reducers';
-import { CGood, CGoodsList, CLoginForm, CMainAppBar, COrder, COrdersList, CSortedFileDropZone } from "./Components";
+import { CEditableGood, CGood, CGoodsList, CLoginForm, CMainAppBar, COrder, COrdersList, CSortedFileDropZone } from "./Components";
 import { CLogout } from './Components';
 import { CSidebar } from './Components/Sidebar';
 import { CRootCats } from './Components';
@@ -94,11 +94,13 @@ function App() {
               <Route path="/orders" component={COrdersList} />
               <Route path="/goods" component={CGoodsList} />
               <Route path="/good/:_id" component={CGood} />
+              <Route path="/editgood/:_id" component={CEditableGood} />
               <Route path="/category/:_id" component={CCategory} />
               <Route path="/order/:_id" component={COrder} />
               <Route path="/cart" component={CCart} />
               <Route path="/login" component={CLoginForm} />
               <Route path="/logout" component={CLogout} />
+
               <Route path="*" component={NotFound} />
             </Switch>
           </div>

+ 2 - 5
src/Components/Cart.js

@@ -2,7 +2,7 @@ import React from 'react';
 import { Button, Typography } from "@mui/material"
 import { Box, Container } from "@mui/system"
 import { connect, useDispatch, useSelector } from "react-redux"
-import { actionAddOrder, useAddOrderMutation, useGetCartGoodsQuery } from "../reducers"
+import { useAddOrderMutation, useGetCartGoodsQuery } from "../reducers"
 import { CartGoodsList } from "./CartGoodsList"
 import { findObjectIndexById } from '../utills';
 
@@ -33,10 +33,7 @@ const Cart = () => {
                     </Typography>
                     <CartGoodsList goods={goodsData ?? []} />
                     <Button size='small' color='primary' disabled={isOrderAdding}
-                        onClick={() => {
-                            let a = '';
-                            addOrderMutation({ order });
-                        }}
+                        onClick={() => addOrderMutation({ order })}
                     >
                         Place Order
                     </Button>

+ 119 - 0
src/Components/EditableGood.js

@@ -0,0 +1,119 @@
+import React, { useState } from 'react';
+import Button from '@mui/material/Button';
+import { styled } from '@mui/material/styles';
+import { Container, Grid, Card, CardContent, CardMedia, AvatarGroup, CardActions, IconButton, TextField, InputAdornment } from '@mui/material';
+import { getFullImageUrl } from "./../utills";
+import { useDispatch } from 'react-redux';
+import { useGetGoodByIdQuery, useSaveGoodMutation } from '../reducers';
+import { useParams } from 'react-router-dom';
+import { actionSetCurrentGood } from '../reducers/frontEndReducer';
+
+
+export const ExpandMore = styled(props => {
+    const { expand, ...other } = props;
+    return <IconButton {...other} />;
+})(({ theme, expand }) => ({
+    transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)',
+    marginLeft: 'auto',
+    transition: theme.transitions.create('transform', { duration: theme.transitions.duration.shortest })
+}))
+
+export const AvatarGroupOriented = styled((props) => {
+    const { vertical, ...other } = props;
+    return <AvatarGroup {...other} />;
+})(({ theme, vertical }) => (vertical && {
+    display: 'flex',
+    flexDirection: 'column',
+    marginLeft: 10,
+    '& >:first-child': {
+        marginTop: 10,
+    },
+    '& >*': {
+        marginLeft: 1,
+        marginTop: theme.spacing(1),
+    },
+    ".MuiAvatar-root": { /*width: 20, height: 20,*/ marginLeft: 1 }
+}));
+
+const EditableGood = ({ goodExt, maxWidth = 'md', saveGood }) => {
+    let [good, setGood] = useState(goodExt);
+    const setGoodData = (data) => {
+        let goodData = { ...good, ...data };
+        setGood(goodData);
+        return goodData;
+    }
+
+
+    return good && (
+        <Container maxWidth={maxWidth}>
+            <Card variant='outlined'>
+                <Grid container spacing={maxWidth === 'xs' ? 7 : 5}>
+                    <Grid item xs>
+                        <Grid container spacing={2}>
+                            <Grid item xs={4}>
+                                <CardMedia
+                                    component="img"
+                                    sx={{ height: 300, padding: "1em 1em 0 1em", objectFit: "contain" }}
+                                    image={good.images?.length > 0 ? getFullImageUrl(good.images[0]) : ''}
+                                    title={good.name}
+                                />
+                            </Grid>
+                            <Grid item xs={8}>
+                                <CardContent>
+                                    <TextField
+                                        required
+                                        id="outlined-required"
+                                        label="Name"
+                                        value={good.name}
+                                        onChange={event => setGoodData({ name: event.target.value })}
+                                    />
+                                    <TextField
+                                        required
+                                        id="outlined-required"
+                                        label="Price"
+                                        type="number"
+                                        startAdornment={<InputAdornment position="start">$</InputAdornment>}
+                                        value={good.price}
+                                        onChange={event => setGoodData({ price: +event.target.value })}
+                                    />
+                                    <TextField
+                                        required
+                                        id="outlined-required"
+                                        label="Description"
+                                        value={good.description}
+                                        onChange={event => setGoodData({ description: event.target.value })}
+                                    />
+                                </CardContent>
+                            </Grid>
+                        </Grid>
+                    </Grid>
+                </Grid>
+                <CardActions>
+                    <Button size='small' color='primary'
+                        onClick={() => saveGood({ good })}
+                    >
+                        Save
+                    </Button>
+                    <Button size='small' color='primary'
+                        onClick={() => setGood(goodExt)}
+                    >
+                        Cancel
+                    </Button>
+                </CardActions>
+            </Card>
+        </Container>
+    )
+}
+
+const CEditableGood = (maxWidth = 'md') => {
+    const { _id } = useParams();
+    const { isLoading, data } = useGetGoodByIdQuery(_id);
+    let good = isLoading ? { name: 'loading', goods: [] } : data?.GoodFindOne;
+    const dispatch = useDispatch();
+    dispatch(actionSetCurrentGood(_id));
+    const [saveGoodMutation, { }] = useSaveGoodMutation();
+
+    return <EditableGood saveGood={saveGoodMutation} goodExt={good} maxWidth={maxWidth} />
+}
+
+export { CEditableGood }

+ 8 - 1
src/Components/Good.js

@@ -6,10 +6,11 @@ import { getFullImageUrl } from "./../utills";
 import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
 import { AvatarAnimated } from './AvatarAnimated';
 import { actionAddGoodToCart } from '../reducers';
-import { connect, useDispatch } from 'react-redux';
+import { useDispatch } from 'react-redux';
 import { useGetGoodByIdQuery } from '../reducers';
 import { useParams } from 'react-router-dom';
 import { actionSetCurrentGood } from '../reducers/frontEndReducer';
+import { MyLink } from './MyLink';
 
 
 export const ExpandMore = styled(props => {
@@ -100,6 +101,12 @@ const Good = ({ good, maxWidth = 'md', showAddToCard = true, actionAddGoodToCart
                             </Button>
                         )
                     }
+                    <MyLink to={`/editgood/${good._id}`}>
+
+                        <Button size='small' color='primary'>
+                            Edit
+                        </Button>
+                    </MyLink>
                 </CardActions>
                 <Collapse in={expanded} timeout='auto' unmountOnExit>
                     <Typography paragraph sx={{ marginLeft: 1 }}>

+ 1 - 1
src/Components/GoodItem.js

@@ -6,7 +6,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
 import { AvatarAnimated } from './AvatarAnimated';
 import { MyLink } from './MyLink';
 import { AvatarGroupOriented, ExpandMore } from './Good';
-import { connect, useDispatch } from 'react-redux';
+import { useDispatch } from 'react-redux';
 import { actionAddGoodToCart } from '../reducers';
 
 export const GoodItem = ({ good, maxWidth = 'md', showAddToCard = true, actionAddGoodToCart }) => {

+ 1 - 0
src/Components/index.js

@@ -12,3 +12,4 @@ export { CMainAppBar } from './MainAppBar';
 export { CRootCats } from './RootCats';
 export { SortedDropZone } from './SortedDropZone';
 export { CSortedFileDropZone } from './SortedFileDropZone';
+export { CEditableGood } from './EditableGood'

+ 16 - 3
src/reducers/goodsReducer.js

@@ -35,7 +35,7 @@ export const goodsApi = createApi({
                         query GoodFind($q: String) {
                             GoodFind(query: $q) {
                                 _id name  price description
-                                images { url }
+                                images { _id url }
                             }
                         }
                 `,
@@ -64,7 +64,7 @@ export const goodsApi = createApi({
                         query GoodFindOne($q: String) {
                             GoodFindOne(query: $q) {
                                 _id name  price description
-                                images { url }
+                                images { _id url }
                             }
                         }
                     `,
@@ -72,8 +72,21 @@ export const goodsApi = createApi({
                 }
             },
         }),
+
+        saveGood: builder.mutation({
+            query: ({ good }) => ({
+                document: gql`
+                            mutation GoodUpsert($good: GoodInput) {
+                                GoodUpsert(good: $good) {
+                                    _id
+                                }
+                            }
+                        `,
+                variables: { good: { ...good, images: good?.images.map(img => ({ _id: img._id })) ?? [] } }
+            })
+        }),
     }),
 })
 
-export const { useGetGoodsQuery, useGetGoodsCountQuery, useGetGoodByIdQuery } = goodsApi;
+export const { useGetGoodsQuery, useGetGoodsCountQuery, useGetGoodByIdQuery, useSaveGoodMutation } = goodsApi;
 

+ 2 - 2
src/reducers/index.js

@@ -5,7 +5,7 @@ export { cartGoodsApi, useGetCartGoodsQuery } from "./cartGoodsReducer";
 export { localStoredReducer, } from "./localStoredReducer";
 export { frontEndReducer, getCurrentCategory, actionSetGoodsPaging, actionSetOrdersPaging, getCurrentGood, getGoodsCount, getOrdersCount } from "./frontEndReducer";
 export { useGetRootCategoriesQuery, useGetCategoryByIdQuery } from './categoryReducer';
-export { ordersApi, useGetOrderByIdQuery, useGetOrdersCountQuery, useGetOrdersQuery, actionAddOrder, useAddOrderMutation } from './ordersReducer';
-export { goodsApi, useGetGoodByIdQuery, useGetGoodsCountQuery, useGetGoodsQuery } from './goodsReducer';
+export { ordersApi, useGetOrderByIdQuery, useGetOrdersCountQuery, useGetOrdersQuery, useAddOrderMutation } from './ordersReducer';
+export { goodsApi, useGetGoodByIdQuery, useGetGoodsCountQuery, useGetGoodsQuery, useSaveGoodMutation } from './goodsReducer';
 
 

+ 1 - 16
src/reducers/ordersReducer.js

@@ -91,22 +91,7 @@ const ordersApi = createApi({
     }),
 });
 
-const actionAddOrder = () => {
-    return async (dispatch, getState) => {
-        let state = getState();
-        if (state.cart.goods.length > 0) {
-            let order = [];
-            for (let good of Object.values(state.cart.goods)) {
-                order.push({ good: { _id: good._id }, count: good.count });
-            }
-            const addOrderMutation = ordersApi.useAddOrderMutation();
-            dispatch(addOrderMutation({ order }));
-            //dispatch(actionClearCart());
-        }
-    }
-}
-
 
 export const { useGetOrdersQuery, useGetOrdersCountQuery, useGetOrderByIdQuery, useAddOrderMutation } = ordersApi;
-export { ordersApi, actionAddOrder };
+export { ordersApi };