Parcourir la source

rtk_dnd_wo_upload

Gennadysht il y a 2 ans
Parent
commit
4d04b005f1

+ 0 - 3
src/App.js

@@ -81,9 +81,6 @@ function App() {
 
   return (
     <>
-      <CSortedFileDropZone />
-      
-      
       <Router history={history}>
         <Provider store={store}>
           <div className="App">

+ 47 - 29
src/Components/EditableGood.js

@@ -1,12 +1,14 @@
 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 { Container, Grid, Card, CardContent, CardMedia, AvatarGroup, CardActions, IconButton, TextField, InputAdornment, Box } 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';
+import { CSortedFileDropZone } from './SortedFileDropZone';
+import { MyDropzone } from './FileDropZone';
 
 
 export const ExpandMore = styled(props => {
@@ -35,7 +37,7 @@ export const AvatarGroupOriented = styled((props) => {
     ".MuiAvatar-root": { /*width: 20, height: 20,*/ marginLeft: 1 }
 }));
 
-const EditableGood = ({ goodExt, maxWidth = 'md', saveGood }) => {
+const EditableGood = ({ good: goodExt, maxWidth = 'md', saveGood }) => {
     let [good, setGood] = useState(goodExt);
     const setGoodData = (data) => {
         let goodData = { ...good, ...data };
@@ -47,8 +49,8 @@ const EditableGood = ({ goodExt, maxWidth = 'md', saveGood }) => {
     return good && (
         <Container maxWidth={maxWidth}>
             <Card variant='outlined'>
-                <Grid container spacing={maxWidth === 'xs' ? 7 : 5}>
-                    <Grid item xs>
+                <Grid container spacing={maxWidth === 'xs' ? 7 : 5} rowSpacing={2}>
+                    <Grid item xs={12}>
                         <Grid container spacing={2}>
                             <Grid item xs={4}>
                                 <CardMedia
@@ -60,33 +62,49 @@ const EditableGood = ({ goodExt, maxWidth = 'md', saveGood }) => {
                             </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 })}
-                                    />
+                                    <Grid container rowSpacing={2}>
+                                        <Grid item width="100%">
+                                            <TextField
+                                                required
+                                                id="outlined-required"
+                                                label="Name"
+                                                value={good.name}
+                                                onChange={event => setGoodData({ name: event.target.value })}
+                                                fullWidth 
+                                            />
+                                        </Grid>
+                                        <Grid item width="100%">
+                                            <TextField
+                                                required
+                                                id="outlined-required"
+                                                label="Price"
+                                                type="number"
+                                                startAdornment={<InputAdornment position="start">$</InputAdornment>}
+                                                value={good.price}
+                                                onChange={event => setGoodData({ price: +event.target.value })}
+                                                fullWidth 
+                                            />
+                                        </Grid>
+                                        <Grid item width="100%">
+                                            <TextField
+                                                required
+                                                id="outlined-required"
+                                                label="Description"
+                                                value={good.description}
+                                                onChange={event => setGoodData({ description: event.target.value })}
+                                                multiline={true}
+                                                rows={15}
+                                                fullWidth 
+                                            />
+                                        </Grid>
+                                    </Grid>
                                 </CardContent>
                             </Grid>
                         </Grid>
                     </Grid>
+                    <Grid>
+                        <CSortedFileDropZone/>
+                    </Grid>
                 </Grid>
                 <CardActions>
                     <Button size='small' color='primary'
@@ -105,7 +123,7 @@ const EditableGood = ({ goodExt, maxWidth = 'md', saveGood }) => {
     )
 }
 
-const CEditableGood = (maxWidth = 'md') => {
+const CEditableGood = ({ maxWidth = 'md' }) => {
     const { _id } = useParams();
     const { isLoading, data } = useGetGoodByIdQuery(_id);
     let good = isLoading ? { name: 'loading', goods: [] } : data?.GoodFindOne;
@@ -113,7 +131,7 @@ const CEditableGood = (maxWidth = 'md') => {
     dispatch(actionSetCurrentGood(_id));
     const [saveGoodMutation, { }] = useSaveGoodMutation();
 
-    return <EditableGood saveGood={saveGoodMutation} goodExt={good} maxWidth={maxWidth} />
+    return <EditableGood saveGood={saveGoodMutation} good={good} maxWidth={maxWidth} />
 }
 
 export { CEditableGood }

+ 51 - 13
src/Components/FileDropZone.js

@@ -1,23 +1,61 @@
-import React, { useCallback } from 'react'
+import React, { useCallback, useState } from 'react'
 import { useDropzone } from 'react-dropzone'
 
-function FileDropZone() {
+function FileDropZone({ onDropFiles }) {
+    const [paths, setPaths] = useState([]);
     const onDrop = useCallback(acceptedFiles => {
         // Do something with the files
-        let a = '';
-    }, [])
+        acceptedFiles = acceptedFiles.map(f => {
+            let url = URL.createObjectURL(f)
+            return { _id: null, name: f.path, url }
+        }
+        );
+        setPaths(acceptedFiles);
+        onDropFiles(acceptedFiles);
+    }, [setPaths])
     const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
-
+    console.log(paths);
     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>
+        <>
+            <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>
+        </>
     )
 }
+/*
+              {
+                paths.map(
+                    f => 
+                    <img key={f.name} src={f.url} />
+               )
+            }
+*/
+
+/*export function MyDropzone() {
+  const [paths, setPaths] = useState([]);
+
+  const onDrop = useCallback(acceptedFiles => {
+    setPaths(acceptedFiles.map(file => URL.createObjectURL(file)));
+  }, [setPaths]);
+  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
+
+  return (
+    <div>
+      <div {...getRootProps()}>
+        <input {...getInputProps()} />
+        <p>Drop the files here ...</p>
+      </div>
+      {paths.map(path => 
+        <img key={path} src={path} />
+       )}
+    </div>
+  );
+}*/
 
 export { FileDropZone }

+ 1 - 1
src/Components/Good.js

@@ -121,7 +121,7 @@ const Good = ({ good, maxWidth = 'md', showAddToCard = true, actionAddGoodToCart
     )
 }
 
-const CGood = (maxWidth = 'md', showAddToCard = true) => {
+const CGood = ({maxWidth = 'md', showAddToCard = true}) => {
     const { _id } = useParams();
     const { isLoading, data } = useGetGoodByIdQuery(_id);
     let good = isLoading ? { name: 'loading', goods: [] } : data?.GoodFindOne;

+ 2 - 2
src/Components/SortedDropZone.js

@@ -100,8 +100,8 @@ function SortedDropZone({ items: startItems, render, itemProp, keyField, onChang
                     items={items}
                     itemProp={itemProp}
                     keyField={keyField}
-                    render={render} >
-                </Droppable>
+                    render={render}
+                />
             </div>
         </DndContext>
     );

+ 48 - 21
src/Components/SortedFileDropZone.js

@@ -34,7 +34,7 @@ const SortableItem = (props) => {
 
     return (
         <div style={itemStyle} ref={setNodeRef} {...attributes} {...listeners}>
-            <Render {...{ [props.itemProp]: props.item }} />
+            <Render {...{ item: props.item, ...(props.itemProp ?? {}) }} />
         </div>
     );
 };
@@ -60,14 +60,27 @@ const Droppable = ({ id, items = [], itemProp, keyField, render }) => {
     );
 };
 
-function CSortedFileDropZone({ items: startItems, render, itemProp, keyField, onChange, horizontal }) {
+function CSortedFileDropZone(props) {
+    let render = file => {
+        file = file.item;
+        return (
+            <div>
+                <img key={file.name} src={file.url} {...props.itemProp}/>
+            </div>
+        );
+    }
+    props = { ...props, render: render, keyField: "name", itemProp: {width: "100px"} }
+    return <SortedFileDropZone {...props} />
 }
 
 function SortedFileDropZone({ items: startItems, render, itemProp, keyField, onChange, horizontal }) {
     const [items, setItems] = useState(
-        startItems
+        startItems ?? []
     );
-    useEffect(() => setItems(startItems), [startItems])
+    useEffect(() => {
+        return setItems(startItems ?? []);
+    }
+        , [startItems])
 
     useEffect(() => {
         if (typeof onChange === 'function') {
@@ -83,33 +96,47 @@ function SortedFileDropZone({ items: startItems, render, itemProp, keyField, onC
     );
 
     const handleDragEnd = ({ active, over }) => {
-        const activeIndex = active.data.current.sortable.index;
-        const overIndex = over.data.current?.sortable.index || 0;
+        let activeIndex = active.data.current.sortable.index;
+        let overIndex = over?.data.current?.sortable.index;
 
         setItems((items) => {
-            return arrayMoveImmutable(items, activeIndex, overIndex)
+            if (overIndex === undefined) {
+                if (items.length === 1)
+                    activeIndex = 0;
+                items.splice(activeIndex, 1);
+                return items;
+            }
+            else
+                return arrayMoveImmutable(items, activeIndex, overIndex)
         });
     }
 
+    const onDropFiles = droppedFiles => {
+        return setItems(items => {
+            return [...items, ...droppedFiles]
+        }
+        );
+    }
+
     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 onDropFiles={onDropFiles}>
             </FileDropZone>
+            <DndContext
+                sensors={sensors}
+                onDragEnd={handleDragEnd}
+            >
+                <div style={containerStyle}>
+                    <Droppable id="aaa"
+                        items={items}
+                        itemProp={itemProp}
+                        keyField={keyField}
+                        render={render} >
+                    </Droppable>
+                </div>
+            </DndContext>
         </>
     );
 }