= 5 years ago
parent
commit
5fde9ed58a
51 changed files with 6492 additions and 4063 deletions
  1. 1 0
      debug.log
  2. 5954 3934
      package-lock.json
  3. 2 1
      package.json
  4. 0 14
      src/PrivateRouter.js
  5. 5 1
      src/actions/auth/index.js
  6. 6 0
      src/actions/auth/tokenAuth/index.js
  7. 18 0
      src/actions/auth/users/users.js
  8. 1 1
      src/actions/index.js
  9. 0 12
      src/components/admin-components/createTestPage/index.js
  10. 1 1
      src/components/common/formInput/index.js
  11. 48 0
      src/components/common/protectedRoute/config.js
  12. 34 0
      src/components/common/protectedRoute/index.js
  13. 2 3
      src/components/auth/signInForm/index.js
  14. 0 0
      src/components/public-components/auth/signInForm/validate/index.js
  15. 1 2
      src/components/auth/signUpForm/index.js
  16. 2 1
      src/components/auth/signUpForm/validate/index.js
  17. 3 1
      src/components/footer/index.js
  18. 2 2
      src/components/header/index.js
  19. 3 3
      src/components/landingPage/index.js
  20. 1 1
      src/components/notFound/index.js
  21. 13 0
      src/components/public-components/permissionDenied/index.js
  22. 10 9
      src/components/admin-components/createTestPage/form/index.js
  23. 0 0
      src/components/user-components/admin-components/createTestForm/validate/index.js
  24. 49 0
      src/components/user-components/categoriesPage/index.js
  25. 0 0
      src/components/user-components/homePage/index.js
  26. 89 0
      src/components/user-components/profilePage/index.js
  27. 6 0
      src/constants/index.js
  28. 7 6
      src/constants/routes.js
  29. 1 2
      src/containers/auth/SignInPage/index.js
  30. 1 2
      src/containers/auth/SignUpPage/index.js
  31. 2 2
      src/containers/header/index.js
  32. 38 6
      src/reducers/user/index.js
  33. 58 38
      src/router.js
  34. 2 0
      src/saga/auth/index.js
  35. 6 9
      src/saga/auth/signIn/index.js
  36. 5 4
      src/saga/auth/signUp/index.js
  37. 20 0
      src/saga/auth/users/users.js
  38. 1 1
      src/styles/abstracts/_variables.scss
  39. 8 1
      src/styles/base/_base.scss
  40. 3 0
      src/styles/components/_button.scss
  41. 31 0
      src/styles/components/_categoriesPage.scss
  42. 5 0
      src/styles/components/_container.scss
  43. 0 0
      src/styles/components/_createTestPage.scss
  44. 0 6
      src/styles/components/_landingPage.scss
  45. 11 0
      src/styles/components/_page.scss
  46. 30 0
      src/styles/components/_profilePage.scss
  47. 1 0
      src/styles/components/_signPage.scss
  48. 3 0
      src/styles/index.scss
  49. 1 0
      src/utils/token.js
  50. 6 0
      грабли.txt
  51. 1 0
      костыли.txt

+ 1 - 0
debug.log

@@ -0,0 +1 @@
+[0109/234712.714:ERROR:settings.cc(319)] Settings magic is not 1129342067

File diff suppressed because it is too large
+ 5954 - 3934
package-lock.json


+ 2 - 1
package.json

