4 Commits 74f2bd2810 ... 6ac13f7c51

Auteur SHA1 Bericht Datum
  Yevheniia Akinshyna 6ac13f7c51 refactor 2 jaren geleden
  Yevheniia Akinshyna d860f79918 fix styles 2 jaren geleden
  Yevheniia Akinshyna 83cd7ecfb8 fix paths 2 jaren geleden
  Yevheniia Akinshyna 4957b4d4ac add prettier 2 jaren geleden
86 gewijzigde bestanden met toevoegingen van 1538 en 1662 verwijderingen
  1. 14 0
      .prettierrc
  2. 8 0
      jsconfig.json
  3. 32 47
      package-lock.json
  4. 3 1
      package.json
  5. 0 0
      public/img/code.png
  6. 0 0
      public/img/logo.png
  7. 0 0
      public/img/user.png
  8. 20 20
      src/App.css
  9. 11 9
      src/App.js
  10. 3 3
      src/App.test.js
  11. 0 1
      src/actions/actionAuthLogin.js
  12. 0 8
      src/actions/actionFindUser.js
  13. 0 9
      src/actions/actionFullAva.js
  14. 0 14
      src/actions/actionFullLogin.js
  15. 0 11
      src/actions/actionFullRegister.js
  16. 0 6
      src/actions/actionImgFind.js
  17. 0 5
      src/actions/actionLogin.js
  18. 0 5
      src/actions/actionPending.js
  19. 0 14
      src/actions/actionPromise.js
  20. 0 5
      src/actions/actionReg.js
  21. 0 6
      src/actions/actionRejected.js
  22. 0 6
      src/actions/actionResolved.js
  23. 0 6
      src/actions/actionSearch.js
  24. 0 8
      src/actions/actionSetAva.js
  25. 0 12
      src/actions/actionSnippetAdd.js
  26. 0 6
      src/actions/actionSnippetById.js
  27. 0 6
      src/actions/actionSnippetFindByOwner.js
  28. 0 18
      src/actions/actionUploadFile.js
  29. 0 13
      src/actions/gql.js
  30. 0 150
      src/actions/requests.js
  31. 10 10
      src/components/Ava.js
  32. 7 7
      src/components/Editor.css
  33. 38 50
      src/components/Editor.js
  34. 63 67
      src/components/EditorsPage.css
  35. 105 113
      src/components/EditorsPage.js
  36. 60 64
      src/components/Header.css
  37. 10 9
      src/components/Header.js
  38. 14 11
      src/components/Logo.js
  39. 37 44
      src/components/Routers.js
  40. 9 9
      src/components/User.js
  41. 19 18
      src/components/UserHeader.js
  42. 18 18
      src/helpers/SelectFontSize.js
  43. 25 25
      src/helpers/SelectMode.js
  44. 19 19
      src/helpers/SelectTheme.js
  45. 35 37
      src/index.css
  46. 5 4
      src/index.js
  47. 21 19
      src/pages/Cabinet.js
  48. 41 40
      src/pages/FormReg.js
  49. 28 30
      src/pages/FormUpload.css
  50. 14 14
      src/pages/FormUpload.js
  51. 33 32
      src/pages/LoginForm.js
  52. 144 202
      src/pages/LoginReg.css
  53. 120 124
      src/pages/Main.css
  54. 20 21
      src/pages/Main.js
  55. 103 114
      src/pages/Project.js
  56. 47 50
      src/pages/Projects.js
  57. 53 54
      src/pages/Search.js
  58. 11 12
      src/pages/WorkPage.js
  59. 0 30
      src/reducers/auth.js
  60. 0 12
      src/reducers/promise.js
  61. 9 9
      src/reportWebVitals.js
  62. 1 1
      src/setupTests.js
  63. 1 0
      src/store/actions/actionAuthLogin.js
  64. 0 0
      src/store/actions/actionAuthLogout.js
  65. 6 0
      src/store/actions/actionFindUser.js
  66. 9 0
      src/store/actions/actionFullAva.js
  67. 14 0
      src/store/actions/actionFullLogin.js
  68. 11 0
      src/store/actions/actionFullRegister.js
  69. 6 0
      src/store/actions/actionImgFind.js
  70. 4 0
      src/store/actions/actionLogin.js
  71. 5 0
      src/store/actions/actionPending.js
  72. 14 0
      src/store/actions/actionPromise.js
  73. 4 0
      src/store/actions/actionReg.js
  74. 6 0
      src/store/actions/actionRejected.js
  75. 6 0
      src/store/actions/actionResolved.js
  76. 6 0
      src/store/actions/actionSearch.js
  77. 6 0
      src/store/actions/actionSetAva.js
  78. 6 0
      src/store/actions/actionSnippetAdd.js
  79. 6 0
      src/store/actions/actionSnippetById.js
  80. 6 0
      src/store/actions/actionSnippetFindByOwner.js
  81. 16 0
      src/store/actions/actionUploadFile.js
  82. 11 0
      src/store/actions/gql.js
  83. 136 0
      src/store/actions/requests.js
  84. 30 0
      src/store/reducers/auth.js
  85. 7 4
      src/reducers/index.js
  86. 12 0
      src/store/reducers/promise.js

+ 14 - 0
.prettierrc

@@ -0,0 +1,14 @@
+{
+   "printWidth": 120,
+   "tabWidth": 3,
+   "useTabs": true,
+   "semi": true,
+   "singleQuote": false,
+   "quoteProps": "as-needed",
+   "jsxSingleQuote": true,
+   "trailingComma": "all",
+   "bracketSpacing": true,
+   "jsxBracketSameLine": false,
+   "arrowParens": "avoid",
+   "endOfLine": "lf"
+}

+ 8 - 0
jsconfig.json

@@ -0,0 +1,8 @@
+{
+   "compilerOptions": {
+      "baseUrl": "src"
+   },
+   "include": [
+      "src"
+   ]
+}

+ 32 - 47
package-lock.json

@@ -3098,9 +3098,9 @@
       "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
     },
     "async": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
-      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+      "version": "2.6.4",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+      "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
       "requires": {
         "lodash": "^4.17.14"
       }
@@ -6216,12 +6216,9 @@
       "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
     },
     "eventsource": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz",
-      "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==",
-      "requires": {
-        "original": "^1.0.0"
-      }
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
+      "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA=="
     },
     "evp_bytestokey": {
       "version": "1.0.3",
@@ -6699,9 +6696,9 @@
       }
     },
     "follow-redirects": {
-      "version": "1.14.4",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
-      "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g=="
+      "version": "1.15.1",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
+      "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
     },
     "for-in": {
       "version": "1.0.2",
@@ -9811,11 +9808,6 @@
       "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
       "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
     },
-    "json3": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
-      "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA=="
-    },
     "json5": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
@@ -10280,9 +10272,9 @@
       }
     },
     "minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
     "minipass": {
       "version": "3.1.5",
@@ -10419,8 +10411,7 @@
     },
     "nanoid": {
       "version": "3.1.28",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.28.tgz",
-      "integrity": "sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw=="
+      "resolved": ""
     },
     "nanomatch": {
       "version": "1.2.13",
@@ -10837,14 +10828,6 @@
         "word-wrap": "^1.2.3"
       }
     },
-    "original": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
-      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
-      "requires": {
-        "url-parse": "^1.4.3"
-      }
-    },
     "os-browserify": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
@@ -12185,6 +12168,12 @@
       "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
       "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
     },
+    "prettier": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
+      "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
+      "dev": true
+    },
     "pretty-bytes": {
       "version": "5.6.0",
       "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
@@ -14133,16 +14122,15 @@
       }
     },
     "sockjs-client": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz",
-      "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==",
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz",
+      "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==",
       "requires": {
-        "debug": "^3.2.6",
-        "eventsource": "^1.0.7",
-        "faye-websocket": "^0.11.3",
+        "debug": "^3.2.7",
+        "eventsource": "^2.0.2",
+        "faye-websocket": "^0.11.4",
         "inherits": "^2.0.4",
-        "json3": "^3.3.3",
-        "url-parse": "^1.5.3"
+        "url-parse": "^1.5.10"
       },
       "dependencies": {
         "debug": {
@@ -15263,9 +15251,9 @@
       }
     },
     "url-parse": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
