Explorar el Código

rtk_cart_clear_orderid

Gennadysht hace 2 años
padre
commit
7ec5d0646a

+ 185 - 0
package-lock.json

@@ -8,6 +8,9 @@
       "name": "shop-project",
       "version": "0.1.0",
       "dependencies": {
+        "@dnd-kit/core": "^6.0.7",
+        "@dnd-kit/modifiers": "^6.0.1",
+        "@dnd-kit/sortable": "^7.0.2",
         "@emotion/react": "^11.10.5",
         "@emotion/styled": "^11.10.5",
         "@fontsource/roboto": "^4.5.8",
@@ -19,12 +22,14 @@
         "@testing-library/jest-dom": "^5.16.5",
         "@testing-library/react": "^13.4.0",
         "@testing-library/user-event": "^13.5.0",
+        "array-move": "^4.0.0",
         "graphql-request": "^5.1.0",
         "http-proxy-middleware": "^2.0.6",
         "install": "^0.13.0",
         "npm": "^9.3.1",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
+        "react-dropzone": "^14.2.3",
         "react-lorem-ipsum": "^1.4.10",
         "react-redux": "^8.0.5",
         "react-router-dom": "^5.3.0",
@@ -2156,6 +2161,68 @@
         "postcss-selector-parser": "^6.0.10"
       }
     },
+    "node_modules/@dnd-kit/accessibility": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
+      "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
+      "dependencies": {
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0"
+      }
+    },
+    "node_modules/@dnd-kit/core": {
+      "version": "6.0.7",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.7.tgz",
+      "integrity": "sha512-qcLBTVTjmLuLqC0RHQ+dFKN5neWmAI56H9xZ+he9WEJEkAvR76YAcz7DSWDJfjErepfG2H3Fkb9lYiX7cPR62g==",
+      "dependencies": {
+        "@dnd-kit/accessibility": "^3.0.0",
+        "@dnd-kit/utilities": "^3.2.1",
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0",
+        "react-dom": ">=16.8.0"
+      }
+    },
+    "node_modules/@dnd-kit/modifiers": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.1.tgz",
+      "integrity": "sha512-rbxcsg3HhzlcMHVHWDuh9LCjpOVAgqbV78wLGI8tziXY3+qcMQ61qVXIvNKQFuhj75dSfD+o+PYZQ/NUk2A23A==",
+      "dependencies": {
+        "@dnd-kit/utilities": "^3.2.1",
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "@dnd-kit/core": "^6.0.6",
+        "react": ">=16.8.0"
+      }
+    },
+    "node_modules/@dnd-kit/sortable": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-7.0.2.tgz",
+      "integrity": "sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==",
+      "dependencies": {
+        "@dnd-kit/utilities": "^3.2.0",
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "@dnd-kit/core": "^6.0.7",
+        "react": ">=16.8.0"
+      }
+    },
+    "node_modules/@dnd-kit/utilities": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz",
+      "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==",
+      "dependencies": {
+        "tslib": "^2.0.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0"
+      }
+    },
     "node_modules/@emotion/babel-plugin": {
       "version": "11.10.5",
       "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz",
@@ -5398,6 +5465,17 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/array-move": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/array-move/-/array-move-4.0.0.tgz",
+      "integrity": "sha512-+RY54S8OuVvg94THpneQvFRmqWdAHeqtMzgMW6JNurHxe8rsS07cHQdfGkXnTUXiBcyZ0j3SiDIxxj0RPiqCkQ==",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/array-union": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -5498,6 +5576,14 @@
         "node": ">= 4.0.0"
       }
     },
+    "node_modules/attr-accept": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
+      "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/autoprefixer": {
       "version": "10.4.13",
       "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz",
@@ -8521,6 +8607,17 @@
         "webpack": "^4.0.0 || ^5.0.0"
       }
     },
+    "node_modules/file-selector": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
+      "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
+      "dependencies": {
+        "tslib": "^2.4.0"
+      },
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/filelist": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -17598,6 +17695,22 @@
         "react": "^18.2.0"
       }
     },
