Browse Source

+sortable upsertPost +actionFindUser +actionPostUpsert

kurkabein 2 years ago
parent
commit
7cf9ae87d1

+ 2 - 1
src/App.js

@@ -19,7 +19,8 @@ function App() {
       <Provider store={store}>
       <Provider store={store}>
       <Switch>
       <Switch>
     <div className="App">
     <div className="App">
-      {localStorage.getItem("authToken") ? <Redirect to="/"/> : <Redirect to="/login"/>}
+      {/* localStorage.getItem("authToken") */
+      /* store.getState().auth.payload?.sub?.id ? <Redirect to="/"/> : <Redirect to="/login"/> */}
         <Route exact path="/login" component={CLoginForm}/>
         <Route exact path="/login" component={CLoginForm}/>
         <Route exact path="/register" component={CRegister}/>
         <Route exact path="/register" component={CRegister}/>
       {/* {store.auth.payload?.sub?.id ? <Redirect to="/"/> : <Redirect to="/login"/>} */}  
       {/* {store.auth.payload?.sub?.id ? <Redirect to="/"/> : <Redirect to="/login"/>} */}  

+ 27 - 3
src/actions/index.js

@@ -62,19 +62,23 @@ export const actionFullRegister = (login,password) => async (dispatch, getState)
       const {
       const {
         promise: {fullRegister}
         promise: {fullRegister}
       } = getState();
       } = getState();
-      if (fullRegister.status === "fULFILLED") {
+      if (fullRegister.status === "FULLFILLED") {
           dispatch(actionFullLogin(login,password))
           dispatch(actionFullLogin(login,password))
       }
       }
 }
 }
           
           
 
 
-export const actionFullLogin = (login,password) => async (dispatch) => {
+export const actionFullLogin = (login,password) => async (dispatch,getState) => {
    const tokennn = await dispatch(
    const tokennn = await dispatch(
     actionPromise('fullLogin', gql(`query login($login:String!,$password:String!){
     actionPromise('fullLogin', gql(`query login($login:String!,$password:String!){
         login(login:$login,password:$password)
         login(login:$login,password:$password)
     }`,{login:login,password:password}))
     }`,{login:login,password:password}))
    );
    );
    await dispatch(actionAuthLogin(tokennn));
    await dispatch(actionAuthLogin(tokennn));
+   const {
+     auth: {payload}
+   } = getState();
+   await dispatch(actionAboutMe(payload.sub.id));
 }
 }
 
 
 
 