@@ -3,6 +3,7 @@
   "version": "0.1.0",
   "version": "0.1.0",
   "private": true,
   "private": true,
   "dependencies": {
   "dependencies": {
+    "axios": "^0.18.0",
     "bootstrap": "^4.1.3",
     "bootstrap": "^4.1.3",
     "firebase": "^5.7.0",
     "firebase": "^5.7.0",
     "node-sass": "^4.11.0",
     "node-sass": "^4.11.0",
@@ -13,7 +14,7 @@
     "react-loader-spinner": "^2.3.0",
     "react-loader-spinner": "^2.3.0",
     "react-redux": "^6.0.0",
     "react-redux": "^6.0.0",
     "react-router-dom": "^4.3.1",
     "react-router-dom": "^4.3.1",
-    "react-scripts": "2.1.1",
+    "react-scripts": "^2.1.3",
     "redux": "^4.0.1",
     "redux": "^4.0.1",
     "redux-form": "^8.0.4",
     "redux-form": "^8.0.4",
     "redux-logger": "^3.0.6",
     "redux-logger": "^3.0.6",

+ 0 - 14
src/PrivateRouter.js

@@ -1,14 +0,0 @@
-import React from 'react';
-import { Route, Redirect } from 'react-router';
-import * as routes from './constants/routes';
-
-export default ({ component: Component, user, ...rest }) => (
-    <Route
-        {...rest}
-        render={props => (
-            user
-                ? <Component {...props} />
-                : <Redirect to={routes.SIGN_IN} />
-        )}
-    />
-)

+ 5 - 1
src/actions/auth/index.js

@@ -1,7 +1,11 @@
 import * as signInActions from './signIn';
 import * as signInActions from './signIn';
 import * as signUpActions from './signUp';
 import * as signUpActions from './signUp';
+import * as signOutActions from './signOut';
+import * as usersGetActions from './signOut';
 
 
 export default {
 export default {
     ...signInActions,
     ...signInActions,
-    ...signUpActions
+    ...signUpActions,
+    ...signOutActions,
+    ...usersGetActions
 }
 }

+ 6 - 0
src/actions/auth/tokenAuth/index.js

@@ -0,0 +1,6 @@
+import { TOKEN_AUTH } from './../../../constants';
+
+export const tokenAuth = (payload) => ({
+    type: TOKEN_AUTH,
+    payload
+})

+ 18 - 0
src/actions/auth/users/users.js

@@ -0,0 +1,18 @@
+import * as types from '../../../constants';
+
+// all actions for signing up
+
+export const usersGetRequest= payload => ({
+    type: types.USERS_GET_REQUEST,
+    payload
+})
+
+export const usersGetRequestSucces = payload => ({
+    type: types.USERS_GET_REQUEST_SUCCESS,
+    payload
+})
+
+export const usersGetRequestFailure = error => ({
+    type: types.USERS_GET_REQUEST_SUCCESS_FAILURE ,
+    error
+})

+ 1 - 1
src/actions/index.js

@@ -1,4 +1,4 @@
-import authActions from './auth/logIn';
+import authActions from './auth';
 
 
 export default {
 export default {
     ...authActions
     ...authActions

+ 0 - 12
src/components/admin-components/createTestPage/index.js

@@ -1,12 +0,0 @@
-import React from 'react';
-import Form from './form';
-
-export default class createTestPage extends React.Component {
-    render() {
-        return (
-            <div className="page create-test">
-                <Form /> 
-            </div>
-        )
-    }
-}

+ 1 - 1
src/components/common/formInput/index.js

@@ -3,6 +3,6 @@ import React, { Fragment } from 'react';
 export default ({ input, className, placeholder, type, meta: { touched, error } }) => (
 export default ({ input, className, placeholder, type, meta: { touched, error } }) => (
     <Fragment>
     <Fragment>
         <input className={className} placeholder={placeholder} type={type} {...input} />
         <input className={className} placeholder={placeholder} type={type} {...input} />
-        {touched && (error && <p style={{"color": "red", "text-transform": "uppercase"}}>⚠ {error}</p>)}
+        {touched && (error && <p style={{"color": "red", "textTransform": "uppercase"}}>⚠ {error}</p>)}
     </Fragment>
     </Fragment>
 )
 )

+ 48 - 0
src/components/common/protectedRoute/config.js

@@ -0,0 +1,48 @@
+import * as routes from './../../../constants/routes';
+import { lazy } from 'react';
+
+const landingPage = lazy(() => import('./../../public-components/landingPage'));
+const homePage = lazy(() => import('./../../user-components/homePage'));
+const signInPage = lazy(() => import('./../../../containers/auth/SignInPage'));
+const signUpPage = lazy(() => import('./../../../containers/auth/SignUpPage'));
+const createTestForm = lazy(() => import('./../../user-components/admin-components/createTestForm'));
+const profilePage = lazy(() => import('./../../user-components/profilePage'));
+const categoriesPage = lazy(() => import('./../../user-components/categoriesPage'));
+
+export default [
+    {
+        path: routes.LANDING,
+        access: 'public',
+        component: landingPage
+    },
+    {
+        path: routes.SIGN_IN,
+        access: 'public',
+        component: signInPage
+    },
+    {
+        path: routes.SIGN_UP,
+        access: 'public',
+        component: signUpPage
+    },
+    {
+        path: routes.HOME,
+        access: 'user-only',
+        component: homePage
+    },
+    {
+        path: routes.CATEGORIES,
+        access: 'user-only',
+        component: categoriesPage
+    },
+    {
+        path: routes.PROFILE,
+        access: 'user-only',
+        component: profilePage
+    },
+    {
+        path: routes.CREATE_TEST,
+        access: 'admin-only',
+        component: createTestForm
+    }
+]

+ 34 - 0
src/components/common/protectedRoute/index.js

@@ -0,0 +1,34 @@
+import React from 'react';
+import { Route, Redirect } from 'react-router-dom';
+import config from './config';
+import * as routes from './../../../constants/routes';
+import PermissionDenied from './../../public-components/permissionDenied';
+
+export default ({ component: Component, user, access, ...rest  }) => (
+    <Route
+        {...rest}
+        render={props => {
+
+            if (access === 'public') {
+                return <Component {...props} />
+            }
+            
+            if ( (access === 'user-only' || access === 'admin-only') && !user.data ) {
+                return <Redirect to={routes.SIGN_IN}/>
+            }
+            
+            if (access === 'user-only' && user.data) {
+                return <Component {...props} />
+            }        
+
+            if (access === 'admin-only') {
+                if (user.isAdmin) {
+                    return <Component {...props} />
+                } 
+
+                return <PermissionDenied />
+            }
+            
+        }}
+    />
+)

+ 2 - 3
src/components/auth/signInForm/index.js

@@ -2,14 +2,13 @@ import React from 'react';
 import { Field, reduxForm } from 'redux-form'
 import { Field, reduxForm } from 'redux-form'
 
 
 import validate from './validate'
 import validate from './validate'
-import formInput from './../../common/formInput'
+import formInput from './../../../common/formInput'
 
 
 import { Link } from 'react-router-dom'
 import { Link } from 'react-router-dom'
-import * as routes from './../../../constants/routes'
+import * as routes from './../../../../constants/routes'
 
 
 class Form extends React.Component {
 class Form extends React.Component {
     sendRequest = values => {
     sendRequest = values => {
-        // console.log("Redux-form values, onSubmithandler before signInRequest:", values);
         const { actions: { signInRequest } } = this.props;
         const { actions: { signInRequest } } = this.props;
         signInRequest(values);
         signInRequest(values);
     }
     }

src/components/auth/signInForm/validate/index.js → src/components/public-components/auth/signInForm/validate/index.js


+ 1 - 2
src/components/auth/signUpForm/index.js

@@ -1,7 +1,7 @@
 import React from 'react';
 import React from 'react';
 import { Field, reduxForm } from 'redux-form'
 import { Field, reduxForm } from 'redux-form'
 import validate from './validate'
 import validate from './validate'
-import formInput from './../../common/formInput'
+import formInput from './../../../common/formInput'
 
 
 class Form extends React.Component {
 class Form extends React.Component {
 
 
@@ -13,7 +13,6 @@ class Form extends React.Component {
 
 
     render() {
     render() {
         const { invalid, handleSubmit } = this.props;
         const { invalid, handleSubmit } = this.props;
-        console.log(this.props);
 
 
         return (
         return (
             <form className="sign-form" onSubmit={handleSubmit(this.sendRequest)}>
             <form className="sign-form" onSubmit={handleSubmit(this.sendRequest)}>

+ 2 - 1
src/components/auth/signUpForm/validate/index.js

@@ -11,7 +11,8 @@ export default function validate(values) {
     else if (login.length < 8 || login.length > 20) {
     else if (login.length < 8 || login.length > 20) {
         errors.login = "Invalid login length: login should be from 8 to 20 symbols";
         errors.login = "Invalid login length: login should be from 8 to 20 symbols";
     }
     }
-    else if (!/^[a-z0-9_-]{8,20}$/i.test(login)) {
+    else if (
+        !/^(([^<>()\]\\.,;:\s@"]+(\.[^<>()\]\\.,;:\s@"]+)*)|(".+"))@(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(login)) {
         errors.login = "Invalid login, try another one";
         errors.login = "Invalid login, try another one";
     }
     }
     
     

+ 3 - 1
src/components/footer/index.js

@@ -1,4 +1,5 @@
 import React from 'react';
 import React from 'react';
+import store from './../../../state';
 
 
 export default props => (
 export default props => (
     <div className="footer">
     <div className="footer">
@@ -6,6 +7,7 @@ export default props => (
             TOP-company
             TOP-company
             "<span className="footer__us us__inline--red">T</span>est.<span className="footer__us us__inline--green">i</span>o"
             "<span className="footer__us us__inline--red">T</span>est.<span className="footer__us us__inline--green">i</span>o"
         </p>
         </p>
-        <p className="footer__copyright">&copy; 2018, "Test.io", all right reserved</p>
+        <p className="footer__copyright">&copy; 2018, 'Test.io', all right reserved</p>
+        <button style={{"z-index": 4000, "color": "red"}} onClick={() => console.log(store.getState())}>Redux - State</button>
     </div>
     </div>
 )
 )

+ 2 - 2
src/components/header/index.js

@@ -1,7 +1,7 @@
 import React, { Component } from 'react';
 import React, { Component } from 'react';
 import { Link } from "react-router-dom";
 import { Link } from "react-router-dom";
-import * as routes from './../../constants/routes';
-import { UserContext } from './../../containers/Header';
+import * as routes from './../../../constants/routes';
+import { UserContext } from './../../../containers/header';
 
 
 export default class header extends Component {
 export default class header extends Component {
 
 

+ 3 - 3
src/components/landingPage/index.js

@@ -1,10 +1,10 @@
 import React from 'react';
 import React from 'react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
-import * as routes from './../../constants/routes'
+import * as routes from './../../../constants/routes'
 
 
 export default props => (
 export default props => (
     <div className="page landing-page">
     <div className="page landing-page">
-        <div className="landing-page__about">
+        <div className="container landing-page__about">
             <h1 className="description__header">
             <h1 className="description__header">
                 We are the powerfull servise providing you the ability to create and manage
                 We are the powerfull servise providing you the ability to create and manage
                 your own tests, in any categories, choosing your own marking methods.
                 your own tests, in any categories, choosing your own marking methods.
@@ -16,7 +16,7 @@ export default props => (
                 can easily pass them, get marks and <span className="description__inline--pretty">share</span> ones!
                 can easily pass them, get marks and <span className="description__inline--pretty">share</span> ones!
             </p>
             </p>
         </div>
         </div>
-        <div className="landing-page__links-container">
+        <div className="container landing-page__links-container">
             <Link to={routes.SIGN_IN} className="landing-page__links landing-page__links--sign-in">
             <Link to={routes.SIGN_IN} className="landing-page__links landing-page__links--sign-in">
                 Sign in
                 Sign in
             </Link>
             </Link>

+ 1 - 1
src/components/notFound/index.js

@@ -1,6 +1,6 @@
 import React from 'react';
 import React from 'react';
 import { Link } from 'react-router-dom';
 import { Link } from 'react-router-dom';
-import { HOME } from './../../constants/routes'
+import { HOME } from './../../../constants/routes'
 
 
 export default props => (
 export default props => (
     <div className="page not-found">
     <div className="page not-found">

+ 13 - 0
src/components/public-components/permissionDenied/index.js

@@ -0,0 +1,13 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+
+
+export default () => (
+    <div className="page permission-denied-page">
+        <h1 className="permission-denied-page__header">
+            Sorry, but looks like u are not the admin...
+        </h1>
+        <p>Buy our superior premium pack to be able to create new tests!</p>
+        <Link className="">Buy!</Link>
+    </div>
+)

+ 10 - 9
src/components/admin-components/createTestPage/form/index.js

@@ -1,33 +1,34 @@
 import React from 'react';
 import React from 'react';
 import { reduxForm, Field } from 'redux-form';
 import { reduxForm, Field } from 'redux-form';
 import validate from './validate';
 import validate from './validate';
-import fieldInput from './../../../common/formInput';
+import formInput from './../../../common/formInput'
 
 
 class Form extends React.Component {
 class Form extends React.Component {
-    handleSubmit(event) {
-        event.preventDefault();
-        alert("lol");
+    sendRequest(values) {
+        console.log('sendRequest createTestForm page values:', values);
     }
     }
 
 
     render() {
     render() {
+        const { handleSubmit } = this.props;
+
         return (
         return (
-            <form action="">
+            <form className="page" onSubmit={handleSubmit(this.sendRequest)}>
                 <h2>Make a title-page for your test!</h2>
                 <h2>Make a title-page for your test!</h2>
 
 
                 <div className="title-page__block">
                 <div className="title-page__block">
                     <p className="titles">Title</p>
                     <p className="titles">Title</p>
                     <Field
                     <Field
-                        className="title-page__block--"
+                        className="title-page__block"
                         name="title"
                         name="title"
                         type="input"
                         type="input"
                         placeholder=""
                         placeholder=""
-                        component={fieldInput}
+                        component={formInput}
                     />
                     />
                 </div>
                 </div>
 
 
                 <div className="title-page__block">
                 <div className="title-page__block">
                     <p className="titles">Description</p>
                     <p className="titles">Description</p>
-                    <Field name="description" type="input" placeholder="" className="" component={fieldInput} />
+                    <Field name="description" type="input" placeholder="" className="" component={formInput} />
                 </div>
                 </div>
 
 
                 <div className="title-page__block">
                 <div className="title-page__block">
@@ -38,7 +39,7 @@ class Form extends React.Component {
                 <button className="">Create card</button>
                 <button className="">Create card</button>
             </form>
             </form>
         )
         )
-    }
+    }   
 }
 }
 
 
 export default reduxForm({
 export default reduxForm({

src/components/admin-components/createTestPage/form/validate/index.js → src/components/user-components/admin-components/createTestForm/validate/index.js


+ 49 - 0
src/components/user-components/categoriesPage/index.js

@@ -0,0 +1,49 @@
+import React from 'react';
+import axios from 'axios';
+
+class categoriesPage extends React.Component {
+
+    state = {
+        categories: []
+    }
+
+    getCategories = () => {
+        axios.get('http://127.0.0.1:2000/api/categories')
+            .then(({ data }) => this.setState({
+                categories: data
+            }))
+            .catch(({ message }) => console.warn(message))
+    }
+
+    componentDidMount() {
+        this.getCategories()
+    }
+
+    render() {
+        const { categories } = this.state;
+        console.log("Categories - ", categories);
+
+        return ( 
+            <div className="page page--bottom-only categories-page">
+                <div className="container categories-grid">
+                    {categories.map(el => (
+                        <div
+                            className="categories-grid__element"
+                            style={{ background: `url("${el.cover}") no-repeat center center` }}
+                        >
+                            <a href={el.title}>
+                                <div className="container categories-grid__content-wrapper">
+                                    <h2>{el.title}</h2>
+                                    <hr className="divider" />
+                                    <p>{el.description}</p>
+                                </div>
+                            </a>
+                        </div>
+                    ))}
+                </div>
+            </div>
+        )
+    }
+}
+
+export default categoriesPage;

src/components/homePage/index.js → src/components/user-components/homePage/index.js


+ 89 - 0
src/components/user-components/profilePage/index.js

@@ -0,0 +1,89 @@
+import React from 'react';
+import { connect } from 'react-redux';
+// import { bindActionCreators } from 'redux'
+// import {} from './../../../actions'
+import axios from 'axios';
+
+// redux-connected container
+
+class profilePage extends React.Component {
+
+    state = {
+        user: {}
+    }
+
+    getUser = () => {
+        const randomUserId = Math.ceil(Math.random() * 10);
+
+        axios.post(`https://quiz.maxcrc.de/api/v1/user`,{
+            "login": 'ddd',
+            "password":"jhgfhgg"
+
+        })
+            .then(({ data }) => this.setState({
+                user: data
+            }))
+            .catch(({ message }) => console.warn(message))
+    }
+
+    componentDidMount() {
+        this.getUser();
+    }
+
+    render() {
+        const { user } = this.state;
+
+        console.log(user);
+
+        return (
+            <div className="page page--bottom-only profile-page">
+                <section className="container section section--about">
+                    <h2 className="section__element section__element--header">{user.login}</h2>
+                    <img className="section__element section__element--image" src={user.avatar} alt="avatar" />
+                    <div className="sedtion__element section__element--login">
+                        <h3>Login</h3>
+                        <p>{user.login}<button className="link link--btn right">Change login</button></p>
+                    </div>
+                    <div className="section__element section__element--">
+                        <h3>E-mail</h3>
+                        <p>{user.email}<button className="link link--btn right">Change e-mail</button></p>
+                    </div>
+                    <div className="section__element section__element--">
+                        <h3>Status</h3>
+                        <p>{user.description}</p>
+                    </div>
+                </section>
+                <section className="container section section--stats">
+                    <div className="section__element section__element--">
+                        <h3>Member Since</h3>
+                        <p>{new Date(user.createdAt).toLocaleString()}</p>
+                    </div>
+                    <div className="section__element section__element--comments">
+                        <h3>Last comments</h3>
+                        <p className="comments-block">
+                            {
+                                user.comments && user.comments
+                                    .slice(0, 60)
+                                    .map(el =>
+                                        <p>
+                                            <h4>{new Date(el.createdAt).toLocaleString()}</h4>
+                                            {el.text}
+                                        </p>)
+                            }
+                        </p>
+                    </div>
+                </section>
+            </div>
+        )
+    }
+
+}
+
+const
+    mapStateToProps = state => ({
+        user: state.user
+    })
+// mapDispatchToProps = dispatch => bindActionCreators({}, dispatch)
+
+export default connect(mapStateToProps)(profilePage);
+

+ 6 - 0
src/constants/index.js

@@ -12,3 +12,9 @@ export const USER_IS_SIGNED_IN = 'USER_IS_SIGNED_IN';
 export const USER_IS_NOT_SIGNED_IN = 'USER_IS_NOT_SIGNED_IN';
 export const USER_IS_NOT_SIGNED_IN = 'USER_IS_NOT_SIGNED_IN';
 
 
 export const SIGN_OUT = 'SIGN_OUT';
 export const SIGN_OUT = 'SIGN_OUT';
+
+export const USERS_GET_REQUEST = 'USERS_GET_REQUEST';
+export const USERS_GET_REQUEST_SUCCESS = 'USERS_GET_REQUEST_SUCCESS';
+export const USERS_GET_REQUEST_SUCCESS_FAILURE = 'USERS_GET_REQUEST_FAILURE';
+
+export const TOKEN_AUTH = 'TOKEN_AUTH';

+ 7 - 6
src/constants/routes.js

@@ -1,13 +1,14 @@
+// Be careful ! Check all dependencies in protectedRoute/config.js,
+// otherwise it may cause mistakes in router.js! 
+
 export const LANDING = '/';
 export const LANDING = '/';
 export const SIGN_UP = '/sign-up';
 export const SIGN_UP = '/sign-up';
 export const SIGN_IN = '/sign-in';
 export const SIGN_IN = '/sign-in';
 export const HOME = '/home';
 export const HOME = '/home';
-export const ACCOUNT = '/account';
-export const ADMIN = '/admin';
-export const PASSWORD_FORGET = '/pw-forget';
-export const CREATE_TEST = '/create-test';
 export const CREATE_CATEGORY = '/create-category';
 export const CREATE_CATEGORY = '/create-category';
+export const CATEGORIES = '/categories';
+export const PROFILE = '/profile';
+export const CREATE_TEST = '/create-test';
 export const DELETE_USER = '/delete-user'
 export const DELETE_USER = '/delete-user'
 export const TESTS = '/test';
 export const TESTS = '/test';
-export const CATEGORIES = '/categories';
-export const PROFILE = '/profile';
+export const PASSWORD_FORGET = '/pw-forget';

+ 1 - 2
src/containers/auth/SignInPage/index.js

@@ -6,12 +6,11 @@ import { connect } from 'react-redux';
 import { Redirect } from 'react-router';
 import { Redirect } from 'react-router';
 import { HOME } from './../../../constants/routes';
 import { HOME } from './../../../constants/routes';
 
 
-import SignInForm from './../../../components/auth/signInForm'
+import SignInForm from './../../../components/public-components/auth/signInForm'
 
 
 class SignInPage extends React.Component {
 class SignInPage extends React.Component {
 
 
     render() {
     render() {
-        console.log("SignInPage containers props:", this.props);
         const { signInRequest, user } = this.props;
         const { signInRequest, user } = this.props;
         return (
         return (
             !(user.data)
             !(user.data)

+ 1 - 2
src/containers/auth/SignUpPage/index.js

@@ -6,12 +6,11 @@ import { connect } from 'react-redux';
 import { Redirect } from 'react-router'
 import { Redirect } from 'react-router'
 import { HOME } from './../../../constants/routes';
 import { HOME } from './../../../constants/routes';
 
 
-import SignUpForm from './../../../components/auth/signUpForm'
+import SignUpForm from './../../../components/public-components/auth/signUpForm';
 
 
 class SignUpPage extends React.Component {
 class SignUpPage extends React.Component {
 
 
     render() {
     render() {
-        console.log("SignInPage containers props:", this.props);
         const { signUpRequest, user } = this.props;
         const { signUpRequest, user } = this.props;
         return (
         return (
             !(user.data)
             !(user.data)

+ 2 - 2
src/containers/header/index.js

@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
 import { func, object } from 'prop-types';
 import { func, object } from 'prop-types';
 import { bindActionCreators } from 'redux' 
 import { bindActionCreators } from 'redux' 
 
 
-import HeaderComponent from './../../components/header';
+import HeaderComponent from './../../components/public-components/header';
 
 
 import {signOut} from './../../actions/auth/signOut'
 import {signOut} from './../../actions/auth/signOut'
 
 
@@ -25,7 +25,7 @@ class Header extends Component {
                     signOut
                     signOut
                 }}
                 }}
             >
             >
-                <HeaderComponent />
+                <HeaderComponent />;
             </UserContext.Provider>
             </UserContext.Provider>
         )
         )
         
         

+ 38 - 6
src/reducers/user/index.js

@@ -1,18 +1,31 @@
-import initialState from './../initialState'
-import * as types from './../../constants'
+import initialState from './../initialState';
+import * as types from './../../constants';
 
 
 export default function (state = initialState.user, { type, error, payload: data }) {
 export default function (state = initialState.user, { type, error, payload: data }) {
     switch(type) {
     switch(type) {
+
+        case types.TOKEN_AUTH: {
+            return {
+                ...state,
+                data
+            }
+        }
+
+        // SIGN_UP
+
         case types.SIGN_UP_REQUEST: {
         case types.SIGN_UP_REQUEST: {
             return {
             return {
                 ...state,
                 ...state,
-                gettingUser: true
+                gettingUser: true,
+                error: null,
+                data: null
             }
             }
         }
         }
         case types.SIGN_UP_REQUEST_SUCCESS: {
         case types.SIGN_UP_REQUEST_SUCCESS: {
             return {
             return {
                 ...state,
                 ...state,
                 gettingUser: false,
                 gettingUser: false,
+                error: null,
                 data
                 data
             }
             }
         }
         }
@@ -20,35 +33,54 @@ export default function (state = initialState.user, { type, error, payload: data
             return {
             return {
                 ...state,
                 ...state,
                 gettingUser: false,
                 gettingUser: false,
+                data: null,
                 error
                 error
             }
             }
         }
         }
+
+        // SIGN_IN
+
         case types.SIGN_IN_REQUEST: {
         case types.SIGN_IN_REQUEST: {
             return {
             return {
                 ...state,
                 ...state,
-                gettingUser: true
+                gettingUser: true,
+                error: null,
+                data: null
             }
             }
         }
         }
         case types.SIGN_IN_REQUEST_SUCCESS: {
         case types.SIGN_IN_REQUEST_SUCCESS: {
             return {
             return {
                 ...state,
                 ...state,
                 gettingUser: false,
                 gettingUser: false,
+                error: null,
                 data                
                 data                
             }
             }
         }
         }
-        case types.SIGN_UP_REQUEST_FAILURE: {
+        case types.SIGN_IN_REQUEST_FAILURE: {
             return {
             return {
                 ...state,
                 ...state,
                 gettingUser: false,
                 gettingUser: false,
+                data: null,
                 error
                 error
             }
             }
         }
         }
+
+        // SIGN_OUT
+
         case types.SIGN_OUT: {
         case types.SIGN_OUT: {
             return initialState.user
             return initialState.user
         }
         }
+
+        // DEFAULT
+
         default: {
         default: {
             return {...state}
             return {...state}
             
             
         }
         }
     }
     }
-}
+}
+
+
+
+
+

+ 58 - 38
src/router.js

@@ -1,43 +1,63 @@
 import React, { Suspense, lazy } from "react";
 import React, { Suspense, lazy } from "react";
-import { Switch, Route } from "react-router-dom";
+import { Switch, Route, withRouter } from "react-router-dom";
+import { connect } from 'react-redux';
+import { tokenAuth } from './actions/auth/tokenAuth'
 
 
-import * as routes from './constants/routes'
-
-import Header from "./containers/Header"
-import landingPage from './components/landingPage'
-import Footer from './components/footer'
-import PrivateRouter from './PrivateRouter'
+import Header from "./containers/header";
+import Footer from './components/public-components/footer';
 
 
 import Spinner from "./components/common/spinner";
 import Spinner from "./components/common/spinner";
 
 
-const notFound   = lazy(() => import("./components/notFound"));
-const homePage   = lazy(() => import("./components/homePage"));
-const signInPage = lazy(() => import("./containers/auth/SignInPage"));
-const signUpPage = lazy(() => import("./containers/auth/SignUpPage"));
-const createTestPage = lazy(() => import("./components/admin-components/createTestPage"));
-
-export default () => (
-    <div className="app">
-        <Header />
-        <Suspense fallback={<Spinner />}>
-            <Switch>
-                <Route path={routes.LANDING} exact component={landingPage} />
-                <Route path={routes.SIGN_IN} exact component={signInPage} />
-                <Route path={routes.SIGN_UP} exact component={signUpPage} />
-                <Route path={routes.HOME} exact component={homePage} />
-
-                {/* <PrivateRouter path={routes.HOME} user={false} component={homePage}/> */}
-                <PrivateRouter path={routes.TESTS} user={false} component={null}/>
-                <PrivateRouter path={routes.CATEGORIES} user={false} component={null}/>
-                <PrivateRouter path={routes.PROFILE} user={false} component={null} />
-
-                <PrivateRouter path={routes.CREATE_TEST} user={true} component={createTestPage} />
-                <PrivateRouter path={routes.CREATE_CATEGORY} user={false} component={createTestPage} />
-                <PrivateRouter path={routes.DELETE_USER} user={false} component={createTestPage} />
-                
-                <Route component={notFound} />
-            </Switch>
-        </Suspense>
-        <Footer />
-    </div>
-);
+import ProtectedRoute from './components/common/protectedRoute';
+import config from './components/common/protectedRoute/config';
+
+import fakeToken from './utils/token'
+import { bindActionCreators } from "redux";
+
+const notFound = lazy(() => import('./components/public-components/notFound'));
+
+class Router extends React.Component {
+
+    componentDidMount() {
+        const storagedUser = localStorage.getItem(fakeToken);
+        const { tokenAuth } = this.props;
+
+        storagedUser && tokenAuth(storagedUser);
+    }
+
+    render() {
+        const { user } = this.props;
+
+        //map located here because of switch-bag
+
+        const protectedRoutes = config.map(route =>
+            <ProtectedRoute
+                path={route.path}
+                component={route.component}
+                access={route.access}
+                user={user}
+                exact
+            />
+        );
+
+        return (
+            <div className="app">
+                <Header />
+                <Suspense fallback={<Spinner />}>
+                    <Switch>
+                        {protectedRoutes}
+                        <Route component={notFound} />
+                    </Switch>
+                </Suspense>
+                <Footer />
+            </div>
+        )
+    }
+}
+
+const mapStateToProps = state => ({
+    user: state.user
+})
+const mapDispatchToProps = dispatch => bindActionCreators({ tokenAuth }, dispatch);
+
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Router));

+ 2 - 0
src/saga/auth/index.js

@@ -3,10 +3,12 @@ import * as types from "./../../constants"
 
 
 import signIn from './signIn';
 import signIn from './signIn';
 import signUp from './signUp';
 import signUp from './signUp';
+import getUsers from './users/users';
 
 
 export default function*() {
 export default function*() {
     yield takeEvery(types.SIGN_IN_REQUEST, signIn);
     yield takeEvery(types.SIGN_IN_REQUEST, signIn);
     yield takeEvery(types.SIGN_UP_REQUEST, signUp);
     yield takeEvery(types.SIGN_UP_REQUEST, signUp);
+    yield takeEvery(types.USERS_GET_REQUEST, getUsers);
 }
 }
 
 
 
 

+ 6 - 9
src/saga/auth/signIn/index.js

@@ -1,24 +1,21 @@
 import { put, call } from "redux-saga/effects";
 import { put, call } from "redux-saga/effects";
 import * as actions from './../../../actions/auth/signIn'
 import * as actions from './../../../actions/auth/signIn'
+import axios from 'axios';
 
 
-import { SIGN_IN_URL } from './../../../constants'
 
 
 // worker-saga for signing in
 // worker-saga for signing in
 
 
 export default function* ({ payload: requestBody }) {
 export default function* ({ payload: requestBody }) {
     try {
     try {
         // console.log('received request body from sign-in worker saga', requestBody);
         // console.log('received request body from sign-in worker saga', requestBody);
-        const payload = yield call(() => 
-            fetch(SIGN_IN_URL, {
-                method: 'POST',
-                body: JSON.stringify(requestBody)
-            })
-                .then(res => res.json())
+        const payload = yield call(() =>
+            axios.post(`https://quiz.maxcrc.de/api/v1/user`, {...requestBody})
+                .then(({ data }) => data)
         );
         );
         // console.log("Payload", payload);
         // console.log("Payload", payload);
         yield put(actions.signInRequestSucces(payload));
         yield put(actions.signInRequestSucces(payload));
     }
     }
-    catch (exception) {
-        yield put(actions.signInRequestFailure(exception.message))
+    catch ({ message }) {
+        yield put(actions.signInRequestFailure(message))
     }
     }
 }
 }

+ 5 - 4
src/saga/auth/signUp/index.js

@@ -1,5 +1,6 @@
 import { put, call } from "redux-saga/effects";
 import { put, call } from "redux-saga/effects";
 import * as actions from './../../../actions/auth/signUp'
 import * as actions from './../../../actions/auth/signUp'
+import axios from 'axios';
 
 
 import { SIGN_UP_URL } from '../../../constants'
 import { SIGN_UP_URL } from '../../../constants'
 
 
@@ -8,11 +9,11 @@ import { SIGN_UP_URL } from '../../../constants'
 export default function* ({ payload: requestBody }) {
 export default function* ({ payload: requestBody }) {
     try {
     try {
         const payload = yield call(() => 
         const payload = yield call(() => 
-        fetch(SIGN_UP_URL, {
-            method: 'POST',
-            body: JSON.stringify(requestBody)
+        axios.post(`https://quiz.maxcrc.de/api/v1/user`, {
+            ...requestBody
         })
         })
-            .then(res => res.json())
+            .then(({ data }) => data)
+
     );
     );
         yield put(actions.signUpRequestSucces(payload));
         yield put(actions.signUpRequestSucces(payload));
     }
     }

+ 20 - 0
src/saga/auth/users/users.js

@@ -0,0 +1,20 @@
+import { put, call } from "redux-saga/effects";
+import * as actions from './../../../actions/auth/users/users'
+import axios from 'axios';
+
+
+
+export default function* ({ payload: requestBody }) {
+    try {
+        // console.log('received request body from sign-in worker saga', requestBody);
+        const payload = yield call(() =>
+            axios.get(`https://quiz.maxcrc.de/api/v1/user`)
+                .then(({ data }) => data)
+        );
+        // console.log("Payload", payload);
+        yield put(actions.usersGetRequestSucces(payload));
+    }
+    catch ({ message }) {
+        yield put(actions.usersGetRequestFailure(message))
+    }
+}

+ 1 - 1
src/styles/abstracts/_variables.scss

@@ -15,5 +15,5 @@ $color-lightsteelgrey-transparent: rgba(190, 195, 221, .9);
 $color-lightsteelblue: #B0C4DE;
 $color-lightsteelblue: #B0C4DE;
 $color-lightsteelblue-transparent: rgba(176, 196, 222, .9);
 $color-lightsteelblue-transparent: rgba(176, 196, 222, .9);
 
 
-$padding-top-fixed: 175px;
+$padding-top-fixed: 155px;
 $padding-bottom-fixed: 45px;
 $padding-bottom-fixed: 45px;

+ 8 - 1
src/styles/base/_base.scss

@@ -31,4 +31,11 @@ code {
     font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
     font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
     monospace;
     monospace;
 }
 }
-  
+
+// recheck
+
+@media screen and (max-width: 1200px) {
+    * {
+        transition: none !important;
+    }
+}

+ 3 - 0
src/styles/components/_button.scss

@@ -31,6 +31,9 @@
             padding: 3vh 6vh;
             padding: 3vh 6vh;
             font-weight: 400;
             font-weight: 400;
         }
         }
+        &-right {
+            float: right;
+        }
     }
     }
     
     
 }
 }

+ 31 - 0
src/styles/components/_categoriesPage.scss

@@ -0,0 +1,31 @@
+
+
+.categories {
+    &-page {
+        width: 95%;
+        margin: auto;
+    }
+    &-grid {
+        display: flex;
+        flex-wrap: wrap;
+        font-family: 'Cormorant Infant', serif;
+        text-align: center;
+        &__element {
+            min-width: 250px;
+            max-width: 370px;
+            margin: 1vw auto;
+            border: 2px solid lightsteelblue;
+            height: 300px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+        }
+        &__content-wrapper {
+            width: 80%;
+            height: 80%;
+        }
+        .divider {
+            width: 60%;
+        }
+    }
+}

+ 5 - 0
src/styles/components/_container.scss

@@ -0,0 +1,5 @@
+.container {
+    margin: auto;
+    background: $color-lightgrey-transparent;
+    box-shadow: 0 0 10px grey;
+}

+ 0 - 0
src/styles/components/_createTestPage.scss


+ 0 - 6
src/styles/components/_landingPage.scss

@@ -5,12 +5,6 @@
     background-size: cover;
     background-size: cover;
     background-position: top center;
     background-position: top center;
     font-family: 'Cormorant Infant', serif;
     font-family: 'Cormorant Infant', serif;
-    &__about,
-    &__links-container, {
-        margin: auto;
-        background: rgba(211,211,211, .9);
-        box-shadow: 0 0 10px grey;
-    }
     &__about {
     &__about {
         width: 65%;
         width: 65%;
         text-align: center;
         text-align: center;

+ 11 - 0
src/styles/components/_page.scss

@@ -1,5 +1,16 @@
 .page {
 .page {
     padding-top: $padding-top-fixed;
     padding-top: $padding-top-fixed;
     padding-bottom: $padding-bottom-fixed;
     padding-bottom: $padding-bottom-fixed;
+    &--bottom-only {
+        padding-top: $padding-top-fixed - 40px;
+    }
 }
 }
+
+// .app {
+//     background-image: url('https://structureofintellect.files.wordpress.com/2017/09/bubble-test.jpg');
+//     background-attachment: fixed;
+//     background-repeat: no-repeat;
+//     background-size: cover;
+//     background-position: top center;
+// }
     
     

+ 30 - 0
src/styles/components/_profilePage.scss

@@ -0,0 +1,30 @@
+.profile-page {
+    display: flex;
+    flex-wrap: wrap;
+    font-family: 'Cormorant Infant', serif;
+    font-size: 20px;
+    .section {
+        flex-grow: 1;
+        flex-basis: 400px;
+        margin: 10px;
+        padding: 10px;
+        &__element {
+            &--image {
+                border: 3px solid $color-lightsteelblue;
+                margin-bottom: 20px;
+            }
+            p {
+                margin-top: 5px;
+            }
+            .comments-block {
+                height: 250px;
+                overflow: auto;
+            }
+            
+        }
+    }
+    .right {
+        float: right;
+    }
+}
+

+ 1 - 0
src/styles/components/_signPage.scss

@@ -1,5 +1,6 @@
 .sign {
 .sign {
     &-form {
     &-form {
+        // background: $color-lightgrey-transparent;
         font-size: 18px;
         font-size: 18px;
         font-family: 'Poiret One', cursive;
         font-family: 'Poiret One', cursive;
         font-weight: bold;
         font-weight: bold;

+ 3 - 0
src/styles/index.scss

@@ -4,6 +4,7 @@
 @import "base/typography";
 @import "base/typography";
 
 
 @import "components/page";
 @import "components/page";
+@import "components/container";
 @import "components/button";
 @import "components/button";
 @import "components/header";
 @import "components/header";
 @import "components/spinner";
 @import "components/spinner";
@@ -11,4 +12,6 @@
 @import "components/footer";
 @import "components/footer";
 @import "components/signPage";
 @import "components/signPage";
 @import "components/notFound";
 @import "components/notFound";
+@import "components/profilePage";
+@import "components/categoriesPage";
 
 

+ 1 - 0
src/utils/token.js

@@ -0,0 +1 @@
+export default "fake-token-lol-kek";

+ 6 - 0
грабли.txt

@@ -0,0 +1,6 @@
+1. Редакс ломает роутер.
+Возможный костыль:
+https://github.com/ReactTraining/react-router/blob/v4.0.0-beta.8/packages/react-router/docs/guides/blocked-updates.md
+2. Анимация на кнопках хэдэра и нотфаунд не работает, хотя работает на кнопках формы.
+ХЗ
+3. Нету адекватного способа прокинуть юзера в роутер -> см. пункт 1.

+ 1 - 0
костыли.txt

@@ -0,0 +1 @@
+Все еще впереди...