Quellcode durchsuchen

Проблемы с авторизацией + bootstrap

Vladislav342 vor 2 Jahren
Ursprung
Commit
ce475b341a

+ 3 - 15
React/CodePen/src/App.js

@@ -8,49 +8,37 @@ import {Router, Route, Link, Redirect, Switch} from 'react-router-dom';
 import createHistory from "history/createBrowserHistory";
 import {store} from "./reducers/store";
 import Routes from "./components/routes";
+import 'bootstrap/dist/css/bootstrap.min.css';
 
 //import {useDropzone} from 'react-dropzone'
-
 /*const actionAboutMe = () => {
 	async(dispatch, getState)=>{
 		
 	}
 }
-
 const actioUploadFile = file =>{
 	return actionPromise('uploadFile', fetch().then(res=>res.json))
 }
-
 const actionSetAvatar = file =>{
 	async(dispatch, getState) => {
 		
 	}
 }*/
-
-
 //const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer}),applyMiddleware(thunk))
-
 //store.subscribe(()=>console.log(store.getState()))
-
 //store.dispatch(actionCatById('5dc49f4d5df9d670df48cc64'))
-
 //store.dispatch(actionFullLogin('vladBraun4','123'))
 
-
-
-
-
-
 const history = createHistory();
 
 function App() {
-  return (
+  	return (
   		<Router history={history}>
   			<Provider store={store} >
 	      		<Routes />
 	    	</Provider>
 	    </Router>
-  );
+  	);
 }
 
 export default App;

+ 15 - 0
React/CodePen/src/App.scss

@@ -1 +1,16 @@
 
+body{
+	margin: 0;
+	width: 100%;
+	overflow: auto;
+	.App{
+	
+		.headerBlock{
+			display:flex;
+			flex-diraction:space-between;
+			border:1px solid black;
+			
+		}
+	}
+}
+

+ 6 - 0
React/CodePen/src/actions/actionSearch.js

@@ -0,0 +1,6 @@
+import { search } from "./gqlRequests";
+import { actionPromise } from "./actionPromise";
+
+export const actionSearch = (string) => async (dispatch) => {
+    return await dispatch(actionPromise('searchSnippet', search(string)))
+}

+ 21 - 0
React/CodePen/src/actions/gqlRequests.js

@@ -24,4 +24,25 @@ export const reg = async (login, password) => {
     };
     let result = await gql(query, qVariables);
     return result;
+  };
+
+  export const search = async (string) => {
+    return gql(
+      `query snippetFind($query:String){
+        SnippetFind(query:$query){
+          owner {
+            _id login
+          }
+              title description _id files {
+               type text name
+             }
+          }
+    }`,
+      { query: JSON.stringify([
+        {
+            $or: [{title: `/${string.trim().split(" ").join('|')}/`},{description: `/${string.trim().split(" ").join('|')}/`}] 
+        },
+        {
+          sort: [{title: 1}]}]) }
+    );
   };

+ 16 - 0
React/CodePen/src/components/ava.js

@@ -0,0 +1,16 @@
+import React from "react";
+import { connect } from "react-redux";
+import icon from "../icon.jpg";
+
+function AvaLogo({px, mrgn, link}) {
+  return (
+    <img src={link ? "http://localhost:3000/" + link : icon} className="ava" 
+    	style={{ width: px, marginRight: mrgn, borderRadius: "50%" }}/>
+  );
+}
+
+const ConnectedAvaLogo = connect((state) => ({
+  link: state?.promise?.findUser?.payload?.data?.UserFindOne?.avatar?.url,
+}))(AvaLogo);
+
+export default ConnectedAvaLogo;

+ 7 - 2
React/CodePen/src/components/header.js

@@ -1,12 +1,17 @@
 import React from "react";
 import { connect } from "react-redux";
 import { useState } from "react";
+import ConnectedNick from "./nickHeader";
+import ImgLogo from "./logo";
+import { actionSearch } from "../actions/actionSearch";
+
 
 const Header = ({onSearch}) => {
   	const [request, setRequest] = useState('');
   	return (
-    	<nav className="">
-    		<p>hello</p>
+    	<nav className="headerBlock">
+    		<ImgLogo props={{width:"100px"}} className="headerSubBlock1" />
+      		<ConnectedNick className="headerSubBlock2" />
     	</nav>
   	);
 };