@@ -93,6 +97,10 @@ return  fetch(backendURL+'/upload', {
 
 
 export const actionUploadFile = file => 
 export const actionUploadFile = file => 
   actionPromise('fileUpload', uploadFile(file));
   actionPromise('fileUpload', uploadFile(file));
+
+export const actionUploadFiles = files =>
+    Promise.all(files.map(file => uploadFile(file)))
+
 export const actionAvatar = (userrId, fileeId) => 
 export const actionAvatar = (userrId, fileeId) => 
   actionPromise("userAvatar", gql(`mutation setAvatar($userId: String, $fileId: ID){
   actionPromise("userAvatar", gql(`mutation setAvatar($userId: String, $fileId: ID){
     UserUpsert(user:{_id: $userId, avatar: {_id: $fileId}}){
     UserUpsert(user:{_id: $userId, avatar: {_id: $fileId}}){
@@ -124,4 +132,20 @@ export const actionSetAvatar = file =>
             await dispatch(actionAvatar(id,_id))
             await dispatch(actionAvatar(id,_id))
             await dispatch(actionAboutMe(id))
             await dispatch(actionAboutMe(id))
           }
           }
-        
+export const actionPostUpsert = post =>
+          actionPromise("postUpsert", gql(`mutation PostUpsert ($post: PostInput){
+            PostUpsert(post:$post){
+              _id
+            }
+          }`, {post:{...post,images:post.images.map(({_id})=>({_id}))}}))
+
+
+
+export const actionFindUser = nick =>
+          actionPromise("findUsers", gql(`query FindUsers($query: String){
+            UserFind(query:$query){
+              _id,nick,avatar{
+                url
+              }
+            }
+          }`, {query:nick}))          

+ 38 - 76
src/components/CreatePostPage/UpsertPost.js

@@ -2,6 +2,8 @@ import { useDropzone } from 'react-dropzone';
 import {arrayMoveImmutable} from 'array-move';
 import {arrayMoveImmutable} from 'array-move';
 import {sortableContainer, sortableElement} from 'react-sortable-hoc';
 import {sortableContainer, sortableElement} from 'react-sortable-hoc';
 import { useState } from 'react';
 import { useState } from 'react';
+import { actionPostUpsert } from '../../actions';
+import { connect } from 'react-redux';
 
 
 const backendURL = 'http://hipstagram.asmer.fs.a-level.com.ua';
 const backendURL = 'http://hipstagram.asmer.fs.a-level.com.ua';
 
 
@@ -10,54 +12,20 @@ const backendURL = 'http://hipstagram.asmer.fs.a-level.com.ua';
 
 
 
 
 
 
-function MyDropZone({props, onLoad}) {
-    const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
-    /* useEffect(() => {
-      if(acceptedFiles[0]){
-          onLoad(acceptedFiles[0])
-      }
-    },[acceptedFiles[0]]) */
-    const files = acceptedFiles.map(file => (
-      <li key={file.path}>
-        {file.path} - {file.size} bytes
-      </li>
-    ));
-  
-    return (
-      <section className="container">
-        <div {...getRootProps({className: 'dropzone'})}>
-          <input {...getInputProps()} />
-          <p>Drag 'n' drop some files here, or click to select files</p>
-        </div>
-        <aside>
-          <h4>Files</h4>
-          <ul>{files}</ul>
-        </aside>
-      </section>
-    );
-  }
-  
-
-
-let defaultPost = [{
-  "_id": "5d6d9aa25bc6e90a3ba1afe2",
-  "title": null,
-  "text": "aaa",
-  "images": [
-    "images/1f8973225107076a4e2f2e4ac5e35e74"
-   ,
-    "images/d766a6cb2d3c232f3e9241abf0751cbc"
-   ,
-    "images/b3def30bab7249af56ef341536327fd3"
-   
- ],
- "owner": {
-   "_id": "5d66e01dc6a7071408ac1e1c",
-   "nick": null
- } 
-}]
-
-const defImg = {images:[{url:"images/b3def30bab7249af56ef341536327fd3"},{url:"images/d766a6cb2d3c232f3e9241abf0751cbc"},{url:"images/1f8973225107076a4e2f2e4ac5e35e74"}]}
+
+
+let defaultPost =  {
+    "_id":"620bb700ad55d22f3e2fb320",
+    "title": null,
+    "text": "aaa",
+    "images": [
+      {"_id":"620bb640ad55d22f3e2fb31d","url":"images/52f69596333a282940913b2f2e157fb7"},
+      {"_id":"620bb66ead55d22f3e2fb31e","url":"images/b10fc2417bfe942a6e56d16d073af186"},
+      {"_id":"620bb6a5ad55d22f3e2fb31f","url":"images/9111d163d7fbc66ad9ce1c170bd7002e"}
+    ]
+  } 
+
+
 
 
 const Photo = ({photo}) => {
 const Photo = ({photo}) => {
   return (
   return (
@@ -65,16 +33,20 @@ const Photo = ({photo}) => {
   )
   )
 }
 }
 
 
+const SortableItem = sortableElement(({image}) => 
+<li>
+  {image._id}
+  <img src={`${backendURL}/${image.url}`}/>
+  </li>);
 
 
+const SortableContainer = sortableContainer(({children}) => {
+  return <div>{children}</div>;
+});
 
 
 
 
 
 
-  const defitems = {items:['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6']};
-
-
-
-  const EntityEditor = ({entity={images: []}, onSave, onFileDrop, fileStatus}) => {
-    const [state,setState] = useState(entity)
+ const PostEditor = ({post=defaultPost, onSave, onFileDrop, fileStatus}) => {
+    const [state,setState] = useState(post)
     //по файлу в дропзоне:
     //по файлу в дропзоне:
         //дергать onFileDrop
         //дергать onFileDrop
         //fileStatus - информация о заливке файла из redux
         //fileStatus - информация о заливке файла из redux
@@ -86,40 +58,30 @@ const Photo = ({photo}) => {
     //где-то рядом остальные поля из state типа title name text
     //где-то рядом остальные поля из state типа title name text
     //но это вы уже знаете
     //но это вы уже знаете
 
 
-    const SortableItem = sortableElement(({value}) => <div>
-    {/* <img src={`${backendURL}+"/"${value.images[0]}`} alt="photo"/> */}
-    <h2>{value._id}</h2>
-    <p>{value.text}</p>
-</div>);
-
-    const SortableContainer = sortableContainer(({children}) => {
-  return <div>{children}</div>;
-});
+    
 
 
 
 
     const  onSortEnd = ({oldIndex, newIndex}) => {
     const  onSortEnd = ({oldIndex, newIndex}) => {
-        console.log(state, oldIndex, newIndex, arrayMoveImmutable(state.images, oldIndex, newIndex));
-        setState((state) => {
-            return {images: arrayMoveImmutable(state.images, oldIndex, newIndex)}
-          })
-        /* setState((state) => ({
-            items: arrayMoveImmutable(state.items, oldIndex, newIndex),
-          })); */
+      setState({...state,images: arrayMoveImmutable(state.images,oldIndex,newIndex)}) 
+      
     }
     }
-    // console.log(state)
+     console.log(state)
             
             
     return(
     return(
-        <SortableContainer onSortEnd={onSortEnd}>
-        {state.images.map((value, index) => (
-          <SortableItem key={`item-${value}`} index={index} value={value} />
+      <>
+      <SortableContainer onSortEnd={onSortEnd}>
+      {state.images.map((image, index) => (
+          <SortableItem key={`item-${image._id}`} index={index} image={image} />
         ))}
         ))}
       </SortableContainer>
       </SortableContainer>
+      <button onClick={() => onSave(state)}>Save</button>
+      </>
     )
     )
 
 
 }
 }
 
 
 
 
-
+const  CPostEditor = connect(null,{onSave: actionPostUpsert})(PostEditor)
 
 
 
 
  const UpsertPost = () => {
  const UpsertPost = () => {
@@ -137,7 +99,7 @@ const Photo = ({photo}) => {
           <SortableItem key={`item-${value}`} index={index} value={value} />
           <SortableItem key={`item-${value}`} index={index} value={value} />
         ))}
         ))}
       </SortableContainer> */
       </SortableContainer> */
-      <EntityEditor entity={defaultPost}/>
+      <CPostEditor/>
     )
     )
         }
         }
 
 

