Browse Source

сохраненные снипеты в истории показывает но не открывает

Vladislav342 2 years ago
parent
commit
98da26bb91

+ 10 - 7
React/CodePen/src/actions/requests.js

@@ -141,13 +141,16 @@ export const changePass = async (login, password, newPassword) => {
 
 export const snippetById = async(id) => {
     let query = `query snippetFind($query:String){
-      SnippetFind(query:$query){
-                        owner{
-                          _id 
-                        }
-            title description _id files {
-             type text name
-           }
+        SnippetFind(query:$query){
+            owner{
+                _id 
+            }
+            title
+            description
+            _id
+            files {
+                type text name
+            }
         }
     }`;
     let variables = {

+ 2 - 6
React/CodePen/src/components/ava.js

@@ -2,14 +2,10 @@ import React from "react";
 import { connect } from "react-redux";
 import icon from "../icon.jpg";
 
-function AvaLogo({ px, mrgn, link }) {
+function AvaLogo({px, mrgn, link}) {
   // Import result is the URL of your image
   return (
-    <img
-      src={link ? "http://localhost:3000/" + link : icon}
-      className="ava"
-      style={{ width: px, marginRight: mrgn, borderRadius: "50%" }}
-    />
+    <img src={link ? "http://localhost:3000/" + link : icon} className="ava" style={{ width: px, marginRight: mrgn, borderRadius: "50%" }}/>
   );
 }
 

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

@@ -6,13 +6,13 @@ import {useState} from "react";
 import {actionSearch} from "../actions/actionSearch";
 
 const Header = ({onSearch}) => {
-  const [request, setRequest] = useState('');
-  return (
-    <nav className="headerBlock">
-      <ImgLogo props={{width:"30%"}} className="headerSubBlock1"/>
-      <ConnectedNick className="headerSubBlock2"/>
-    </nav>
-  );
+	const [request, setRequest] = useState('');
+	return (
+		<nav className="navbar navbar-expand-lg shadow-lg navbar-light bg-white ">
+			<ImgLogo props={{width:"40%"}} className="headerSubBlock1"/>
+			<ConnectedNick className="headerSubBlock2"/>
+		</nav>
+	);
 };
 
 export default Header;

+ 2 - 3
React/CodePen/src/components/logo.js

@@ -3,9 +3,8 @@ import logo from "../logo.png";
 
 function ImgLogo({props}) {
   return (
-    <a href="/" style={{paddingTop: '30xp', marginLeft: "10px"}}>
-      	{" "}
-      	<img src={logo} alt="Logo" style={props}/>{" "}
+    <a href="/" style={{paddingTop: '100xp', marginLeft: "10px"}}>
+      	<img src={logo} alt="Logo" style={props}/>
     </a>
   );
 }

+ 2 - 6
React/CodePen/src/components/nickHeader.js

@@ -9,7 +9,7 @@ const NickName = ({nick, onLogOut}) => {
     <>
       <div className="container">
         <div className="">
-           <div style={{ paddingLeft: "64%", marginTop: "-55px",width: "100%", paddingBottom: "20px"}}>
+           <div style={{width: "100%", paddingBottom: "20px"}}>
                 <span style={{color: "black", left:"50px"}}>Your nickname </span>
                 <a href="/cabinet" style={{textDecoration: "none", color: "dark"}}>
                     {nick} &nbsp;&nbsp;
@@ -19,11 +19,7 @@ const NickName = ({nick, onLogOut}) => {
                     Log out
                 </button>
             </div>
-            <div>
-                <Link to= "/changePass" style={{paddingLeft: "84%"}}>
-                  <button className="btn btn-warning btn-sm">Change pass</button>
-                </Link>
-            </div>
+            
             <div>
                 <Link to = "/search" style={{paddingLeft: "86.5%"}}> 
                     <button className="btn btn-info btn-sm">Search</button> 

+ 3 - 0
React/CodePen/src/components/routes.js

@@ -12,6 +12,8 @@ import {useEffect, useState, useRef} from "react";
 import {BrowserRouter as Router, Switch, Route} from "react-router-dom";
 import ChangePass from "../pages/changePass";
 import Project from "../pages/project";
+import CProjects from "../pages/projects";
+
 
 const LoginForm = ({onLogin}) =>{
   const [login, setLogin] = useState(''); //braunvlad4
@@ -36,6 +38,7 @@ const Routes = ({ isAuth }) => {
                 <ConnectedPrivateRoute path="/cabinet" roles = {['user']} component={ConnectCabinet} />
                 <ConnectedPrivateRoute path="/search" roles = {['user']} component={Search} />
                 <ConnectedPrivateRoute path="/changePass" roles={['user']} component={ChangePass} />
+                <ConnectedPrivateRoute path="/projects" roles = {['user']} component={CProjects} />
                 <ConnectedPrivateRoute path="/login" roles = {['unknown']} component={LogForm} /> 
                 <ConnectedPrivateRoute path="/registration" roles = {['unknown']} component={RegForm} />
                 <ConnectedPrivateRoute path="/project" roles = {['user']} component={Project} />

+ 11 - 12
React/CodePen/src/pages/cabinet.js

@@ -10,7 +10,7 @@ const Cabinet = ({onLogOut}) => {
     <>
       <Link to="/">
           <button className="float-left btn-secondary d-inline-block mt-2 ml-2">
-                Back to Main Page
+              <span>&larr;</span>   Back to Main Page
           </button>
       </Link>
       <br/>
@@ -26,22 +26,21 @@ const Cabinet = ({onLogOut}) => {
             </div>
           </div>
           <div>
-            <h4>
-              <ConnectNickName />
-            </h4>
+            <h4><ConnectNickName /></h4>
             <a href="/projects">
-              <button type="button">
-                My Projects
-              </button>
+              <button type="button" className="btn btn-warning btn-sm">My Projects</button>
             </a>
-            <div>
+            <div style={{marginTop:"5px"}}>
               <a href="/">
-                <button>
-                  Main Page
-                </button>
+                <button className="btn btn-warning btn-sm">Main Page</button>
               </a>
             </div>
-            <button onClick={() => onLogOut()}>Log out</button>
+            <div style={{marginTop:"5px"}}>
+                <Link to= "/changePass">
+                  <button className="btn btn-warning btn-sm">Change pass</button>
+                </Link>
+            </div>
+            <button onClick={() => onLogOut()} className="btn btn-warning btn-sm" style={{marginTop:"5px"}}>Log out</button>
           </div>
         </div>
       </div>

+ 28 - 7
React/CodePen/src/pages/homePage.js

@@ -1,18 +1,39 @@
-import React from "react";
-import Header from "../components/header";
-import CSnippets from "../components/snippet";
-import Footer from "../components/footer";
+import  React      from "react";
+import  Header     from "../components/header";
+import  CSnippets  from "../components/snippet";
+import  Footer     from "../components/footer";
+import {useRef, useState} from "react";
+import {useEffect} from "react";
 
 const Home = () => {
-  	return (
+	const [sec, setSec] = useState(2);
+
+	useEffect(() => {
+		if(sec === 0) return;
+		const interval = setInterval(()=>{
+ 			setSec(sec=>sec-1)
+		},1000)
+
+		return () => { 
+        	clearInterval(interval)	
+        }
+	}, [sec])
+
+  	return sec===0 ? (
   		<>
-	    	<div>
+	    	<div> 
 	      		<Header/>
 				<CSnippets/>
 				<Footer/>
 	    	</div>
     	</>
-  	);
+  	) : (
+  		<div className="d-flex justify-content-center">
+                <div className="spinner-grow" style={{width: "10rem", height: "10rem", marginTop: "20%"}} role="status">
+                    <span className="sr-only">Loading...</span>
+            	</div>
+        	</div>
+  	)
 };
 
 export default Home;

+ 56 - 48
React/CodePen/src/pages/project.js

@@ -8,10 +8,21 @@ import {Link} from "react-router-dom";
 import {Redirect} from "react-router";
 
 const ProjectSnippet = ({onSave, getSnippet, match:{params:{id},}, titleText, descriptionText, filesArr, nameText,}) => {
+	useEffect(() => {
+      	getSnippet(id);
+    }, []);
+
     const [files, setFiles] = useState([]);
     const [name, setName] = useState("");
     const [title, setTitle] = useState("");
     const [description, setDescription] = useState("");
+
+    useEffect(() => {
+	    setFiles(filesArr);
+	    setTitle(titleText);
+	    setDescription(descriptionText);
+    }, [filesArr, titleText, descriptionText]);
+
     const [srcDoc, setSrcDoc] = useState("");
 
     const html = files?.filter((el) => {
@@ -28,16 +39,6 @@ const ProjectSnippet = ({onSave, getSnippet, match:{params:{id},}, titleText, de
 
     console.log(js);
 
-    useEffect(() => {
-      getSnippet(id);
-    }, []);
-  
-    useEffect(() => {
-      setFiles(filesArr);
-      setTitle(titleText);
-      setDescription(descriptionText);
-    }, [filesArr, titleText, descriptionText]);
- 
   
   useEffect(() => {
     const timeout = setTimeout(() => {
@@ -55,51 +56,58 @@ const ProjectSnippet = ({onSave, getSnippet, match:{params:{id},}, titleText, de
 
   return (
     <div>
+        <Link to="/">
+            <button className="float-left btn-secondary d-inline-block mt-2 ml-2">
+                Back to Main Page
+            </button>
+         </Link>
+
         <br />
         {files?.map((data, index) => (
             <>
                 <Editor onDelete={() => setFiles(files?.filter((item) => item !== data))} data={data} 
-                    onChange={({ type, name, text }) => setFiles([...files.slice(0, index), { type, name, text }, ...files.slice(index + 1),])}
+                    onChange={({type, name, text}) => setFiles([...files.slice(0, index), {type, name, text}, ...files.slice(index + 1),])}
                 />
             </>
         ))}
-      <br />
-      <div style={{alignItems: "center", textAlign: "center", marginBottom: "10px"}}>
-        <div>
-          <button className="btn btn-primary" onClick={() => setFiles([...files, { type: "html" }])} key={files}>
-            Add editor
-          </button>
-          <iframe srcDoc={srcDoc} title="output" sandbox="allow-scripts" frameBorder="0" width="95%" height="95%"
-            style={{marginTop: "10px",border: "1px solid #F0FFFF",boxShadow: "0px 5px 10px 2px rgba(34, 60, 80, 0.2)"}}
-          />
-          <div>
-            <Link to="/projects">
-              <button className="btn btn-outline-info border-info mt-3">
-                All projects
-              </button>
-            </Link>
-          </div>
-        </div>
-        <div className="input-group mb-3 mt-5 ml-auto mr-auto w-25">
-          <div className="input-group-prepend">
-            <span className="input-group-text" id="basic-addon1">
-              Name of your project
-            </span>
-          </div>
-          <input value={title} onChange={(e) => setTitle(e.target.value)} type="text" className="form-control"
-            placeholder="Name of project" aria-label="Name of project" aria-describedby="basic-addon1"/>
-        </div>
-        <div className="input-group ml-auto mr-auto w-50">
-          <div className="input-group-prepend">
-            <span className="input-group-text ">Description</span>
-          </div>
-          <textarea value={description} onChange={(e) => setDescription(e.target.value)} className="form-control "
-            aria-label="With textarea" placeholder="Your description"></textarea>
-        </div>
-        <button className="btn btn-success float-right mr-5 mb-5" onClick={() => onSave(title, description, files, id)}>
-          Save project
-        </button>
-      </div>
+
+      	<br />
+	    <div style={{alignItems: "center", textAlign: "center", marginBottom: "10px"}}>
+	        <div>
+	          <button className="btn btn-primary" onClick={() => setFiles([...files, {type: "html"}])} key={files}>
+	            Add editor
+	          </button>
+	          <iframe srcDoc={srcDoc} title="output" sandbox="allow-scripts" frameBorder="0" width="95%" height="95%"
+	            style={{marginTop: "10px",border: "1px solid #F0FFFF",boxShadow: "0px 5px 10px 2px rgba(34, 60, 80, 0.2)"}}
+	          />
+	          <div>
+	            <Link to="/projects">
+	              <button className="btn btn-outline-info border-info mt-3">
+	                All projects
+	              </button>
+	            </Link>
+	          </div>
+	        </div>
+	        <div className="input-group mb-3 mt-5 ml-auto mr-auto w-25">
+	          <div className="input-group-prepend">
+	            <span className="input-group-text" id="basic-addon1">
+	              Name of your project
+	            </span>
+	          </div>
+	          <input value={title} onChange={(e) => setTitle(e.target.value)} type="text" className="form-control"
+	            placeholder="Name of project" aria-label="Name of project" aria-describedby="basic-addon1"/>
+	        </div>
+	        <div className="input-group ml-auto mr-auto w-50">
+	          <div className="input-group-prepend">
+	            <span className="input-group-text ">Description</span>
+	          </div>
+	          <textarea value={description} onChange={(e) => setDescription(e.target.value)} className="form-control "
+	            aria-label="With textarea" placeholder="Your description"></textarea>
+	        </div>
+	        <button className="btn btn-success float-right mr-5 mb-5" onClick={() => onSave(title, description, files, id)}>
+	          Save project
+	        </button>
+	    </div>
     </div>
   );
 };

+ 60 - 0
React/CodePen/src/pages/projects.js

@@ -0,0 +1,60 @@
+import {connect} from "react-redux";
+import {Link} from "react-router-dom";
+
+
+const Projects = ({snippets}) => {
+    return snippets ? (
+        <div>
+              <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={{ alignItems: "center", textAlign: "center" }}>
+                  <Link to="/">
+                      <button className="btn btn-success">New project</button>
+                  </Link>
+              </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>
+                              <Link to={"/project/" + snippets?.[index]?._id}>
+                                  <button className="btn btn-primary mt-3">Open project</button>
+                              </Link>
+                          </div>
+                      </div>
+                  </div>
+              ))}     
+            </div>
+
+          ) : (
+
+            <div>
+                <Link to="/">
+                    <button className="float-left btn-secondary d-inline-block mt-2 ml-2">
+                        Back to Main Page
+                    </button>
+                </Link>
+                <br /> <br />
+                <div className="d-flex justify-content-center">
+                    <div className="spinner-border mt-3" style={{width: "10rem", height: "10rem"}} role="status">
+                        <span className="sr-only">Loading...</span>
+                    </div>
+                </div>
+            </div>
+        );
+    };
+
+const CProjects = connect((state) => ({
+  snippets: state?.promise?.findSnippet?.payload?.data?.SnippetFind,
+}))(Projects);
+
+export default CProjects;

+ 11 - 15
React/CodePen/src/reducers/store.js

@@ -1,22 +1,18 @@
-import { createStore, combineReducers, applyMiddleware } from "redux";
-import thunk from "redux-thunk";
-import promiseReducer from "./promiseReducer";
-import authReducer from "./authReducer";
-import { actionFindUser } from "../actions/actionFindUser";
-import { actionSnippetFindByOwner } from "../actions/actionSnippetFindByOwner";
+import {createStore, combineReducers, applyMiddleware}      from "redux";
+import thunk                                                from "redux-thunk";
+import promiseReducer       								from "./promiseReducer";
+import authReducer 											from "./authReducer";
+import {actionFindUser} 									from "../actions/actionFindUser";
+import {actionSnippetFindByOwner} 							from "../actions/actionSnippetFindByOwner";
 
 export const store = createStore(
-  combineReducers({promise: promiseReducer,auth: authReducer}),
-  applyMiddleware(thunk)
+	combineReducers({promise: promiseReducer,auth: authReducer}),
+	applyMiddleware(thunk)
 );
 
-store.subscribe(() =>
-  console.log(store.getState())
-);
+store.subscribe(() => console.log(store.getState()));
 
 if (localStorage.authToken) {
-  store.dispatch(actionFindUser());
-  store.dispatch(
-    actionSnippetFindByOwner(store.getState().auth.payload.sub.id)
-  );
+	store.dispatch(actionFindUser());
+	store.dispatch(actionSnippetFindByOwner(store.getState().auth.payload.sub.id));
 }