+ 13 - 0
React/CodePen/src/components/logo.js

@@ -0,0 +1,13 @@
+import React from "react";
+import logo from "../logo.svg";
+
+function ImgLogo({props}) {
+  return (
+    <a href="/">
+      {" "}
+      <img src={logo} alt="Logo" style={props} />{" "}
+    </a>
+  );
+}
+
+export default ImgLogo;

+ 35 - 0
React/CodePen/src/components/nickHeader.js

@@ -0,0 +1,35 @@
+import { connect } from "react-redux";
+import ConnectedAvaLogo from "./ava";
+import { actionAuthLogout } from "../actions/actionAuthLogout";
+import { Redirect } from "react-router";
+import { Link } from "react-router-dom";
+
+const NickName = ({nick, onLogOut}) => {
+  return (
+    <>
+      <div style={{position: "relative", left: "50%", paddingTop:"10px"}}>
+          <div>
+              <span style={{color: "black"}}>Your nickname </span>
+              <a href="/cabinet" style={{textDecoration: "none", color: "#5F9EA0"}}>
+                  {nick} &nbsp;&nbsp;
+                  <ConnectedAvaLogo px={"50px"} mrgn={"10px"} />
+              </a>
+              <button className="btn btn-secondary btn-sm" onClick={() => onLogOut()}>
+                  Log out
+              </button>
+          </div>
+          <div style={{}}>
+              <Link to = "/search"> 
+                  <button className="btn btn-info btn-sm">Search</button> 
+              </Link>
+          </div>
+      </div>
+    </>
+  );
+};
+
+const ConnectedNick = connect(
+  (state) => ({ nick: state?.auth?.payload?.sub?.login , logedIn: state.auth.token}),
+  { onLogOut: actionAuthLogout }
+)(NickName);
+export default ConnectedNick;

+ 13 - 13
React/CodePen/src/components/privateRout.js

@@ -4,22 +4,22 @@ import { Redirect,Route } from "react-router"
 
 const PrivateRoute = ({component,roles,auth, ...originProps}) => {
     const PageWrapper = (pageProps) => {
-      const OriginalPage = component
-      if(roles.includes('unknown')){
-        return <OriginalPage {...pageProps} />
-      }
-      if(auth === undefined) {
+        const OriginalPage = component
+        if(roles.includes('noname')){
+            return <OriginalPage {...pageProps} />
+        }
+        if(auth === undefined) {
+            return <Redirect to='/login' />
+        }
+        let userLogged = roles.filter(item => auth.includes(item))
+        if(userLogged){
+            return <OriginalPage {...pageProps} />
+        }
         return <Redirect to='/login' />
-      }
-      let userL = roles.filter(item => auth.includes(item))
-      if(userL){
-        return <OriginalPage {...pageProps} />
-      }
-      return <Redirect to='/login' />
     }
     return (
-      <Route component={PageWrapper} {...originProps} />
+        <Route component={PageWrapper} {...originProps} />
     )
-  }
+}
 const ConnectedPrivateRoute = connect(state => ({auth: state?.auth?.token}))(PrivateRoute)
 export default ConnectedPrivateRoute

+ 13 - 0
React/CodePen/src/components/profile.js.js

@@ -0,0 +1,13 @@
+import React from "react";
+import wall from "../profileWall.jpeg";
+
+function ImgProfile({ px }) {
+  return (
+    <a href="/">
+      {" "}
+      <img src={wall} alt="wall" style={{width: px}} />{" "}
+    </a>
+  );
+}
+
+export default ImgProfile;

+ 16 - 10
React/CodePen/src/components/routes.js

@@ -8,6 +8,8 @@ import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
 import ConnectedPrivateRoute from "./privateRout";
 import { Redirect } from "react-router";
 import {useEffect, useState, useRef} from "react";
