Prechádzať zdrojové kódy

added fullRegister with Login +Usersettings(not complite) +Dropzone +ReworkHeader +addQuerys for main page

kurkabein 2 rokov pred
rodič
commit
bfd87cceed

+ 12 - 7
src/App.js

@@ -1,30 +1,35 @@
 
 import './App.scss';
 import Header from './components/Header';
-import Main from './components/MainPage/Main';
+import CMain from './components/MainPage/Main';
 import CLoginForm from './components/LoginPage/Login';
-import Register from './components/RegisterPage/Register';
+import CRegister from './components/RegisterPage/Register';
 import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
 import createHistory from "history/createBrowserHistory";
 import { Provider } from 'react-redux';
 import store from './reducers';
+import { Redirect } from 'react-router-dom';
 const history = createHistory();
 
 
 function App() {
+    
   return (
     <Router history={history}>
       <Provider store={store}>
       <Switch>
     <div className="App">
-        {/* {store.auth.payload?.sub?.id && } */}
+      {localStorage.getItem("authToken") ? <Redirect to="/"/> : <Redirect to="/login"/>}
         <Route exact path="/login" component={CLoginForm}/>
-        <Route exact path="/register" component={Register}/>
+        <Route exact path="/register" component={CRegister}/>
+      {/* {store.auth.payload?.sub?.id ? <Redirect to="/"/> : <Redirect to="/login"/>} */}  
         <Route exact path="/" component={Header}/>
-        <Route exact path="/" component={Main}/>
+        <Route exact path="/" component={CMain}/>
         <Route exact path="/collections" component={Header}/>
-        <Route exact path="/collections" component={Main}/>
-        <Route exact path="/createpost" component={Main}/>
+        <Route exact path="/collections" component={CMain}/>
+        <Route exact path="/createpost" component={CMain}/>
+        <Route exact path="/settings" component={Header}/>
+        <Route exact path="/settings" component={CMain}/>
     </div>
     </Switch>
     </Provider>

+ 47 - 28
src/actions/index.js

@@ -19,17 +19,6 @@ const backendURL = 'http://hipstagram.asmer.fs.a-level.com.ua';
 const gql = getGQL(backendURL + '/graphql');
 
 
-const uploadFile = file => {
-    const fd = new FormData;
-    fd.append('photo', file);
-  return  fetch(backendURL+'/upload', {
-      method: "POST",
-      headers: localStorage.authToken ? {Authorization: 'Bearer ' + localStorage.authToken} : {},
-      body: fd
-  }).then(res => res.json());
-  
-}
-
 
 
 
@@ -52,28 +41,32 @@ export const actionPromise = (name,promise) =>{
  }
 }
 
-export const actionUploadFile = file => 
-  actionPromise('fileUpload', uploadFile(file));
-export const actionAvatar = (userrId, fileeId) => 
-  actionPromise("userAvatar", gql(`mutation setAvatar($userId: String, $fileId: ID){
-    UserUpsert(user:{_id: $userId, avatar: {_id: $fileId}}){
-        _id, avatar{
-            _id
-        }
-    }
-}`, {userId: userrId,
-      fileId: fileeId}))
 
 export const actionAuthLogin = (tokennn) =>({type:'AUTH_LOGIN',token:tokennn})
 export const actionAuthLogout= () => ({type: 'AUTH_LOGOUT'})
 
 
-export const actionFullRegister = (Login,password) =>
-          actionPromise('fullRegister', gql(`mutation register($login:String!,$password:String!){
-            UserUpsert(user:{login:$login,password:$password}){
-              _id login
-            }
-          }`,{login: Login, password: password}))
+
+
+
+
+
+export const actionFullRegister = (login,password) => async (dispatch, getState) => {
+      await dispatch(
+        actionPromise('fullRegister', gql(`mutation register($login:String!,$password:String!){
+          UserUpsert(user:{login:$login,password:$password}){
+            _id login
+          }
+        }`,{login: login, password: password}))
+      );
+      const {
+        promise: {fullRegister}
+      } = getState();
+      if (fullRegister.status === "fULFILLED") {
+          dispatch(actionFullLogin(login,password))
+      }
+}
+          
 
 export const actionFullLogin = (login,password) => async (dispatch) => {
    const tokennn = await dispatch(
@@ -84,6 +77,32 @@ export const actionFullLogin = (login,password) => async (dispatch) => {
    await dispatch(actionAuthLogin(tokennn));
 }
 
+
+export const uploadFile = file => {
+  const fd = new FormData();
+  fd.append('photo', file);
+return  fetch(backendURL+'/upload', {
+    method: "POST",
+    headers: localStorage.authToken ? {Authorization: 'Bearer ' + localStorage.authToken} : {},
+    body: fd
+}).then(res => res.json());
+
+}
+
+
+
+export const actionUploadFile = file => 
+  actionPromise('fileUpload', uploadFile(file));
+export const actionAvatar = (userrId, fileeId) => 
+  actionPromise("userAvatar", gql(`mutation setAvatar($userId: String, $fileId: ID){
+    UserUpsert(user:{_id: $userId, avatar: {_id: $fileId}}){
+        _id, avatar{
+            _id
+        }
+    }
+}`, {userId: userrId,
+      fileId: fileeId}))
+
 export const actionAboutMe = (_id) => 
         actionPromise("userInfo", gql(`query AboutMe ($Id: String){
             UserFindOne(query:$Id){

+ 31 - 0
src/components/DropZone.js

@@ -0,0 +1,31 @@
+import { useDropzone } from 'react-dropzone';
+import { useEffect } from 'react';
+
+function DropZoneForFiles ({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>
+    );
+  }
+
+  export default DropZoneForFiles;

+ 45 - 23
src/components/Header.js

@@ -14,9 +14,51 @@ const LogOutButton = ({onClick})=> {
 const CLogOut = connect(state => ({children: `logout(${state.auth.payload && state.auth.payload.sub.login || 'anon'})`}),
 {onClick: actionAuthLogout})(LogOutButton)
 
-
-const Header =  ({onLogOut}) => {
+const defaultUserInfo = {
+    _id:"61fe9cf2ad55d22f3e2fb226",
+    nick: "Nik",
+    avatar:'1',
+    following:"2"
+}
+/* const UserItem = ({user:{_id,nick,avatar}}) =>{
+    return(
+        <div>
+            {nick}
+        </div>
+    )
+} */
+const UserBlock = ({userInfo = defaultUserInfo}) => {
     const [isOpen, setIsOpen] = useState(false);
+    console.log(userInfo)
+    return(
+        <div className="relative inline-block text-left">
+                        <button onClick={() => setIsOpen(!isOpen)}>
+                            {userInfo.nick}
+                        </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">
+                        <div className="py-1 w-full text-center">
+                            <div className="text-gray-700   hover:bg-fuchsia-700 hover:rounded-md hover:text-white">
+                            <Link to={`/user/${userInfo._id}`} className="block px-4 py-2 text-sm">
+                            Account
+                    </Link>
+                            </div>
+                            <div className="text-gray-700   hover:bg-fuchsia-700 hover:rounded-md hover:text-white">
+                            <Link to="/settings" className="block px-4 py-2 text-sm">Settings</Link>
+                            </div>
+                            <div className="text-gray-700 flex justify-center  hover:bg-fuchsia-700 hover:rounded-md hover:text-white">
+                                <CLogOut/>
+                            </div>
+                        </div>
+                        </div>}
+                    
+                    </div>
+    )
+}
+
+const CUserBlock = connect(state => ({userInfo: state.promise?.userInfo?.payload || []}))(UserBlock)
+
+
+const Header =  ({}) => {
     return(
         <nav className="flex mx-auto px-4 justify-between p-6 xl:container xls:mx-auto dark:bg-slate-900 dark:text-white">
             {/* left */}
@@ -54,27 +96,7 @@ const Header =  ({onLogOut}) => {
                     </div>
                 </div>
                 <div>
-                    <div className="relative inline-block text-left">
-                        <button onClick={() => setIsOpen(!isOpen)}>
-                            Account
-                        </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">
-                        <div className="py-1 w-full text-center">
-                            <div className="text-gray-700   hover:bg-fuchsia-700 hover:rounded-md hover:text-white">
-                            <Link to="/user" className="block px-4 py-2 text-sm">
-                            Account
-                    </Link>
-                            </div>
-                            <div className="text-gray-700   hover:bg-fuchsia-700 hover:rounded-md hover:text-white">
-                            <a className="block px-4 py-2 text-sm">settings</a>
-                            </div>
-                            <div className="text-gray-700 flex justify-center  hover:bg-fuchsia-700 hover:rounded-md hover:text-white">
-                                <CLogOut/>
-                            </div>
-                        </div>
-                        </div>}
-                    
-                    </div>
+                    <CUserBlock/>
         
                 </div>
             </div>

+ 0 - 2
src/components/LoginPage/Login.js

@@ -6,8 +6,6 @@ import {Link} from "react-router-dom"
 const Login = ({onLogin}) => {
        const[login,setLogin] = useState('');
        const[password,setPassword] = useState(''); 
-       console.log(login);
-       console.log(password);
     return (
         <div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
                 <div className="max-w-md w-full space-y-8">

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

@@ -3,17 +3,25 @@ import Feed from '../Feed/Feed';
 import User from '../UserPage/User';
 import Collections from '../CollectionsPage/Collections';
 import UpsertPost from '../CreatePostPage/UpsertPost';
-
-
-const Main = () => {
-
-
+import UserSettings from '../UserSettings/UserSettings';
+import { actionAboutMe } from '../../actions';
+import { useEffect } from 'react';
+import { connect } from 'react-redux';
+import store from '../../reducers';
+
+const Main = ({auth}) => {
+    console.log(auth)
+useEffect(()=>{
+    
+    store.dispatch(actionAboutMe(auth));
+})
 
     return(
         <div className='flex mx-auto px-4 justify-between p-6 xl:container xls:mx-auto'>
             <Switch>
                 <Route path="/" exact component={Feed}/>
                 <Route path="/user/:id" exact component={User}/>
+                <Route path="/settings" exect component={UserSettings}/>
                 <Route path="/collections" exact component={Collections}/>
                 <Route path="/createpost" exact component={UpsertPost}/>
             </Switch>
@@ -23,8 +31,8 @@ const Main = () => {
 
 
 
+const CMain = connect(state =>({auth: state.auth?.payload?.sub?.id || []}))(Main);
 
 
 
-
-export default Main;
+export default CMain;

+ 6 - 5
src/components/RegisterPage/Register.js

@@ -1,8 +1,9 @@
 import { useEffect, useState } from "react";
+import { connect } from "react-redux";
 import { Link } from "react-router-dom";
+import { actionFullRegister } from "../../actions";
 
-
-const Register = () => {
+const Register = ({onRegister}) => {
 
     const [login, setLogin] = useState('');
     const [password, setPassword] = useState('');
@@ -45,7 +46,7 @@ const Register = () => {
                     You have account? 
                         <Link  className="text-gray-600 hover:underline hover:text-fuchsia-600" to="/login"> Login</Link>
                     </div>
-                   <button className="LoginButton" disabled={errmsg} onClick={event => console.log(event)}>Register</button>
+                   <button className="LoginButton" disabled={errmsg} onClick={() => onRegister(login,password) }>Register</button>
                 </div>
         </div>
 </div>
@@ -54,8 +55,8 @@ const Register = () => {
 
 }
 
+const CRegister = connect(state => ({errorFromServer: state.promise?.fullRegister?.error || []}),{onRegister: actionFullRegister})(Register);
 
 
 
-
-export default Register;
+export default CRegister;

+ 30 - 0
src/components/UserSettings/UserSettings.js

@@ -0,0 +1,30 @@
+import DropZoneForFiles from "../DropZone";
+
+const UserSettings = () =>{
+    return(
+        <div className="flex mx-auto px-4 justify-center items-center p-6 xl:container xls:mx-auto">
+
+            <div className="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
+                <div className="max-w-md w-full space-y-8">
+                    <div>
+                    <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">Settings</h2>
+                    </div>
+                <div className="mt-8 space-y-6 rounded-md shadow-sm ">
+                    <div>
+                        <label>Nick: </label>
+                        <input placeholder="nick" type="text" className="LoginInput"/>
+                    </div>
+                    <div>
+                        <label>Avatar:</label>
+                        <DropZoneForFiles/>
+                    </div>
+                    <button className="LoginButton">Save Settings</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    )
+}
+
+
+export default UserSettings;