Parcourir la source

rtk_clearCart-abracadabra

Gennadysht il y a 2 ans
Parent
commit
f7019e95f7

+ 9 - 4
src/Components/Cart.js

@@ -1,8 +1,8 @@
 import React, { useEffect } from 'react';
-import { Typography } from "@mui/material"
+import { Button, Typography } from "@mui/material"
 import { Box, Container } from "@mui/system"
 import { connect } from "react-redux"
-import { actionLoadCart, getCart } from "../reducers"
+import { actionLoadCart, getCart, actionPlaceOrder } from "../reducers"
 import { CartGoodsList } from "./CartGoodsList"
 import { findObjectIndexById } from '../utills';
 
@@ -14,7 +14,7 @@ const mapCountToGood = (goodData, goodsCounts) => {
     return count;
 }
 
-const Cart = ({ goods, goodsData, uniqueId, loadData }) => {
+const Cart = ({ goods, goodsData, uniqueId, loadData, placeOrder }) => {
     goodsData = goodsData?.map(gd => ({ ...gd, count: mapCountToGood(gd, goods) })) ?? [];
 
     useEffect(() => {
@@ -28,6 +28,11 @@ const Cart = ({ goods, goodsData, uniqueId, loadData }) => {
                         Cart
                     </Typography>
                     <CartGoodsList goods={goodsData ?? []} />
+                    <Button size='small' color='primary'
+                        onClick={() => placeOrder()}
+                    >
+                        Place Order
+                    </Button>
                 </Box>
             </Container>
         </>
@@ -40,6 +45,6 @@ const CCart = connect(state => ({
     ...getCart(state) 
     //cart: getCart(state) 
 }),
-    { loadData: actionLoadCart })(Cart);
+    { loadData: actionLoadCart, placeOrder: actionPlaceOrder })(Cart);
 
 export { CCart };

+ 17 - 2
src/Components/CartGood.js

@@ -4,8 +4,11 @@ import { AvatarImage } from "./AvatarAnimated";
 import { StyledTableCell, StyledTableRow } from "./StyledTableElements";
 import "./cartGood.css"
 import { MyLink } from "./MyLink";
+import { connect } from "react-redux";
+import { actionAddGoodToCart } from "../reducers";
+import Button from '@mui/material/Button';
 
-const CartGood = ({ good, goodNum }) => {
+const CartGood = ({ good, goodNum, addToCart = undefined }) => {
     return (
         <>
             <StyledTableRow>
@@ -38,9 +41,19 @@ const CartGood = ({ good, goodNum }) => {
                     </Typography>
                 </StyledTableCell>
                 <StyledTableCell item align="right" xs={2}>
+                    <Button size='small' color='primary'
+                        onClick={() => addToCart(good, -1)}
+                    >
+                        -
+                    </Button>
                     <Typography>
                         {good.count}
                     </Typography>
+                    <Button size='small' color='primary'
+                        onClick={() => addToCart(good, +1)}
+                    >
+                        +
+                    </Button>
                 </StyledTableCell>
                 <StyledTableCell item align="right" xs={2}>
                     <Typography>
@@ -51,4 +64,6 @@ const CartGood = ({ good, goodNum }) => {
         </>
     )
 }
-export { CartGood };
+const CCartGood = connect(state => ({}),
+    { addToCart: actionAddGoodToCart })(CartGood);
+export { CCartGood };

+ 2 - 2
src/Components/CartGoodsList.js

@@ -1,6 +1,6 @@
 import React from 'react';
 import { Paper } from '@mui/material';
-import { CartGood } from './CartGood';
+import { CCartGood } from './CartGood';
 import { Table, TableBody, TableContainer, TableHead, TableRow, TableCell } from "@mui/material";
 import { StyledTableCell } from './StyledTableElements';
 
@@ -33,7 +33,7 @@ const CartGoodsList = ({ goods = [], tax_rate = 0 }) => {
                         {
                             goods.map((good, index) => {
                                 return (
-                                    <CartGood key={good._id} good={good} goodNum={index} maxWidth='xs' />
+                                    <CCartGood key={good._id} good={good} goodNum={index} maxWidth='xs' />
                                 )
                             })
                         }

+ 8 - 56
src/gql/gqlOrders.js

@@ -1,45 +1,6 @@
 import { gql } from "../utills/gql";
-import { actionClearCart, actionPromise } from "../reducers";
 import { createFullQuery } from "./gqlUtils";
 
-const orderUpsert = (order, id = null) => {
-    const orderUpsertQuery = `mutation OrderUpsert($order: OrderInput) {
-                            OrderUpsert(order: $order) {
-                                _id
-                            }
-                        }`;
-    return gql(orderUpsertQuery, { order: { "_id": id, "orderGoods": order } });
-}
-export const actionOrderUpsert = (order, id) =>
-    actionPromise('orderUpsert', orderUpsert(order, id));
-
-const orderFullUpsert = (then) => {
-    return async (dispatch, getState) => {
-        let state = getState();
-        let order = [];
-        for (let cartItem of Object.values(state.cartReducer)) {
-            //{count: 3, good: {_id: "xxxx" }}
-            order.push({ good: { _id: cartItem.good._id }, count: cartItem.count });
-        }
-        if (order.length > 0) {
-            //dispatch возвращает то, что вернул thunk, возвращаемый actionLogin, а там промис, 
-            //так как actionPromise возвращает асинхронную функцию
-            let promiseResult = orderUpsert(order);
-            let res = await promiseResult;
-            if (res && res.errors && res.errors.length > 0) {
-                throw res.errors[0];
-            }
-            dispatch(actionClearCart());
-        }
-        if (then)
-            then();
-        //проверьте что token - строка и отдайте его в actionAuthLogin
-    }
-}
-export const actionOrderFullUpsert = (then) =>
-    actionPromise('orderUpsert', orderFullUpsert(then));
-
-
 const getOrderSearchParams = query => ({ searchStr: query, searchFieldNames: ["_id"] });
 
 export const gqlOrderFindOne = (_id) => {
@@ -83,20 +44,11 @@ export const gqlOrdersCount = (query = '') => {
     return gql(catQuery, params);
 }
 
-/*
-    const gqlFindOrders = (fromPage, pageSize) => {
-        const findOrdersQuery = `query OrderFind {
-                                OrderFind(query: "[{}]") {
-                                    _id total
-                                    orderGoods {
-                                        _id price count total createdAt
-                                        good {
-                                            name 
-                                            images { url }
-                                        }
-                                    }
-                                }
-                                }`;
-        return gql(findOrdersQuery);
-    }
-*/
+export const gqlAddOrder = (order, id = null) => {
+    const orderUpsertQuery = `mutation OrderUpsert($order: OrderInput) {
+                            OrderUpsert(order: $order) {
+                                _id
+                            }
+                        }`;
+    return gql(orderUpsertQuery, { order: { "_id": id, "orderGoods": order } });
+}

+ 1 - 1
src/gql/index.js

@@ -1,4 +1,4 @@
 export { actionAuthUpsert, actionLogin, actionFullLogin } from './gqlAuth';
 export { gqlGoodFind, gqlGoodFindOne } from './gqlGoods';
-export { actionOrderFullUpsert, actionOrderUpsert , gqlOrderFindOne, gqlFindOrders, gqlOrdersCount } from './gqlOrders';
+export { gqlOrderFindOne, gqlFindOrders, gqlOrdersCount, gqlAddOrder } from './gqlOrders';
 export {createFullQuery} from './gqlUtils';

+ 23 - 7
src/reducers/cartGoodsReducer.js

@@ -1,4 +1,5 @@
 import { gqlGoodFind } from "../gql";
+import { actionClearCartData } from "./cartReducer";
 import { actionPromiseGeneric, createPromiseReducerSlice } from "./promiseReducer";
 
 let actionCartGoodsFindInt = (dispatch, goods) => {
@@ -6,25 +7,40 @@ let actionCartGoodsFindInt = (dispatch, goods) => {
         actionGetCartGoods({ _id: { "$in": goods.map(g => g._id) } }));
 }
 
-const goodsData="goodsData";
-const actionGetCartGoods = (goodsQuery) =>
-    actionPromiseCartGoods(goodsData, gqlGoodFind(undefined, undefined, null, goodsQuery));
+const goodsData = "goodsData";
+const actionGetCartGoods = (goodsQuery) => {
+    let a = '';
+    return actionPromiseCartGoods(goodsData, gqlGoodFind(undefined, undefined, null, goodsQuery));
+}
 
 let actionLoadCart = () =>
     async (dispatch, getState) => {
         let state = getState();
         let goods = state.cart.goods;
-        if (goods?.length > 0) {
+        if (goods?.length > 0)
             actionCartGoodsFindInt(dispatch, goods);
-        }
+        else
+            dispatch(actionClearCartData());
     }
 
 let getCartData = state => {
-    return state.cartData[goodsData];
+    var cartData = state.cartData;
+    if (!cartData)
+        return [];
+    return cartData[goodsData]?.payload ?? [];
+}
+let clearCartData = state => {
+    let res = false;
+    let cartData = getCartData(state);
+    if (cartData?.length > 0) {
+        state.cartData = { [goodsData]: { payload: [] } };
+        res = true;
+    }
+    return res;
 }
 
 const cartGoodsReducerSlice = createPromiseReducerSlice('cartData');
 const actionPromiseCartGoods = (name, promise) =>
     actionPromiseGeneric(cartGoodsReducerSlice, name, promise);
 let cartGoodsReducer = cartGoodsReducerSlice.reducer;
-export { cartGoodsReducer, actionLoadCart, getCartData }
+export { cartGoodsReducer, actionLoadCart, getCartData, clearCartData }

+ 28 - 9
src/reducers/cartReducer.js

@@ -1,7 +1,7 @@
 import { createSlice } from "@reduxjs/toolkit"
 import { v4 } from "uuid";
 import { findObjectIndexById } from "../utills";
-import { getCartData } from "./cartGoodsReducer";
+import { clearCartData, getCartData } from "./cartGoodsReducer";
 
 const cartReducerSlice = createSlice({ //promiseReducer
     name: 'cart', //префикс типа наподобие AUTH_
@@ -9,18 +9,23 @@ const cartReducerSlice = createSlice({ //promiseReducer
         goods: []
     },
     reducers: {
+        cleanCartData(state, { payload: { commonState } }) {
+            if (clearCartData(commonState))
+                state.uniqueId = v4();
+            return state;
+        },
         restoreCart(state, action) {
             let goods = localStorage.cart.goods;
             if (!goods) {
                 goods = [];
                 localStorage.cart = { goods: goods };
             }
-            state = { goods: goods, uniqueId: v4() };
+            setStateData(state, goods, v4());
             return state;
         },
         cleanCart(state, action) {
             localStorage.cart = { goods: [] };
-            state = { goods: [], uniqueId: v4() };
+            setStateData(state, [], v4());
             return state;
         },
         refreshCart(state, action) {
@@ -62,9 +67,9 @@ const cartReducerSlice = createSlice({ //promiseReducer
 })
 
 let cartReducer = cartReducerSlice.reducer;
-let actionAddGoodToCart = good =>
+let actionAddGoodToCart = (good, count = 1) =>
     async (dispatch, state) => {
-        dispatch(cartReducerSlice.actions.addGood({ good }))
+        dispatch(cartReducerSlice.actions.addGood({ good: { ...good, count } }))
     }
 
 let actionDeleteGoodFromCart = good =>
@@ -81,18 +86,32 @@ let actionClearCart = () =>
         dispatch(cartReducerSlice.actions.cleanCart({}))
     }
 
+let actionClearCartData = () =>
+    async (dispatch, useState) => {
+        let commonState = useState();
+        dispatch(cartReducerSlice.actions.cleanCartData({ commonState }))
+    }
+
 let getCart = state => {
     let res = {
         goods: state.cart.goods,
-        goodsData: (state.cartData?.goodsData?.payload ?? []),
+        goodsData: getCartData(state),
         uniqueId: state.cart.uniqueId,
     };
     return res;
 }
 
+const setStateData = (state, goods, uniqueId = undefined) => {
+    if (goods != undefined)
+        state.goods = goods;
+    if (uniqueId != undefined)
+        state.uniqueId = uniqueId;
+}
+
+
 
 export {
-    cartReducer,
-    getCart,
-    actionAddGoodToCart, actionDeleteGoodFromCart, actionRestoreCart, actionClearCart
+    cartReducer, getCart,
+    actionAddGoodToCart, actionDeleteGoodFromCart, actionRestoreCart,
+    actionClearCart, actionClearCartData
 };

+ 1 - 1
src/reducers/index.js

@@ -5,5 +5,5 @@ export { cartGoodsReducer, actionLoadCart } from "./cartGoodsReducer";
 export { localStoredReducer, } from "./localStoredReducer";
 export { frontEndReducer, } from "./frontEndReducer";
 export { actionRootCats, actionCategoryFindOne } from './categoryReducer';
-export { actionFindOrders, actionOrdersCount } from './ordersReducer';
+export { actionFindOrders, actionOrdersCount, actionPlaceOrder } from './ordersReducer';
 export { goodsReducer, actionGoodFind, actionGoodFindOne, actionGoodsCount } from './goodsReducer';

+ 18 - 2
src/reducers/ordersReducer.js

@@ -1,4 +1,6 @@
-import { gqlFindOrders, gqlOrderFindOne, gqlOrdersCount } from "../gql/gqlOrders";
+import { gqlFindOrders, gqlOrderFindOne, gqlOrdersCount, gqlAddOrder } from "../gql/gqlOrders";
+import { actionClearCart } from "./cartReducer";
+
 import { actionPromiseGeneric, createPromiseReducerSlice } from "./promiseReducer";
 
 const actionFindOrders = (fromPage = 0, pageSize = undefined, query = null) =>
@@ -13,10 +15,24 @@ const actionOrderFindOne = (id) =>
 const getCurrentOrder = state => (
     state.orders[currentOrder]?.payload
 )
+const actionPlaceOrder = () => {
+    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 });
+            }
+            dispatch(actionPromiseOrders('placedOrderInfo', gqlAddOrder(order)));
+            dispatch(actionClearCart());
+        }
+    }
+}
+
 
 const ordersReducerSlice = createPromiseReducerSlice('orders');
 const actionPromiseOrders = (name, promise) =>
     actionPromiseGeneric(ordersReducerSlice, name, promise);
 
 let ordersReducer = ordersReducerSlice.reducer;
-export { ordersReducer, actionOrdersCount, actionFindOrders, actionOrderFindOne, getCurrentOrder }
+export { ordersReducer, actionOrdersCount, actionFindOrders, actionOrderFindOne, actionPlaceOrder, getCurrentOrder }