-      "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
       "requires": {
         "querystringify": "^2.1.1",
         "requires-port": "^1.0.0"
@@ -16052,8 +16040,7 @@
           "dependencies": {
             "ansi-regex": {
               "version": "4.1.0",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+              "resolved": ""
             },
             "strip-ansi": {
               "version": "5.2.0",
@@ -16283,8 +16270,7 @@
           "dependencies": {
             "ansi-regex": {
               "version": "4.1.0",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+              "resolved": ""
             },
             "strip-ansi": {
               "version": "5.2.0",
@@ -16333,8 +16319,7 @@
           "dependencies": {
             "ansi-regex": {
               "version": "4.1.0",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+              "resolved": ""
             },
             "strip-ansi": {
               "version": "5.2.0",

+ 3 - 1
package.json

@@ -27,7 +27,8 @@
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test",
-    "eject": "react-scripts eject"
+    "eject": "react-scripts eject",
+    "format": "npx prettier --write src"
   },
   "eslintConfig": {
     "extends": [
@@ -49,6 +50,7 @@
   },
   "proxy": "http://snippet.node.ed.asmer.org.ua/",
   "devDependencies": {
+    "prettier": "2.6.2",
     "webpack": "^4.44.2"
   }
 }

src/code.png → public/img/code.png


src/logo.png → public/img/logo.png


src/user.png → public/img/user.png


+ 20 - 20
src/App.css

@@ -3,36 +3,36 @@
 } */
 
 .App-logo {
-  height: 40vmin;
-  pointer-events: none;
+	height: 40vmin;
+	pointer-events: none;
 }
 
 @media (prefers-reduced-motion: no-preference) {
-  .App-logo {
-    animation: App-logo-spin infinite 20s linear;
-  }
+	.App-logo {
+		animation: App-logo-spin infinite 20s linear;
+	}
 }
 
 .App-header {
-  background-color: #282c34;
-  min-height: 100vh;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  font-size: calc(10px + 2vmin);
-  color: white;
+	background-color: #282c34;
+	min-height: 100vh;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	font-size: calc(10px + 2vmin);
+	color: white;
 }
 
 .App-link {
-  color: #61dafb;
+	color: #61dafb;
 }
 
 @keyframes App-logo-spin {
-  from {
-    transform: rotate(0deg);
-  }
-  to {
-    transform: rotate(360deg);
-  }
+	from {
+		transform: rotate(0deg);
+	}
+	to {
+		transform: rotate(360deg);
+	}
 }

+ 11 - 9
src/App.js

@@ -1,17 +1,19 @@
 import React from "react";
 import { Provider } from "react-redux";
-import ConnectedRouts from "./components/Routers";
-import store from "./reducers";
+
+import ConnectedRouts from "components/Routers";
+import store from "store/reducers";
+
 import "./App.css";
 
 function App() {
-  return (
-    <>
-      <Provider store={store}>
-        <ConnectedRouts />
-      </Provider>
-    </>
-  );
+	return (
+		<>
+			<Provider store={store}>
+				<ConnectedRouts />
+			</Provider>
+		</>
+	);
 }
 
 export default App;

+ 3 - 3
src/App.test.js

@@ -2,7 +2,7 @@ import { render, screen } from "@testing-library/react";
 import App from "./App";
 
 test("renders learn react link", () => {
-  render(<App />);
-  const linkElement = screen.getByText(/learn react/i);
-  expect(linkElement).toBeInTheDocument();
+	render(<App />);
+	const linkElement = screen.getByText(/learn react/i);
+	expect(linkElement).toBeInTheDocument();
 });

+ 0 - 1
src/actions/actionAuthLogin.js

@@ -1 +0,0 @@
-export const actionAuthLogin = (token) => ({ type: "LOGIN", token });

+ 0 - 8
src/actions/actionFindUser.js

@@ -1,8 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { userFind } from "./requests";
-
-export const actionFindUser = () => async (dispatch, getState) => {
-  return await dispatch(
-    actionPromise("findUser", userFind(getState()?.a?.payload?.sub?.id))
-  );
-};

+ 0 - 9
src/actions/actionFullAva.js

@@ -1,9 +0,0 @@
-import { actionUploadFile } from "./actionUploadFile";
-import { actionSetAva } from "./actionSetAva";
-import { actionFindUser } from "./actionFindUser";
-
-export const actionFullAva = (file) => async (dispatch) => {
-  let result = await dispatch(actionUploadFile(file));
-  await dispatch(actionSetAva(result._id));
-  await dispatch(actionFindUser());
-};

+ 0 - 14
src/actions/actionFullLogin.js

@@ -1,14 +0,0 @@
-import { actionLogin } from "./actionLogin";
-import { actionAuthLogin } from "./actionAuthLogin";
-import { actionFindUser } from "./actionFindUser";
-
-export const actionFullLogin = (login, password) => async (dispatch) => {
-  let result = await dispatch(actionLogin(login, password));
-  if (result !== null) {
-    dispatch(actionAuthLogin(result));
-  } else {
-    alert("That user doesn’t exist!");
-    localStorage.clear();
-  }
-  await dispatch(actionFindUser());
-};

+ 0 - 11
src/actions/actionFullRegister.js

@@ -1,11 +0,0 @@
-import { actionReg } from "./actionReg";
-import { actionFullLogin } from "./actionFullLogin";
-
-export const actionFullRegister = (login, password) => async (dispatch) => {
-  let result = await dispatch(actionReg(login, password));
-  if (result?.data?.createUser !== null) {
-    dispatch(actionFullLogin(login, password));
-  } else {
-    alert("Such a user already exists!");
-  }
-};

+ 0 - 6
src/actions/actionImgFind.js

@@ -1,6 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { imgFind } from "./requests";
-
-export const actionImgFind = () => async (dispatch) => {
-  return await dispatch(actionPromise("img", imgFind()));
-};

+ 0 - 5
src/actions/actionLogin.js

@@ -1,5 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { log } from "./requests";
-
-export const actionLogin = (login, password) =>
-  actionPromise("login", log(login, password));

+ 0 - 5
src/actions/actionPending.js

@@ -1,5 +0,0 @@
-export const actionPending = (name) => ({
-  type: "PROMISE",
-  status: "PENDING",
-  name,
-});

+ 0 - 14
src/actions/actionPromise.js

@@ -1,14 +0,0 @@
-import { actionPending } from "./actionPending";
-import { actionResolved } from "./actionResolved";
-import { actionRejected } from "./actionRejected";
-
-export const actionPromise = (name, promise) => async (dispatch) => {
-  dispatch(actionPending(name));
-  try {
-    let payload = await promise;
-    dispatch(actionResolved(name, payload));
-    return payload;
-  } catch (error) {
-    dispatch(actionRejected(name, error));
-  }
-};

+ 0 - 5
src/actions/actionReg.js

@@ -1,5 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { reg } from "./requests";
-
-export const actionReg = (login, password) =>
-  actionPromise("reg", reg(login, password));

+ 0 - 6
src/actions/actionRejected.js

@@ -1,6 +0,0 @@
-export const actionRejected = (name, error) => ({
-  type: "PROMISE",
-  status: "REJECTED",
-  name,
-  error,
-});

+ 0 - 6
src/actions/actionResolved.js

@@ -1,6 +0,0 @@
-export const actionResolved = (name, payload) => ({
-  type: "PROMISE",
-  status: "RESOLVED",
-  name,
-  payload,
-});

+ 0 - 6
src/actions/actionSearch.js

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

+ 0 - 8
src/actions/actionSetAva.js

@@ -1,8 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { setAva } from "./requests";
-
-export const actionSetAva = (id) => async (dispatch, getState) => {
-  return await dispatch(
-    actionPromise("setAva", setAva(getState()?.a?.payload?.sub?.id, id))
-  );
-};

+ 0 - 12
src/actions/actionSnippetAdd.js

@@ -1,12 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { snippetAdd } from "./requests";
-
-export const actionSnippetAdd =
-  (title, description, files, idSnippet) => async (dispatch) => {
-    return await dispatch(
-      actionPromise(
-        "addSnippet",
-        snippetAdd(title, description, files, idSnippet)
-      )
-    );
-  };

+ 0 - 6
src/actions/actionSnippetById.js

@@ -1,6 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { snippetById } from "./requests";
-
-export const actionSnippetById = (id) => async (dispatch) => {
-  return await dispatch(actionPromise("findSnippetById", snippetById(id)));
-};

+ 0 - 6
src/actions/actionSnippetFindByOwner.js

@@ -1,6 +0,0 @@
-import { actionPromise } from "./actionPromise";
-import { snippetByOwner } from "./requests";
-
-export const actionSnippetFindByOwner = (id) => async (dispatch) => {
-  return await dispatch(actionPromise("findSnippet", snippetByOwner(id)));
-};

+ 0 - 18
src/actions/actionUploadFile.js

@@ -1,18 +0,0 @@
-import { actionPromise } from "./actionPromise";
-
-export const actionUploadFile = (files) => async (dispatch) => {
-  let fd = new FormData();
-  fd.append("photo", files);
-  return await dispatch(
-    actionPromise(
-      "upload",
-      fetch("/upload", {
-        method: "POST",
-        headers: localStorage.authToken
-          ? { Authorization: "Bearer " + localStorage.authToken }
-          : {},
-        body: fd,
-      }).then((res) => res.json())
-    )
-  );
-};

+ 0 - 13
src/actions/gql.js

@@ -1,13 +0,0 @@
-const getGQL = (url) => (query, variables) =>
-  fetch(url, {
-    method: "POST",
-    headers: {
-      "content-type": "application/json",
-      ...(localStorage.authToken
-        ? { Authorization: "Bearer " + localStorage.authToken }
-        : {}),
-    },
-    body: JSON.stringify({ query, variables }),
-  }).then((res) => res.json());
-
-export const gql = getGQL("/graphql");

+ 0 - 150
src/actions/requests.js

@@ -1,150 +0,0 @@
-import { gql } from "./gql";
-
-export const log = async (login, password) => {
-  let query = `query login($login:String!, $password:String!) {
-        login(
-            login: $login,
-            password: $password
-         )}`;
-
-  let variables = { login, password };
-
-  let token = await gql(query, variables);
-  localStorage.authToken = token.data.login;
-  console.log(token);
-  return token.data.login;
-};
-
-export const reg = async (login, password) => {
-  let query = `mutation reg($login:String!, $password:String!) {
-    createUser(
-        login: $login,
-        password: $password
-
-    ){
-       _id
-    }}`;
-
-  let variables = { login: login, password: password };
-
-  let res = await gql(query, variables);
-  return res;
-};
-
-export const imgFind = async () => {
-  return await gql(`query imgFind{
-      ImageFind(query:"[{}]"){
-        url owner{
-          nick
-        }
-      }
-    }`);
-};
-
-export const userFind = (_id) => {
-  return gql(
-    `query userOne($query:String) {
-            UserFindOne(query:$query){
-                _id avatar{
-                url
-                }
-            }
-        }`,
-    { query: JSON.stringify([{ _id }]) }
-  );
-};
-
-export const setAva = async (idUser, id) => {
-  let query = `mutation setAvatar($idUser:String , $idAvatar:ID){ 
-      UserUpsert(user:{_id: $idUser, avatar: {_id: $idAvatar}}){
-          _id, avatar{
-              url
-          }
-      }
-  }`;
-
-  let variables = { idUser: idUser, idAvatar: id };
-
-  let res = await gql(query, variables);
-  return res;
-};
-
-export const snippetAdd = async (title, description, files, idSnippet) => {
-  let query = `mutation newSnippet($snippet:SnippetInput) {
-      SnippetUpsert(snippet:$snippet){
-        _id
-      }
-    }`;
-
-  let qVariables = { snippet: { title, description, files, _id: idSnippet } };
-
-  let res = await gql(query, qVariables);
-  return res;
-};
-
-export const snippetById = async (id) => {
-  let query = `query snippetFind($query:String){
-      SnippetFind(query:$query){
-                        owner{
-                          _id 
-                        }
-            title description _id files {
-             type text name
-           }
-        }
-  }`;
-
-  let variables = {
-    query: JSON.stringify([{ _id: id }]),
-  };
-  let res = gql(query, variables);
-  return res;
-};
-
-export const snippetByOwner = async (id) => {
-  let query = `query snippetFind($query:String){
-        SnippetFind(query:$query){
-                          owner{
-                            _id 
-                          }
-              title description _id files {
-               type text name
-            }
-        }
-  }`;
-
-  let variables = {
-    query: JSON.stringify([{ ___owner: id }, { sort: [{ _id: -1 }] }]),
-  };
-
-  let res = gql(query, variables);
-  return res;
-};
-
-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 }],
-        },
-      ]),
-    }
-  );
-};

+ 10 - 10
src/components/Ava.js

@@ -1,18 +1,18 @@
 import React from "react";
 import { connect } from "react-redux";
+
 import "./Header.css";
-import icon from "../user.png";
 
 function AvaLogo({ link }) {
-  return (
-    <img
-      src={link ? "http://localhost:3000/" + link : icon}
-      className="avatar"
-      alt="ava"
-    ></img>
-  );
+	return (
+		<img
+			src={link ? "http://localhost:3000/" + link : `${process.env.PUBLIC_URL}/img/user.png`}
+			className='avatar'
+			alt='ava'
+		></img>
+	);
 }
 