+import ConnectCabinet from "../pages/cabinet";
+import Search from "../pages/search";
 
 const LoginForm = ({onLogin}) =>{
   const [login, setLogin] = useState(''); //braunvlad4
@@ -24,16 +26,20 @@ const LoginForm = ({onLogin}) =>{
 }
 
 const Routes = ({ isAuth }) => {
-  return (
-    <div className="App">
-      <div className="contentDiv">
-          <LoginForm onLogin={(l,p)=>console.log(l,p)} />
-          <ConnectedPrivateRoute exact path="/" roles = {['user']} component={Home} />
-          <ConnectedPrivateRoute path="/login" roles = {['unknown']} component={LogForm} /> 
-          <ConnectedPrivateRoute path="/registration" roles = {['unknown']} component={RegForm} />
-      </div>
-    </div>
-  );
+    return (
+        <div className="App">
+            <div className="contentDiv">
+            <LoginForm onLogin={(l,p)=>console.log(l,p)} />
+                <Switch>
+                    <ConnectedPrivateRoute exact path="/" roles = {['user']} component={Home} />
+                    <ConnectedPrivateRoute path="/cabinet" roles = {['user']} component={ConnectCabinet} />
+                    <ConnectedPrivateRoute path="/search" roles = {['user']} component={Search} />
+                    <ConnectedPrivateRoute path="/login" roles = {['noname']} component={LogForm} /> 
+                    <ConnectedPrivateRoute path="/registration" roles = {['noname']} component={RegForm} />
+                </Switch>
+            </div>
+        </div>
+    );
 };
 
 export default Routes

BIN
React/CodePen/src/icon.jpg


BIN
React/CodePen/src/logo.png


+ 7 - 7
React/CodePen/src/pages/cabinet.js

@@ -5,18 +5,18 @@ import { connect } from "react-redux";
 const Cabinet = ({ onLogOut }) => {
   return (
     <>
-      <div className="" >
-        <div className="card" style = {{boxShadow:'7px 5px 10px 2px rgba(34, 60, 80, 0.2)'}}>
-          <div className="">
+      <div>
+        <div>
+          <div >
             <a href="/projects">
-              <button type="button" className="">My Projects</button>
+              <button type="button">My Projects</button>
             </a>
-            <div className="">
+            <div>
               <a href="/">
-                <button className=" ">Main Page</button>
+                <button>Main Page</button>
               </a>
             </div>
-            <button className="" onClick={() => onLogOut()}>Log out</button>
+            <button onClick={() => onLogOut()}>Log out</button>
           </div>
         </div>
       </div>

+ 13 - 13
React/CodePen/src/pages/login.js

@@ -11,17 +11,17 @@ const Log = ({ onLog, LogedIn }) => {
   ) : (
     <>
       <div className="container" >
-        <div id="loginbox" style={{ marginTop: "120px"}} className="">
-          <div className="" style = {{boxShadow:'0px 5px 10px 2px rgba(34, 60, 80, 0.5)'}}>
-            <div className="">
-              <div className="">Login</div>
+        <div id="loginbox" style={{marginTop: "120px", border:"1px solid black"}} className="">
+          <div >
+            <div>
+              <div style={{backgroundColor:'pink'}}>Авторизация</div>
             </div>
 
-            <div style={{ "padding-top": "30px" }} className="">
+            <div style={{ paddingTop: "30px" }} className="">
               <div style={{ display: "none" }} id="" className=""></div>
 
               <form id="loginform" className="form-horizontal" role="form">
-                <div style={{ "margin-bottom": "25px" }} className="input-group">
+                <div style={{ "marginBottom": "25px" }} className="input-group">
                   <span className="">
                     <i className=""></i>
                   </span>
@@ -30,7 +30,7 @@ const Log = ({ onLog, LogedIn }) => {
                     	onChange={(e) => setLogin(e.target.value) && <Redirect to ="/"/>}	
                   />
                 </div>
-                <div style={{ "margin-bottom": "25px" }} className="input-group">
+                <div style={{ marginBottom: "25px" }} className="input-group">
                   <span className="">
                     <i className=""></i>
                   </span>
@@ -39,17 +39,17 @@ const Log = ({ onLog, LogedIn }) => {
                  	onChange={(e) => setPassword(e.target.value)}
                   />
                 </div>
-                <div style={{ "margin-top": "10px" }} className="form-group">
+                <div style={{ marginTop: "10px" }} className="form-group">
                   <div className="">
-                    <a id="btn-login" href="#" className="" onClick={() =>onLog(login, password)}>
-                      Sign In
+                    <a id="btn-login" href="#" onClick={() =>onLog(login, password)}>
+                      Войти
                     </a>
                   </div>
                 </div>
                 <div className="form-group">
-                  <div className="">
-                    <div style={{"border-top": "1px solid#888","padding-top": "15px","font-size": "85%",}}>
-                      <a href="/registration">Sign Up Here</a>
+                  <div>
+                    <div style={{borderTop: "1px solid#888",paddingTop: "15px",fontSize: "85%",}}>
+                      <a href="/registration">Зарегестрироваться</a>
                     </div>
                   </div>
                 </div>

+ 14 - 35
React/CodePen/src/pages/reg.js

@@ -9,59 +9,38 @@ const Reg = ({ onReg, LogedIn }) => {
   return (
     <>
       <div className="container">
-        <div
-          id="loginbox"
-          style={{ marginTop: "120px" }}
-          className=""
-        >
-          <div className="" style = {{boxShadow:'0px 5px 10px 2px rgba(34, 60, 80, 0.5)'}}>
-            <div className="" style = {{backgroundColor:'#ADD8E6' }}>
-              <div className="" >Registration</div>
+        <div id="loginbox" style={{ marginTop: "120px", border:"1px solid black"}}>
+          <div>
+            <div  style = {{backgroundColor:'pink'}}>
+              <div>Registration</div>
             </div>
 
-            <div style={{ "padding-top": "30px" }} className="panel-body">
-              <div
-                style={{ display: "none" }}
-                id=""
-                className=""
-              ></div>
-
-              <form id="loginform" className="" role="form">
-                <div style={{ "margin-bottom": "25px" }}>
-                  <span className="">
-                    <i className=""></i>
-                  </span>
+            <div style={{paddingTop: "30px"}} className="panel-body">
+              <form id="loginform" role="form">
+                <div style={{marginBottom: "25px"}}>
                   <input id="login-username" type="text" className="form-control" name="username"
                     value={login} onChange={(e) => setLogin(e.target.value)} placeholder="Login"/>
                 </div>
 
-                <div style={{ "margin-bottom": "25px" }} className="">
-                  <span className="">
-                    <i className=""></i>
-                  </span>
+                <div style={{marginBottom: "25px"}}>
                   <input id="login-password" type="password" className="form-control"
                     name="password" placeholder="Password" value={password}
                     onChange={(e) => setPassword(e.target.value)}
                   />
                 </div>
-                <div style={{ "margin-top": "10px" }} className="form-group">
+
+                <div style={{marginTop: "10px"}} className="form-group">
                   <div className="">
-                    <a id="btn-login" href="#" className="" onClick={() => onReg(login, password)}>
-                      Sign up{" "}
+                    <a id="btn-login" href="#" onClick={() => onReg(login, password)}>
+                      Зарегестрироваться
                     </a>
                   </div>
                 </div>
 
                 <div className="form-group">
                   <div className="">
-                    <div
-                      style={{
-                        "border-top": "1px solid#888",
-                        "padding-top": "15px",
-                        "font-size": "85%",
-                      }}
-                    >
-                      <a href="/login">Login Here</a>
+                    <div style={{borderTop: "1px solid#888",paddingTop: "15px",fontSize: "85%",}}>
+                      <a href="/login">Авторизоваться</a>
                     </div>
                   </div>
                 </div>

+ 59 - 0
React/CodePen/src/pages/search.js

@@ -0,0 +1,59 @@
+import { Link } from "react-router-dom";
+import { actionSearch } from "../actions/actionSearch";
+import { connect } from "react-redux";
+import { useState } from "react";
+
+const Search = ({onSearch , snippets}) => {
+    const [request, setRequest] = useState('');
+  return (
+    <>
+    <Link to="/">
+        <button className="float-left btn-secondary d-inline-block mt-2 ml-2">
+          Back to Main Page
+        </button>
+      </Link>
+      <br/>
+      <br/>
+      <div style ={{textAlign: "center" , alignItems:"center", justifyContent:'center'}}>
+    <input
+    value={request}
+    onChange={(e) => setRequest(e.target.value)}
+      className="form-control d-inline-block w-50 mt-2"
+      type="search"
+      placeholder="Name of project"
+      aria-label="Search"
+    />
+    <br/>
+    <button
+      className="btn btn-outline-success border-success mt-4 mb-4" onClick = {() => onSearch(request)}
+    >
+      Search
+    </button>
+    </div>
+
+  {snippets?.map((key, index) => (
+    <div style={{ textAlign: "center", alignItems: "center" }}>
+      <div className="card w-50 ml-auto mr-auto mt-3 mb-5" style = {{boxShadow:'0px 5px 10px 2px rgba(34, 60, 80, 0.2)'}}>
+        <div className="card-body" style={{ textAlign: "center" }}>
+          <h3 className="card-title mb-4 text-info">
+            {snippets?.[index]?.title || "Project without name"}
+          </h3>
+          <p className="card-text">
+            <span className="text-muted">Description</span>&nbsp;
+            {snippets?.[index]?.description || ""}
+          </p>
+          <p>{`Owner: ${snippets?.[index]?.owner?.login}`}</p>
+          <Link to={"/project/" + snippets?.[index]?._id}>
+            <button className="btn btn-primary mt-3">Open project</button>
+          </Link>
+        </div>
+      </div>
+    </div>
+  ))}
+</>
+  )
+};
+
+const CSearch = connect(state => ({snippets:state?.promise?.searchSnippet?.payload?.data?.SnippetFind}) , {onSearch:actionSearch})(Search)
+
+export default CSearch;

BIN
React/CodePen/src/profileWall.jpeg


+ 1 - 1
React/CodePen/src/reducers/authReducer.js

@@ -34,4 +34,4 @@ function authReducer(state, { type, token }) {
     return state
 }
 
-//export default authReducer
+export default authReducer

+ 1 - 1
React/CodePen/src/reducers/promiseRedicer.js

@@ -8,4 +8,4 @@ function promiseReducer(state = {}, { type, status, payload, error, name }) {
     return state;
 }
 
-//export default promiseReducer;
+//export promiseReducer;

+ 3 - 37
React/CodePen/src/reducers/store.js

@@ -1,43 +1,8 @@
-//import {promiseReducer} from "./promiseReducer";
-//import {authReducer} from "./authReducer";
+//import promiseReducer from "./promiseReducer";
+import authReducer from "./authReducer";
 import {createStore, combineReducers, applyMiddleware} from "redux";
 import thunk from "redux-thunk";
 
-const jwtDecode = token => {
-    try {
-        let arrToken = token.split('.')
-        let base64Token = atob(arrToken[1])
-        return JSON.parse(base64Token)
-    }
-    catch (e) {
-        console.log('Лажа, Бро ' + e);
-    }
-}
-
-function authReducer(state, { type, token }) {
-    if (!state) {
-        if (localStorage.authToken) {
-            type = 'AUTH_LOGIN'
-            token = localStorage.authToken
-        } else state = {}
-    }
-    if (type === 'AUTH_LOGIN') {
-        localStorage.setItem('authToken', token)
-        let payload = jwtDecode(token)
-        if (typeof payload === 'object') {
-            return {
-                ...state,
-                token,
-                payload
-            }
-        } else return state
-    }
-    if (type === 'AUTH_LOGOUT') {
-        localStorage.removeItem('authToken')
-        return {}
-    }
-    return state
-}
 
 function promiseReducer(state = {}, { type, status, payload, error, name }) {
     if (type === 'PROMISE') {
@@ -49,6 +14,7 @@ function promiseReducer(state = {}, { type, status, payload, error, name }) {
     return state;
 }
 
+
 export const store = createStore(
 	combineReducers({promise: promiseReducer, auth: authReducer}),
 	applyMiddleware(thunk)