+ 8 - 4
src/components/DropZone.js

@@ -1,13 +1,15 @@
 import { useDropzone } from 'react-dropzone';
 import { useDropzone } from 'react-dropzone';
 import { useEffect } from 'react';
 import { useEffect } from 'react';
+import { connect } from 'react-redux';
+import { actionSetAvatar } from '../actions';
 
 
 function DropZoneForFiles ({props, onLoad}) {
 function DropZoneForFiles ({props, onLoad}) {
     const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
     const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
     useEffect(() => {
     useEffect(() => {
-      if(acceptedFiles[0]){
-          onLoad(acceptedFiles[0])
+      if(acceptedFiles){
+          onLoad(acceptedFiles)
       }
       }
-    },[acceptedFiles[0]])
+    },[acceptedFiles])
     const files = acceptedFiles.map(file => (
     const files = acceptedFiles.map(file => (
       <li key={file.path}>
       <li key={file.path}>
         {file.path} - {file.size} bytes
         {file.path} - {file.size} bytes
@@ -28,4 +30,6 @@ function DropZoneForFiles ({props, onLoad}) {
     );
     );
   }
   }
 
 
-  export default DropZoneForFiles;
+  const CDropZoneForFiles = connect(null,{onLoad: actionSetAvatar})(DropZoneForFiles)
+
+  export default CDropZoneForFiles;

+ 1 - 1
src/components/Header.js

@@ -33,7 +33,7 @@ const UserBlock = ({userInfo = defaultUserInfo}) => {
     return(
     return(
         <div className="relative inline-block text-left">
         <div className="relative inline-block text-left">
                         <button onClick={() => setIsOpen(!isOpen)}>
                         <button onClick={() => setIsOpen(!isOpen)}>
-                            {userInfo.nick}
+                            {userInfo.nick ? userInfo.nick : "something"}
                         </button>
                         </button>
                     {isOpen && <div className="origin-top-right absolute right-0 mt-2 w-36 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none flex justify-center">
                     {isOpen && <div className="origin-top-right absolute right-0 mt-2 w-36 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none flex justify-center">
                         <div className="py-1 w-full text-center">
                         <div className="py-1 w-full text-center">

+ 7 - 5
src/components/MainPage/Main.js

@@ -10,11 +10,13 @@ import { connect } from 'react-redux';
 import store from '../../reducers';
 import store from '../../reducers';
 
 
 const Main = ({auth}) => {
 const Main = ({auth}) => {
-    console.log(auth)
-useEffect(()=>{
-    
-    store.dispatch(actionAboutMe(auth));
-})
+/* useEffect(()=>{
+    if(auth){ 
+   store.dispatch(actionAboutMe(auth));
+    } else {
+        <Redirect to="/login"/>
+    }
+}) */
 
 
     return(
     return(
         <div className='flex mx-auto px-4 justify-between p-6 xl:container xls:mx-auto'>
         <div className='flex mx-auto px-4 justify-between p-6 xl:container xls:mx-auto'>

+ 4 - 2
src/components/UserSettings/UserSettings.js

@@ -1,4 +1,4 @@
-import DropZoneForFiles from "../DropZone";
+import CDropZoneForFiles from "../DropZone";
 
 
 const UserSettings = () =>{
 const UserSettings = () =>{
     return(
     return(
@@ -16,7 +16,7 @@ const UserSettings = () =>{
                     </div>
                     </div>
                     <div>
                     <div>
                         <label>Avatar:</label>
                         <label>Avatar:</label>
-                        <DropZoneForFiles/>
+                        <CDropZoneForFiles/>
                     </div>
                     </div>
                     <button className="LoginButton">Save Settings</button>
                     <button className="LoginButton">Save Settings</button>
                 </div>
                 </div>
@@ -27,4 +27,6 @@ const UserSettings = () =>{
 }
 }
 
 
 
 
+
+
 export default UserSettings;
 export default UserSettings;

+ 4 - 0
src/reducers/index.js

@@ -1,5 +1,6 @@
 import {createStore, applyMiddleware, combineReducers} from 'redux';
 import {createStore, applyMiddleware, combineReducers} from 'redux';
 import thunk from 'redux-thunk';
 import thunk from 'redux-thunk';
+import { actionAboutMe } from '../actions';
 
 
 
 
 function promiseReducer(state={}, {type,name,status,payload,error}){
 function promiseReducer(state={}, {type,name,status,payload,error}){
@@ -51,6 +52,9 @@ function promiseReducer(state={}, {type,name,status,payload,error}){
   }
   }
   
   
   const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer}), applyMiddleware(thunk))
   const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer}), applyMiddleware(thunk))
+  if(store.getState().auth){
+  store.dispatch(actionAboutMe(store.getState().auth?.payload?.sub?.id))
+  }
   store.subscribe(() => console.log(store.getState()));
   store.subscribe(() => console.log(store.getState()));
   
   
 export default store;
 export default store;