-export const ConnectedAvaLogo = connect((state) => ({
-  link: state?.p?.findUser?.payload?.data?.UserFindOne?.avatar?.url,
+export const ConnectedAvaLogo = connect(state => ({
+	link: state?.promise?.findUser?.payload?.data?.UserFindOne?.avatar?.url,
 }))(AvaLogo);

+ 7 - 7
src/components/Editor.css

@@ -1,15 +1,15 @@
 .all_editors {
-  display: inline-block;
-  width: 464px;
-  padding-left: 10px;
-  color: rgb(196, 192, 192);
+	display: inline-block;
+	width: 464px;
+	padding-left: 10px;
+	color: rgb(196, 192, 192);
 }
 
 select {
-  margin: 5px;
-  font-size: 17px;
+	margin: 5px;
+	font-size: 17px;
 }
 
 .editor {
-  margin-top: 5px;
+	margin-top: 5px;
 }

+ 38 - 50
src/components/Editor.js

@@ -27,56 +27,44 @@ import "ace-builds/src-noconflict/theme-textmate";
 import "ace-builds/src-noconflict/theme-terminal";
 import "ace-builds/src-noconflict/theme-solarized_dark";
 import "ace-builds/src-noconflict/theme-solarized_light";
-import { SelectMode } from "../helpers/SelectMode";
+
+import { SelectMode } from "helpers/SelectMode";
+
 import "./Editor.css";
 
-export const Editor = ({
-  data = { type: "", name: "", text: "", index: "" },
-  onChange,
-  theme,
-  font,
-}) => {
-  return (
-    <div className="all_editors">
-      {"Mode: "}
-      <SelectMode
-        onChange={(type) =>
-          onChange({ type, text: data.text, name: data.name })
-        }
-        value={data.type}
-      />
-      <br />
-      {"Name of editor: "}
-      <input
-        placeholder="Enter a name for your editor"
-        type="text"
-        value={data.name}
-        onChange={(e) =>
-          onChange({ type: data.type, text: data.text, name: e.target.value })
-        }
-      />
-      <AceEditor
-        className="editor"
-        value={data.text}
-        onChange={(text) =>
-          onChange({ type: data.type, text, name: data.name })
-        }
-        placeholder="Your Code"
-        mode={data.type}
-        name={data.name}
-        theme={theme}
-        fontSize={Number(font)}
-        showPrintMargin={true}
-        showGutter={true}
-        highlightActiveLine={true}
-        setOptions={{
-          enableBasicAutocompletion: true,
-          enableLiveAutocompletion: true,
-          enableSnippets: true,
-          showLineNumbers: true,
-          tabSize: 2,
-        }}
-      />
-    </div>
-  );
+export const Editor = ({ data = { type: "", name: "", text: "", index: "" }, onChange, theme, font }) => {
+	return (
+		<div className='all_editors'>
+			{"Mode: "}
+			<SelectMode onChange={type => onChange({ type, text: data.text, name: data.name })} value={data.type} />
+			<br />
+			{"Name of editor: "}
+			<input
+				placeholder='Enter a name for your editor'
+				type='text'
+				value={data.name}
+				onChange={e => onChange({ type: data.type, text: data.text, name: e.target.value })}
+			/>
+			<AceEditor
+				className='editor'
+				value={data.text}
+				onChange={text => onChange({ type: data.type, text, name: data.name })}
+				placeholder='Your Code'
+				mode={data.type}
+				name={data.name}
+				theme={theme}
+				fontSize={Number(font)}
+				showPrintMargin={true}
+				showGutter={true}
+				highlightActiveLine={true}
+				setOptions={{
+					enableBasicAutocompletion: true,
+					enableLiveAutocompletion: true,
+					enableSnippets: true,
+					showLineNumbers: true,
+					tabSize: 2,
+				}}
+			/>
+		</div>
+	);
 };

+ 63 - 67
src/components/EditorsPage.css

@@ -1,94 +1,90 @@
-body {
-  margin-top: 20px;
-}
+/* body {
+	margin-top: 20px;
+} */
 
 .button_plus {
-  display: flex;
-  justify-content: center;
-  cursor: pointer;
-  margin-left: 47.2%;
-  margin-bottom: 20px;
-  width: 6em;
-  height: 2.5em;
-  cursor: pointer;
-  margin-top: 7px;
-  line-height: 2.4em;
-  vertical-align: middle;
-  font-weight: 550;
-  text-align: center;
-  text-decoration: none;
-  user-select: none;
-  color: rgb(41, 14, 66);
-  outline: none;
-  border: 1px solid rgba(110, 121, 128, 0.8);
-  border-top-color: rgba(0, 0, 0, 0.3);
-  border-radius: 5px;
-  background: rgb(206, 220, 231)
-    linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
-  box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset,
-    0 1px rgba(255, 255, 255, 0.5) inset;
+	display: flex;
+	justify-content: center;
+	cursor: pointer;
+	margin-left: 47.2%;
+	margin-bottom: 20px;
+	width: 6em;
+	height: 2.5em;
+	cursor: pointer;
+	margin-top: 7px;
+	line-height: 2.4em;
+	vertical-align: middle;
+	font-weight: 550;
+	text-align: center;
+	text-decoration: none;
+	user-select: none;
+	color: rgb(41, 14, 66);
+	outline: none;
+	border: 1px solid rgba(110, 121, 128, 0.8);
+	border-top-color: rgba(0, 0, 0, 0.3);
+	border-radius: 5px;
+	background: rgb(206, 220, 231) linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
+	box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset, 0 1px rgba(255, 255, 255, 0.5) inset;
 }
 
 .button_plus:hover {
-  background: linear-gradient(#baa7cc, #9285b4);
+	background: linear-gradient(#baa7cc, #9285b4);
 }
 
 .pane {
-  background-color: white;
-  width: 99%;
-  height: 300px;
-  margin-left: 10px;
-  margin-bottom: 30px;
-  border: dotted;
+	background-color: white;
+	width: 99%;
+	height: 300px;
+	margin-left: 10px;
+	margin-bottom: 30px;
+	border: dotted;
 }
 
 .input_title {
-  margin-left: 37.5%;
-  width: 400px;
+	margin-left: 37.5%;
+	width: 400px;
 }
 
 .text_desc {
-  margin-left: 37.5%;
-  width: 400px;
+	margin-left: 37.5%;
+	width: 400px;
 }
 
 .text {
-  margin-left: 37.5%;
-  font-size: 17px;
-  color: rgb(197, 193, 226);
+	margin-left: 37.5%;
+	font-size: 17px;
+	color: rgb(197, 193, 226);
 }
 
 .button_submit {
-  cursor: pointer;
-  margin-bottom: 90px;
-  margin-left: 46%;
-  width: 10em;
-  height: 2.5em;
-  cursor: pointer;
-  margin-top: 30px;
-  line-height: 2.4em;
-  vertical-align: middle;
-  font-weight: 550;
-  text-align: center;
-  text-decoration: none;
-  user-select: none;
-  color: rgb(41, 14, 66);
-  outline: none;
-  border: 1px solid rgba(110, 121, 128, 0.8);
-  border-top-color: rgba(0, 0, 0, 0.3);
-  border-radius: 5px;
-  background: rgb(206, 220, 231)
-    linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
-  box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset,
-    0 1px rgba(255, 255, 255, 0.5) inset;
+	cursor: pointer;
+	margin-bottom: 90px;
+	margin-left: 46%;
+	width: 10em;
+	height: 2.5em;
+	cursor: pointer;
+	margin-top: 30px;
+	line-height: 2.4em;
+	vertical-align: middle;
+	font-weight: 550;
+	text-align: center;
+	text-decoration: none;
+	user-select: none;
+	color: rgb(41, 14, 66);
+	outline: none;
+	border: 1px solid rgba(110, 121, 128, 0.8);
+	border-top-color: rgba(0, 0, 0, 0.3);
+	border-radius: 5px;
+	background: rgb(206, 220, 231) linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
+	box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset, 0 1px rgba(255, 255, 255, 0.5) inset;
 }
 
 .button_submit:hover {
-  background: linear-gradient(#baa7cc, #9285b4);
+	background: linear-gradient(#baa7cc, #9285b4);
 }
 
 .styles {
-  padding-left: 10px;
-  color: rgb(196, 192, 192);
-  padding-bottom: 30px;
+	padding-left: 10px;
+	color: rgb(196, 192, 192);
+	padding-bottom: 30px;
 }

+ 105 - 113
src/components/EditorsPage.js

@@ -1,29 +1,31 @@
 import { useState, useEffect } from "react";
-import { Editor } from "../components/Editor";
-import { SelectTheme } from "../helpers/SelectTheme";
-import { SelectFontSize } from "../helpers/SelectFontSize";
+
+import { SelectTheme } from "helpers/SelectTheme";
+import { SelectFontSize } from "helpers/SelectFontSize";
+
 import "./EditorsPage.css";
+import { Editor } from "./Editor";
 
 const datas = [
-  {
-    type: "html",
-    name: "",
-    text: `<!DOCTYPE html> 
+	{
+		type: "html",
+		name: "",
+		text: `<!DOCTYPE html> 
     <h1 id="codepen">Welcome to the Codepen</h1>`,
-  },
-  {
-    type: "css",
-    name: "",
-    text: `#codepen {
+	},
+	{
+		type: "css",
+		name: "",
+		text: `#codepen {
     color: blue;
     font-size: 25px;
     font-family: Times New Roman;
 }`,
-  },
-  {
-    type: "javascript",
-    name: "",
-    text: `let btn = document.createElement('button');
+	},
+	{
+		type: "javascript",
+		name: "",
+		text: `let btn = document.createElement('button');
     btn.innerHTML = 'Change color';
     btn.style.color = 'red';
     btn.style.fontSize = '20px';
@@ -31,115 +33,105 @@ const datas = [
     btn.style.cursor = 'pointer';
     btn.onclick = () => {
     document.getElementById('codepen').style.color = 'red'};`,
-  },
+	},
 ];
 
 export const EditorsPage = ({ onSave }) => {
-  const [editors, setEditors] = useState(datas);
-  const [title, setTitle] = useState("");
-  const [description, setDescription] = useState("");
-  const [srcDoc, setSrcDoc] = useState("");
-  const [theme, setTheme] = useState();
-  const [font, setFont] = useState();
+	const [editors, setEditors] = useState(datas);
+	const [title, setTitle] = useState("");
+	const [description, setDescription] = useState("");
+	const [srcDoc, setSrcDoc] = useState("");
+	const [theme, setTheme] = useState();
+	const [font, setFont] = useState();
 
-  useEffect(() => {
-    const timeout = setTimeout(() => {
-      let html, css, javascript;
-      editors.forEach((e) => {
-        if (e.type === "html") html = e.text;
-        if (e.type === "css") css = e.text;
-        if (e.type === "javascript") javascript = e.text;
-      });
-      setSrcDoc(`
+	useEffect(() => {
+		const timeout = setTimeout(() => {
+			let html, css, javascript;
+			editors.forEach(e => {
+				if (e.type === "html") html = e.text;
+				if (e.type === "css") css = e.text;
+				if (e.type === "javascript") javascript = e.text;
+			});
+			setSrcDoc(`
             <html>
               <body>${html}</body>
               <style>${css}</style>
               <script>${javascript}</script>
             </html>
           `);
-    }, 250);
+		}, 250);
 
-    return () => clearTimeout(timeout);
-  }, [editors]);
+		return () => clearTimeout(timeout);
+	}, [editors]);
 
-  return (
-    <>
-      <div className="styles">
-        {"Theme: "}
-        <SelectTheme onChange={setTheme} value={theme} />
-        <br />
-        {"FontSize: "}
-        <SelectFontSize onChange={setFont} value={font} />
-        <br />
-      </div>
-      {editors.map((data, index) => {
-        return (
-          <Editor
-            data={data}
-            key={index}
-            theme={theme}
-            font={font}
-            onChange={(newData) => {
-              let editor = [...editors];
-              editor.splice(index, 1, newData);
-              setEditors(editor);
-            }}
-          />
-        );
-      })}
+	return (
+		<>
+			<div className='styles'>
+				{"Theme: "}
+				<SelectTheme onChange={setTheme} value={theme} />
+				<br />
+				{"FontSize: "}
+				<SelectFontSize onChange={setFont} value={font} />
+				<br />
+			</div>
+			{editors.map((data, index) => {
+				return (
+					<Editor
+						data={data}
+						key={index}
+						theme={theme}
+						font={font}
+						onChange={newData => {
+							let editor = [...editors];
+							editor.splice(index, 1, newData);
+							setEditors(editor);
+						}}
+					/>
+				);
+			})}
 
-      <button
-        className="button_plus"
-        onClick={(newArray) => {
-          let editors2 = [...editors];
-          editors2.push(newArray);
-          setEditors(editors2);
-        }}
-      >
-        +
-      </button>
+			<button
+				className='button_plus'
+				onClick={newArray => {
+					let editors2 = [...editors];
+					editors2.push(newArray);
+					setEditors(editors2);
+				}}
+			>
+				+
+			</button>
 
-      <button
-        className="button_plus"
-        onClick={(newArray) => {
-          let editors2 = [...editors];
-          editors2.pop(newArray);
-          setEditors(editors2);
-        }}
-      >
-        -
-      </button>
+			<button
+				className='button_plus'
+				onClick={newArray => {
+					let editors2 = [...editors];
+					editors2.pop(newArray);
+					setEditors(editors2);
+				}}
+			>
+				-
+			</button>
 
-      <div className="pane">
-        <iframe
-          srcDoc={srcDoc}
-          title="output"
-          sandbox="allow-scripts"
-          frameBorder="0"
-          width="100%"
-          height="100%"
-        />
-      </div>
-      <p className="text">Name of your project: </p>
-      <input
-        className="input_title"
-        placeholder="Name of your project"
-        value={title}
-        onChange={(e) => setTitle(e.target.value)}
-      />
-      <p className="text">Description: </p>
-      <textarea
-        className="text_desc"
-        placeholder="Description"
-        value={description}
-        onChange={(e) => setDescription(e.target.value)}
-      />
-      <button
-        className="button_submit"
-        onClick={() => onSave(title, description, editors)}
-      >
-        Submit this Editor
-      </button>
-    </>
-  );
+			<div className='pane'>
+				<iframe srcDoc={srcDoc} title='output' sandbox='allow-scripts' frameBorder='0' width='100%' height='100%' />
+			</div>
+			<p className='text'>Name of your project: </p>
+			<input
+				className='input_title'
+				placeholder='Name of your project'
+				value={title}
+				onChange={e => setTitle(e.target.value)}
+			/>
+			<p className='text'>Description: </p>
+			<textarea
+				className='text_desc'
+				placeholder='Description'
+				value={description}
+				onChange={e => setDescription(e.target.value)}
+			/>
+			<button className='button_submit' onClick={() => onSave(title, description, editors)}>
+				Submit this Editor
+			</button>
+		</>
+	);
 };

+ 60 - 64
src/components/Header.css

@@ -1,93 +1,89 @@
 body {
-  margin: 0;
+	margin: 0;
 }
 
 nav {
-  display: flex;
-  margin-bottom: 30px;
-  padding: 5px;
-  background: linear-gradient(#a088bd, #c7a9aa);
+	display: flex;
+	margin-bottom: 30px;
+	padding: 5px;
+	background: linear-gradient(#a088bd, #c7a9aa);
 }
 
 .img_logo {
-  width: 100px;
-  margin-right: 1035px;
-  border: 1.5px solid rgb(72, 70, 75);
-  margin-top: 10px;
-  margin-left: 15px;
+	width: 100px;
+	margin-right: 1035px;
+	border: 1.5px solid rgb(72, 70, 75);
+	margin-top: 10px;
+	margin-left: 15px;
 }
 
 .img_logo:hover {
-  border: 1.5px solid rgb(231, 224, 224);
-  width: 99px;
+	border: 1.5px solid rgb(231, 224, 224);
+	width: 99px;
 }
 
 .logaut a {
-  color: rgb(23, 6, 39);
-  text-decoration: none;
-  font-size: 20px;
+	color: rgb(23, 6, 39);
+	text-decoration: none;
+	font-size: 20px;
 }
 
 .logaut button {
-  position: relative;
-  display: inline-block;
-  width: 6.5em;
-  height: 2.5em;
-  cursor: pointer;
-  margin-top: 7px;
-  margin-bottom: 5px;
-  vertical-align: middle;
-  font-weight: 550;
-  text-align: center;
-  text-decoration: none;
-  user-select: none;
-  color: rgb(41, 14, 66);
-  outline: none;
-  border: 1px solid rgba(110, 121, 128, 0.8);
-  border-top-color: rgba(0, 0, 0, 0.3);
-  border-radius: 5px;
-  background: rgb(206, 220, 231)
-    linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
-  box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset,
-    0 1px rgba(255, 255, 255, 0.5) inset;
+	position: relative;
+	display: inline-block;
+	width: 6.5em;
+	height: 2.5em;
+	cursor: pointer;
+	margin-top: 7px;
+	margin-bottom: 5px;
+	vertical-align: middle;
+	font-weight: 550;
+	text-align: center;
+	text-decoration: none;
+	user-select: none;
+	color: rgb(41, 14, 66);
+	outline: none;
+	border: 1px solid rgba(110, 121, 128, 0.8);
+	border-top-color: rgba(0, 0, 0, 0.3);
+	border-radius: 5px;
+	background: rgb(206, 220, 231) linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
+	box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset, 0 1px rgba(255, 255, 255, 0.5) inset;
 }
 
 .logaut button:hover {
-  background: linear-gradient(#baa7cc, #9285b4);
+	background: linear-gradient(#baa7cc, #9285b4);
 }
 
 .avatar {
-  margin-top: 25px;
-  margin-right: 10px;
-  width: 70px;
-  height: 70px;
+	margin-top: 25px;
+	margin-right: 10px;
+	width: 70px;
+	height: 70px;
 }
 
 .button_search {
-  cursor: pointer;
-  margin-top: 50px;
-  margin-right: 10px;
-  position: relative;
-  display: inline-block;
-  width: 6.5em;
-  height: 2.5em;
-  margin-bottom: 5px;
-  vertical-align: middle;
-  font-weight: 550;
-  text-align: center;
-  text-decoration: none;
-  user-select: none;
-  color: rgb(41, 14, 66);
-  outline: none;
-  border: 1px solid rgba(110, 121, 128, 0.8);
-  border-top-color: rgba(0, 0, 0, 0.3);
-  border-radius: 5px;
-  background: rgb(206, 220, 231)
-    linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
-  box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset,
-    0 1px rgba(255, 255, 255, 0.5) inset;
+	cursor: pointer;
+	margin-top: 50px;
+	margin-right: 10px;
+	position: relative;
+	display: inline-block;
+	width: 6.5em;
+	height: 2.5em;
+	margin-bottom: 5px;
+	vertical-align: middle;
+	font-weight: 550;
+	text-align: center;
+	text-decoration: none;
+	user-select: none;
+	color: rgb(41, 14, 66);
+	outline: none;
+	border: 1px solid rgba(110, 121, 128, 0.8);
+	border-top-color: rgba(0, 0, 0, 0.3);
+	border-radius: 5px;
+	background: rgb(206, 220, 231) linear-gradient(rgb(206, 220, 231), rgb(106, 70, 148));
+	box-shadow: 0 -1px rgba(10, 21, 28, 0.9) inset, 0 1px rgba(255, 255, 255, 0.5) inset;
 }
 
 .button_search:hover {
-  background: linear-gradient(#baa7cc, #9285b4);
+	background: linear-gradient(#baa7cc, #9285b4);
 }

+ 10 - 9
src/components/Header.js

@@ -1,16 +1,17 @@
+import { ConnectFormUpload } from "pages/FormUpload";
+
+import "./Header.css";
 import ImgLogo from "./Logo";
 import ConnectedNick from "./UserHeader";
-import { ConnectFormUpload } from "../pages/FormUpload";
-import "./Header.css";
 
 const Header = () => {
-  return (
-    <nav className="navbar_header">
-      <ImgLogo />
-      <ConnectFormUpload />
-      <ConnectedNick />
-    </nav>
-  );
+	return (
+		<nav className='navbar_header'>
+			<ImgLogo />
+			<ConnectFormUpload />
+			<ConnectedNick />
+		</nav>
+	);
 };
 
 export default Header;

+ 14 - 11
src/components/Logo.js

@@ -1,16 +1,19 @@
 import React from "react";
-import logo from "../logo.png";
+
 import "./Header.css";
 
 function ImgLogo() {
-    return <>
-    <a href="/work"> <img src={logo} alt="logo" className='img_logo'/></a>
-    <a href="/search">
-        <button className='button_search'>
-            Search
-        </button>
-    </a>
-    </>
+	return (
+		<>
+			<a href='/work'>
+				{" "}
+				<img src={`${process.env.PUBLIC_URL}/img/logo.png`} alt='logo' className='img_logo' />
+			</a>
+			<a href='/search'>
+				<button className='button_search'>Search</button>
+			</a>
+		</>
+	);
 }
-  
-export default ImgLogo;
+
+export default ImgLogo;

+ 37 - 44
src/components/Routers.js

@@ -1,22 +1,18 @@
 import React from "react";
-import {
-  BrowserRouter as Router,
-  Route,
-  Switch,
-  Redirect,
-} from "react-router-dom";
+import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";
 import * as createHistory from "history";
 import { connect } from "react-redux";
-import { actionFullLogin } from "../actions/actionFullLogin";
-import { actionFullRegister } from "../actions/actionFullRegister";
-import { LoginForm } from "../pages/LoginForm";
-import { FormReg } from "../pages/FormReg";
-import { Main } from "../pages/Main";
-import { Home } from "../pages/WorkPage";
-import { Cabinet } from "../pages/Cabinet";
-import ConnectFormSearch from "../pages/Search";
-import CProjects from "../pages/Projects";
-import ConnectedProject from "../pages/Project";
+
+import { actionFullLogin } from "store/actions/actionFullLogin";
+import { actionFullRegister } from "store/actions/actionFullRegister";
+import { LoginForm } from "pages/LoginForm";
+import { FormReg } from "pages/FormReg";
+import { Main } from "pages/Main";
+import { Home } from "pages/WorkPage";
+import { Cabinet } from "pages/Cabinet";
+import ConnectFormSearch from "pages/Search";
+import CProjects from "pages/Projects";
+import ConnectedProject from "pages/Project";
 
 const history = createHistory.createBrowserHistory();
 
@@ -25,35 +21,32 @@ const ConnectLoginForm = connect(null, { onLogin: actionFullLogin })(LoginForm);
 const ConnectFormReg = connect(null, { FormReg: actionFullRegister })(FormReg);
 
 const Routs = ({ token }) => {
-  return (
-    <div className="App">
-      <Router history={history}>
-        {token && (
-          <Switch>
-            <Redirect from="/login" to="/work" />
-            <Redirect from="/reg" to="/work" />
-            <Route exact path="/work" component={Home} />
-            <Route path="/cabinet" component={Cabinet} />
-            <Route path="/projects" component={CProjects} />
-            <Route path="/project" component={ConnectedProject} />
-            <Route path="/search" component={ConnectFormSearch} />
-          </Switch>
-        )}
-        {!token && (
-          <Switch>
-            <Route path="/login" component={ConnectLoginForm} />
-            <Route path="/reg" component={ConnectFormReg} />
-            <Route path="/" component={Main} />
-          </Switch>
-        )}
-      </Router>
-    </div>
-  );
+	return (
+		<div className='App'>
+			<Router history={history}>
+				{token && (
+					<Switch>
+						<Redirect from='/login' to='/work' />
+						<Redirect from='/reg' to='/work' />
+						<Route exact path='/work' component={Home} />
+						<Route path='/cabinet' component={Cabinet} />
+						<Route path='/projects' component={CProjects} />
+						<Route path='/project' component={ConnectedProject} />
+						<Route path='/search' component={ConnectFormSearch} />
+					</Switch>
+				)}
+				{!token && (
+					<Switch>
+						<Route path='/login' component={ConnectLoginForm} />
+						<Route path='/reg' component={ConnectFormReg} />
+						<Route path='/' component={Main} />
+					</Switch>
+				)}
+			</Router>
+		</div>
+	);
 };
 
-const ConnectedRouts = connect(
-  (state) => ({ token: state.a.token }),
-  null
-)(Routs);
+const ConnectedRouts = connect(state => ({ token: state.auth.token }), null)(Routs);
 
 export default ConnectedRouts;

+ 9 - 9
src/components/User.js

@@ -1,16 +1,16 @@
 import { connect } from "react-redux";
 
 const Nick = ({ nick }) => {
-  return (
-    <>
-      <div>
-        <p>{nick}</p>
-      </div>
-    </>
-  );
+	return (
+		<>
+			<div>
+				<p>{nick}</p>
+			</div>
+		</>
+	);
 };
 
-const ConnectNickName = connect((state) => ({
-  nick: state?.a?.payload?.sub?.login,
+const ConnectNickName = connect(state => ({
+	nick: state?.auth?.payload?.sub?.login,
 }))(Nick);
 export default ConnectNickName;

+ 19 - 18
src/components/UserHeader.js

@@ -1,25 +1,26 @@
 import { connect } from "react-redux";
-import { actionAuthLogout } from "../actions/actionAuthLogout";
+
+import { actionAuthLogout } from "store/actions/actionAuthLogout";
+
 import "./Header.css";
 
 const NickName = ({ nick, onLogOut }) => {
-  return (
-    <>
-      <div className="logaut">
-        <a href="/cabinet">{nick}</a>
-        <a href="/cabinet">
-          <button className="cabinet">My Cabinet</button>
-        </a>
-        <a href="/">
-          <button onClick={() => onLogOut()}>Log out</button>
-        </a>
-      </div>
-    </>
-  );
+	return (
+		<>
+			<div className='logaut'>
+				<a href='/cabinet'>{nick}</a>
+				<a href='/cabinet'>
+					<button className='cabinet'>My Cabinet</button>
+				</a>
+				<a href='/'>
+					<button onClick={() => onLogOut()}>Log out</button>
+				</a>
+			</div>
+		</>
+	);
 };
 
-const ConnectedNick = connect(
-  (state) => ({ nick: state?.a?.payload?.sub?.login, logedIn: state.a.token }),
-  { onLogOut: actionAuthLogout }
-)(NickName);
+const ConnectedNick = connect(state => ({ nick: state?.auth?.payload?.sub?.login, logedIn: state.auth.token }), {
+	onLogOut: actionAuthLogout,
+})(NickName);
 export default ConnectedNick;

+ 18 - 18
src/helpers/SelectFontSize.js

@@ -1,23 +1,23 @@
 const fonts = {
-  12: 12,
-  14: 14,
-  16: 16,
-  18: 18,
-  20: 20,
-  24: 24,
-  28: 28,
-  32: 32,
-  40: 40,
+	12: 12,
+	14: 14,
+	16: 16,
+	18: 18,
+	20: 20,
+	24: 24,
+	28: 28,
+	32: 32,
+	40: 40,
 };
 
 export const SelectFontSize = ({ listObj = fonts, onChange, value }) => {
-  return (
-    <select value={value} onChange={(e) => onChange(e.target.value)}>
-      {Object.entries(listObj).map(([value, text]) => (
-        <option value={value} key={value}>
-          {text}
-        </option>
-      ))}
-    </select>
-  );
+	return (
+		<select value={value} onChange={e => onChange(e.target.value)}>
+			{Object.entries(listObj).map(([value, text]) => (
+				<option value={value} key={value}>
+					{text}
+				</option>
+			))}
+		</select>
+	);
 };

+ 25 - 25
src/helpers/SelectMode.js

@@ -1,30 +1,30 @@
 const types = {
-  html: "html",
-  css: "css",
-  javascript: "javascript",
-  java: "java",
-  python: "python",
-  ruby: "ruby",
-  xml: "xml",
-  sass: "sass",
-  json: "json",
-  typescript: "typescript",
-  markdown: "markdown",
-  mysql: "mysql",
-  handlebars: "handlebars",
-  golang: "golang",
-  csharp: "csharp",
-  elixir: "elixir",
+	html: "html",
+	css: "css",
+	javascript: "javascript",
+	java: "java",
+	python: "python",
+	ruby: "ruby",
+	xml: "xml",
+	sass: "sass",
+	json: "json",
+	typescript: "typescript",
+	markdown: "markdown",
+	mysql: "mysql",
+	handlebars: "handlebars",
+	golang: "golang",
+	csharp: "csharp",
+	elixir: "elixir",
 };
 
 export const SelectMode = ({ listObj = types, onChange, value }) => {
-  return (
-    <select value={value} onChange={(e) => onChange(e.target.value)}>
-      {Object.entries(listObj).map(([value, text]) => (
-        <option value={value} key={value}>
-          {text}
-        </option>
-      ))}
-    </select>
-  );
+	return (
+		<select value={value} onChange={e => onChange(e.target.value)}>
+			{Object.entries(listObj).map(([value, text]) => (
+				<option value={value} key={value}>
+					{text}
+				</option>
+			))}
+		</select>
+	);
 };

+ 19 - 19
src/helpers/SelectTheme.js

@@ -1,24 +1,24 @@
 const themes = {
-  textmate: "textmate",
-  monokai: "monokai",
-  xcode: "xcode",
-  twilight: "twilight",
-  terminal: "terminal",
-  github: "github",
-  tomorrow: "tomorrow",
-  kuroir: "kuroir",
-  solarized_dark: "solarized_dark",
-  solarized_light: "solarized_light",
+	textmate: "textmate",
+	monokai: "monokai",
+	xcode: "xcode",
+	twilight: "twilight",
+	terminal: "terminal",
+	github: "github",
+	tomorrow: "tomorrow",
+	kuroir: "kuroir",
+	solarized_dark: "solarized_dark",
+	solarized_light: "solarized_light",
 };
 
 export const SelectTheme = ({ listObj = themes, onChange, value }) => {
-  return (
-    <select value={value} onChange={(e) => onChange(e.target.value)}>
-      {Object.entries(listObj).map(([value, text]) => (
-        <option value={value} key={value}>
-          {text}
-        </option>
-      ))}
-    </select>
-  );
+	return (
+		<select value={value} onChange={e => onChange(e.target.value)}>
+			{Object.entries(listObj).map(([value, text]) => (
+				<option value={value} key={value}>
+					{text}
+				</option>
+			))}
+		</select>
+	);
 };

+ 35 - 37
src/index.css

@@ -1,69 +1,67 @@
 body {
-  margin: 0;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
-    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
-    sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
+	margin: 0;
+	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
+		"Droid Sans", "Helvetica Neue", sans-serif;
+	-webkit-font-smoothing: antialiased;
+	-moz-osx-font-smoothing: grayscale;
 }
 
 code {
-  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
-    monospace;
+	font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
 }
 
 .top-pane {
-  background-color: hsl(225, 6%, 25%);
+	background-color: hsl(225, 6%, 25%);
 }
 
 .pane {
-  height: 50vh;
-  display: flex;
+	height: 50vh;
+	display: flex;
 }
 
 .editor-container {
-  flex-grow: 1;
-  flex-basis: 0;
-  display: flex;
-  flex-direction: column;
-  padding: 0.5rem;
-  background-color: hsl(225, 6%, 25%);
+	flex-grow: 1;
+	flex-basis: 0;
+	display: flex;
+	flex-direction: column;
+	padding: 0.5rem;
+	background-color: hsl(225, 6%, 25%);
 }
 
 .editor-container.collapsed {
-  flex-grow: 0;
+	flex-grow: 0;
 }
 
 .editor-container.collapsed .CodeMirror-scroll {
-  position: absolute;
-  overflow: hidden !important;
+	position: absolute;
+	overflow: hidden !important;
 }
 
 .expand-collapse-btn {
-  margin-left: 0.5rem;
-  background: none;
-  border: none;
-  color: white;
-  cursor: pointer;
+	margin-left: 0.5rem;
+	background: none;
+	border: none;
+	color: white;
+	cursor: pointer;
 }
 
 .editor-title {
-  display: flex;
-  justify-content: space-between;
-  background-color: hsl(225, 6%, 13%);
-  color: white;
-  padding: 0.5rem 0.5rem 0.5rem 1rem;
-  border-top-right-radius: 0.5rem;
-  border-top-left-radius: 0.5rem;
+	display: flex;
+	justify-content: space-between;
+	background-color: hsl(225, 6%, 13%);
+	color: white;
+	padding: 0.5rem 0.5rem 0.5rem 1rem;
+	border-top-right-radius: 0.5rem;
+	border-top-left-radius: 0.5rem;
 }
 
 .CodeMirror {
-  height: 100% !important;
+	height: 100% !important;
 }
 
 .code-mirror-wrapper {
-  flex-grow: 1;
-  border-bottom-right-radius: 0.5rem;
-  border-bottom-left-radius: 0.5rem;
-  overflow: hidden;
+	flex-grow: 1;
+	border-bottom-right-radius: 0.5rem;
+	border-bottom-left-radius: 0.5rem;
+	overflow: hidden;
 }

+ 5 - 4
src/index.js

@@ -1,14 +1,15 @@
 import React from "react";
 import ReactDOM from "react-dom";
+
 import "./index.css";
 import App from "./App";
 import reportWebVitals from "./reportWebVitals";
 
 ReactDOM.render(
-  <React.StrictMode>
-    <App />
-  </React.StrictMode>,
-  document.getElementById("root")
+	<React.StrictMode>
+		<App />
+	</React.StrictMode>,
+	document.getElementById("root"),
 );
 
 // If you want to start measuring performance in your app, pass a function

+ 21 - 19
src/pages/Cabinet.js

@@ -1,25 +1,27 @@
 import React from "react";
-import ConnectedNick from "../components/UserHeader";
+
+import ConnectedNick from "components/UserHeader";
+
 import { ConnectFormUpload } from "./FormUpload";
 import "./Main.css";
 
 export const Cabinet = () => {
-  return (
-    <>
-      <div className="card">
-        <div className="nick_style">
-          <ConnectFormUpload />
-          <ConnectedNick />
-        </div>
-        <div className="cart_1">
-          <a href="/work">
-            <button className="btn">Work Page</button>
-          </a>
-          <a href="/projects">
-            <button className="btn">My Projects</button>
-          </a>
-        </div>
-      </div>
-    </>
-  );
+	return (
+		<>
+			<div className='card'>
+				<div className='nick_style'>
+					<ConnectFormUpload />
+					<ConnectedNick />
+				</div>
+				<div className='cart_1'>
+					<a href='/work'>
+						<button className='btn'>Work Page</button>
+					</a>
+					<a href='/projects'>
+						<button className='btn'>My Projects</button>
+					</a>
+				</div>
+			</div>
+		</>
+	);
 };

+ 41 - 40
src/pages/FormReg.js

@@ -1,45 +1,46 @@
 import React, { useState } from "react";
+
 import "./LoginReg.css";
 
 export const FormReg = ({ FormReg }) => {
-  const [login, setLogin] = useState("");
-  const [password, setPassword] = useState("");
-  const [passwordValid, setPasswordValid] = useState("");
-  return (
-    <div className="login">
-      <h3>Registration</h3>
-      <input
-        className="u"
-        type="login"
-        placeholder="Username"
-        value={login}
-        onChange={(e) => setLogin(e.target.value)}
-      />
-      <input
-        className="p"
-        type="password"
-        placeholder="Password"
-        value={password}
-        onChange={(e) => setPassword(e.target.value)}
-      />
-      <input
-        className="p"
-        type="password"
-        placeholder="RepeatYourPassword"
-        value={passwordValid}
-        onChange={(e) => setPasswordValid(e.target.value)}
-      />
-      <button
-        type="submit"
-        className="btn btn-primary btn-block btn-large"
-        disabled={!login || !password || password !== passwordValid}
-        onClick={() => FormReg(login, password)}
-      >
-        Remember me.{" "}
-      </button>
-      <button className="main_page">
-        <a href="/">Main page</a>
-      </button>
-    </div>
-  );
+	const [login, setLogin] = useState("");
+	const [password, setPassword] = useState("");
+	const [passwordValid, setPasswordValid] = useState("");
+	return (
+		<div className='login'>
+			<h3>Registration</h3>
+			<input
+				className='u'
+				type='login'
+				placeholder='Username'
+				value={login}
+				onChange={e => setLogin(e.target.value)}
+			/>
+			<input
+				className='p'
+				type='password'
+				placeholder='Password'
+				value={password}
+				onChange={e => setPassword(e.target.value)}
+			/>
+			<input
+				className='p'
+				type='password'
+				placeholder='RepeatYourPassword'
+				value={passwordValid}
+				onChange={e => setPasswordValid(e.target.value)}
+			/>
+			<button
+				type='submit'
+				className='btn btn-primary btn-block btn-large'
+				disabled={!login || !password || password !== passwordValid}
+				onClick={() => FormReg(login, password)}
+			>
+				Remember me.{" "}
+			</button>
+			<button className='main_page'>
+				<a href='/'>Main page</a>
+			</button>
+		</div>
+	);
 };

+ 28 - 30
src/pages/FormUpload.css

@@ -1,48 +1,46 @@
 .buttons {
-  width: 180px;
-  height: 40px;
-  text-decoration: none;
-  padding-top: 9px;
-  color: #c9b6cf;
-  text-align: center;
-  line-height: 20px;
-  display: block;
-  margin: 200px auto 15px;
-  font: normal 17px arial;
-  cursor: pointer;
+	width: 180px;
+	height: 40px;
+	text-decoration: none;
+	padding-top: 9px;
+	color: #c9b6cf;
+	text-align: center;
+	line-height: 20px;
+	display: block;
+	margin: 200px auto 15px;
+	font: normal 17px arial;
+	cursor: pointer;
 }
 
 .buttons:not(.active) {
-  box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8),
-    inset 0 -1px 0px rgba(63, 59, 113, 0.2), 0 9px 16px 0 rgba(0, 0, 0, 0.3),
-    0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
-  background-image: linear-gradient(#3b2751, #271739);
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
+	box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8), inset 0 -1px 0px rgba(63, 59, 113, 0.2),
+		0 9px 16px 0 rgba(0, 0, 0, 0.3), 0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
+	background-image: linear-gradient(#3b2751, #271739);
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
 }
 
 .buttons:not(.active):hover,
 .buttons:not(.active):focus {
-  transition: color 200ms linear, text-shadow 500ms linear;
-  color: #fff;
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5),
-    0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
+	transition: color 200ms linear, text-shadow 500ms linear;
+	color: #fff;
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
 }
 
 .buttons:not(:hover) {
-  transition: 0.6s;
+	transition: 0.6s;
 }
 
 .back a {
-  text-decoration: none;
+	text-decoration: none;
 }
 
 .back {
-  display: block;
-  width: 100px;
-  height: 20px;
-  text-decoration: none;
-  color: #c9b6cf;
-  text-align: center;
-  margin: auto;
-  cursor: pointer;
+	display: block;
+	width: 100px;
+	height: 20px;
+	text-decoration: none;
+	color: #c9b6cf;
+	text-align: center;
+	margin: auto;
+	cursor: pointer;
 }

+ 14 - 14
src/pages/FormUpload.js

@@ -1,21 +1,21 @@
 import { connect } from "react-redux";
-import { actionFullAva } from "../actions/actionFullAva";
 import { useDropzone } from "react-dropzone";
-import { ConnectedAvaLogo } from "../components/Ava";
+
+import { actionFullAva } from "store/actions/actionFullAva";
+import { ConnectedAvaLogo } from "components/Ava";
+
 import "./FormUpload.css";
 
 const FormUpload = ({ onUpload }) => {
-  const { acceptedFiles, getRootProps, getInputProps } = useDropzone();
-  let files = acceptedFiles.map((file) => onUpload(file));
-  console.log(files);
-  return (
-    <div {...getRootProps({})}>
-      <input {...getInputProps()} />
-      <ConnectedAvaLogo />
-    </div>
-  );
+	const { acceptedFiles, getRootProps, getInputProps } = useDropzone();
+	let files = acceptedFiles.map(file => onUpload(file));
+	console.log(files);
+	return (
+		<div {...getRootProps({})}>
+			<input {...getInputProps()} />
+			<ConnectedAvaLogo />
+		</div>
+	);
 };
 
-export const ConnectFormUpload = connect(null, { onUpload: actionFullAva })(
-  FormUpload
-);
+export const ConnectFormUpload = connect(null, { onUpload: actionFullAva })(FormUpload);

+ 33 - 32
src/pages/LoginForm.js

@@ -1,37 +1,38 @@
 import { useState } from "react";
+
 import "./LoginReg.css";
 
 export const LoginForm = ({ onLogin }) => {
-  const [login, setLogin] = useState("");
-  const [password, setPassword] = useState("");
-  return (
-    <div className="login">
-      <h3>Login</h3>
-      <input
-        className="u"
-        type="login"
-        placeholder="Username"
-        value={login}
-        onChange={(e) => setLogin(e.target.value)}
-      />
-      <input
-        className="p"
-        type="password"
-        placeholder="Password"
-        value={password}
-        onChange={(e) => setPassword(e.target.value)}
-      />
-      <button
-        type="submit"
-        className="btn btn-primary btn-block btn-large"
-        disabled={!login || !password}
-        onClick={() => onLogin(login, password)}
-      >
-        Let me in.{" "}
-      </button>
-      <button className="main_page">
-        <a href="/">Main page</a>
-      </button>
-    </div>
-  );
+	const [login, setLogin] = useState("");
+	const [password, setPassword] = useState("");
+	return (
+		<div className='login'>
+			<h3>Login</h3>
+			<input
+				className='u'
+				type='login'
+				placeholder='Username'
+				value={login}
+				onChange={e => setLogin(e.target.value)}
+			/>
+			<input
+				className='p'
+				type='password'
+				placeholder='Password'
+				value={password}
+				onChange={e => setPassword(e.target.value)}
+			/>
+			<button
+				type='submit'
+				className='btn btn-primary btn-block btn-large'
+				disabled={!login || !password}
+				onClick={() => onLogin(login, password)}
+			>
+				Let me in.{" "}
+			</button>
+			<button className='main_page'>
+				<a href='/'>Main page</a>
+			</button>
+		</div>
+	);
 };

+ 144 - 202
src/pages/LoginReg.css

@@ -1,274 +1,216 @@
 @import url(https://fonts.googleapis.com/css?family=Open+Sans);
 .btn {
-  display: inline-block;
-  *display: inline;
-  *zoom: 1;
-  padding: 4px 10px 4px;
-  margin-bottom: 0;
-  font-size: 13px;
-  line-height: 18px;
-  color: #333333;
-  text-align: center;
-  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
-  vertical-align: middle;
-  background-color: #f5f5f5;
-  background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: -webkit-gradient(
-    linear,
-    0 0,
-    0 100%,
-    from(#ffffff),
-    to(#e6e6e6)
-  );
-  background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: linear-gradient(top, #ffffff, #e6e6e6);
-  background-repeat: repeat-x;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr=#ffffff, endColorstr=#e6e6e6, GradientType=0);
-  border-color: #e6e6e6 #e6e6e6 #e6e6e6;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  border: 1px solid #e6e6e6;
-  -webkit-border-radius: 4px;
-  -moz-border-radius: 4px;
-  border-radius: 4px;
-  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
-    0 1px 2px rgba(0, 0, 0, 0.05);
-  -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
-    0 1px 2px rgba(0, 0, 0, 0.05);
-  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
-    0 1px 2px rgba(0, 0, 0, 0.05);
-  cursor: pointer;
-  *margin-left: 0.3em;
+	display: inline-block;
+	*display: inline;
+	*zoom: 1;
+	padding: 4px 10px 4px;
+	margin-bottom: 0;
+	font-size: 13px;
+	line-height: 18px;
+	color: #333333;
+	text-align: center;
+	text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
+	vertical-align: middle;
+	background-color: #f5f5f5;
+	background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
+	background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6);
+	background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
+	background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
+	background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
+	background-image: linear-gradient(top, #ffffff, #e6e6e6);
+	background-repeat: repeat-x;
+	filter: progid:dximagetransform.microsoft.gradient(startColorstr=#ffffff, endColorstr=#e6e6e6, GradientType=0);
+	border-color: #e6e6e6 #e6e6e6 #e6e6e6;
+	border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+	border: 1px solid #e6e6e6;
+	-webkit-border-radius: 4px;
+	-moz-border-radius: 4px;
+	border-radius: 4px;
+	-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+	-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+	cursor: pointer;
+	*margin-left: 0.3em;
 }
 .btn:hover,
 .btn:active,
 .btn.active,
 .btn.disabled,
 .btn[disabled] {
-  background-color: #e6e6e6;
+	background-color: #e6e6e6;
 }
 .btn-large {
-  padding: 9px 14px;
-  font-size: 15px;
-  line-height: normal;
-  -webkit-border-radius: 5px;
-  -moz-border-radius: 5px;
-  border-radius: 5px;
+	padding: 9px 14px;
+	font-size: 15px;
+	line-height: normal;
+	-webkit-border-radius: 5px;
+	-moz-border-radius: 5px;
+	border-radius: 5px;
 }
 .btn:hover {
-  color: #333333;
-  text-decoration: none;
-  background-color: #e6e6e6;
-  -webkit-transition: background-position 0.1s linear;
-  -moz-transition: background-position 0.1s linear;
-  -ms-transition: background-position 0.1s linear;
-  -o-transition: background-position 0.1s linear;
-  transition: background-position 0.1s linear;
+	color: #333333;
+	text-decoration: none;
+	background-color: #e6e6e6;
+	-webkit-transition: background-position 0.1s linear;
+	-moz-transition: background-position 0.1s linear;
+	-ms-transition: background-position 0.1s linear;
+	-o-transition: background-position 0.1s linear;
+	transition: background-position 0.1s linear;
 }
 .btn-primary,
 .btn-primary:hover {
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  color: #ffffff;
+	text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+	color: #ffffff;
 }
 .btn-primary.active {
-  color: rgba(255, 255, 255, 0.75);
+	color: rgba(255, 255, 255, 0.75);
 }
 .btn-primary {
-  background-color: #7160bd;
-  background-image: -moz-linear-gradient(top, #7160bd, #7160bd);
-  background-image: -ms-linear-gradient(top, #7160bd, #7160bd);
-  background-image: -webkit-gradient(
-    linear,
-    0 0,
-    0 100%,
-    from(#7160bd),
-    to(#7160bd)
-  );
-  background-image: -webkit-linear-gradient(top, #7160bd, #7160bd);
-  background-image: -o-linear-gradient(top, #7160bd, #7160bd);
-  background-image: linear-gradient(top, #7160bd, #7160bd);
-  background-repeat: repeat-x;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr=#7160bd, endColorstr=#7160bd, GradientType=0);
-  border: 1px solid #7160bd;
-  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
-  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
-    0 1px 2px rgba(0, 0, 0, 0.5);
+	background-color: #7160bd;
+	background-image: -moz-linear-gradient(top, #7160bd, #7160bd);
+	background-image: -ms-linear-gradient(top, #7160bd, #7160bd);
+	background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#7160bd), to(#7160bd));
+	background-image: -webkit-linear-gradient(top, #7160bd, #7160bd);
+	background-image: -o-linear-gradient(top, #7160bd, #7160bd);
+	background-image: linear-gradient(top, #7160bd, #7160bd);
+	background-repeat: repeat-x;
+	filter: progid:dximagetransform.microsoft.gradient(startColorstr=#7160bd, endColorstr=#7160bd, GradientType=0);
+	border: 1px solid #7160bd;
+	text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
+	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.5);
 }
 .btn-primary:hover,
 .btn-primary:active,
 .btn-primary.active,
 .btn-primary.disabled,
 .btn-primary[disabled] {
-  filter: none;
-  background-color: #4a77d4;
+	filter: none;
+	background-color: #4a77d4;
 }
 .btn-block {
-  width: 100%;
-  display: block;
+	width: 100%;
+	display: block;
 }
 
 * {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  -ms-box-sizing: border-box;
-  -o-box-sizing: border-box;
-  box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	-ms-box-sizing: border-box;
+	-o-box-sizing: border-box;
+	box-sizing: border-box;
 }
 
 html {
-  min-width: 100%;
-  min-height: 100%;
+	min-width: 100%;
+	min-height: 100%;
 }
 
 body {
-  width: 100%;
-  height: 100%;
-  font-family: "Open Sans", sans-serif;
-  background: #092756;
-  background: -moz-radial-gradient(
-      0% 100%,
-      ellipse cover,
-      rgba(104, 128, 138, 0.4) 10%,
-      rgba(138, 114, 76, 0) 40%
-    ),
-    -moz-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4)
-          100%),
-    -moz-linear-gradient(-45deg, #670d10 0%, #092756 100%);
-  background: -webkit-radial-gradient(
-      0% 100%,
-      ellipse cover,
-      rgba(104, 128, 138, 0.4) 10%,
-      rgba(138, 114, 76, 0) 40%
-    ),
-    -webkit-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(
-            42,
-            60,
-            87,
-            0.4
-          )
-          100%),
-    -webkit-linear-gradient(-45deg, #670d10 0%, #092756 100%);
-  background: -o-radial-gradient(
-      0% 100%,
-      ellipse cover,
-      rgba(104, 128, 138, 0.4) 10%,
-      rgba(138, 114, 76, 0) 40%
-    ),
-    -o-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4)
-          100%),
-    -o-linear-gradient(-45deg, #670d10 0%, #092756 100%);
-  background: -ms-radial-gradient(
-      0% 100%,
-      ellipse cover,
-      rgba(104, 128, 138, 0.4) 10%,
-      rgba(138, 114, 76, 0) 40%
-    ),
-    -ms-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4)
-          100%),
-    -ms-linear-gradient(-45deg, #670d10 0%, #092756 100%);
-  background: -webkit-radial-gradient(
-      0% 100%,
-      ellipse cover,
-      rgba(104, 128, 138, 0.4) 10%,
-      rgba(138, 114, 76, 0) 40%
-    ),
-    linear-gradient(
-      to bottom,
-      rgba(57, 173, 219, 0.25) 0%,
-      rgba(42, 60, 87, 0.4) 100%
-    ),
-    linear-gradient(135deg, #670d10 0%, #281c50 100%);
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3E1D6D', endColorstr='#092756',GradientType=1 );
+	width: 100%;
+	height: 100%;
+	font-family: "Open Sans", sans-serif;
+	background: #092756;
+	background: -moz-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, 0.4) 10%, rgba(138, 114, 76, 0) 40%),
+		-moz-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4) 100%),
+		-moz-linear-gradient(-45deg, #670d10 0%, #092756 100%);
+	background: -webkit-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, 0.4) 10%, rgba(138, 114, 76, 0) 40%),
+		-webkit-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4) 100%),
+		-webkit-linear-gradient(-45deg, #670d10 0%, #092756 100%);
+	background: -o-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, 0.4) 10%, rgba(138, 114, 76, 0) 40%),
+		-o-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4) 100%),
+		-o-linear-gradient(-45deg, #670d10 0%, #092756 100%);
+	background: -ms-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, 0.4) 10%, rgba(138, 114, 76, 0) 40%),
+		-ms-linear-gradient(top, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4) 100%),
+		-ms-linear-gradient(-45deg, #670d10 0%, #092756 100%);
+	background: -webkit-radial-gradient(0% 100%, ellipse cover, rgba(104, 128, 138, 0.4) 10%, rgba(138, 114, 76, 0) 40%),
+		linear-gradient(to bottom, rgba(57, 173, 219, 0.25) 0%, rgba(42, 60, 87, 0.4) 100%),
+		linear-gradient(135deg, #670d10 0%, #281c50 100%);
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3E1D6D', endColorstr='#092756',GradientType=1 );
 }
 
 .btn {
-  width: 300px;
-  height: 40px;
-  text-decoration: none;
-  color: #b5a2bb;
-  text-align: center;
-  line-height: 20px;
-  display: block;
-  font: normal 17px arial;
-  cursor: pointer;
-  margin-top: 5px;
-  margin-bottom: 5px;
+	width: 300px;
+	height: 40px;
+	text-decoration: none;
+	color: #b5a2bb;
+	text-align: center;
+	line-height: 20px;
+	display: block;
+	font: normal 17px arial;
+	cursor: pointer;
+	margin-top: 5px;
+	margin-bottom: 5px;
 }
 
 .cart_1 a {
-  text-decoration: none;
+	text-decoration: none;
 }
 
 .btn:not(.active) {
-  box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8),
-    inset 0 -1px 0px rgba(63, 59, 113, 0.2), 0 9px 16px 0 rgba(0, 0, 0, 0.3),
-    0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
-  background-image: linear-gradient(#3b2751, #271739);
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
+	box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8), inset 0 -1px 0px rgba(63, 59, 113, 0.2),
+		0 9px 16px 0 rgba(0, 0, 0, 0.3), 0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
+	background-image: linear-gradient(#3b2751, #271739);
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
 }
 
 .btn:not(.active):hover,
 .btn:not(.active):focus {
-  transition: color 200ms linear, text-shadow 500ms linear;
-  color: #fff;
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5),
-    0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
+	transition: color 200ms linear, text-shadow 500ms linear;
+	color: #fff;
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
 }
 
 .btn:not(:hover) {
-  transition: 0.6s;
+	transition: 0.6s;
 }
 
 .login {
-  position: absolute;
-  top: 40%;
-  left: 50%;
-  margin: -150px 0 0 -150px;
-  width: 300px;
-  height: 300px;
+	position: absolute;
+	top: 40%;
+	left: 50%;
+	margin: -150px 0 0 -150px;
+	width: 300px;
+	height: 300px;
 }
 
 .login h3 {
-  color: #fff;
-  text-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
-  letter-spacing: 1px;
-  text-align: center;
+	color: #fff;
+	text-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
+	letter-spacing: 1px;
+	text-align: center;
 }
 
 input,
 textarea {
-  width: 100%;
-  margin-bottom: 10px;
-  background: rgba(0, 0, 0, 0.3);
-  border: none;
-  outline: none;
-  padding: 10px;
-  font-size: 13px;
-  margin-top: 5px;
-  color: #fff;
-  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
-  border: 1px solid rgba(0, 0, 0, 0.3);
-  border-radius: 4px;
-  box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.2),
-    0 1px 1px rgba(255, 255, 255, 0.2);
-  -webkit-transition: box-shadow 0.5s ease;
-  -moz-transition: box-shadow 0.5s ease;
-  -o-transition: box-shadow 0.5s ease;
-  -ms-transition: box-shadow 0.5s ease;
-  transition: box-shadow 0.5s ease;
-  font-family: "Open Sans", sans-serif;
+	width: 100%;
+	margin-bottom: 10px;
+	background: rgba(0, 0, 0, 0.3);
+	border: none;
+	outline: none;
+	padding: 10px;
+	font-size: 13px;
+	margin-top: 5px;
+	color: #fff;
+	text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
+	border: 1px solid rgba(0, 0, 0, 0.3);
+	border-radius: 4px;
+	box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.2), 0 1px 1px rgba(255, 255, 255, 0.2);
+	-webkit-transition: box-shadow 0.5s ease;
+	-moz-transition: box-shadow 0.5s ease;
+	-o-transition: box-shadow 0.5s ease;
+	-ms-transition: box-shadow 0.5s ease;
+	transition: box-shadow 0.5s ease;
+	font-family: "Open Sans", sans-serif;
 }
 
 input:focus {
-  box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.4),
-    0 1px 1px rgba(255, 255, 255, 0.2);
+	box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.4), 0 1px 1px rgba(255, 255, 255, 0.2);
 }
 
 .main_page {
-  margin-top: 10px;
+	margin-top: 10px;
 }
 
 .main_page a {
-  text-decoration: none;
+	text-decoration: none;
 }

+ 120 - 124
src/pages/Main.css

@@ -1,213 +1,209 @@
 #body {
-  margin: 0;
-  padding: 0;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  min-height: 90vh;
-  font-family: "Telefon Black", Sans-Serif;
+	margin: 0;
+	padding: 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	min-height: 90vh;
+	font-family: "Telefon Black", Sans-Serif;
 }
 
 .box {
-  position: relative;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  background: #170422;
-  max-width: 500px;
+	position: relative;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	background: #170422;
+	max-width: 500px;
 }
 
 .box::before {
-  content: "";
-  position: absolute;
-  top: -2px;
-  left: -2px;
-  right: -2px;
-  bottom: -2px;
-  background: #fff;
-  z-index: -1;
+	content: "";
+	position: absolute;
+	top: -2px;
+	left: -2px;
+	right: -2px;
+	bottom: -2px;
+	background: #fff;
+	z-index: -1;
 }
 
 .box::after {
-  content: "";
-  position: absolute;
-  top: -2px;
-  left: -2px;
-  right: -2px;
-  bottom: -2px;
-  background: #fff;
-  z-index: -2;
-  filter: blur(40px);
+	content: "";
+	position: absolute;
+	top: -2px;
+	left: -2px;
+	right: -2px;
+	bottom: -2px;
+	background: #fff;
+	z-index: -2;
+	filter: blur(40px);
 }
 
 .box::before,
 .box::after {
-  background: linear-gradient(235deg, #89ff00, #060c21, #00bcd4);
+	background: linear-gradient(235deg, #89ff00, #060c21, #00bcd4);
 }
 
 .content {
-  padding: 40px;
-  box-sizing: border-box;
-  color: #ffffff;
-  font-size: 20px;
+	padding: 40px;
+	box-sizing: border-box;
+	color: #ffffff;
+	font-size: 20px;
 }
 
 .btn_form {
-  width: 180px;
-  height: 40px;
-  text-decoration: none;
-  color: #c9b6cf;
-  text-align: center;
-  line-height: 20px;
-  display: block;
-  margin-left: 10px;
-  margin-right: 10px;
-  font: normal 17px arial;
-  cursor: pointer;
+	width: 180px;
+	height: 40px;
+	text-decoration: none;
+	color: #c9b6cf;
+	text-align: center;
+	line-height: 20px;
+	display: block;
+	margin-left: 10px;
+	margin-right: 10px;
+	font: normal 17px arial;
+	cursor: pointer;
 }
 
 .btn_form:not(.active) {
-  box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8),
-    inset 0 -1px 0px rgba(63, 59, 113, 0.2), 0 9px 16px 0 rgba(0, 0, 0, 0.3),
-    0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
-  background-image: linear-gradient(#3b2751, #271739);
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
+	box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8), inset 0 -1px 0px rgba(63, 59, 113, 0.2),
+		0 9px 16px 0 rgba(0, 0, 0, 0.3), 0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
+	background-image: linear-gradient(#3b2751, #271739);
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
 }
 
 .btn_form:not(.active):hover,
 .btn_form:not(.active):focus {
-  transition: color 200ms linear, text-shadow 500ms linear;
-  color: #fff;
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5),
-    0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
+	transition: color 200ms linear, text-shadow 500ms linear;
+	color: #fff;
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
 }
 
 .btn_form:not(:hover) {
-  transition: 0.6s;
+	transition: 0.6s;
 }
 
 .card {
-  width: 500px;
-  height: 360px;
-  padding-left: 100px;
-  margin-left: 470px;
-  margin-top: 100px;
-  padding-top: 10px;
-  background: linear-gradient(#f0e2ef, #faf5f5);
-  -webkit-box-shadow: inset 0 0 40px rgb(36, 16, 61);
-  -moz-box-shadow: inset 0 0 40px rgb(37, 12, 58);
-  box-shadow: inset 0 0 40px rgb(26, 10, 48);
+	width: 500px;
+	height: 360px;
+	padding-left: 100px;
+	margin-left: 470px;
+	margin-top: 100px;
+	padding-top: 10px;
+	background: linear-gradient(#f0e2ef, #faf5f5);
+	-webkit-box-shadow: inset 0 0 40px rgb(36, 16, 61);
+	-moz-box-shadow: inset 0 0 40px rgb(37, 12, 58);
+	box-shadow: inset 0 0 40px rgb(26, 10, 48);
 }
 
 .nick_style {
-  display: block;
-  width: 100px;
-  margin-left: 115px;
+	display: block;
+	width: 100px;
+	margin-left: 115px;
 }
 
 .block_search {
-  display: flex;
-  justify-content: center;
-  align-items: center;
+	display: flex;
+	justify-content: center;
+	align-items: center;
 }
 
 .btn_search {
-  width: 180px;
-  height: 40px;
-  text-decoration: none;
-  color: #b5a2bb;
-  margin-right: 200px;
-  text-align: center;
-  line-height: 20px;
-  font: normal 17px arial;
-  cursor: pointer;
-  margin-bottom: 10px;
+	width: 180px;
+	height: 40px;
+	text-decoration: none;
+	color: #b5a2bb;
+	margin-right: 200px;
+	text-align: center;
+	line-height: 20px;
+	font: normal 17px arial;
+	cursor: pointer;
+	margin-bottom: 10px;
 }
 
 .btn_search:not(.active) {
-  box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8),
-    inset 0 -1px 0px rgba(63, 59, 113, 0.2), 0 9px 16px 0 rgba(0, 0, 0, 0.3),
-    0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
-  background-image: linear-gradient(#3b2751, #271739);
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
+	box-shadow: inset 0 1px 1px rgba(111, 55, 125, 0.8), inset 0 -1px 0px rgba(63, 59, 113, 0.2),
+		0 9px 16px 0 rgba(0, 0, 0, 0.3), 0 4px 3px 0 rgba(0, 0, 0, 0.3), 0 0 0 1px #150a1e;
+	background-image: linear-gradient(#3b2751, #271739);
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 -1px 0 #311d47;
 }
 
 .btn_search:not(.active):hover,
 .btn_search:not(.active):focus {
-  transition: color 200ms linear, text-shadow 500ms linear;
-  color: #fff;
-  text-shadow: 0 0 21px rgba(223, 206, 228, 0.5),
-    0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
+	transition: color 200ms linear, text-shadow 500ms linear;
+	color: #fff;
+	text-shadow: 0 0 21px rgba(223, 206, 228, 0.5), 0 0 10px rgba(223, 206, 228, 0.4), 0 0 2px #2a153c;
 }
 
 .btn_search:not(:hover) {
-  transition: 0.6s;
+	transition: 0.6s;
 }
 
 .block_button_back {
-  padding-top: 20px;
+	padding-top: 20px;
 }
 
 .field_for_search {
-  width: 50%;
-  margin-left: 370px;
+	width: 50%;
+	margin-left: 370px;
 }
 
 ::-webkit-input-placeholder {
-  text-align: center;
+	text-align: center;
 }
 
 .btn_block_search {
-  margin-top: 10px;
-  margin-left: 44%;
-  margin-bottom: 10px;
+	margin-top: 10px;
+	margin-left: 44%;
+	margin-bottom: 10px;
 }
 
 .btn_block_back {
-  padding: 10px;
+	padding: 10px;
 }
 
 .snippet_block {
-  display: flex;
-  flex-wrap: wrap;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
+	display: flex;
+	flex-wrap: wrap;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
 }
 
 .snippet {
-  margin-bottom: 10px;
-  border: 1px solid rgb(131, 111, 145);
-  border-radius: 10px;
+	margin-bottom: 10px;
+	border: 1px solid rgb(131, 111, 145);
+	border-radius: 10px;
 }
 
 .snippet img {
-  width: 100%;
-  padding: 10px;
-  height: 300px;
-  box-shadow: 0 6px 10px 0 rgba(152, 128, 168, 0.4);
-  transition: 0.3s;
-  border-radius: 10px;
+	width: 100%;
+	padding: 10px;
+	height: 300px;
+	box-shadow: 0 6px 10px 0 rgba(152, 128, 168, 0.4);
+	transition: 0.3s;
+	border-radius: 10px;
 }
 
 .snippet img:hover {
-  box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
+	box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
 }
 
 .block_content {
-  display: flex;
-  flex-wrap: wrap;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
+	display: flex;
+	flex-wrap: wrap;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
 }
 
 .block_content p {
-  font-size: 18px;
-  font-family: "Telefon Black", Sans-Serif;
-  line-height: 7px;
+	font-size: 18px;
+	font-family: "Telefon Black", Sans-Serif;
+	line-height: 7px;
 }
 
 .btn_center {
-  margin-left: 200px;
+	margin-left: 200px;
 }

+ 20 - 21
src/pages/Main.js

@@ -1,25 +1,24 @@
 import "./Main.css";
 
 export const Main = ({ history }) => {
-  return (
-    <section id="body">
-      <button className="btn_form" onClick={() => history.push("./login")}>
-        Login
-      </button>
-      <div className="box">
-        <div className="content">
-          <h1>Welcome To The CodePen</h1>
-          <p>
-            The best place to build, test, and discover front-end code. CodePen
-            is a social development environment for front-end designers and
-            developers. Build and deploy a website, show off your work, build
-            test cases to learn and debug, and find inspiration.
-          </p>
-        </div>
-      </div>
-      <button className="btn_form" onClick={() => history.push("./reg")}>
-        Reristration
-      </button>
-    </section>
-  );
+	return (
+		<section id='body'>
+			<button className='btn_form' onClick={() => history.push("./login")}>
+				Login
+			</button>
+			<div className='box'>
+				<div className='content'>
+					<h1>Welcome To The CodePen</h1>
+					<p>
+						The best place to build, test, and discover front-end code. CodePen is a social development
+						environment for front-end designers and developers. Build and deploy a website, show off your work,
+						build test cases to learn and debug, and find inspiration.
+					</p>
+				</div>
+			</div>
+			<button className='btn_form' onClick={() => history.push("./reg")}>
+				Reristration
+			</button>
+		</section>
+	);
 };

+ 103 - 114
src/pages/Project.js

@@ -1,11 +1,11 @@
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
 import { connect } from "react-redux";
-import { actionSnippetById } from "./../actions/actionSnippetById";
-import { useState } from "react";
-import { Editor } from "../components/Editor";
-import "../components/EditorsPage.css";
 import { Link } from "react-router-dom";
 
+import { actionSnippetById } from "store/actions/actionSnippetById";
+import { Editor } from "components/Editor";
+import "components/EditorsPage.css";
+
 //  const [editors, setEditors] = useState(datas);
 //   const [title, setTitle] = useState("");
 //   const [description, setDescription] = useState("");
@@ -34,125 +34,114 @@ import { Link } from "react-router-dom";
 //   }, [editors]);
 
 const ProjectSnippet = ({
-  getSnippet,
-  match: {
-    params: { _id },
-  },
-  titleText,
-  descriptionText,
-  filesArr,
-  nameText,
+	getSnippet,
+	match: {
+		params: { _id },
+	},
+	titleText,
+	descriptionText,
+	filesArr,
+	nameText,
 }) => {
-  useEffect(() => {
-    getSnippet(_id);
-  }, [_id, getSnippet]);
-  const [editors, setEditors] = useState([]);
-  const [title, setTitle] = useState("");
-  const [description, setDescription] = useState("");
-  useEffect(() => {
-    setEditors(filesArr);
-    setTitle(titleText);
-    setDescription(descriptionText);
-  }, [filesArr, titleText, descriptionText]);
-  const [srcDoc, setSrcDoc] = useState("");
-  const html = editors?.filter((e) => {
-    return e?.type === "html";
-  })[0]?.text;
-  const css = editors?.filter((e) => {
-    return e?.type === "css";
-  })[0]?.text;
-  const javascript = editors?.filter((e) => {
-    return e?.type === "javascript";
-  })[0]?.text;
-  console.log(javascript);
-  useEffect(() => {
-    const timeout = setTimeout(() => {
-      setSrcDoc(`
+	useEffect(() => {
+		getSnippet(_id);
+	}, [_id, getSnippet]);
+	const [editors, setEditors] = useState([]);
+	const [title, setTitle] = useState("");
+	const [description, setDescription] = useState("");
+	useEffect(() => {
+		setEditors(filesArr);
+		setTitle(titleText);
+		setDescription(descriptionText);
+	}, [filesArr, titleText, descriptionText]);
+	const [srcDoc, setSrcDoc] = useState("");
+	const html = editors?.filter(e => {
+		return e?.type === "html";
+	})[0]?.text;
+	const css = editors?.filter(e => {
+		return e?.type === "css";
+	})[0]?.text;
+	const javascript = editors?.filter(e => {
+		return e?.type === "javascript";
+	})[0]?.text;
+	console.log(javascript);
+	useEffect(() => {
+		const timeout = setTimeout(() => {
+			setSrcDoc(`
             <html>
               <body>${html}</body>
               <style>${css}</style>
               <script>${javascript}</script>
             </html>
           `);
-    }, 250);
+		}, 250);
 
-    return () => clearTimeout(timeout);
-  }, [html, css, javascript]);
-  return (
-    <div>
-      <div>
-        <Link to="/propjects">
-          <button
-            className="btn_search"
-            style={{ margin: 10, marginBottom: 50 }}
-          >
-            Back to
-          </button>
-        </Link>
-      </div>
-      <br />
-      {editors?.map((data, index) => (
-        <>
-          <Editor
-            onDelete={() =>
-              setEditors(editors?.filter((item) => item !== data))
-            }
-            data={data}
-            onChange={({ type, name, text }) =>
-              setEditors([
-                ...editors.slice(0, index),
-                { type, name, text },
-                ...editors.slice(index, 1),
-              ])
-            }
-          />
-        </>
-      ))}
-      <br />
-      <div>
-        <div>
-          <iframe
-            className="pane"
-            srcDoc={srcDoc}
-            title="output"
-            sandbox="allow-scripts"
-            frameBorder="0"
-            style={{ marginTop: 20 }}
-            width="95%"
-            height="95%"
-          />
-        </div>
-        <div>
-          <p className="text">Name of your project: </p>
-          <input
-            className="input_title"
-            placeholder="Name of your project"
-            value={title}
-            onChange={(e) => setTitle(e.target.value)}
-          />
-        </div>
-        <p className="text">Description: </p>
-        <textarea
-          className="text_desc"
-          placeholder="Description"
-          value={description}
-          onChange={(e) => setDescription(e.target.value)}
-          style={{ marginBottom: 50 }}
-        />
-      </div>
-    </div>
-  );
+		return () => clearTimeout(timeout);
+	}, [html, css, javascript]);
+	return (
+		<div>
+			<div>
+				<Link to='/propjects'>
+					<button className='btn_search' style={{ margin: 10, marginBottom: 50 }}>
+						Back to
+					</button>
+				</Link>
+			</div>
+			<br />
+			{editors?.map((data, index) => (
+				<>
+					<Editor
+						onDelete={() => setEditors(editors?.filter(item => item !== data))}
+						data={data}
+						onChange={({ type, name, text }) =>
+							setEditors([...editors.slice(0, index), { type, name, text }, ...editors.slice(index, 1)])
+						}
+					/>
+				</>
+			))}
+			<br />
+			<div>
+				<div>
+					<iframe
+						className='pane'
+						srcDoc={srcDoc}
+						title='output'
+						sandbox='allow-scripts'
+						frameBorder='0'
+						style={{ marginTop: 20 }}
+						width='95%'
+						height='95%'
+					/>
+				</div>
+				<div>
+					<p className='text'>Name of your project: </p>
+					<input
+						className='input_title'
+						placeholder='Name of your project'
+						value={title}
+						onChange={e => setTitle(e.target.value)}
+					/>
+				</div>
+				<p className='text'>Description: </p>
+				<textarea
+					className='text_desc'
+					placeholder='Description'
+					value={description}
+					onChange={e => setDescription(e.target.value)}
+					style={{ marginBottom: 50 }}
+				/>
+			</div>
+		</div>
+	);
 };
 
 const ConnectedProject = connect(
-  (state) => ({
-    titleText:
-      state?.p?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.title,
-    descriptionText:
-      state?.p?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.description,
-    nameText: state?.p?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.name,
-    filesArr: state?.p?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.files,
-  }),
-  { getSnippet: actionSnippetById }
+	state => ({
+		titleText: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.title,
+		descriptionText: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.description,
+		nameText: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.name,
+		filesArr: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.files,
+	}),
+	{ getSnippet: actionSnippetById },
 )(ProjectSnippet);
 export default ConnectedProject;

+ 47 - 50
src/pages/Projects.js

@@ -1,58 +1,55 @@
 import { connect } from "react-redux";
 import { Link } from "react-router-dom";
-import code from "../../src/code.png";
 
 const Projects = ({ snippets }) => {
-  return snippets ? (
-    <div>
-      <div style={{ margin: 10 }}>
-        <div>
-          <Link to="/cabinet">
-            <button className="btn_search">Back to Cabinet</button>
-          </Link>
-        </div>
-        <div>
-          <Link to="/work">
-            <button className="btn_search" style={{ marginTop: 5 }}>
-              New project
-            </button>
-          </Link>
-        </div>
-      </div>
-      <br />
-      <div className="snippet_block">
-        {snippets?.map((key, index) => (
-          <div className="snippet">
-            <img src={code} alt="code"></img>
-            <div className="block_content">
-              <p>
-                {`Name: ${snippets?.[index]?.title}` || "Project without name"}
-              </p>
-              <p>{`Description: ${snippets?.[index]?.description}` || ""}</p>
-              <div className="btn_center">
-                <Link to={"/project/" + snippets?.[index]?._id}>
-                  <button className="btn_search">Open project</button>
-                </Link>
-              </div>
-            </div>
-          </div>
-        ))}
-      </div>
-    </div>
-  ) : (
-    <div>
-      <Link to="/">
-        <button className="btn_search">Back to Main Page</button>
-      </Link>{" "}
-      <br /> <br />
-      <div>
-        <span style={{ margin: 10, fontSize: 20 }}>Loading...</span>
-      </div>
-    </div>
-  );
+	return snippets ? (
+		<div>
+			<div style={{ margin: 10 }}>
+				<div>
+					<Link to='/cabinet'>
+						<button className='btn_search'>Back to Cabinet</button>
+					</Link>
+				</div>
+				<div>
+					<Link to='/work'>
+						<button className='btn_search' style={{ marginTop: 5 }}>
+							New project
+						</button>
+					</Link>
+				</div>
+			</div>
+			<br />
+			<div className='snippet_block'>
+				{snippets?.map((key, index) => (
+					<div className='snippet'>
+						<img src={`${process.env.PUBLIC_URL}/img/code.png`} alt='code'></img>
+						<div className='block_content'>
+							<p>{`Name: ${snippets?.[index]?.title}` || "Project without name"}</p>
+							<p>{`Description: ${snippets?.[index]?.description}` || ""}</p>
+							<div className='btn_center'>
+								<Link to={"/project/" + snippets?.[index]?._id}>
+									<button className='btn_search'>Open project</button>
+								</Link>
+							</div>
+						</div>
+					</div>
+				))}
+			</div>
+		</div>
+	) : (
+		<div>
+			<Link to='/'>
+				<button className='btn_search'>Back to Main Page</button>
+			</Link>{" "}
+			<br /> <br />
+			<div>
+				<span style={{ margin: 10, fontSize: 20 }}>Loading...</span>
+			</div>
+		</div>
+	);
 };
 
-const CProjects = connect((state) => ({
-  snippets: state?.p?.findSnippet?.payload?.data?.SnippetFind,
+const CProjects = connect(state => ({
+	snippets: state?.promise?.findSnippet?.payload?.data?.SnippetFind,
 }))(Projects);
 export default CProjects;

+ 53 - 54
src/pages/Search.js

@@ -1,65 +1,64 @@
-import { actionSearch } from "../actions/actionSearch";
+import { useState } from "react";
 import { Link } from "react-router-dom";
 import { connect } from "react-redux";
-import { useState } from "react";
-import code from "../../src/code.png";
+
+import { actionSearch } from "store/actions/actionSearch";
+
 import "./Main.css";
 
 const Search = ({ onSearch, snippets }) => {
-  const [request, setRequest] = useState("");
-  return (
-    <>
-      <Link to="/work">
-        <div className="btn_block_back">
-          <button className="btn_search">Back to Work Page</button>
-        </div>
-      </Link>
-      <br />
-      <br />
-      <div>
-        <input
-          className="field_for_search"
-          value={request}
-          onChange={(e) => setRequest(e.target.value)}
-          type="search"
-          placeholder="Type name or description"
-          aria-label="Search"
-        />
-        <br />
-        <div className="btn_block_search">
-          <button className="btn_search" onClick={() => onSearch(request)}>
-            Search
-          </button>
-        </div>
-      </div>
-      <div className="snippet_block">
-        {snippets?.map((key, index) => (
-          <div key={key} className="snippet">
-            <img src={code} alt="code"></img>
-            <div className="block_content">
-              <p>
-                {`Name: ${snippets?.[index]?.title}` || "Project without name"}
-              </p>
-              <p>{`Description: ${snippets?.[index]?.description}` || ""}</p>
-              <p>{`Owner: ${snippets?.[index]?.owner?.login}`}</p>
-              <div className="btn_center">
-                <Link to={"/project/" + snippets?.[index]?._id}>
-                  <button className="btn_search">Open project</button>
-                </Link>
-              </div>
-            </div>
-          </div>
-        ))}
-      </div>
-    </>
-  );
+	const [request, setRequest] = useState("");
+	return (
+		<>
+			<Link to='/work'>
+				<div className='btn_block_back'>
+					<button className='btn_search'>Back to Work Page</button>
+				</div>
+			</Link>
+			<br />
+			<br />
+			<div>
+				<input
+					className='field_for_search'
+					value={request}
+					onChange={e => setRequest(e.target.value)}
+					type='search'
+					placeholder='Type name or description'
+					aria-label='Search'
+				/>
+				<br />
+				<div className='btn_block_search'>
+					<button className='btn_search' onClick={() => onSearch(request)}>
+						Search
+					</button>
+				</div>
+			</div>
+			<div className='snippet_block'>
+				{snippets?.map((key, index) => (
+					<div key={key} className='snippet'>
+						<img src={`${process.env.PUBLIC_URL}/img/code.png`} alt='code'></img>
+						<div className='block_content'>
+							<p>{`Name: ${snippets?.[index]?.title}` || "Project without name"}</p>
+							<p>{`Description: ${snippets?.[index]?.description}` || ""}</p>
+							<p>{`Owner: ${snippets?.[index]?.owner?.login}`}</p>
+							<div className='btn_center'>
+								<Link to={"/project/" + snippets?.[index]?._id}>
+									<button className='btn_search'>Open project</button>
+								</Link>
+							</div>
+						</div>
+					</div>
+				))}
+			</div>
+		</>
+	);
 };
 
 const ConnectFormSearch = connect(
-  (state) => ({
-    snippets: state?.p?.searchSnippet?.payload?.data?.SnippetFind,
-  }),
-  { onSearch: actionSearch }
+	state => ({
+		snippets: state?.promise?.searchSnippet?.payload?.data?.SnippetFind,
+	}),
+	{ onSearch: actionSearch },
 )(Search);
 
 export default ConnectFormSearch;

+ 11 - 12
src/pages/WorkPage.js

@@ -1,18 +1,17 @@
-import { EditorsPage } from "../components/EditorsPage";
-import { actionSnippetAdd } from "../actions/actionSnippetAdd";
 import { connect } from "react-redux";
-import Header from "../components/Header";
+
+import Header from "components/Header";
+import { EditorsPage } from "components/EditorsPage";
+import { actionSnippetAdd } from "store/actions/actionSnippetAdd";
 
 export const Home = () => {
-  return (
-    <>
-      <Header />
-      <ConnectEditorsPage />
-    </>
-  );
+	return (
+		<>
+			<Header />
+			<ConnectEditorsPage />
+		</>
+	);
 };
 
-const ConnectEditorsPage = connect(null, { onSave: actionSnippetAdd })(
-  EditorsPage
-);
+const ConnectEditorsPage = connect(null, { onSave: actionSnippetAdd })(EditorsPage);
 export default ConnectEditorsPage;

+ 0 - 30
src/reducers/auth.js

@@ -1,30 +0,0 @@
-import { decode as atob } from "base-64";
-
-let signatureToken = (token) => JSON.parse(atob(token.split(".")[1]));
-
-function authReducer(state, { type, token }) {
-  if (state === undefined) {
-    if (localStorage.authToken) {
-      type = "LOGIN";
-      token = localStorage.authToken;
-    } else {
-      return {};
-    }
-  }
-
-  if (type === "LOGIN") {
-    console.log("LOGIN");
-    localStorage.authToken = token;
-    return { token, payload: signatureToken(token) };
-  }
-
-  if (type === "LOGOUT") {
-    console.log("LOGOUT");
-    localStorage.removeItem("authToken");
-    return {};
-  }
-
-  return state;
-}
-
-export default authReducer;

+ 0 - 12
src/reducers/promise.js

@@ -1,12 +0,0 @@
-function promiseReducer(state = {}, { type, status, payload, error, name }) {
-  if (type === "PROMISE") {
-    return {
-      ...state,
-      [name]: { status, payload, error },
-    };
-  }
-
-  return state;
-}
-
-export default promiseReducer;

+ 9 - 9
src/reportWebVitals.js

@@ -1,13 +1,13 @@
 const reportWebVitals = onPerfEntry => {
-  if (onPerfEntry && onPerfEntry instanceof Function) {
-    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
-      getCLS(onPerfEntry);
-      getFID(onPerfEntry);
-      getFCP(onPerfEntry);
-      getLCP(onPerfEntry);
-      getTTFB(onPerfEntry);
-    });
-  }
+	if (onPerfEntry && onPerfEntry instanceof Function) {
+		import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+			getCLS(onPerfEntry);
+			getFID(onPerfEntry);
+			getFCP(onPerfEntry);
+			getLCP(onPerfEntry);
+			getTTFB(onPerfEntry);
+		});
+	}
 };
 
 export default reportWebVitals;

+ 1 - 1
src/setupTests.js

@@ -2,4 +2,4 @@
 // allows you to do things like:
 // expect(element).toHaveTextContent(/react/i)
 // learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
+import "@testing-library/jest-dom";

+ 1 - 0
src/store/actions/actionAuthLogin.js

@@ -0,0 +1 @@
+export const actionAuthLogin = token => ({ type: "LOGIN", token });

src/actions/actionAuthLogout.js → src/store/actions/actionAuthLogout.js


+ 6 - 0
src/store/actions/actionFindUser.js

@@ -0,0 +1,6 @@
+import { actionPromise } from "./actionPromise";
+import { findUser } from "./requests";
+
+export const actionFindUser = () => async (dispatch, getState) => {
+	return await dispatch(actionPromise("findUser", findUser(getState()?.auth?.payload?.sub?.id)));
+};

+ 9 - 0
src/store/actions/actionFullAva.js

@@ -0,0 +1,9 @@
+import { actionUploadFile } from "./actionUploadFile";
+import { actionSetAva } from "./actionSetAva";
+import { actionFindUser } from "./actionFindUser";
+
+export const actionFullAva = file => async dispatch => {
+	let result = await dispatch(actionUploadFile(file));
+	await dispatch(actionSetAva(result._id));
+	await dispatch(actionFindUser());
+};

+ 14 - 0
src/store/actions/actionFullLogin.js

@@ -0,0 +1,14 @@
+import { actionLogin } from "./actionLogin";
+import { actionAuthLogin } from "./actionAuthLogin";
+import { actionFindUser } from "./actionFindUser";
+
+export const actionFullLogin = (login, password) => async dispatch => {
+	let result = await dispatch(actionLogin(login, password));
+	if (result !== null) {
+		dispatch(actionAuthLogin(result));
+	} else {
+		alert("That user doesn’t exist!");
+		localStorage.clear();
+	}
+	await dispatch(actionFindUser());
+};

+ 11 - 0
src/store/actions/actionFullRegister.js

@@ -0,0 +1,11 @@
+import { actionReg } from "./actionReg";
+import { actionFullLogin } from "./actionFullLogin";
+
+export const actionFullRegister = (login, password) => async dispatch => {
+	let result = await dispatch(actionReg(login, password));
+	if (result?.data?.createUser !== null) {
+		dispatch(actionFullLogin(login, password));
+	} else {
+		alert("Such a user already exists!");
+	}
+};

+ 6 - 0
src/store/actions/actionImgFind.js

@@ -0,0 +1,6 @@
+import { actionPromise } from "./actionPromise";
+import { findImage } from "./requests";
+
+export const actionImgFind = () => async dispatch => {
+	return await dispatch(actionPromise("img", findImage()));
+};

+ 4 - 0
src/store/actions/actionLogin.js

@@ -0,0 +1,4 @@
+import { actionPromise } from "./actionPromise";
+import { login } from "./requests";
+
+export const actionLogin = (_login, password) => actionPromise("login", login(_login, password));

+ 5 - 0
src/store/actions/actionPending.js

@@ -0,0 +1,5 @@
+export const actionPending = name => ({
+	type: "PROMISE",
+	status: "PENDING",
+	name,
+});

+ 14 - 0
src/store/actions/actionPromise.js

@@ -0,0 +1,14 @@
+import { actionPending } from "./actionPending";
+import { actionResolved } from "./actionResolved";
+import { actionRejected } from "./actionRejected";
+
+export const actionPromise = (name, promise) => async dispatch => {
+	dispatch(actionPending(name));
+	try {
+		let payload = await promise;
+		dispatch(actionResolved(name, payload));
+		return payload;
+	} catch (error) {
+		dispatch(actionRejected(name, error));
+	}
+};

+ 4 - 0
src/store/actions/actionReg.js

@@ -0,0 +1,4 @@
+import { actionPromise } from "./actionPromise";
+import { registration } from "./requests";
+
+export const actionReg = (login, password) => actionPromise("reg", registration(login, password));

+ 6 - 0
src/store/actions/actionRejected.js

@@ -0,0 +1,6 @@
+export const actionRejected = (name, error) => ({
+	type: "PROMISE",
+	status: "REJECTED",
+	name,
+	error,
+});

+ 6 - 0
src/store/actions/actionResolved.js

@@ -0,0 +1,6 @@
+export const actionResolved = (name, payload) => ({
+	type: "PROMISE",
+	status: "RESOLVED",
+	name,
+	payload,
+});

+ 6 - 0
src/store/actions/actionSearch.js

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

+ 6 - 0
src/store/actions/actionSetAva.js

@@ -0,0 +1,6 @@
+import { actionPromise } from "./actionPromise";
+import { setAvatar } from "./requests";
+
+export const actionSetAva = id => async (dispatch, getState) => {
+	return await dispatch(actionPromise("setAva", setAvatar(getState()?.auth?.payload?.sub?.id, id)));
+};

+ 6 - 0
src/store/actions/actionSnippetAdd.js

@@ -0,0 +1,6 @@
+import { actionPromise } from "./actionPromise";
+import { addSnippet } from "./requests";
+
+export const actionSnippetAdd = (title, description, files, idSnippet) => async dispatch => {
+	return await dispatch(actionPromise("addSnippet", addSnippet(title, description, files, idSnippet)));
+};

+ 6 - 0
src/store/actions/actionSnippetById.js

@@ -0,0 +1,6 @@
+import { actionPromise } from "./actionPromise";
+import { getSnippetById } from "./requests";
+
+export const actionSnippetById = id => async dispatch => {
+	return await dispatch(actionPromise("findSnippetById", getSnippetById(id)));
+};

+ 6 - 0
src/store/actions/actionSnippetFindByOwner.js

@@ -0,0 +1,6 @@
+import { actionPromise } from "./actionPromise";
+import { getSnippetByOwnerId } from "./requests";
+
+export const actionSnippetFindByOwner = id => async dispatch => {
+	return await dispatch(actionPromise("findSnippet", getSnippetByOwnerId(id)));
+};

+ 16 - 0
src/store/actions/actionUploadFile.js

@@ -0,0 +1,16 @@
+import { actionPromise } from "./actionPromise";
+
+export const actionUploadFile = files => async dispatch => {
+	let fd = new FormData();
+	fd.append("photo", files);
+	return await dispatch(
+		actionPromise(
+			"upload",
+			fetch("/upload", {
+				method: "POST",
+				headers: localStorage.authToken ? { Authorization: "Bearer " + localStorage.authToken } : {},
+				body: fd,
+			}).then(res => res.json()),
+		),
+	);
+};

+ 11 - 0
src/store/actions/gql.js

@@ -0,0 +1,11 @@
+const getGQL = url => (query, variables) =>
+	fetch(url, {
+		method: "POST",
+		headers: {
+			"content-type": "application/json",
+			...(localStorage.authToken ? { Authorization: "Bearer " + localStorage.authToken } : {}),
+		},
+		body: JSON.stringify({ query, variables }),
+	}).then(res => res.json());
+
+export const gql = getGQL("/graphql");

+ 136 - 0
src/store/actions/requests.js

@@ -0,0 +1,136 @@
+import { gql } from "./gql";
+
+export const login = async (_login, password) => {
+	const query = `query login($login:String!, $password:String!) {
+      login(
+         login: $login,
+         password: $password
+      )
+   }`;
+
+	const token = await gql(query, { login: _login, password });
+	localStorage.authToken = token.data.login;
+
+	console.log(token);
+	return token.data.login;
+};
+
+export const registration = async (login, password) => {
+	const query = `mutation reg($login:String!, $password:String!) {
+      createUser(
+         login: $login,
+         password: $password
+      ){
+         _id
+      }
+   }`;
+
+	return await gql(query, { login, password });
+};
+
+export const findImage = async () => {
+	const query = `query imgFind {
+      ImageFind(query:"[{}]") {
+         url owner{
+            nick
+         }
+      }
+   }`;
+
+	return await gql(query);
+};
+
+export const findUser = async _id => {
+	const query = `query userOne($query:String) {
+      UserFindOne(query:$query) {
+         _id avatar{
+            url
+         }
+      }
+   }`;
+
+	return await gql(query, { query: JSON.stringify([{ _id }]) });
+};
+
+export const setAvatar = async (idUser, idAvatar) => {
+	const query = `mutation setAvatar($idUser:String , $idAvatar:ID) { 
+      UserUpsert(user:{_id: $idUser, avatar: {_id: $idAvatar}}) {
+         _id, avatar{
+            url
+         }
+      }
+   }`;
+
+	return await gql(query, { idUser, idAvatar });
+};
+
+export const addSnippet = async (title, description, files, idSnippet) => {
+	const query = `mutation newSnippet($snippet:SnippetInput) {
+      SnippetUpsert(snippet:$snippet){
+        _id
+      }
+   }`;
+
+	return await gql(query, {
+		snippet: { title, description, files, _id: idSnippet },
+	});
+};
+
+export const getSnippetById = async id => {
+	const query = `query snippetFind($query:String) {
+      SnippetFind(query:$query) {
+         owner{
+            _id 
+         }
+         title description _id files {
+            type text name
+         }
+      }
+   }`;
+
+	return await gql(query, { query: JSON.stringify([{ _id: id }]) });
+};
+
+export const getSnippetByOwnerId = async id => {
+	const query = `query snippetFind($query:String) {
+      SnippetFind(query:$query) {
+         owner{
+            _id
+         }
+         title description _id files {
+            type text name
+         }
+      }
+   }`;
+
+	return await gql(query, {
+		query: JSON.stringify([{ ___owner: id }, { sort: [{ _id: -1 }] }]),
+	});
+};
+
+export const search = async string => {
+	const query = `query snippetFind($query:String) {
+      SnippetFind(query:$query) {
+         owner {
+            _id login
+         }
+         title description _id files {
+            type text name
+         }
+      }
+   }`;
+
+	return await gql(query, {
+		query: JSON.stringify([
+			{
+				$or: [
+					{ title: `/${string.trim().split(" ").join("|")}/` },
+					{ description: `/${string.trim().split(" ").join("|")}/` },
+				],
+			},
+			{
+				sort: [{ title: 1 }],
+			},
+		]),
+	});
+};

+ 30 - 0
src/store/reducers/auth.js

@@ -0,0 +1,30 @@
+import { decode as atob } from "base-64";
+
+let signatureToken = token => JSON.parse(atob(token.split(".")[1]));
+
+function authReducer(state, { type, token }) {
+	if (state === undefined) {
+		if (localStorage.authToken) {
+			type = "LOGIN";
+			token = localStorage.authToken;
+		} else {
+			return {};
+		}
+	}
+
+	if (type === "LOGIN") {
+		console.log("LOGIN");
+		localStorage.authToken = token;
+		return { token, payload: signatureToken(token) };
+	}
+
+	if (type === "LOGOUT") {
+		console.log("LOGOUT");
+		localStorage.removeItem("authToken");
+		return {};
+	}
+
+	return state;
+}
+
+export default authReducer;

+ 7 - 4
src/reducers/index.js

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

+ 12 - 0
src/store/reducers/promise.js

@@ -0,0 +1,12 @@
+function promiseReducer(state = {}, { type, status, payload, error, name }) {
+	if (type === "PROMISE") {
+		return {
+			...state,
+			[name]: { status, payload, error },
+		};
+	}
+
+	return state;
+}
+
+export default promiseReducer;