+    "node_modules/react-dropzone": {
+      "version": "14.2.3",
+      "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
+      "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
+      "dependencies": {
+        "attr-accept": "^2.2.2",
+        "file-selector": "^0.6.0",
+        "prop-types": "^15.8.1"
+      },
+      "engines": {
+        "node": ">= 10.13"
+      },
+      "peerDependencies": {
+        "react": ">= 16.8 || 18.0.0"
+      }
+    },
     "node_modules/react-error-overlay": {
       "version": "6.0.11",
       "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
@@ -22104,6 +22217,50 @@
       "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
       "requires": {}
     },
+    "@dnd-kit/accessibility": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
+      "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
+      "requires": {
+        "tslib": "^2.0.0"
+      }
+    },
+    "@dnd-kit/core": {
+      "version": "6.0.7",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.7.tgz",
+      "integrity": "sha512-qcLBTVTjmLuLqC0RHQ+dFKN5neWmAI56H9xZ+he9WEJEkAvR76YAcz7DSWDJfjErepfG2H3Fkb9lYiX7cPR62g==",
+      "requires": {
+        "@dnd-kit/accessibility": "^3.0.0",
+        "@dnd-kit/utilities": "^3.2.1",
+        "tslib": "^2.0.0"
+      }
+    },
+    "@dnd-kit/modifiers": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-6.0.1.tgz",
+      "integrity": "sha512-rbxcsg3HhzlcMHVHWDuh9LCjpOVAgqbV78wLGI8tziXY3+qcMQ61qVXIvNKQFuhj75dSfD+o+PYZQ/NUk2A23A==",
+      "requires": {
+        "@dnd-kit/utilities": "^3.2.1",
+        "tslib": "^2.0.0"
+      }
+    },
+    "@dnd-kit/sortable": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-7.0.2.tgz",
+      "integrity": "sha512-wDkBHHf9iCi1veM834Gbk1429bd4lHX4RpAwT0y2cHLf246GAvU2sVw/oxWNpPKQNQRQaeGXhAVgrOl1IT+iyA==",
+      "requires": {
+        "@dnd-kit/utilities": "^3.2.0",
+        "tslib": "^2.0.0"
+      }
+    },
+    "@dnd-kit/utilities": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz",
+      "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==",
+      "requires": {
+        "tslib": "^2.0.0"
+      }
+    },
     "@emotion/babel-plugin": {
       "version": "11.10.5",
       "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz",
@@ -24449,6 +24606,11 @@
         "is-string": "^1.0.7"
       }
     },
+    "array-move": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/array-move/-/array-move-4.0.0.tgz",
+      "integrity": "sha512-+RY54S8OuVvg94THpneQvFRmqWdAHeqtMzgMW6JNurHxe8rsS07cHQdfGkXnTUXiBcyZ0j3SiDIxxj0RPiqCkQ=="
+    },
     "array-union": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -24525,6 +24687,11 @@
       "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
       "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
     },
+    "attr-accept": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
+      "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg=="
+    },
     "autoprefixer": {
       "version": "10.4.13",
       "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz",
@@ -26751,6 +26918,14 @@
         "schema-utils": "^3.0.0"
       }
     },
+    "file-selector": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
+      "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
+      "requires": {
+        "tslib": "^2.4.0"
+      }
+    },
     "filelist": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@@ -32963,6 +33138,16 @@
         "scheduler": "^0.23.0"
       }
     },
+    "react-dropzone": {
+      "version": "14.2.3",
+      "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
+      "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
+      "requires": {
+        "attr-accept": "^2.2.2",
+        "file-selector": "^0.6.0",
+        "prop-types": "^15.8.1"
+      }
+    },
     "react-error-overlay": {
       "version": "6.0.11",
       "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",

+ 5 - 0
package.json

@@ -3,6 +3,9 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "@dnd-kit/core": "^6.0.7",
+    "@dnd-kit/modifiers": "^6.0.1",
+    "@dnd-kit/sortable": "^7.0.2",
     "@emotion/react": "^11.10.5",
     "@emotion/styled": "^11.10.5",
     "@fontsource/roboto": "^4.5.8",
@@ -14,12 +17,14 @@
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "^13.4.0",
     "@testing-library/user-event": "^13.5.0",
+    "array-move": "^4.0.0",
     "graphql-request": "^5.1.0",
     "http-proxy-middleware": "^2.0.6",
     "install": "^0.13.0",
     "npm": "^9.3.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
+    "react-dropzone": "^14.2.3",
     "react-lorem-ipsum": "^1.4.10",
     "react-redux": "^8.0.5",
     "react-router-dom": "^5.3.0",

+ 8 - 2
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 } from "./Components";
+import { CGood, CGoodsList, CLoginForm, CMainAppBar, COrder, COrdersList, CSortedFileDropZone } from "./Components";
 import { CLogout } from './Components';
 import { CSidebar } from './Components/Sidebar';
 import { CRootCats } from './Components';
@@ -24,6 +24,8 @@ import {
   PURGE,
   REGISTER,
 } from 'redux-persist';
+import { EditPost } from './Test/drop';
+import { FileDropZone } from './Components/FileDropZone';
 
 
 
@@ -73,11 +75,15 @@ const Main = () =>
     <h1>Main page</h1>
   </div>
 
-
+//<EditPost onSave={post => console.log(post)}/>
+//<SortedDropZone />
 function App() {
 
   return (
     <>
+      <CSortedFileDropZone />
+      
+      
       <Router history={history}>
         <Provider store={store}>
           <div className="App">

+ 1 - 2
src/Components/Cart.js

@@ -14,7 +14,7 @@ const mapCountToGood = (goodData, goodsCounts) => {
     return count;
 }
 
-const Cart = ({ uniqueId }) => {
+const Cart = () => {
     let goods = useSelector(state => state.cart.goods) ?? [];
     let { isLoading, data } = useGetCartGoodsQuery({ goods });
     let goodsData = data?.GoodFind?.map(gd => ({ ...gd, count: mapCountToGood(gd, goods) })) ?? [];
@@ -24,7 +24,6 @@ const Cart = ({ uniqueId }) => {
         order.push({ good: { _id: good._id }, count: good.count });
     }
     const [addOrderMutation, { isLoading: isOrderAdding, data: orderAddingData }] = useAddOrderMutation();
-    const dispatch = useDispatch();
     return !isLoading && (
         <>
             <Container>

+ 23 - 0
src/Components/FileDropZone.js

@@ -0,0 +1,23 @@
+import React, { useCallback } from 'react'
+import { useDropzone } from 'react-dropzone'
+
+function FileDropZone() {
+    const onDrop = useCallback(acceptedFiles => {
+        // Do something with the files
+        let a = '';
+    }, [])
+    const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
+
+    return (
+        <div {...getRootProps()}>
+            <input {...getInputProps()} />
+            {
+                isDragActive ?
+                    <p>Drop the files here ...</p> :
+                    <p>Drag 'n' drop some files here, or click to select files</p>
+            }
+        </div>
+    )
+}
+
+export { FileDropZone }

+ 109 - 0
src/Components/SortedDropZone.js

@@ -0,0 +1,109 @@
+import { DndContext, KeyboardSensor, PointerSensor, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
+import { rectSortingStrategy, SortableContext, sortableKeyboardCoordinates, useSortable } from "@dnd-kit/sortable";
+import { arrayMoveImmutable } from "array-move";
+import { useEffect, useState } from "react";
+import { CSS } from "@dnd-kit/utilities";
+
+const SortableItem = (props) => {
+    const {
+        attributes,
+        listeners,
+        setNodeRef,
+        transform,
+        transition
+    } = useSortable({ id: props.id });
+
+    const itemStyle = {
+        transform: CSS.Transform.toString(transform),
+        transition,
+        //width: 110,
+        //height: 30,
+        //display: "flex",
+        //alignItems: "center",
+        //paddingLeft: 5,
+        //border: "1px solid gray",
+        //borderRadius: 5,
+        //marginBottom: 5,
+        //userSelect: "none",
+        cursor: "grab",
+        //boxSizing: "border-box"
+    };
+
+    const Render = props.render
+
+    return (
+        <div style={itemStyle} ref={setNodeRef} {...attributes} {...listeners}>
+            <Render {...{ [props.itemProp]: props.item }} />
+        </div>
+    );
+};
+
+
+const Droppable = ({ id, items = [], itemProp, keyField, render }) => {
+    const { setNodeRef } = useDroppable({ id });
+
+    const droppableStyle = {
+        //padding: "20px 10px",
+        //border: "1px solid black",
+        //borderRadius: "5px",
+        //minWidth: 110
+    };
+
+    return (
+        <SortableContext id={id} items={items} strategy={rectSortingStrategy}>
+            {items.map((item) => (
+                <SortableItem render={render} key={item[keyField]} id={item}
+                    itemProp={itemProp} item={item} />
+            ))}
+        </SortableContext>
+    );
+};
+
+
+function SortedDropZone({ items: startItems, render, itemProp, keyField, onChange, horizontal }) {
+    const [items, setItems] = useState(
+        startItems
+    );
+    useEffect(() => setItems(startItems), [startItems])
+
+    useEffect(() => {
+        if (typeof onChange === 'function') {
+            onChange(items)
+        }
+    }, [items])
+
+    const sensors = useSensors(
+        useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
+        useSensor(KeyboardSensor, {
+            coordinateGetter: sortableKeyboardCoordinates
+        })
+    );
+
+    const handleDragEnd = ({ active, over }) => {
+        const activeIndex = active.data.current.sortable.index;
+        const overIndex = over.data.current?.sortable.index || 0;
+
+        setItems((items) => {
+            return arrayMoveImmutable(items, activeIndex, overIndex)
+        });
+    }
+
+    const containerStyle = { display: horizontal ? "flex" : '' };
+
+    return (
+        <DndContext
+            sensors={sensors}
+            onDragEnd={handleDragEnd}
+        >
+            <div style={containerStyle}>
+                <Droppable id="aaa"
+                    items={items}
+                    itemProp={itemProp}
+                    keyField={keyField}
+                    render={render} >
+                </Droppable>
+            </div>
+        </DndContext>
+    );
+}
+export { SortedDropZone };

+ 116 - 0
src/Components/SortedFileDropZone.js

@@ -0,0 +1,116 @@
+import { DndContext, KeyboardSensor, PointerSensor, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
+import { rectSortingStrategy, SortableContext, sortableKeyboardCoordinates, useSortable } from "@dnd-kit/sortable";
+import { arrayMoveImmutable } from "array-move";
+import { useEffect, useState } from "react";
+import { CSS } from "@dnd-kit/utilities";
+import { FileDropZone } from "./FileDropZone";
+
+const SortableItem = (props) => {
+    const {
+        attributes,
+        listeners,
+        setNodeRef,
+        transform,
+        transition
+    } = useSortable({ id: props.id });
+
+    const itemStyle = {
+        transform: CSS.Transform.toString(transform),
+        transition,
+        //width: 110,
+        //height: 30,
+        //display: "flex",
+        //alignItems: "center",
+        //paddingLeft: 5,
+        //border: "1px solid gray",
+        //borderRadius: 5,
+        //marginBottom: 5,
+        //userSelect: "none",
+        cursor: "grab",
+        //boxSizing: "border-box"
+    };
+
+    const Render = props.render
+
+    return (
+        <div style={itemStyle} ref={setNodeRef} {...attributes} {...listeners}>
+            <Render {...{ [props.itemProp]: props.item }} />
+        </div>
+    );
+};
+
+
+const Droppable = ({ id, items = [], itemProp, keyField, render }) => {
+    const { setNodeRef } = useDroppable({ id });
+
+    const droppableStyle = {
+        //padding: "20px 10px",
+        //border: "1px solid black",
+        //borderRadius: "5px",
+        //minWidth: 110
+    };
+
+    return (
+        <SortableContext id={id} items={items} strategy={rectSortingStrategy}>
+            {items.map((item) => (
+                <SortableItem render={render} key={item[keyField]} id={item}
+                    itemProp={itemProp} item={item} />
+            ))}
+        </SortableContext>
+    );
+};
+
+function CSortedFileDropZone({ items: startItems, render, itemProp, keyField, onChange, horizontal }) {
+}
+
+function SortedFileDropZone({ items: startItems, render, itemProp, keyField, onChange, horizontal }) {
+    const [items, setItems] = useState(
+        startItems
+    );
+    useEffect(() => setItems(startItems), [startItems])
+
+    useEffect(() => {
+        if (typeof onChange === 'function') {
+            onChange(items)
+        }
+    }, [items])
+
+    const sensors = useSensors(
+        useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
+        useSensor(KeyboardSensor, {
+            coordinateGetter: sortableKeyboardCoordinates
+        })
+    );
+
+    const handleDragEnd = ({ active, over }) => {
+        const activeIndex = active.data.current.sortable.index;
+        const overIndex = over.data.current?.sortable.index || 0;
+
+        setItems((items) => {
+            return arrayMoveImmutable(items, activeIndex, overIndex)
+        });
+    }
+
+    const containerStyle = { display: horizontal ? "flex" : '' };
+
+    return (
+        <>
+            <FileDropZone>
+                <DndContext
+                    sensors={sensors}
+                    onDragEnd={handleDragEnd}
+                >
+                    <div style={containerStyle}>
+                        <Droppable id="aaa"
+                            items={items}
+                            itemProp={itemProp}
+                            keyField={keyField}
+                            render={render} >
+                        </Droppable>
+                    </div>
+                </DndContext>
+            </FileDropZone>
+        </>
+    );
+}
+export { CSortedFileDropZone };

+ 4 - 2
src/Components/index.js

@@ -3,10 +3,12 @@ export { CGoodItem } from './GoodItem';
 export { CGood } from './Good';
 export { CGoodsList } from './GoodsList';
 export { OrderGood } from './OrderGood';
-export { OrderGoodsList} from './OrderGoodsList'
+export { OrderGoodsList } from './OrderGoodsList'
 export { COrder } from './Order';
 export { COrdersList } from './OrderList';
 export { MyLink } from './MyLink';
 export { CLogout } from './Logout';
 export { CMainAppBar } from './MainAppBar';
-export { CRootCats } from './RootCats';
+export { CRootCats } from './RootCats';
+export { SortedDropZone } from './SortedDropZone';
+export { CSortedFileDropZone } from './SortedFileDropZone';

+ 52 - 0
src/Test/drop.js

@@ -0,0 +1,52 @@
+import { useState } from "react"
+import { SortedDropZone } from "../Components"
+
+const imgSet = ['https://mir-s3-cdn-cf.behance.net/project_modules/disp/8a1f1813765711.56277edb36b94.gif',
+    'http://shop.asmer.fe.a-level.com.ua/loading.gif',
+    'https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif?20151024034921'
+]
+
+const getRandomItemFromArr = arr => arr[Math.floor(Math.random() * arr.length)]
+
+const PostImage = ({ image, onDelete }) =>
+    <img src={image.url} key={image._id} onClick={() => onDelete(image)} />
+
+const EditPost = ({ onSave }) => {
+    const [post, setPost] = useState({ title: '', text: '', images: [] })
+    const addImageToState = () => setPost({
+        ...post,
+        images: [...post.images,
+        { _id: Math.random(), url: getRandomItemFromArr(imgSet) }]
+    })
+    const deleteImage = image => setPost({ ...post, images: post.images.filter(i => i !== image) })
+
+    const localPostImage = ({ image }) => <PostImage image={image}
+        onDelete={imgToDelete => deleteImage(imgToDelete)} />
+    console.log(post)
+    return (
+        <div>
+            <input type='text' value={post.title} placeholder="title"
+                onChange={e => setPost({ ...post, title: e.target.value })} />
+            <input type='text' value={post.text} placeholder="text"
+                onChange={e => setPost({ ...post, text: e.target.value })} />
+            <div>
+                <SortedDropZone items={post.images} render={localPostImage} itemProp="image" keyField="_id"
+                    onChange={images => setPost({ ...post, images })}
+                    horizontal
+                />
+                <button onClick={addImageToState}>+</button>
+            </div>
+            <button onClick={() => onSave(post)}>Save</button>
+        </div>
+    )
+}
+
+const data = [{ name: 'aaa', _id: 'a1' }, { name: 'bbb', _id: 'b2' }, { name: 'ccc', _id: 'c3' }]
+
+
+const Item = ({ data: { name } }) =>
+    <div style={{ backgroundColor: 'yellow', fontSize: '2em', padding: '20px', borderRadius: '10px', margin: '10px' }}>
+        {name}
+    </div>
+
+export { EditPost }

+ 3 - 2
src/reducers/cartGoodsReducer.js

@@ -21,8 +21,9 @@ const cartGoodsApi = createApi({
     endpoints: (builder) => ({
         getCartGoods: builder.query({
             query: ({ goods }) => {
-                let params = createFullQuery({ queryExt: { _id: { "$in": goods.map(g => g._id) } } });
-                //JSON.stringify({ q: [{ _id: { "$in": goods.map(g => g._id) } }] });
+                let params = createFullQuery({queryExt: { _id: { "$in": goods.map(g => g._id) } } })
+                //{ q: { _id: { "$in": goods.map(g => g._id) } } };
+                //let params = JSON.stringify({ q: [{ _id: { "$in": goods.map(g => g._id) } }] });
                 return {
                     document: gql`
                         query GoodFind($q: String) {

+ 17 - 8
src/reducers/cartReducer.js

@@ -1,6 +1,8 @@
 import { createSlice } from "@reduxjs/toolkit"
 import { v4 } from "uuid";
+import { history } from "../App";
 import { findObjectIndexById } from "../utills";
+import { ordersApi } from "./ordersReducer";
 //import { clearCartData, getCartData } from "./cartGoodsReducer";
 
 const cartReducerSlice = createSlice({ //promiseReducer
@@ -9,11 +11,6 @@ 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) {
@@ -24,9 +21,7 @@ const cartReducerSlice = createSlice({ //promiseReducer
             return state;
         },
         cleanCart(state, action) {
-            localStorage.cart = { goods: [] };
-            setStateData(state, [], v4());
-            return state;
+            return cleanCartInt(state);
         },
         refreshCart(state, action) {
             state.uniqueId = v4();
@@ -63,8 +58,21 @@ const cartReducerSlice = createSlice({ //promiseReducer
             }
             return state;
         }
+    },
+    extraReducers: builder => {
+        builder.addMatcher(ordersApi.endpoints.addOrder.matchFulfilled,
+            (state, { payload }) => {
+                cleanCartInt(state);
+                let orderId = payload.OrderUpsert._id;
+                history.push(`/order/${orderId}`);
+            });
     }
 })
+function cleanCartInt(state) {
+    localStorage.cart = { goods: [] };
+    setStateData(state, [], v4());
+    return state;
+}
 
 let cartReducer = cartReducerSlice.reducer;
 let actionAddGoodToCart = (good, count = 1) =>
@@ -81,6 +89,7 @@ let actionRestoreCart = () =>
     async dispatch => {
         dispatch(cartReducerSlice.actions.restoreCart({}))
     }
+
 let actionClearCart = () =>
     async dispatch => {
         dispatch(cartReducerSlice.actions.cleanCart({}))

+ 2 - 8
src/reducers/frontEndReducer.js

@@ -1,5 +1,5 @@
-import { createSlice } from "@reduxjs/toolkit"
-import { useDispatch } from "react-redux";
+import { createSlice, current } from "@reduxjs/toolkit"
+import { v4 } from "uuid";
 import { actionClearCart } from "./cartReducer";
 import { categoryApi } from "./categoryReducer";
 import { goodsApi } from "./goodsReducer";
@@ -65,13 +65,7 @@ const frontEndReducerSlice = createSlice({ //promiseReducer
             (state, { payload }) => {
                 state.orders = { ordersCount: { payload: payload.OrderCount } }
             });
-        builder.addMatcher(ordersApi.endpoints.addOrder.matchFulfilled,
-            (state, { payload }) => {
-                const dispatch = useDispatch();
-                dispatch(actionClearCart());
-            });
     }
-
 })
 
 let frontEndReducer = frontEndReducerSlice.reducer;

+ 1 - 1
src/reducers/ordersReducer.js

@@ -85,7 +85,7 @@ const ordersApi = createApi({
                             } 
                         }
                         `,
-                variables: JSON.stringify({ order: { "_id": id, "orderGoods": order } })
+                variables: { order: { "_id": id, "orderGoods": order } }
             })
         }),
     }),