12 Commity 44569b3daa ... 028624f45b

Autor SHA1 Wiadomość Data
  sveta 028624f45b Merge Sveta 5 lat temu
  sveta 51acd675b4 bred 5 lat temu
  sveta 38435bf311 Merge Maxim 5 lat temu
  sveta 7925d5eb61 test 5 lat temu
  sveta 0f33146481 test 5 lat temu
  sveta 31d7915f23 change test 5 lat temu
  sveta cbf6b70436 create,change, test 5 lat temu
  Maxim 15844d82bd auth changes => logOut is done 5 lat temu
  sveta 37604e9378 create test 5 lat temu
  Maxim 293bffe5b2 somewhat 5 lat temu
  Svetlana e99b4855da category admin 5 lat temu
  Maxim 063a04fffd router logic rewrote: static -> using token 5 lat temu
100 zmienionych plików z 4696 dodań i 275 usunięć
  1. 1357 52
      package-lock.json
  2. 8 2
      package.json
  3. 14 0
      src/actions/admin/category/changeCategory.js
  4. 14 0
      src/actions/admin/category/createCategory.js
  5. 14 0
      src/actions/admin/category/deleteCategory.js
  6. 14 0
      src/actions/admin/category/getCategory.js
  7. 24 0
      src/actions/admin/changeTest/changeTest.js
  8. 17 0
      src/actions/admin/changeTest/deleteAnswer.js
  9. 17 0
      src/actions/admin/changeTest/deleteQuestion.js
  10. 17 0
      src/actions/admin/changeTest/deleteTopic.js
  11. 17 0
      src/actions/admin/changeTest/getAnswers.js
  12. 17 0
      src/actions/admin/changeTest/getQuestions.js
  13. 16 0
      src/actions/admin/changeTest/getTopic.js
  14. 13 0
      src/actions/admin/meUser.js
  15. 21 0
      src/actions/admin/test/createTest.js
  16. 25 0
      src/actions/admin/test/createTopics.js
  17. 19 0
      src/actions/admin/user/changeUser.js
  18. 0 0
      src/actions/admin/user/changeUserRole.js
  19. 19 0
      src/actions/admin/user/deleteUser.js
  20. 17 0
      src/actions/admin/user/getUser.js
  21. 17 3
      src/actions/auth/logOut.js
  22. 6 1
      src/actions/auth/signIn.js
  23. 3 1
      src/actions/auth/signUp.js
  24. 10 0
      src/actions/auth/tokenCheckout.js
  25. 0 1
      src/actions/user/changeEmail.js
  26. 0 1
      src/actions/user/changePassword.js
  27. 0 1
      src/actions/user/changelogin.js
  28. 17 0
      src/actions/user/test/checkTest.js
  29. 17 0
      src/actions/user/test/getTopics.js
  30. 17 0
      src/actions/user/test/nextTest.js
  31. 17 0
      src/actions/user/test/testStart.js
  32. 35 0
      src/components/admin/CardsCreator/index.js
  33. 161 0
      src/components/admin/CreateTest/CreateTopic.js
  34. 69 0
      src/components/admin/CreateTest/index.js
  35. 49 0
      src/components/admin/addDeleteCategory/ChangeCategory.js
  36. 33 0
      src/components/admin/addDeleteCategory/CreateCategoryForm/index.js
  37. 48 0
      src/components/admin/addDeleteCategory/DeleteCategory.js
  38. 140 0
      src/components/admin/addDeleteCategory/GetCategory.js
  39. 56 0
      src/components/admin/addDeleteCategory/index.js
  40. 0 25
      src/components/admin/deleteUser/DeleteUserForm/index.js
  41. 71 0
      src/components/admin/deleteUser/GetUsers.js
  42. 62 0
      src/components/admin/deleteUser/changeUsers.js
  43. 54 11
      src/components/admin/deleteUser/index.js
  44. 106 0
      src/components/admin/getChangeDeleteTest/GetQuestions.js
  45. 39 0
      src/components/admin/getChangeDeleteTest/GetTest.js
  46. 76 0
      src/components/admin/getChangeDeleteTest/GetTopic.js
  47. 162 0
      src/components/admin/getChangeDeleteTest/OpenModal.js
  48. 112 0
      src/components/admin/getChangeDeleteTest/changeQuestions.js
  49. 125 0
      src/components/admin/getChangeDeleteTest/index.js
  50. 3 2
      src/components/common/formInput.js
  51. 33 30
      src/components/common/protectedRoute.js
  52. 89 28
      src/components/public/Header.js
  53. 0 42
      src/components/public/SignIn/index.js
  54. 32 0
      src/components/public/landing.js
  55. 7 5
      src/components/public/SignIn/Form/index.js
  56. 0 0
      src/components/public/signIn/Form/validate.js
  57. 51 0
      src/components/public/signIn/index.js
  58. 0 0
      src/components/public/signUp/Form/index.js
  59. 0 0
      src/components/public/signUp/Form/validate.js
  60. 1 1
      src/components/public/SignUp/index.js
  61. 63 0
      src/components/user/Categoty.js
  62. 4 4
      src/components/user/ProfilePage/ChangeEmailForm/index.js
  63. 3 5
      src/components/user/ProfilePage/ChangeLoginForm/index.js
  64. 5 5
      src/components/user/ProfilePage/changePassword/index.js
  65. 37 35
      src/components/user/ProfilePage/index.js
  66. 25 0
      src/components/user/Test/ModalSommary.js
  67. 60 0
      src/components/user/Test/getTest.js
  68. 95 0
      src/components/user/Test/index.js
  69. 12 0
      src/configs/requestsConfigs/index.js
  70. 43 8
      src/configs/routerConfig.js
  71. 47 0
      src/configs/validate.js
  72. 83 0
      src/constants/admin.js
  73. 10 1
      src/constants/auth.js
  74. 1 0
      src/constants/routes.js
  75. 20 1
      src/constants/user.js
  76. 43 0
      src/reducers/admin/changeCategory.js
  77. 42 0
      src/reducers/admin/createCategory.js
  78. 35 0
      src/reducers/admin/getCategory.js
  79. 33 0
      src/reducers/admin/getUsers.js
  80. 32 0
      src/reducers/admin/initialValues.js
  81. 35 0
      src/reducers/admin/test/changeUser.js
  82. 34 0
      src/reducers/admin/test/createTopics.js
  83. 34 0
      src/reducers/admin/test/deleteQuestion.js
  84. 34 0
      src/reducers/admin/test/deleteTopic.js
  85. 36 0
      src/reducers/admin/test/deleteUsers.js
  86. 36 0
      src/reducers/admin/test/getAnswers.js
  87. 36 0
      src/reducers/admin/test/getQuestions.js
  88. 37 0
      src/reducers/admin/test/getTopic.js
  89. 34 0
      src/reducers/admin/test/newTopic.js
  90. 31 0
      src/reducers/auth/logOut.js
  91. 4 3
      src/reducers/auth/signIn.js
  92. 22 0
      src/reducers/auth/tokenCheckout.js
  93. 40 1
      src/reducers/index.js
  94. 102 4
      src/reducers/initialState.js
  95. 0 1
      src/reducers/user/chageLogin.js
  96. 0 1
      src/reducers/user/changeEmail.js
  97. 36 0
      src/reducers/user/getTopicTest.js
  98. 33 0
      src/reducers/user/myUser.js
  99. 41 0
      src/reducers/user/startTest.js
  100. 0 0
      src/router.js

Plik diff jest za duży
+ 1357 - 52
package-lock.json


+ 8 - 2
package.json

@@ -3,20 +3,26 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "antd": "^3.13.2",
     "axios": "^0.18.0",
-    "bootstrap": "^4.2.1",
+    "bootstrap": "^4.3.0",
     "jquery": "^3.3.1",
+    "jwt-decode": "^2.2.0",
     "node-sass": "^4.11.0",
     "popper.js": "^1.14.6",
     "react": "^16.6.3",
+    "react-bootstrap": "^1.0.0-beta.5",
     "react-dom": "^16.6.3",
     "react-redux": "^6.0.0",
     "react-router": "^4.3.1",
     "react-router-dom": "^4.3.1",
     "react-scripts": "^2.1.3",
+    "react-spinners": "^0.5.1",
+    "react-transition-group": "^2.5.3",
     "redux": "^4.0.1",
     "redux-form": "^8.1.0",
-    "redux-saga": "^1.0.0"
+    "redux-saga": "^1.0.0",
+    "stylefire": "^2.4.0"
   },
   "scripts": {
     "start": "react-scripts start",

+ 14 - 0
src/actions/admin/category/changeCategory.js

@@ -0,0 +1,14 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const changeCategoryRequest = payload => ({
+    type: actionTypes.CHANGE_CATEGORY_REQUEST,
+    payload
+});
+export const changeCategorySuccess = payload => ({
+    type: actionTypes.CHANGE_CATEGORY_REQUEST_SUCCESS,
+    payload
+});
+export const changeCategoryFailure = error => ({
+    type: actionTypes.CHANGE_CATEGORY_REQUEST_FAILURE,
+    error
+});

+ 14 - 0
src/actions/admin/category/createCategory.js

@@ -0,0 +1,14 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const createCategoryRequest = payload => {
+  return{  type: actionTypes.CREATE_CATEGORY_REQUEST,
+    payload
+}};
+export const createCategorySuccess = payload => ({
+    type: actionTypes.CREATE_CATEGORY_REQUEST_SUCCESS,
+    payload
+});
+export const createCategoryFailure = error => ({
+    type: actionTypes.CREATE_CATEGORY_REQUEST_FAILURE,
+    error
+});

+ 14 - 0
src/actions/admin/category/deleteCategory.js

@@ -0,0 +1,14 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const deleteCategoryRequest = payload => ({
+    type: actionTypes.DELETE_CATEGORY_REQUEST,
+    payload
+});
+export const deleteCategorySuccess = payload => ({
+    type: actionTypes.DELETE_CATEGORY_REQUEST_SUCCESS,
+    payload
+});
+export const deleteCategoryFailure = error => ({
+    type: actionTypes.DELETE_CATEGORY_REQUEST_FAILURE,
+    error
+});

+ 14 - 0
src/actions/admin/category/getCategory.js

@@ -0,0 +1,14 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const getCategoryRequest = payload => ({
+    type: actionTypes.GET_CATEGORY_REQUEST,
+    payload
+});
+export const getCategorySuccess = payload => ({
+    type: actionTypes.GET_CATEGORY_REQUEST_SUCCESS,
+    payload
+});
+export const getCategoryFailure = error => ({
+    type: actionTypes.GET_CATEGORY_REQUEST_FAILURE,
+    error
+});

+ 24 - 0
src/actions/admin/changeTest/changeTest.js

@@ -0,0 +1,24 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const changeTestRequest = payload => {
+    return{
+    type: actionTypes.CHANGE_TEST_REQUEST,
+    payload
+};
+}
+export const changeTopicSuccess = payload => ({
+    type: actionTypes.CHANGE_TOPIC_REQUEST_SUCCESS,
+    payload
+});
+export const changeQuestionSuccess = payload => ({
+    type: actionTypes.CHANGE_QUESTIONS_REQUEST_SUCCESS,
+    payload
+});
+export const changeAnswersSuccess = payload => ({
+    type: actionTypes.CHANGE_ANSVERS_REQUEST_SUCCESS,
+    payload
+});
+export const createTopicsFailure = error => ({
+    type: actionTypes.CHANGE_TEST_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/admin/changeTest/deleteAnswer.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const deleteAnswerRequest = payload => {
+    return{
+    type: actionTypes.DELETE_ANSWER_REQUEST,
+    payload
+};
+}
+export const deleteAnswerSuccess = payload => ({
+    type: actionTypes.DELETE_ANSWER_REQUEST_SUCCESS,
+    payload
+});
+
+export const deleteAnswerFailure = error => ({
+    type: actionTypes.DELETE_ANSWER_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/admin/changeTest/deleteQuestion.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const deleteQuestionRequest = payload => {
+    return{
+    type: actionTypes.DELETE_QUESTION_REQUEST,
+    payload
+};
+}
+export const deleteQuestionSuccess = payload => ({
+    type: actionTypes.DELETE_QUESTION_REQUEST_SUCCESS,
+    payload
+});
+
+export const deleteQuestionFailure = error => ({
+    type: actionTypes.DELETE_QUESTION_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/admin/changeTest/deleteTopic.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const deleteTopicRequest = payload => {
+    return{
+    type: actionTypes.DELETE_TOPIC_REQUEST,
+    payload
+};
+}
+export const deleteTopicSuccess = payload => ({
+    type: actionTypes.DELETE_TOPIC_REQUEST_SUCCESS,
+    payload
+});
+
+export const deleteTopicFailure = error => ({
+    type: actionTypes.DELETE_TOPIC_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/admin/changeTest/getAnswers.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const getAnswersRequest = payload => {
+    return{
+    type: actionTypes.GET_ANSWERS_REQUEST,
+    payload
+};
+}
+export const getAnswersSuccess = payload => ({
+    type: actionTypes.GET_ANSWERS_REQUEST_SUCCESS,
+    payload
+});
+
+export const getAnswersFailure = error => ({
+    type: actionTypes.GET_ANSWERS_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/admin/changeTest/getQuestions.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const getQuestionsRequest = payload => {
+    return{
+    type: actionTypes.GET_QUESTIONS_REQUEST,
+    payload
+};
+}
+export const getQuestionsSuccess = payload => ({
+    type: actionTypes.GET_QUESTIONS_REQUEST_SUCCESS,
+    payload
+});
+
+export const getQuestionsFailure = error => ({
+    type: actionTypes.GET_QUESTIONS_REQUEST_FAILURE,
+    error
+});

+ 16 - 0
src/actions/admin/changeTest/getTopic.js

@@ -0,0 +1,16 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const getTopicRequest = payload => {
+    return{
+    type: actionTypes.GET_TOPIC_REQUEST,
+    payload
+};
+}
+export const getTopicSuccess = payload => ({
+    type: actionTypes.GET_TOPIC_REQUEST_SUCCESS,
+    payload
+});
+export const getTopicFailure = error => ({
+    type: actionTypes.GET_TOPIC_REQUEST_FAILURE,
+    error
+});

+ 13 - 0
src/actions/admin/meUser.js

@@ -0,0 +1,13 @@
+import * as actionTypes from '../../constants/admin';
+
+export const myUserRequest = payload => ({
+    type: actionTypes.MY_USER_REQUEST,
+});
+export const myUserSuccess = payload => ({
+    type: actionTypes.MY_USER_REQUEST_SUCCESS,
+    payload
+});
+export const myUserFailure = error => ({
+    type: actionTypes.MY_USER_REQUEST_FAILURE,
+    error
+});

+ 21 - 0
src/actions/admin/test/createTest.js

@@ -0,0 +1,21 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const createTestRequest = payload => {
+    console.log(payload)
+    return{
+    type: actionTypes.CREATE_TEST_REQUEST,
+    payload
+};
+}
+export const createQuestionSuccess = payload => ({
+    type: actionTypes.CREATE_QUESTIONS_REQUEST_SUCCESS,
+    payload
+});
+export const createAnswersSuccess = payload => ({
+    type: actionTypes.CREATE_ANSVERS_REQUEST_SUCCESS,
+    payload
+});
+export const createTestFailure = error => ({
+    type: actionTypes.CREATE_TEST_REQUEST_FAILURE,
+    error
+});

+ 25 - 0
src/actions/admin/test/createTopics.js

@@ -0,0 +1,25 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const createTopicsRequest = payload => {
+    console.log(payload)
+    return{
+    type: actionTypes.CREATE_TOPICS_REQUEST,
+    payload
+};
+}
+export const createTopicsSuccess = payload => ({
+    type: actionTypes.CREATE_TOPICS_REQUEST_SUCCESS,
+    payload
+});
+export const createQuestionSuccess = payload => ({
+    type: actionTypes.CREATE_QUESTIONS_REQUEST_SUCCESS,
+    payload
+});
+export const createAnswersSuccess = payload => ({
+    type: actionTypes.CREATE_ANSVERS_REQUEST_SUCCESS,
+    payload
+});
+export const createTopicsFailure = error => ({
+    type: actionTypes.CREATE_TOPICS_REQUEST_FAILURE,
+    error
+});

+ 19 - 0
src/actions/admin/user/changeUser.js

@@ -0,0 +1,19 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const changeUserRequest = payload => {
+    console.log(payload)
+    return{
+
+        type: actionTypes.CHANGE_USERS_REQUEST,
+        payload
+    }
+    
+}
+export const changeUserSuccess = payload => ({
+    type: actionTypes.CHANGE_USERS_REQUEST_SUCCESS,
+    payload
+});
+export const changeUserFailure = error => ({
+    type: actionTypes.CHANGE_USERS_REQUEST_FAILURE,
+    error
+});

src/actions/auth/saveToken.js → src/actions/admin/user/changeUserRole.js


+ 19 - 0
src/actions/admin/user/deleteUser.js

@@ -0,0 +1,19 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const deleteUsersRequest = payload => {
+    console.log(payload)
+    return{
+
+        type: actionTypes.DELETE_USERS_REQUEST,
+        payload
+    }
+    
+}
+export const deleteUsersSuccess = payload => ({
+    type: actionTypes.DELETE_USERS_REQUEST_SUCCESS,
+    payload
+});
+export const deleteUsersFailure = error => ({
+    type: actionTypes.DELETE_USERS_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/admin/user/getUser.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/admin';
+
+export const getUserRequest = payload => {
+    console.log('Inside the getUser action', payload);
+    return {
+        type: actionTypes.GET_USERS_REQUEST,
+        payload
+    };
+}
+export const getUserSuccess = payload => ({
+    type: actionTypes.GET_USERS_REQUEST_SUCCESS,
+    payload
+});
+export const getUserFailure = error => ({
+    type: actionTypes.GET_USERS_REQUEST_FAILURE,
+    error
+});

+ 17 - 3
src/actions/auth/logOut.js

@@ -1,3 +1,17 @@
-export const logOut = () => ({
-    
-})
+import * as actionTypes from './../../constants/auth';
+
+const logOut = () => ({
+    type: actionTypes.LOG_OUT_REQUEST
+})
+
+export const logOutSuccess = payload => ({
+    type: actionTypes.LOG_OUT_REQUEST_SUCCESS,
+    payload
+})
+
+export const logOutFailure = ({ message: error }) => ({
+    type: actionTypes.LOG_OUT_REQUEST_FAILURE,
+    error
+})
+
+export default logOut;

+ 6 - 1
src/actions/auth/signIn.js

@@ -1,6 +1,6 @@
 import * as actionTypes from './../../constants/auth';
 
-export const signIn = payload => ({
+const signIn = payload => ({
     type: actionTypes.SIGN_IN_REQUEST,
     payload
 });
@@ -12,3 +12,8 @@ export const signInFailure = error => ({
     type: actionTypes.SIGN_IN_REQUEST_FAILURE,
     error
 });
+export const signInStateZeroing = () => ({
+    type: actionTypes.SIGN_IN_STATE_ZEROING
+})
+
+export default signIn;

+ 3 - 1
src/actions/auth/signUp.js

@@ -1,6 +1,6 @@
 import * as actionTypes from './../../constants/auth';
 
-export const signUp = payload => ({
+const signUp = payload => ({
     type: actionTypes.SIGN_UP_REQUEST,
     payload
 });
@@ -12,3 +12,5 @@ export const signUpFailure = error => ({
     type: actionTypes.SIGN_UP_REQUEST_FAILURE,
     error
 });
+
+export default signUp;

+ 10 - 0
src/actions/auth/tokenCheckout.js

@@ -0,0 +1,10 @@
+import * as types from './../../constants/auth';
+
+export const activeToken = payload => ({
+    type: types.ACTIVE_TOKEN,
+    payload
+})
+
+export const inactiveToken = () => ({
+    type: types.INACTIVE_TOKEN
+})

+ 0 - 1
src/actions/user/changeEmail.js

@@ -1,7 +1,6 @@
 import * as actionTypes from './../../constants/user';
 
 export const changeEmailRequest = payload => {
-    console.log('Inside the changeEMAIL action', payload);
     return {
         type: actionTypes.CHANGE_EMAIL_REQUEST,
         payload

+ 0 - 1
src/actions/user/changePassword.js

@@ -1,7 +1,6 @@
 import * as actionTypes from './../../constants/user';
 
 export const changePasswordRequest = payload => {
-    console.log('Inside the changePassword action', payload);
     return {
         type: actionTypes.CHANGE_PASSWORD_REQUEST,
         payload

+ 0 - 1
src/actions/user/changelogin.js

@@ -1,7 +1,6 @@
 import * as actionTypes from './../../constants/user';
 
 export const changeLoginRequest = payload => {
-    console.log('Inside the changeLogin action', payload);
     return {
         type: actionTypes.CHANGE_LOGIN_REQUEST,
         payload

+ 17 - 0
src/actions/user/test/checkTest.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/user';
+
+
+export const checkTestRequest = payload => {
+    return{
+    type: actionTypes.CHECK_TEST_REQUEST,
+    payload
+};
+}
+export const checkTestSuccess = payload => ({
+    type: actionTypes.CHECK_TEST_REQUEST_SUCCESS,
+    payload
+});
+export const checkTestFailure = error => ({
+    type: actionTypes.CHECK_TEST_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/user/test/getTopics.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/user';
+
+
+export const getTopicTestRequest = payload => {
+    return{
+    type: actionTypes.GET_TOPIC_TEST_REQUEST,
+    payload
+};
+}
+export const getTopicTestSuccess = payload => ({
+    type: actionTypes.GET_TOPIC_TEST_REQUEST_SUCCESS,
+    payload
+});
+export const getTopicTestFailure = error => ({
+    type: actionTypes.GET_TOPIC_TEST_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/user/test/nextTest.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/user';
+
+
+export const nextTestRequest = payload => {
+    return{
+    type: actionTypes.NEXT_TEST_REQUEST,
+    payload
+};
+}
+export const nextTestSuccess = payload => ({
+    type: actionTypes.NEXT_TEST_REQUEST_SUCCESS,
+    payload
+});
+export const nextTestFailure = error => ({
+    type: actionTypes.NEXT_TEST_REQUEST_FAILURE,
+    error
+});

+ 17 - 0
src/actions/user/test/testStart.js

@@ -0,0 +1,17 @@
+import * as actionTypes from '../../../constants/user';
+
+
+export const startTestRequest = payload => {
+    return{
+    type: actionTypes.START_TEST_REQUEST,
+    payload
+};
+}
+export const startTestSuccess = payload => ({
+    type: actionTypes.START_TEST_REQUEST_SUCCESS,
+    payload
+});
+export const startTestFailure = error => ({
+    type: actionTypes.START_TEST_REQUEST_FAILURE,
+    error
+});

+ 35 - 0
src/components/admin/CardsCreator/index.js

@@ -0,0 +1,35 @@
+import React from 'react';
+import { Field, reduxForm } from 'redux-form';
+import { connect } from 'react-redux';
+
+class CardCreator extends React.Component {
+    state = {
+        type: null
+    }
+
+    render() {
+        const { formProps } = this.props;
+        console.log('------------ PROPS --------------');
+        console.log(formProps);
+
+        return (
+            <div>
+                <h1>Create Test</h1>
+                <Field name='some' component='select'>
+                    <option value="some value 1">Optional</option>
+                    <option value="some value 2">Multioptional</option>
+                    <option value="some value 3">Open Answer</option>
+                    <option value="some value 4">Conformity</option>
+                </Field>
+            </div>
+        )
+    }
+}
+
+const mapStateToProps = state => ({
+    formProps: state.form
+})
+
+export default connect(mapStateToProps, null)(reduxForm({
+    form: "CardCreator"
+})(CardCreator))

+ 161 - 0
src/components/admin/CreateTest/CreateTopic.js

@@ -0,0 +1,161 @@
+import React from 'react';
+import { Field, reduxForm, formValueSelector } from 'redux-form';
+import formInput from '../../common/formInput';
+import { connect } from 'react-redux';
+import validate from '../../../configs/validate'
+
+class CreateTopic extends React.Component {
+
+    state = {
+        click: false,
+        arrayAnswers: [],
+        array: [],
+        simple: false,
+        click_2: false,
+        click_3: false
+
+    }
+
+    submit = () => {
+        const { actions: { createTopicsRequest }, categoryId, formValues: { name, description } } = this.props;
+        console.log(name, description)
+        createTopicsRequest({
+            name,
+            description,
+            categoryId,
+
+        })
+    }
+    qestionAnswerSubmit = () => {
+        const { simple, array } = this.state
+        const {  topic: { _id }  , actions: { createTestRequest }, formValues: { questions } } = this.props;
+        console.log(questions)
+        createTestRequest({
+            questions,
+            simple,
+            _id,
+            array
+        })
+        this.setState({ arrayAnswers:[] })
+        this.setState({ array:[] })
+
+
+
+
+    }
+
+    handelChange = () => { this.setState((prevState) => ({ simple: !prevState.simple })) }
+
+    handelClick = () => { this.setState((prevState) => ({ click: !prevState.click })) }
+
+    handleClick_3 = () => {
+        this.setState((prevState) => ({ click_2: !prevState.click_2 }))
+        this.setState({ click_3:true })
+        this.setState((prevState) => ({ arrayAnswers: prevState.arrayAnswers.concat(prevState.arrayAnswers.length + 1) }))
+
+    }
+    handelClick_2 =()=>{
+        this.setState((prevState) => ({ click_3: !prevState.click_3 }))
+
+    }
+    formSubmitinput = (event) => {
+        const currentId = this.state.arrayAnswers.length;
+
+        const values = {
+            answer: event[`answers${currentId}`],
+            price: Number(event[`price${currentId}`]),
+            correct: event[`correct${currentId}`] || false
+        }
+        console.log(values)
+        this.setState((prevState) => ({ array: prevState.array.push(values) }, console.log(prevState.array)))
+        this.setState((prevState) => ({ click_2: !prevState.click_2 }))
+
+    }
+
+
+    render() {
+        const { handleSubmit} = this.props;
+        const { simple, price, correct, click, array, arrayAnswers, click_2, click_3 } = this.state;
+        const { handelChange, submit, handelClick, formSubmitinput, qestionAnswerSubmit, handelClick_2, handleClick_3 } = this;
+console.log(this.state)
+        return (
+            <div>
+                <form onSubmit={handleSubmit(qestionAnswerSubmit)}>
+                    <h4 className="text-white font-ci"> Enter topic </h4>
+                    <Field className="bg-mist bg-mist-op text-white mt-3 mb-3 border rounded w-100 " name="name" type="name" placeholder="Create Name Topic" component={formInput} />
+                    <h4 className="text-white font-ci"> Enter description </h4>
+                    <Field className="bg-mist bg-mist-op text-white mt-3 mb-3 border rounded w-100 " name="description" type="textarea" placeholder="Create Descriptions" component={formInput} />
+                    {
+                        !click
+                            ?
+                            <button className= "btn  btn-outline-light bg-stone"
+                                onClick={() => {
+                                    handelClick()
+                                    submit()
+                                }}>
+                                Create questions
+                            </button>
+                            :
+                            <div>
+                                <h4 className="text-white font-ci"> Enter question and set the difficulty level</h4>
+                                <div className="d-flex w-100 ">
+                                    <Field className="bg-stone bg-mist-op text-white mt-3 mb-3 border rounded w-100 " name="questions" type="questions" placeholder="Create Qestions" component={formInput} />
+                                    <Field className="bg-mist bg-mist-op text-white mt-4 pb-1  border rounded w-25 flex-row align-items-end check" name="simple" type="checkbox" checked={simple} onChange={handelChange} component={formInput} />
+                                </div>
+                                {
+                                    click_3
+                                        ?
+
+                                        arrayAnswers.map(el =>
+                                            <div key={el} id={el}>
+                                                <Field className="bg-mist bg-mist-op text-white mt-3 mb-3 border rounded" name={`answers${el}`} type="name" placeholder="Add anwer" ref='ansversInput' component={formInput} />
+                                                <Field className="bg-mist bg-mist-op text-white mt-3 mb-3 border rounded" name={`price${el}`} type="number" value={price} component={formInput} />
+                                                <Field className="bg-mist bg-mist-op text-white mt-3 mb-3 border rounded" name={`correct${el}`} type="checkbox" checked={correct} component={formInput} />
+                                            </div>
+                                        )
+                                        :
+                                null
+
+                                }
+
+                                <React.Fragment>
+                                    {
+                                        click_2
+                                            ?
+                                            <button className= "btn  btn-outline-light bg-stone m-3" type="button" onClick={handleSubmit(formSubmitinput)}>Add answer</button>
+                                            :
+                                            <React.Fragment>
+                                                <button className= "btn  btn-outline-light bg-stone m-3" type="button " onClick={handleClick_3}>Create answers</button>
+                                                <button className= "btn  btn-outline-light bg-stone m-3" onClick ={handelClick_2} >Create Questions</button>
+                                            </React.Fragment>
+                                    }
+
+
+
+                                </React.Fragment>
+
+
+                        
+
+                            </div>
+                    }
+
+                </form>
+            </div>
+        )
+
+    }
+
+}
+
+const selector = formValueSelector('createTopicForm');
+
+const mapStateToProps = state => ({
+
+    formValues: selector(state, 'name', 'description', 'questions', 'simple', 'answer', 'price', 'correct')
+})
+
+export default connect(mapStateToProps, null)(reduxForm({
+    form: "createTopicForm",
+    validate
+})(CreateTopic));

+ 69 - 0
src/components/admin/CreateTest/index.js

@@ -0,0 +1,69 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { getCategoryRequest } from '../../../actions/admin/category/getCategory';
+import CreateTopic from './CreateTopic';
+import { createTopicsRequest } from '../../../actions/admin/test/createTopics';
+import { createTestRequest } from '../../../actions/admin/test/createTest';
+import { myUserRequest } from '../../../actions/admin/meUser'
+
+
+
+
+class CreateTest extends React.Component {
+    state = {
+        categoryId: null
+    }
+
+    componentDidMount() {
+        const { getCategoryRequest, myUserRequest } = this.props;
+        getCategoryRequest()
+    }
+
+    onClick = (event) => {
+        this.setState({ categoryId: event.target.value })
+    }
+
+
+
+
+    render() {
+        const { category: { data }, createTopicsRequest, createTestRequest, topicId: { topic } } = this.props;
+        const { categoryId } = this.state
+        const { onClick } = this;
+
+
+        console.log(topic)
+
+        return (
+            <div className=" padding profile-page  d-flex flex-row font-ci">
+                <div className=" slideDown w-100 m-5 bg-gradient border rounded">
+                    <div className=" m-5 text-center  text-white font-ci font-ci-bold ">
+                        <h4 className="text-white font-ci">Select category for creating tests</h4>
+                        <select class="custom-select bg-mist bg-mist-op text-white mt-3 mb-3" onChange={onClick} value={categoryId}>
+                            <option selected>Open this Category menu</option>
+                            {
+                                data && data.map(mass => <option key={mass._id} value={mass._id}>{mass.name}</option>)
+
+                            }
+                        </select>
+                        <CreateTopic categoryId={categoryId} topic={topic} actions={{ createTopicsRequest, createTestRequest }} ></CreateTopic>
+                    </div>
+                </div>
+            </div>
+
+        )
+    }
+
+}
+
+const
+    mapStateToProps = state => ({
+        myUser: state.myUser,
+        category: state.category,
+        topicId: state.topicId
+    });
+
+const mapDispatchToProps = dispatch => bindActionCreators({ getCategoryRequest, createTopicsRequest, createTestRequest, myUserRequest }, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(CreateTest);

+ 49 - 0
src/components/admin/addDeleteCategory/ChangeCategory.js

@@ -0,0 +1,49 @@
+import React from 'react';
+import { Field, reduxForm } from 'redux-form';
+import formInput from '../../common/formInput'
+import DeleteCategory from './DeleteCategory';
+
+
+
+class ChangeCategory extends React.Component {
+
+    submit = ({ name }) => {
+        const { actions: { changeCategoryRequest }, categorys: { id } } = this.props;
+        changeCategoryRequest({
+            name,
+            id
+        })
+    }
+
+    render() {
+        const { handleSubmit, handlers:{changeCategoryClick, deleteClick},categorys} = this.props;
+        const { submit } = this;
+
+        return (
+
+            <form className="m-2" onSubmin={handleSubmit(submit)}>
+                <Field className="form-control mb-3" name="name" type="name" placeholder="Change Category" component={formInput} />
+                <div className="d-flex">
+                <button className="btn  btn-outline-light bg-stone m-3" type="button" onClick={
+                    function () {
+                        
+                        handleSubmit(submit)();
+                    }
+                }
+                >
+                Сhange
+                </button>
+                <DeleteCategory handlers={{deleteClick}} categorys={categorys}></DeleteCategory>
+                </div>
+            </form >
+
+        )
+    }
+
+}
+
+
+
+export default reduxForm({
+    form: "changeCategoryForm",
+})(ChangeCategory);

+ 33 - 0
src/components/admin/addDeleteCategory/CreateCategoryForm/index.js

@@ -0,0 +1,33 @@
+import React from 'react';
+import { Field, reduxForm } from 'redux-form';
+
+import formInput from '../../..//common/formInput';
+
+class CreateCategoryForm extends React.Component {
+    submit = async ({ name }) => {
+        const { actions: { createCategoryRequest } } = this.props;
+        console.log('---- EXPRECTED PROMISE------', await createCategoryRequest({
+            name
+        }))
+    }
+    render() {
+        const { handleSubmit, handlers: { handelClick } } = this.props;
+        const { submit } = this;
+        return (
+            <form onSubmin={handleSubmit(submit)}>
+                <Field required name="name" type="name" placeholder="Add new Category" component={formInput} />
+                <button className="btn  btn-outline-light bg-stone m-3"
+                    type="button"  onClick={() => {
+                        handleSubmit(submit)();
+                    }
+                    }>
+                    Add
+                </button>
+            </form >
+        )
+    }
+}
+
+export default reduxForm({
+    form: "createCategoryForm"
+})(CreateCategoryForm);

+ 48 - 0
src/components/admin/addDeleteCategory/DeleteCategory.js

@@ -0,0 +1,48 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux'
+import { deleteCategoryRequest } from '../../../actions/admin/category/deleteCategory';
+
+
+
+class DeleteCategory extends React.Component {
+    state ={
+        click:true
+    }
+
+    onClick = () => {
+        const { deleteCategoryRequest, categorys: { id },click } = this.props;
+        console.log(
+        deleteCategoryRequest({
+            id
+        }))
+        this.setState(prevState=>console.log(prevState))
+    }
+
+
+
+    render() {
+        const { onClick } = this;
+        const {handlers:{deleteClick} } = this.props;
+        console.log(deleteClick)
+
+        return (
+            <div>
+                <button className="btn  btn-outline-light bg-stone m-3 right" type="button" onClick={()=>{
+                    deleteClick()
+                    onClick()
+                }
+                }
+                >Delete</button>
+            </div>
+
+        )
+    }
+
+}
+
+
+
+const mapDispatchToProps = dispatch => bindActionCreators({ deleteCategoryRequest }, dispatch);
+
+export default connect(null, mapDispatchToProps)(DeleteCategory);

+ 140 - 0
src/components/admin/addDeleteCategory/GetCategory.js

@@ -0,0 +1,140 @@
+import React from 'react';
+import { CSSTransition, TransitionGroup } from 'react-transition-group';
+import PropagateLoader from 'react-spinners/PropagateLoader';
+
+import CreateCategoryForm from "./CreateCategoryForm";
+import ChangeCategory from "./ChangeCategory";
+import DeleteCategory from './DeleteCategory';
+
+import store from './../../../state';
+
+
+class GetCategory extends React.Component {
+
+    state = {
+        click: false,
+        clicked: false,
+        categorys: { // categorIEs
+            id: null,
+            names: null
+        },
+        chpic: false,
+        massCategory: null,
+    }
+    componentDidMount() {
+        const { category } = this.props;
+        this.setState({ massCategory: category.data })
+    }
+
+    cclics = () => { //cliCKS
+        this.setState((prevState) => ({ click: !prevState.click }));
+
+    }
+    deleteClick = () => {
+        const { massCategory, categorys: { id } } = this.state;
+        for (let key in massCategory) {
+            if (massCategory[key]._id == id) {
+                delete massCategory[key]
+            }
+            else {
+            }
+        }
+        this.setState((prevState) => ({ clicked: !prevState.clicked }))
+    }
+
+    componentWillReceiveProps(nextProps) {
+        const { data, isFlag, actions: { changeCategoryRequest }, changeCategory } = nextProps;
+        const { massCategory } = this.state;
+
+        if (data) {
+            this.setState(prevState => {
+                this.setState({ massCategory: this.state.massCategory.concat(data) });
+                store.dispatch({
+                    type: 'wtfCreate'
+                })
+            })
+        }
+        if (changeCategory.data) {
+            for (const key in massCategory) {
+                if (massCategory[key]._id === changeCategory.data._id) {
+                    this.setState(prevState => {
+                        const categoriesArray = prevState.massCategory.slice();
+                        categoriesArray.splice(key, 1, changeCategory.data);
+
+                        return {
+                            massCategory: categoriesArray
+                        }
+                    })
+                    break;
+                }
+            }
+            store.dispatch({
+                type: 'wtfUpdate'
+            })
+        }
+
+        return true
+    }
+
+    onClicked = ({ mass: { _id, name } }) => {
+        this.setState({ categorys: { id: _id, name: name } })
+        this.setState((prevState) => ({ clicked: !prevState.clicked }))
+    }
+
+    render() {
+        const { actions: { createCategoryRequest, changeCategoryRequest }, data } = this.props;
+        const { category } = this.props;
+        const { handelClick, onClicked, deleteClick, changeCategoryClick } = this;
+        const { click, categorys, newCategory, massCategory, clicked } = this.state;
+        console.log(this.state)
+
+        return (
+            <div>
+            <div className="overflow-hidden padding profile-page  d-flex flex-row font-ci">
+                <div className="slideDown w-100 p-5 bg-gradient border rounded">
+                    <div className=" text-center  text-white font-ci font-ci-bold ">
+                    {
+                        massCategory !== null
+                            ?
+                            massCategory.map(mass =>
+                                <div className="btn " key={mass.id}>
+                                    <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " onClick={onClicked.bind(null, { mass })} type="button" id={mass.id} key={mass.id} >
+                                        {mass.name}
+                                    </button>
+                                </div>
+
+                            )
+                            :
+                            null
+                    }
+                    <div>
+                        {
+                            click
+                                ?
+                                <CreateCategoryForm newCategory={newCategory} actions={{ createCategoryRequest }} handlers={{ handelClick }}></CreateCategoryForm>
+                                :
+                                <button className="btn  btn-outline-light bg-stone m-3" type='button' onClick={this.cclics}>Create Category</button>
+                        }
+                    </div>
+
+                </div>
+                {
+                    clicked
+                        ?
+                        <div>
+                            <ChangeCategory actions={{ changeCategoryRequest }} categorys={categorys} handlers={{ changeCategoryClick,deleteClick }}></ChangeCategory>
+                            {/* <DeleteCategory categorys={categorys} handlers={{  }} ></DeleteCategory> */}
+                        </div>
+                        :
+                        null
+                }
+                </div>
+                </div>
+            </div>
+        )
+    }
+
+}
+
+
+export default GetCategory;

+ 56 - 0
src/components/admin/addDeleteCategory/index.js

@@ -0,0 +1,56 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux'
+import { createCategoryRequest } from '../../../actions/admin/category/createCategory';
+import { changeCategoryRequest } from '../../../actions/admin/category/changeCategory';
+import { getCategoryRequest } from '../../../actions/admin/category/getCategory';
+import PropagateLoader from 'react-spinners/PropagateLoader';
+import GetCategory from './GetCategory'
+
+
+
+class AddDeleteCategory extends React.Component {
+    state = {
+        ckick: false
+    }
+    componentDidMount() {
+        const { getCategoryRequest } = this.props
+        getCategoryRequest()
+    }
+    onClick = () => {
+        this.setState((prevState) => ({ click: !prevState.click }));
+    }
+
+
+
+    render() {
+        const { category, createCategoryRequest, getCategoryRequest, changeCategoryRequest, newCategory: { data, isFlag }, changeCategory } = this.props
+        const { onClick } = this;
+
+        return (
+            <div>
+                {
+                    !category.isFlag
+                        ?
+                        <PropagateLoader />
+                        :
+                        <GetCategory actions={{ getCategoryRequest, createCategoryRequest, changeCategoryRequest }} category={category} data={data} isFlag={isFlag} changeCategory={changeCategory}></GetCategory>
+                }
+            </div>
+
+        )
+    }
+
+}
+
+const
+    mapStateToProps = state => ({
+        signIn: state.signIn,
+        category: state.category,
+        newCategory: state.newCategory,
+        changeCategory: state.changeCategory
+    });
+
+const mapDispatchToProps = dispatch => bindActionCreators({ createCategoryRequest, getCategoryRequest, changeCategoryRequest }, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(AddDeleteCategory);

+ 0 - 25
src/components/admin/deleteUser/DeleteUserForm/index.js

@@ -1,25 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { Field, reduxForm } from 'redux-form';
-
-import formInput from '../../../common/formInput';
-
-class DeleteUserForm extends React.Component {
-
-    render() {
-        return (
-            <form>
-                <Field name="name" type="name" placeholder="Enter login" component={formInput} />
-                <button
-                    type="button" className="link link--btn right"        
-                    >
-                    Search
-                </button>
-            </form >
-        )
-    }
-}
-
-export default reduxForm({
-    form: "deleteUserForm",
-})(DeleteUserForm);

+ 71 - 0
src/components/admin/deleteUser/GetUsers.js

@@ -0,0 +1,71 @@
+import React from 'react';
+
+
+
+
+class GetUser extends React.Component {
+    state = {
+        arrayUsers: []
+    }
+    componentDidMount() {
+        const { user } = this.props;
+        this.setState({ arrayUsers: user })
+
+    }
+    componentWillReceiveProps(nextProps) {
+        const { isFetching, data, deleteUsers, initialValues} = nextProps;
+        const { arrayUsers } = this.state;
+        if (isFetching){
+            for (let key in arrayUsers) {
+                if (arrayUsers[key]._id == data._id) {
+                    this.setState(prevState => {
+                        const newArray = prevState.arrayUsers.slice();
+                        newArray.splice(key, 1, data)
+                        return {
+                            arrayUsers: newArray
+                        }
+                    })
+                    break;
+
+                }
+            }
+        }
+        if(deleteUsers.isFetching){
+            for (let key in arrayUsers) {
+                if (arrayUsers[key]._id ==initialValues._id) {
+                    this.setState(prevState => {
+                        const newArray = prevState.arrayUsers.slice();
+                        newArray.splice(key, 1)
+                        return {
+                            arrayUsers: newArray
+                        }
+                    })
+                    break;
+                }
+
+        }
+        }
+    }
+
+
+        render() {
+            const { handlers: { handelClick } } = this.props;
+            const { arrayUsers } = this.state;
+
+
+            return (
+                <div class="list-group">
+
+                    {arrayUsers && arrayUsers.map(el =>
+                        <button type="button" class="text-center overflow-hidden rounded-pill btn-outline-light btn mb-4 borber bg-rgba border-0  font-ci font-ci-bold " id={el._id} onClick={handelClick.bind(null, { el })}>{el.name}</button>
+                    )}
+                </div>
+
+            )
+        }
+    }
+
+
+
+
+    export default GetUser

+ 62 - 0
src/components/admin/deleteUser/changeUsers.js

@@ -0,0 +1,62 @@
+import React from 'react';
+
+import formInput from '../../common/formInput';
+import { Field, reduxForm } from 'redux-form';
+import validate from '../../../configs/validate'
+
+
+class ChangeUsers extends React.Component {
+
+
+    submit = ({ name, email, newPassword, confirmPassword }) => {
+        const { action: { changeUserRequest }, initialValues: { _id } } = this.props
+        changeUserRequest({
+            name,
+            email,
+            newPassword,
+            confirmPassword,
+            _id
+        })
+    }
+
+    deleteUser=()=>{
+        const {action:{deleteUsersRequest},initialValues: { _id }}=this.props
+        deleteUsersRequest({_id})
+        
+    }
+
+
+
+    render() {
+        const { initialValues, handleSubmit } = this.props;
+        const { submit, deleteUser } = this
+
+        return (
+            <div>
+
+                <form onSubmit={handleSubmit(submit)} className="ml-3 mr-3 mt-3">
+                    <h5 className="font-ci font-ci-bold text-white mb-3">User Name</h5>
+                    <Field name="name" type="name" component={formInput} className="form-control mb-3" />
+                    <h5 className="font-ci font-ci-bold text-white mb-3">Email</h5>
+                    <Field name="email" type="email" component={formInput} className="form-control mb-3"/>
+                    <h5 className="font-ci font-ci-bold text-white mb-3">Password</h5>
+                    <Field name="newPassword" type="password" placeholder="Enter login" component={formInput} className="form-control mb-3"/>
+                    <h5 className="font-ci font-ci-bold text-white mb-3">Confirm Password</h5>
+                    <Field name="confirmPassword" type="password" placeholder="Enter login" component={formInput} className="form-control mb-3"/>
+                    <button className= "btn  btn-outline-light bg-stone">Change</button>
+                    <button type="button" className= "btn  btn-outline-light bg-stone" onClick ={handleSubmit(deleteUser)} >Delete</button>
+                </form >
+            </div>
+
+        )
+    }
+
+}
+
+
+
+export default reduxForm({
+    form: "ChangeUserForm",
+    enableReinitialize: true,
+    validate
+})(ChangeUsers)

+ 54 - 11
src/components/admin/deleteUser/index.js

@@ -1,21 +1,62 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import { bindActionCreators } from 'redux'
-import DeleteUserForm from './DeleteUserForm/index'
+import { getUserRequest } from '../../../actions/admin/user/getUser';
+import { changeUserRequest } from '../../../actions/admin/user/changeUser';
+import { deleteUsersRequest } from '../../../actions/admin/user/deleteUser'
+import ChangeUser from './changeUsers';
+import GetUser from './GetUsers';
+import PropagateLoader from 'react-spinners/PropagateLoader';
 
 
 
-class ProfilePage extends React.Component {
-    
+
+class DeleteUser extends React.Component {
+    state = {
+        initialValues: null,
+        flag: false
+    }
+    componentDidMount() {
+        const { getUserRequest } = this.props;
+        getUserRequest()
+
+    }
+    handelClick = ({ el }) => {
+        this.setState({ initialValues: el });
+        this.setState((prevState) => ({ flag: !prevState.flag }))
+    }
 
     render() {
-       
+        const { handelClick } = this
+        const { users: { user }, changeUserRequest, changeUser: { data, isFetching }, deleteUsers, deleteUsersRequest } = this.props;
+        const { initialValues, flag } = this.state;
+
+
         return (
-            <div>
-                <input type="file"/>
-                <DeleteUserForm></DeleteUserForm>
+            <div className="overflow-hidden profile-page d-flex flex-row font-ci padding ">
+                <div className='slideRight w-25 p-3 bg-gradient border rounded'  >
+                    <h4 class=" text-center  text-white font-ci font-ci-bold">USERS</h4>
+                    <div class="list-group">
+                        {
+                            user !== null
+                                ?
+                                <GetUser data={data} deleteUsers={deleteUsers} initialValues={initialValues} user={user} isFetching={isFetching} handlers={{ handelClick }}></GetUser>
+                                :
+                                <PropagateLoader />
+                        }
+                    </div>
+                </div>
+                <div className='w-75 p-3 bg-gradient ml-3 border rounded slideLeft'  >
+
+                    {
+                        flag
+                            ?
+                            <ChangeUser initialValues={initialValues} action={{ changeUserRequest, deleteUsersRequest }} ></ChangeUser>
+                            :
+                            null
+                    }
+                </div>
             </div>
-            
         )
     }
 
@@ -23,9 +64,11 @@ class ProfilePage extends React.Component {
 
 const
     mapStateToProps = state => ({
-
+        users: state.users,
+        changeUser: state.changeUser,
+        deleteUsers: state.deleteUsers
     });
 
-const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);
+const mapDispatchToProps = dispatch => bindActionCreators({ getUserRequest, changeUserRequest, deleteUsersRequest }, dispatch);
 
-export default connect(mapStateToProps, mapDispatchToProps)(ProfilePage);
+export default connect(mapStateToProps, mapDispatchToProps)(DeleteUser);

+ 106 - 0
src/components/admin/getChangeDeleteTest/GetQuestions.js

@@ -0,0 +1,106 @@
+import React from 'react';
+import { Field, reduxForm } from 'redux-form';
+// import {ChangeQuestion} from './changeQuestions'
+import formInput from '../../common/formInput'
+
+
+
+
+class GetQuestions extends React.Component {
+    state = {
+        id: null,
+        arrayQuestion: [],
+        questionS:{question:null}
+    }
+
+    componentWillMount = () => {
+        const { questions } = this.props;
+        console.log(questions)
+        this.setState({ arrayQuestion: questions })
+    }
+    changeQuestion = (event) => {
+        this.setState({questionS:{question:event.target.value}})
+    }
+  
+    submit =(payload)=>{
+console.log(payload)
+    }
+
+    deleteClick = ({ el: { _id } }) => {
+        this.setState({ id: _id })
+        const { actions: { deleteQuestionRequest } } = this.props;
+        deleteQuestionRequest({ _id })
+    }
+
+    componentWillUpdate(nextState, nextProps) {
+        const { deleteQuestion: { isFetching } } = nextState;
+        const { arrayQuestion, id } = nextProps;
+        if (!isFetching) {
+            for (let key in arrayQuestion) {
+                if (arrayQuestion[key]._id == id) {
+                    this.setState(prevState => {
+                        const array = prevState.arrayQuestion.slice()
+                        array.splice(key, 1)
+                        return {
+                            arrayQuestion: array
+                        }
+                    })
+                    break;
+                }
+            }
+
+        }
+    }
+
+    render() {
+        const { handleClick, deleteClick, changeQuestion } = this;
+        const{handleSubmit} =this.props
+        const { questionS:{question}, arrayQuestion } = this.state;
+        console.log(this.state)
+
+        return (
+            <div className=" profile-page p-4 d-flex flex-row font-ci">
+                <div className="container w-100 h-auto  bg-stone  bg-mist-border">
+                    <form onSubmit ={handleSubmit(this.submit)}>
+                        <Field name="name" type="name" component={formInput} />
+
+                        <select class="custom-select bg-mist bg-mist-op text-white mt-3 mb-3" onChange={changeQuestion} value={question} >
+                            <option selected>Open this Category menu</option>
+                            {
+                                arrayQuestion && arrayQuestion.map(el =>
+                                    <React.Fragment>
+                                        <option key={el._id} value={el.question}>{el.question}</option>
+                                        <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " type="button"  >
+                                            P
+                                    </button>
+                                        <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " onClick={deleteClick.bind(null, { el })} type="button"  >
+                                            X
+                                    </button>
+                                    </React.Fragment>
+                                )
+                            }
+                        </select>
+                        {
+                            question == null
+                                ?
+                                null
+                                :
+
+                        <Field name="question" type="question" component={formInput} />
+
+                        }
+
+                        <button>ssss</button>
+                    </form>
+                </div>
+            </div >
+        )
+    }
+
+}
+
+
+export default reduxForm({
+    form: "changeTestForm",
+    enableReinitialize: true
+})(GetQuestions)

+ 39 - 0
src/components/admin/getChangeDeleteTest/GetTest.js

@@ -0,0 +1,39 @@
+import React from 'react';
+
+
+
+class GetTest extends React.Component {
+    state = {
+        arrayTopic: [],
+        arrayCategory: []
+    }
+    componentWillMount() {
+        const { data } = this.props;
+        this.setState({ arrayCategory: data })
+    }
+
+    render() {
+
+        const { handlers:{getQuestionClick} } = this.props;
+        const { arrayTopic, topicElement, arrayCategory } = this.state
+
+        return (
+                <div className=' slideRight w-45 p-3 bg-gradient border rounded'  >
+                    {
+                        arrayCategory.map(el =>
+
+                            <div className="btn ">
+                                <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " onClick={getQuestionClick.bind(null, { el })} type="button" id={el._id} key={el._id} >
+                                    {el.name}
+                                </button>
+                            </div>
+                        )
+                    }
+                </div>
+        )
+    }
+
+}
+
+
+export default GetTest;

+ 76 - 0
src/components/admin/getChangeDeleteTest/GetTopic.js

@@ -0,0 +1,76 @@
+import React from 'react';
+
+
+
+class GetTest extends React.Component {
+    state = {
+        arrayTopic: {
+            categotyId: null,
+            topic: null
+        }
+    }
+    componentWillMount() {
+        const { topic: { payload, topics } } = this.props;
+        this.setState({ arrayTopic: { categogyId: payload, topic: topics } })
+    }
+
+
+    componentWillUpdate(nextState, nextProps) {
+        const { newTopic, deleteTopic, topicId } = nextState;
+        const { arrayTopic: { topic } } = nextProps;
+        if (newTopic.data !== null) {
+            for (let key in topic) {
+                if (topic[key]._id == newTopic.data._id) {
+                    this.setState(prevState => {
+                        const array = prevState.arrayTopic.topic.slice()
+                        array.splice(key, 1, newTopic.data)
+                        return {
+                            arrayTopic: array
+                        }
+                    })
+                    break;
+                }
+            }
+
+        }
+        if (!deleteTopic.isFetching) {
+            for (let key in topic) {
+                if (topic[key]._id == topicId) {
+                    this.setState(prevState => {
+                        const array = prevState.arrayTopic.topic.slice()
+                        array.splice(key, 1)
+                        return {
+                            arrayTopic: array
+                        }
+                    })
+                    break;
+                }
+            }
+        }
+    }
+
+
+    render() {
+        const { handlers: { openEditModal } } = this.props;
+        const { arrayTopic: { topic } } = this.state
+
+        return (
+
+            <div className='slideLeft w-45 p-3 bg-gradient border rounded'  >
+                {
+                    topic && topic.map(el =>
+                        <div className="btn ">
+                            <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " onClick={openEditModal.bind(null, { el })} type="button" id={el._id} key={el._id} >
+                                {el.name}
+                            </button>
+                        </div>)
+                }
+            </div>
+
+        )
+    }
+
+}
+
+
+export default GetTest;

+ 162 - 0
src/components/admin/getChangeDeleteTest/OpenModal.js

@@ -0,0 +1,162 @@
+import React, { Component } from "react";
+import { Modal } from "react-bootstrap";
+
+import { Field, reduxForm } from 'redux-form';
+import formInput from '../../common/formInput'
+
+class EditModal extends React.Component {
+    state = {
+        clicked: false,
+        answers_id: null,
+        answers: [],
+        clicks: false,
+        questionId: null
+    }
+
+    submit = (payload) => {
+        const { name, categoryId, description, question, simple, topicId } = payload
+        const { answers, questionId } = this.state
+        const { actions: { changeTestRequest } } = this.props;
+        changeTestRequest({ questionId, name, categoryId, description, question, simple, topicId, answers })
+
+    }
+
+    changeQuestion = (event) => {
+        const { value } = event.target
+        const { actions: { getAnswersRequest } } = this.props;
+        getAnswersRequest({ value })
+        this.setState((prevState) => ({ clicked: !prevState.clicked, }))
+        this.setState({ questionId: value })
+
+    }
+
+    answersChange = (event) => {
+        const { value } = event.target
+        this.setState({ clicks: true, answers_id: value })
+    }
+
+    changeAnswers = (payload) => {
+        const { answers_id } = this.state
+        const { answer, price, correct } = payload
+        const value = {
+            _id: answers_id,
+            answer: answer,
+            price: +price,
+            correct: correct
+        }
+        this.setState((prevState) => ({ answers: prevState.answers.concat(value) }))
+        this.setState({ clicks: false })
+
+    }
+
+    deleteAnswer = () => {
+        const { answers_id } = this.state
+        const { actions: { deleteAnswerRequest } } = this.props;
+        deleteAnswerRequest({ answers_id })
+
+    }
+
+    deleteQuestions = () => {
+        const { questionId } = this.state
+        const { actions: { deleteQuestionRequest } } = this.props;
+        deleteQuestionRequest({ questionId })
+    }
+
+    deleteTopic = (payload) => {
+        const { topicId } = payload
+        const { actions: { deleteTopicRequest } } = this.props;
+        deleteTopicRequest({ topicId })
+
+    }
+
+    render() {
+        const { visible, handleClose: { closeModal }, inputData, editLoads, initialValues, arrayQuestions: { questions, _id }, answers, handlers: { handelClick }, click, handleSubmit } = this.props;
+        const { submit, answersChange, changeAnswers, deleteAnswer, deleteQuestions, deleteTopic } = this
+        const { clicked, clicks } = this.state
+        return (
+            <Modal show={visible} onHide={closeModal} aria-labelledby="contained-modal-title-vcenter" >
+                < Modal.Header closeButton >
+                    < Modal.Title className="text-center  text-white font-ci font-ci-bold" >Changes Test  </ Modal.Title >
+                </ Modal.Header >
+                < Modal.Body >
+                    <h4 class="text-center  text-white font-ci font-ci-bold">Topic</h4>
+                    <form onSubmit={handleSubmit(submit)}>
+                        <Field name="name" type="name" component={formInput} className="form-control mb-3" />
+                        <h4 class="text-center  text-white font-ci font-ci-bold">Description</h4>
+                        <Field name="description" type="description" component={formInput} className="form-control mb-3" />
+
+                        <h4 class="text-center  text-white font-ci font-ci-bold">Questions</h4>
+                        <select class="custom-select bg-mist bg-mist-op text-white mt-3 mb-3" onChange={this.changeQuestion} >
+                            <option selected>Question</option>
+                            {questions !== null
+                                ?
+                                questions.map(el =>
+                                    <option key={el._id} name={el._id} value={el._id}>{el.question}</option>
+
+
+                                )
+                                : null
+                            }
+                        </select>
+                        {
+                            clicked
+                                ?
+                                <React.Fragment>
+                                    <h4 class="text-center  text-white font-ci font-ci-bold">Questions and Simple</h4>
+                                    <Field name="question" type="question" component={formInput} />
+                                    <Field name="simple" type="checkbox" component={formInput} />
+                                    <button className="btn  btn-outline-light bg-stone m-3" onClick={handleSubmit(deleteQuestions)} >Delete Question</button >
+                                </React.Fragment>
+                                : null
+                        }
+                        <ul class="list-group list-group-flush">
+                            {
+                                clicked
+                                    ?
+                                    <select class="custom-select bg-mist bg-mist-op text-white mt-3 mb-3" onChange={answersChange} >
+                                        <option selected>Aswers</option>
+                                        {answers !== null
+                                            ?
+                                            answers.map(el =>
+                                                <option key={el._id} name={el._id} value={el._id}>{el.answer}</option>
+
+
+                                            )
+                                            : null
+                                        }
+                                    </select>
+                                    : null
+                            }
+                            {
+                                clicks
+                                    ?
+                                    <React.Fragment>
+                                        <Field name="answer" type="answer" component={formInput} className="form-control mb-3" />
+                                        <Field name="correct" type="checkbox" component={formInput} />
+                                        <Field name="price" type="number" component={formInput} />
+                                        <div>
+                                            <button className="btn  btn-outline-light bg-stone m-3" onClick={handleSubmit(deleteAnswer)}>Delete Answer</button>
+                                            <button className="btn  btn-outline-light bg-stone m-3" onClick={handleSubmit(changeAnswers)} >Change Answers</button >
+                                        </div>
+                                    </React.Fragment>
+                                    : null
+                            }
+
+                        </ul>
+                    </form>
+                </ Modal.Body >
+                < Modal.Footer>
+                    <React.Fragment>
+                        <button className="btn  btn-outline-light bg-stone m-3" onClick={handleSubmit(deleteTopic)}>Delete Answer</button>
+                        <button type="submit" className="btn  btn-outline-light bg-stone m-3" onClick={handleSubmit(submit)} >Change</button>
+                    </React.Fragment>
+                </ Modal.Footer >
+            </Modal>
+        );
+    }
+}
+
+export default reduxForm({
+    form: "editModal",
+    enableReinitialize: true
+})(EditModal)

+ 112 - 0
src/components/admin/getChangeDeleteTest/changeQuestions.js

@@ -0,0 +1,112 @@
+import React from 'react';
+import { Field, reduxForm } from 'redux-form';
+import formInput from '../../common/formInput';
+
+
+
+
+class GetQuestions extends React.Component {
+    state = {
+        id: null,
+        arrayQuestion: [],
+        question:{
+        names: null
+        }
+    }
+
+    componentWillMount = () => {
+        const { questions } = this.props;
+        console.log(questions)
+        this.setState({ arrayQuestion: questions })
+    }
+
+    changeQuestion = (event) => {
+        this.setState({ question:{names: event.target.value} })
+    }
+
+    // handleClick =({el:{_id}})=>{
+    //     const {actions:{getQestionsRequest}} =this.props
+    //     console.log(_id)
+    //     getQestionsRequest({_id})
+
+    // }
+
+    deleteClick = ({ el: { _id } }) => {
+        this.setState({ id: _id })
+        const { actions: { deleteQuestionRequest } } = this.props;
+        deleteQuestionRequest({ _id })
+    }
+
+    componentWillUpdate(nextState, nextProps) {
+        const { deleteQuestion: { isFetching } } = nextState;
+        const { arrayQuestion, id } = nextProps;
+        console.log(isFetching, "nextState---------", nextState, "nextProps_________", nextProps)
+        if (!isFetching) {
+            for (let key in arrayQuestion) {
+                if (arrayQuestion[key]._id == id) {
+                    this.setState(prevState => {
+                        console.log("-------TRUE--------")
+                        const array = prevState.arrayQuestion.slice()
+                        array.splice(key, 1)
+                        return {
+                            arrayQuestion: array
+                        }
+                    })
+                    break;
+                }
+            }
+
+        }
+    }
+
+    render() {
+        const { handleClick, deleteClick, changeQuestion } = this;
+        const{question}=this.state
+        const { arrayQuestion } = this.state;
+        console.log(this.state)
+
+        return (
+            <div className=" profile-page p-4 d-flex flex-row font-ci">
+                <div className="container w-100 h-auto  bg-stone  bg-mist-border">
+                    <form >
+                        <Field name="name" type="name" component={formInput} />
+                        {
+                            question.names==null
+                        ?
+                        <select class="custom-select bg-mist bg-mist-op text-white mt-3 mb-3" onChange={changeQuestion} value={question} >
+                            <option selected>Open this Category menu</option>
+                            {
+                                arrayQuestion && arrayQuestion.map(el =>
+                                    <React.Fragment>
+                                        <option key={el._id} value={el.question}>{el.question}</option>
+                                        <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " type="button"  >
+                                            P
+                                    </button>
+                                        <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " onClick={deleteClick.bind(null, { el })} type="button"  >
+                                            X
+                                    </button>
+                                    </React.Fragment>
+                                )
+                            }
+                        </select>
+                        :
+                        <Field name="name" type="name" initialize ={this.state.question.names}component={formInput} />
+                        
+                        
+                        }
+                    </form>
+                </div>
+            </div >
+        )
+    }
+
+}
+
+
+export default reduxForm({
+    form: "changeTestForm",
+    enableReinitialize: true
+})(GetQuestions)
+
+
+

+ 125 - 0
src/components/admin/getChangeDeleteTest/index.js

@@ -0,0 +1,125 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { getTopicRequest } from '../../../actions/admin/changeTest/getTopic';
+import { getQuestionsRequest } from '../../../actions/admin/changeTest/getQuestions';
+import { deleteTopicRequest } from '../../../actions/admin/changeTest/deleteTopic';
+import { deleteQuestionRequest } from '../../../actions/admin/changeTest/deleteQuestion';
+import { getCategoryRequest } from '../../../actions/admin/category/getCategory';
+import { getAnswersRequest } from '../../../actions/admin/changeTest/getAnswers';
+import { changeTestRequest } from '../../../actions/admin/changeTest/changeTest';
+import { deleteAnswerRequest } from '../../../actions/admin/changeTest/deleteAnswer';
+
+
+
+
+import GetTest from './GetTest';
+import GetTopic from './GetTopic';
+import EditModal from './OpenModal';
+
+
+
+
+class ChangeTest extends React.Component {
+    state = {
+
+        categoryId: null,
+        name: null,
+        topicId: null,
+        description: null,
+        answers: [],
+        answer: null,
+        correct: null,
+        price: null,
+        simple: null,
+        openModal: false,
+        toggleModal: false,
+        click: false
+
+    }
+
+    openEditModal = ({ el: { _id, description, name } }) => {
+        const { getQuestionsRequest } = this.props
+        getQuestionsRequest({ _id })
+        this.setState(({ openModal: true, toggleModal: false, topicId: _id, description: description, name: name }))
+    }
+
+    closeModal = () => { this.setState((prevState) => ({ openModal: !prevState.openModal })) }
+
+    getQuestionClick = ({ el: { _id } }) => {
+        const { getTopicRequest } = this.props
+        getTopicRequest({ _id })
+        this.setState({ categoryId: _id })
+    }
+
+    handelClick = ({ el: { answer, correct, price, _id } }) => {
+        this.setState({ answer: answer, corrent: correct, price: price });
+        this.setState((prevState) => ({ click: !prevState.click }))
+    }
+
+    componentWillMount = () => {
+        const { getCategoryRequest } = this.props
+        getCategoryRequest()
+    }
+    componentWillReceiveProps(nextProps) {
+        const { arrayAnswers: { answers } } = nextProps;
+        if (answers !== null) {
+            this.setState({ answers: answers })
+        }
+    }
+
+
+    render() {
+        const { getQuestionClick, openEditModal, closeModal, handelClick, state } = this;
+        const { openModal, questionId, name, topicId, description, answers, click } = this.state
+        const initialValues = {
+            ...state
+        }
+        const { category: { data, isFlag }, deleteTopic, topic, arrayQuestions, getAnswersRequest, deleteTopicRequest, arrayAnswers, changeTestRequest, newTopic, deleteAnswerRequest, deleteQuestionRequest } = this.props
+
+        return (
+            <div className=" profile-page  font-ci padding ">
+
+                {
+                    !isFlag
+                        ?
+                        null
+                        :
+                        <React.Fragment>
+                            <GetTest data={data} handlers={{ getQuestionClick }}></GetTest>
+                            {
+                                topic.isFlag
+                                    ?
+                                    <React.Fragment>
+                                        <GetTopic handlers={{ openEditModal }} topicId={topicId} deleteTopic={deleteTopic} newTopic={newTopic} topic={topic}></GetTopic>
+                                        <EditModal className="bg-mist" visible={openModal} handlers={{ handelClick }} click={click} answers={answers} actions={{ getAnswersRequest, deleteTopicRequest, deleteAnswerRequest, deleteQuestionRequest, changeTestRequest }} arrayQuestions={arrayQuestions} initialValues={initialValues}
+                                            handleClose={{ closeModal }}></EditModal>
+                                    </React.Fragment>
+                                    :
+                                    null
+
+                            }
+
+                        </React.Fragment>
+                }
+            </div>
+        )
+    }
+
+}
+
+const
+    mapStateToProps = state => ({
+        topic: state.topic,
+        arrayQuestions: state.arrayQuestions,
+        deleteTopic: state.deleteTopic,
+        deleteQuestion: state.deleteQuestion,
+        category: state.category,
+        arrayAnswers: state.arrayAnswers,
+        newTopic: state.newTopic
+
+    });
+
+const mapDispatchToProps = dispatch => bindActionCreators({ getCategoryRequest, deleteAnswerRequest, getTopicRequest, changeTestRequest, getQuestionsRequest, deleteTopicRequest, deleteQuestionRequest, getAnswersRequest }, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(ChangeTest);

+ 3 - 2
src/components/common/formInput.js

@@ -1,8 +1,9 @@
 import React, { Fragment } from 'react';
 
-export default ({ input, className, placeholder, type, meta: { touched, error } }) => (
+export default ({ input, className, placeholder, required, type, meta: { touched, error } }) => (
     <Fragment>
-        <input className={className} placeholder={placeholder} type={type} {...input} />
+        <input className={className} placeholder={placeholder} type={type} {...input}/>
         {touched && (error && <p className="text-af pt-2 text-uppercase">⚠ {error}</p>)}
+        {required ? <p className="text-af pt-2 text-uppercase">⚠ Reqired</p> : null}
     </Fragment>
 )

+ 33 - 30
src/components/common/protectedRoute.js

@@ -1,47 +1,50 @@
 import React from 'react';
 import { Route, Redirect } from 'react-router-dom';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import { inactiveToken, activeToken } from './../../actions/auth/tokenCheckout'
+import decode from 'jwt-decode';
+
 import * as routes from './../../constants/routes';
+import storageKey from './../../utils/storageKey';
 
-export default ({ component: Component, user, tokenAuth, access, ...rest }) => (
+const protectedRoute = ({ component: Component, activeToken, inactiveToken, access, ...rest }) => (
     <Route
         {...rest}
         render={props => {
-            {/* let checkedData;
-
-            if (data) {
-                checkedData = data;
-            }
-            else {
-                const storagedUser = JSON.parse(localStorage.getItem(token));
-                if (storagedUser) {
-                    checkedData = storagedUser;
-                    tokenAuth(storagedUser);
-                }
-                else {
-                    checkedData = null;
+            try {
+                const user = decode(localStorage.getItem(storageKey));
+                activeToken(user.role);
+                {/* if (user.exp < Date.now()*1000) {
+                    throw new Error('Date expired');
+                } */}
+
+                if (access === 'admin-only' && !user.role) {
+                    throw new Error('Permission Denied')
                 }
-            } */}
-            const checkedData = user && user.data ? user.data : null;
 
-            console.log('\n\nHere goes the route:', '\nUser', user, '\n\n\n')
-
-            if (access === 'public') {
                 return <Component {...props} />
             }
+            catch ({ message }) {
+                if (message === 'Permission Denied') {
+                    return <div>Permission denied</div>
+                }
 
-            if ((access === 'user-only' || access === 'admin-only') && !checkedData) {
-                return <Redirect to={routes.SIGN_IN} />
-            }
+                inactiveToken();
 
-            if (access === 'user-only' && checkedData) {
-                return <Component {...props} />
-            }
+                if (access === 'public') {
+                    return <Component {...props} />
+                }
 
-            if (access === 'admin-only' && checkedData.role) {
-                return <Component {...props} />
+                return <Redirect to={routes.SIGN_IN} />
             }
-
-            return null // permission denied
         }}
     />
-)
+)
+
+const mapDispatchToProps = dispatch => bindActionCreators({
+    activeToken,
+    inactiveToken
+}, dispatch);
+
+export default connect(null, mapDispatchToProps)(protectedRoute);

+ 89 - 28
src/components/public/Header.js

@@ -1,59 +1,120 @@
-import React from 'react';
-import { Link } from "react-router-dom";
-import * as routes from '../../constants/routes'
+import React, { PureComponent } from 'react';
+import { Link, withRouter, Redirect } from "react-router-dom";
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import axios from 'axios';
+
+import storageKey from './../../utils/storageKey';
+import { signInStateZeroing } from './../../actions/auth/signIn';
+import { LOG_OUT_URL } from './../../constants/auth';
+
+import * as routes from '../../constants/routes';
+
+//pure component + make storage check an action -> connect router
+class Header extends PureComponent {
+    handleLogOut = () => {
+        console.log(this.props)
+        const { history, zeroState } = this.props;
+
+        axios.get(LOG_OUT_URL, {})
+            .then(() => {
+                console.log('request was succesfull')
+                localStorage.removeItem(storageKey);
+                zeroState();
+                history.push('/sign-in');
+            })
+            .catch(e => alert('Sorry, something bad happened, try log out later \n' + e.message));
+    }
 
-export default class Header extends React.Component {
     render() {
+        const { role } = this.props;
+
         return (
-            <nav class="navbar navbar-expand-lg navbar-dark bg-dark p-3">
-                <a class="navbar-brand" href="#">Test.io</a>
+
+            <nav class="navbar navbar-expand-lg navbar-expand-lg bg-gradient1 p-4 position-absolute w-100 ">
+                <Link to={routes.LANDING} class="navbar-brand font-label text-af" href="#">Test.io</Link>
                 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
-                    <span class="navbar-toggler-icon"></span>
+                    <span class="navbar-toggler-icon" />
                 </button>
 
                 <div class="collapse navbar-collapse" id="navbarSupportedContent">
                     <ul class="navbar-nav mr-auto">
                         <li class="nav-item active">
-                            <Link onClick={this.handleClick} class="nav-link font-ci font-ci-bold" to={routes.HOME}>Home <span class="sr-only">(current)</span></Link>
+                            <Link onClick={this.handleClick} class="nav-link text-shadow font-ci font-ci-bold" to={routes.HOME}>Home <span class="sr-only">(current)</span></Link>
                         </li>
                         <li class="nav-item">
-                            <Link onClick={this.handleClick} class="nav-link font-ci font-ci-bold" to={routes.PROFILE}>Profile</Link>
+                            <Link onClick={this.handleClick} class="nav-link text-shadow font-ci font-ci-bold" to={routes.PROFILE}>Profile</Link>
                         </li>
                         <li class="nav-item">
-                            <Link onClick={this.handleClick} class="nav-link font-ci font-ci-bold " to={routes.TESTS}>Tests</Link>
+                            <Link onClick={this.handleClick} class="nav-link text-shadow font-ci font-ci-bold " to={routes.TESTS}>Tests</Link>
                         </li>
                         <li class="nav-item">
-                            <Link onClick={this.handleClick} class="nav-link font-ci font-ci-bold " to={routes.CATEGORIES}>Catigories</Link>
+                            <Link onClick={this.handleClick} class="nav-link text-shadow font-ci font-ci-bold " to={routes.CATEGORIES}>Catigories</Link>
+
                         </li>
-                        {/* TODO: admin-only ! */}
+                        {role
+                                ?
                         <li class="nav-item dropdown">
-                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                                Menu Admina
-                                    </a>
+
+                            <a class="nav-link text-shadow font-ci font-ci-bold" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                                Menu Admin
+                                </a>
                             <div class="dropdown-menu" aria-labelledby="navbarDropdown">
-                                <Link onClick={this.handleClick} class="nav-link font-ci font-ci-bold " to={routes.DELETE_USER}>Delete</Link>
-                                <a class="dropdown-item" href="#">Action</a>
-                                <a class="dropdown-item" href="#">Another action</a>
-                                <div class="dropdown-divider"></div>
-                                <a class="dropdown-item" href="#">Something else here</a>
+                            <Link to={routes.DELETE_USER} className="nav-link text-secondary text-shadow font-ci">Delete User</Link>
+                                <Link to={routes.CREATE_TEST} className="nav-link text-secondary text-shadow font-ci">Create Test</Link>
+                                <Link to={routes.CHANGE_TEST} className="nav-link text-secondary text-shadow font-ci">Change Test</Link>
+                                
+                                <Link to={routes.CREATE_CATEGORY} className="nav-link text-secondary text-shadow font-ci">Create Category</Link>
+
+                                
                             </div>
                         </li>
-
+                                
+                                :
+                                null
+                        }
                     </ul>
-                    <form class="form-inline my-2 my-lg-0">
-                        <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" />
-                        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
-                    </form>
-                    <div className="pl-2">
+                    
+                    <div className="controls">
+                        {
+                            role !== null
+                                ?
+                                <button onClick={this.handleLogOut} className="btn  btn-outline-light ml-2 bg-stone">Log Out</button>
+                                :
+                                <React.Fragment>
+                                    <Link to={routes.SIGN_IN}>
+                                        <button className="btn  btn-outline-light ml-2 bg-stone">Sign In</button>
+                                    </Link>
+                                    <Link to={routes.SIGN_UP}>
+                                        <button className="btn  btn-outline-light ml-2 bg-stone">Sign Up</button>
+                                    </Link>
+                                </React.Fragment>
+                        }
+{/* =======
+
+                    <div className="">
                         <Link to={routes.SIGN_IN}>
-                            <button className="btn btn-outline-primary">Sign In</button>
+                            <button className="btn  btn-outline-light bg-stone">Sign In</button>
                         </Link>
                         <Link to={routes.SIGN_UP}>
-                            <button className="btn btn-outline-primary ml-2">Sign Up</button>
+                            <button className="btn  btn-outline-light ml-2 bg-stone">Sign Up</button>
+
                         </Link>
+                        <button onClick={this.handleLogOut} className="btn btn-outline-primary">Log Out</button>
+>>>>>>> new_Sveta */}
                     </div>
                 </div>
+            
             </nav>
         )
     }
 }
+
+const mapStateToProps = state => ({
+    role: state.tokenCheckout.role,
+});
+const mapDispatchToProps = dispatch => bindActionCreators({
+    zeroState: signInStateZeroing
+}, dispatch)
+
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header));

+ 0 - 42
src/components/public/SignIn/index.js

@@ -1,42 +0,0 @@
-import React from 'react';
-import Form from './Form';
-import { bindActionCreators } from 'redux';
-import { connect } from 'react-redux';
-import { Redirect } from 'react-router-dom'
-
-import Spinner from './../../common/spinner';
-import { signIn } from './../../../actions/auth/signIn';
-
-const SignIn = ({ signIn, user }) => {
-    const someShit = user.isFetching
-        ?
-        <Spinner />
-        : user.data
-            ?
-            <Redirect to='/' />
-            : user.error
-                ?
-                (
-                    <React.Fragment>
-                        <Form signIn={signIn} requestError={user.error} />
-                    </React.Fragment>
-
-                )
-                :
-                <Form signIn={signIn} />
-
-    return someShit
-
-}
-
-
-
-const mapStateToProps = state => ({
-    user: state.signIn
-});
-const mapDispatchToProps = dispatch => bindActionCreators({
-    signIn
-}, dispatch);
-
-
-export default connect(mapStateToProps, mapDispatchToProps)(SignIn);

+ 32 - 0
src/components/public/landing.js

@@ -0,0 +1,32 @@
+import React from 'react';
+
+const landing = () => (
+    <div id="carouselExampleIndicators" className="carousel slide" data-ride="carousel">
+        <ol className="carousel-indicators">
+            <li data-target="#carouselExampleIndicators" data-slide-to="0" className="active"></li>
+            <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
+            <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
+        </ol>
+        <div className="carousel-inner">
+            <div className="carousel-item active">
+                <img src="https://images.theconversation.com/files/17962/original/jt558trs-1353642967.jpg?ixlib=rb-1.1.0&rect=23%2C5%2C3831%2C2573&q=45&auto=format&w=926&fit=clip" className="d-block w-100 slider-image" alt="..." />
+            </div>
+            <div className="carousel-item">
+                <img src="http://dyslexiahelp.umich.edu/sites/default/files/upload/testing%20instuments%20dreamstimesmall_5908127.jpg" className="d-block w-100 slider-image" alt="..." />
+            </div>
+            <div className="carousel-item">
+                <img src="https://amp.businessinsider.com/images/55a7e74f2acae716008b7469-750-562.jpg" className="d-block w-100 slider-image" alt="..." />
+            </div>
+        </div>
+        <a className="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
+            <span className="carousel-control-prev-icon" aria-hidden="true"></span>
+            <span className="sr-only">Previous</span>
+        </a>
+        <a className="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
+            <span className="carousel-control-next-icon" aria-hidden="true"></span>
+            <span className="sr-only">Next</span>
+        </a>
+    </div>
+)
+
+export default landing;

+ 7 - 5
src/components/public/SignIn/Form/index.js

@@ -1,6 +1,5 @@
 import React from 'react';
 import { reduxForm, Field } from 'redux-form';
-
 import validate from './validate';
 import formInput from './../../../common/formInput';
 
@@ -17,10 +16,12 @@ class Form extends React.Component {
     render() {
         const { handleSubmit, requestError, invalid } = this.props;
 
+
         return (
-            <div className="container">
+            <div className="container p-5">
                 <div className="row">
-                    <div className="col-md-8 col-10 col-lg-6 m-auto p-4 border rounded">
+                    <div className="col-md-8 col-4 col-lg-5 m-auto p-4  border rounded">
+                        <h1 className = "position-absolute pl-5 pr-5 sinein bg-white text-stone">SignIn</h1>
 
                         <form className="text-center" onSubmit={handleSubmit(this.submit)}>
                             {
@@ -32,12 +33,12 @@ class Form extends React.Component {
                             }
 
                             <div className="form-group">
-                                <label className="text-uppercase">Email address</label>
+                                <label className="text-uppercase font-ci">Email address</label>
                                 <Field type="email" name='email' className="form-control" placeholder="name@example.com" component={formInput} />
                             </div>
 
                             <div className="form-group">
-                                <label className="text-uppercase">Password</label>
+                                <label className="text-uppercase font-ci">Password</label>
                                 <Field type="password" name='password' className="form-control" component={formInput} />
                             </div>
 
@@ -45,6 +46,7 @@ class Form extends React.Component {
                         </form>
                     </div>
                 </div>
+                
             </div>
         )
     }

src/components/public/SignIn/Form/validate.js → src/components/public/signIn/Form/validate.js


+ 51 - 0
src/components/public/signIn/index.js

@@ -0,0 +1,51 @@
+import React from 'react';
+import Form from './Form';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import { Redirect } from 'react-router-dom'
+
+import PropagateLoader from 'react-spinners/PropagateLoader';
+
+import Spinner from './../../common/spinner';
+import signIn from './../../../actions/auth/signIn';
+
+
+
+const SignIn = ({ signIn, user }) => {
+// <<<<<<< HEAD
+    return (
+        user.isFetching
+// =======
+//     const someShit = user.isFetching
+//         ?
+//          <PropagateLoader/>
+//         : user.data
+// >>>>>>> new_Sveta
+            ?
+            <Spinner />
+            : user.data
+                ?
+                <Redirect to='/' />
+                : user.error
+                    ?
+                    (
+                        <React.Fragment>
+                            <Form signIn={signIn} requestError={user.error} />
+                        </React.Fragment>
+                    )
+                    :
+                    <Form signIn={signIn} />
+    )
+}
+
+
+
+const mapStateToProps = state => ({
+    user: state.signIn,
+});
+const mapDispatchToProps = dispatch => bindActionCreators({
+    signIn
+}, dispatch);
+
+
+export default connect(mapStateToProps, mapDispatchToProps)(SignIn);

src/components/public/SignUp/Form/index.js → src/components/public/signUp/Form/index.js


src/components/public/SignUp/Form/validate.js → src/components/public/signUp/Form/validate.js


+ 1 - 1
src/components/public/SignUp/index.js

@@ -5,7 +5,7 @@ import { connect } from 'react-redux';
 import { Redirect } from 'react-router-dom';
 
 import Spinner from './../../common/spinner';
-import { signUp } from './../../../actions/auth/signUp';
+import signUp from './../../../actions/auth/signUp';
 
 const SignUp = ({ status, signUp }) => (
     status.isFetching

+ 63 - 0
src/components/user/Categoty.js

@@ -0,0 +1,63 @@
+import React from 'react';
+import { Link } from "react-router-dom";
+
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux'
+import { getCategoryRequest } from '../../actions/admin/category/getCategory';
+import * as routes from '../../constants/routes';
+
+
+
+
+class AddDeleteCategory extends React.Component {
+    state = {
+        ckick: false
+    }
+    componentDidMount() {
+        const { getCategoryRequest } = this.props
+        getCategoryRequest()
+    }
+
+
+
+
+    render() {
+        const { category:{data}  } = this.props
+        // console.log(category)
+
+        return (
+                  <div className="slideDown padding profile-page  d-flex flex-row font-ci">
+                <div className="w-100 m-5 bg-gradient border rounded">
+                    <div className=" m-5 text-center  text-white font-ci font-ci-bold ">
+                        {
+                            data !== null
+                                ?
+                                data.map(mass =>
+                                    <div className="btn " key={mass.id}>
+                                        <button class="btn btn-secondary font-ci font-ci-bold text-light bg-mist " type="button" id={mass.id} key={mass.id} >
+                                        <Link  class="font-ci font-ci-bold text-light" to={routes.TESTS}>{mass.name}</Link>
+                                        </button>
+                                    </div>
+
+                                )
+                                :
+                                null
+                        }
+
+                    </div>
+                </div>
+            </div>
+
+        )
+    }
+
+}
+
+const
+    mapStateToProps = state => ({
+        category: state.category,
+    });
+
+const mapDispatchToProps = dispatch => bindActionCreators({getCategoryRequest}, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(AddDeleteCategory);

+ 4 - 4
src/components/user/ProfilePage/ChangeEmailForm/index.js

@@ -1,5 +1,4 @@
 import React from 'react';
-import { connect } from 'react-redux';
 import { Field, reduxForm } from 'redux-form';
 
 import formInput from '../../../common/formInput';
@@ -8,7 +7,6 @@ class ChangeEmailForm extends React.Component {
 
     submit = ({email}) => {
         const {actions:{changeEmailRequest},data:{_id},token } = this.props
-        console.log(_id, email,token);
 
         changeEmailRequest({
             token,
@@ -23,9 +21,9 @@ class ChangeEmailForm extends React.Component {
         const { submit}=this
         return (
             <form onSubmit={handleSubmit(submit)} >
-                <Field name="email" type="email" placeholder="Enter new login" component={formInput} />
+                <Field name="email" type="email" placeholder="Enter new login" component={formInput} className="bg-rgba1 border" />
                 <button
-                    type="button" className="link link--btn right"  onClick={
+                    type="button" className="link link--btn right flex-fill bg-shadow btn text-white font-ci font-ci-bold col-3"  onClick={
                         function() {
                         handleClicks();
                             handleSubmit(submit)();
@@ -41,4 +39,6 @@ class ChangeEmailForm extends React.Component {
 
 export default reduxForm({
     form: "changeEmailForm",
+    enableReinitialize: true
+
 })(ChangeEmailForm);

+ 3 - 5
src/components/user/ProfilePage/ChangeLoginForm/index.js

@@ -1,5 +1,4 @@
 import React from 'react';
-import { connect } from 'react-redux';
 import { Field, reduxForm } from 'redux-form';
 
 import formInput from '../../../common/formInput';
@@ -8,7 +7,6 @@ class ChangeLoginForm extends React.Component {
 
     submit = ({ name}) => {
         const {actions:{changeLoginRequest},data:{_id},token } = this.props
-        console.log(_id, name,token);
 
         changeLoginRequest({
             token,
@@ -21,12 +19,12 @@ class ChangeLoginForm extends React.Component {
     render() {
         const { children, handleSubmit, actions:{changeLoginRequest}, handlers: {  handleClick }, data, token } = this.props;
         const { submit}=this
-        console.log( data)
+
         return (
             <form onSubmit={handleSubmit(submit)} >
-                <Field name="name" type="email" placeholder="Enter new login" component={formInput} />
+                <Field name="name" type="email" placeholder="Enter new login" component={formInput} className="bg-rgba1 border" />
                 <button
-                    type="button" className="link link--btn right"  onClick={
+                    type="button" className="link link--btn right flex-fill bg-shadow btn text-white font-ci font-ci-bold col-3"  onClick={
                         function() {
                         handleClick();
                             handleSubmit(submit)();

+ 5 - 5
src/components/user/ProfilePage/changePassword/index.js

@@ -1,5 +1,6 @@
 import React from 'react';
 import { Field, reduxForm } from 'redux-form';
+import validate from '../../../../configs/validate'
 
 import formInput from '../../../common/formInput';
 
@@ -7,7 +8,6 @@ class ChangePasswordForm extends React.Component {
 
     submit = ({password, confirmPassword }) => {
         const {actions:{changePasswordRequest},data:{_id},token } = this.props
-        console.log(_id, password, confirmPassword, token);
 
         changePasswordRequest({
             token,
@@ -21,14 +21,13 @@ class ChangePasswordForm extends React.Component {
     render() {
         const { children, handleSubmit, actions:{ changePasswordRequest }, handlers: {  handleClicked }, data, token } = this.props;
         const { submit}=this
-        console.log( data)
         return (
             <form onSubmit={handleSubmit(submit)} >
-                <Field name="password" type="password" placeholder="Password" component={formInput} />
-                <Field name="confirmPassword" type="password" placeholder="new Password" component={formInput} />
+                <Field name="password" type="password" placeholder="Password" className ='' component={formInput} className="bg-rgba1 border" />
+                <Field name="confirmPassword" type="password" placeholder="new Password" component={formInput} className="bg-rgba1 border"/>
 
                 <button
-                    type="button" className="link link--btn right"  onClick={
+                    type="button" className="link link--btn flex-fill bg-shadow btn text-white font-ci font-ci-bold col-3 "  onClick={
                         function() {
                         handleClicked();
                             handleSubmit(submit)();
@@ -44,4 +43,5 @@ class ChangePasswordForm extends React.Component {
 
 export default reduxForm({
     form: "changePasswordForm",
+    validate
 })(ChangePasswordForm);

+ 37 - 35
src/components/user/ProfilePage/index.js

@@ -6,8 +6,8 @@ import ChangeEmailForm from './ChangeEmailForm/index';
 import ChangePasswordForm from './changePassword/index'
 import {changeLoginRequest} from '../../../actions/user/changelogin';
 import {changeEmailRequest} from '../../../actions/user/changeEmail';
-import {changePasswordRequest } from '../../../actions/user/changePassword'
-
+import {changePasswordRequest } from '../../../actions/user/changePassword';
+import {myUserRequest} from '../../../actions/admin/meUser'
 
 class ProfilePage extends React.Component {
     
@@ -16,6 +16,10 @@ class ProfilePage extends React.Component {
         klick: false,
         click: false
     }
+    componentDidMount(){
+        const {myUserRequest} =this.props
+        myUserRequest()
+    }
 
     handleClick = () => {
         this.setState((prevState) => ({ clicked: !prevState.clicked }));
@@ -28,47 +32,41 @@ class ProfilePage extends React.Component {
     }
 
     render() {
-        const { signIn:{data, token}, changeLoginRequest, chageLoginReducer, changeEmailRequest, changeEmailReducer, changePasswordRequest} = this.props;
-      console.log(changeEmailReducer)
+
+        const { myUser:{data, token}, changeLoginRequest, chageLoginReducer, changeEmailRequest, changeEmailReducer, changePasswordRequest} = this.props;
         const {clicked, klick, click} =this.state;
         const {handleClick, handleClicks, handleClicked} = this;
 
+
         return (
-            <div className="page page--bottom-only profile-page">
-                <div className="border bg-autumn-foliage m-5 rounded d-flex">
+            <div className="slideDown page page--bottom-only profile-page bg-img d-block w-100 slider-image padding" >
+                <div className="border bg-rgba rounded d-flex  ">
                     <div>
-                {/* <h5 className="p-2 font-po-bold flex-fill bd-highlight align-self-end">{data.name}</h5> */}
-                {/* <div className="d-flex"  >
-                <p className="p-2 flex-fill font-po-bold bd-highlight align-self-end">Email</p><p className="p-2 flex-fill font-po-bold bd-highlight align-self-end">{data.email}</p>
-                </div> */}
-                {/* <div className="d-flex"  >
-                <p className="p-2 flex-fill font-po-bold bd-highlight align-self-end">Role</p><p className="p-2 flex-fill font-po-bold bd-highlight align-self-end">{data.role}</p>
-                </div> */}
-                
                     <div>
-                        <img className="m-4 " src=" https://cdn.iconscout.com/icon/free/png-256/avatar-373-456325.png" ></img>
+
+                        <img className="m-4 " src=" https://ru.opensuse.org/images/0/0b/Icon-user.png" ></img>
                     </div>
                     </div>
-                    <div className="border-left bg-autumn-foliage m-5 rounded w-75 ">
+                    <div className="border-left bg-autumn-foliage m-5 rounded w-75 text-white font-ci font-ci-bold">
                             {!clicked
                             ?
                         <div  className ="d-flex mb-3" >
-                            <h3 className = " p-2 flex-fill bd-highlight">Name</h3>
+                            <h3 className = " p-2 flex-fill bd-highlight ">Name</h3>
                             <h5 className="p-2 font-po-bold flex-fill bd-highlight align-self-end">{
                                 chageLoginReducer.data == null
                                 ?
-                                data.name 
+                                data&&data.name 
                                 :
                                 chageLoginReducer.data
 
-                                }</h5>
-                            <button type="button" onClick ={handleClick}  className=" flex-fill bg-shadow btn btn-outline-primary col-3">Change</button>
+                    
+                                }</h5> 
+                             <button type="button" onClick ={handleClick}  className=" flex-fill bg-shadow btn text-white font-ci font-ci-bold col-3">Change</button>
                         </div>
                         :
-                        <div>
+                        <div className ="d-flex mb-3">
                         <h3 className = " p-2 flex-fill bd-highlight">Name</h3>
-                        <h5 className="p-2 font-po-bold flex-fill bd-highlight align-self-end">{data.name}</h5>
-                        <ChangeLoginForm data ={data} token={token} actions ={{changeLoginRequest}} handlers={{ handleClick}}> </ChangeLoginForm>
+                        <ChangeLoginForm  data ={data} initialValues={data} token={token} actions ={{changeLoginRequest}} handlers={{ handleClick}}> </ChangeLoginForm>
                         </div>
                             }
                             {!klick
@@ -79,38 +77,42 @@ class ProfilePage extends React.Component {
                                 {
                                     changeEmailReducer.data ===null
                                     ?
-                                    data.email
+                                    data&&data.email
                                     :
                                     changeEmailReducer.data
-                                }
-                            </h5>
-                            <button type="button" name ="name"  onClick ={handleClicks} className=" flex-fill bg-shadow btn btn-outline-primary col-3">Change</button>
+                                } 
+                             </h5>
+                            <button type="button" name ="name"  onClick ={handleClicks} className=" flex-fill bg-shadow btn text-white font-ci font-ci-bold col-3">Change</button>
                         </div>
                         :
                         <div  className ="d-flex mb-3" >
+
                             <h3 className = "p-2 flex-fill bd-highlight">Email</h3>
-                            <h5 className="p-2 flex-fill font-po-bold bd-highlight align-self-end">{data.email}</h5>
-                            <ChangeEmailForm  data ={data} token={token} actions ={{changeEmailRequest}} handlers={{ handleClicks}}></ChangeEmailForm>
+                            <ChangeEmailForm  data ={data} token={token} initialValues={data} actions ={{changeEmailRequest}} handlers={{ handleClicks}}></ChangeEmailForm>
                         </div>
                             }
                             {
                                 !click
                                 ?
                         <div  className ="d-flex mb-3" >
+
                             <h3 className = "p-2 flex-fill bd-highlight">Password</h3>
-                            <button type="button" onClick ={handleClicked} className=" flex-fill bg-shadow btn btn-outline-primary col-3">Change</button>
-                        </div>
-                        :
+                            <button type="button" onClick ={handleClicked} className=" flex-fill bg-shadow btn text-white font-ci font-ci-bold col-3">Change</button>
+                        </div> 
+                         :
                         <div  className ="d-flex mb-3" >
                             <h3 className = "p-2 flex-fill bd-highlight">Password</h3>
                            <ChangePasswordForm data ={data} token={token} actions ={{changePasswordRequest}} handlers={{ handleClicked}}></ChangePasswordForm>
+
                         </div>
                             }
                  
                     </div>
                 </div>
-                
                 </div>
+                
+                
+                
             
         )
     }
@@ -119,11 +121,11 @@ class ProfilePage extends React.Component {
 
 const
     mapStateToProps = state => ({
-        signIn: state.signIn,
+        myUser:state.myUser,
         chageLoginReducer: state.chageLoginReducer,
         changeEmailReducer:state.changeEmailReducer
     });
 
-const mapDispatchToProps = dispatch => bindActionCreators({changeLoginRequest, changeEmailRequest, changePasswordRequest}, dispatch);
+const mapDispatchToProps = dispatch => bindActionCreators({changeLoginRequest, changeEmailRequest, changePasswordRequest, myUserRequest}, dispatch);
 
 export default connect(mapStateToProps, mapDispatchToProps)(ProfilePage);

+ 25 - 0
src/components/user/Test/ModalSommary.js

@@ -0,0 +1,25 @@
+import React, { Component } from "react";
+import { Modal } from "react-bootstrap";
+
+
+class ModalSummary extends React.Component {
+
+
+    render() {
+        const{clickModal, summary, handlers:{closeModal}}= this.props
+        return (
+            <Modal show={clickModal} onHide={closeModal} aria-labelledby="contained-modal-title-vcenter" >
+                < Modal.Header closeButton >
+                    < Modal.Title className="text-center  text-white font-ci font-ci-bold" >Summary </ Modal.Title >
+                </ Modal.Header >
+                < Modal.Body >
+                    <h4>{summary}</h4>
+                </ Modal.Body >
+                < Modal.Footer>
+                </ Modal.Footer >
+            </Modal>
+        );
+    }
+}
+
+export default ModalSummary

+ 60 - 0
src/components/user/Test/getTest.js

@@ -0,0 +1,60 @@
+import React, { Component } from "react";
+import { Field, reduxForm } from 'redux-form';
+import formInput from '../../common/formInput';
+import ModalSummary from './ModalSommary'
+import {reset} from 'redux-form';
+class Test extends React.Component {
+    state={
+        answers:[],
+        question:null,
+    }
+
+    submit=()=>{
+        const{sessionId,_id, actions:{checkTestRequest, nextTestRequest, startTestRequest} } =this.props;
+        const {answers, question} = this.state;
+        checkTestRequest({_id})
+        nextTestRequest({_id, sessionId,question, answers})
+        reset("gfhfh")
+        // startTestRequest({_id})
+
+    }
+    handelChange=({el:{_id, question}})=>{
+this.setState((prevState)=>({answers:prevState.answers.concat(_id)}))
+this.setState({question:question})
+    }
+
+    render() {
+        const { data, handleSubmit, summary, clickModal, handlers:{closeModal} } = this.props;
+        const{submit}=this
+        return (
+            <form onSubmit={handleSubmit(submit)}>
+
+                <h4 className="text-white font-ci">{
+                    data.question !==undefined
+                    ?
+                    data.question.question
+                    :null
+                    }</h4>
+                <div className=' d-flex flex-column'>
+                    {
+                        data.question !==undefined
+                        ?
+                        data.question.answersArr.map(el =>
+                            <div key={el._id}>
+                                <Field name={`answer${el.answer}`}  value={el.answer} type="checkbox" onChange={this.handelChange.bind(null,{el})} component={formInput} />
+                                <span className="text-white font-ci">{el.answer}</span>
+                                </div>
+                        )
+                        :
+                        <ModalSummary handlers={{closeModal}} summary={summary} clickModal ={clickModal}></ModalSummary>
+                    }
+                </div>
+                <button  className="btn  btn-outline-light bg-stone m-3 right">Next</button>
+            </form>
+        )
+    }
+}
+
+export default reduxForm({
+    form: "Test",
+})(Test)

+ 95 - 0
src/components/user/Test/index.js

@@ -0,0 +1,95 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import {getTopicTestRequest} from '../../../actions/user/test/getTopics'
+import {startTestRequest} from '../../../actions/user/test/testStart';
+import {checkTestRequest} from '../../../actions/user/test/checkTest';
+import {nextTestRequest} from '../../../actions/user/test/nextTest'
+import Test from './getTest';
+
+	
+
+
+class PassingTests extends React.Component {
+    state={
+        _id:null,
+        sessionId:null,
+        summary:null,
+        clickModal:false
+    }
+
+componentWillMount(){
+    const{getTopicTestRequest} =this.props
+    getTopicTestRequest()
+}
+
+closeModal = () => { this.setState((prevState) => ({ clickModal: !prevState.clickModal })) }
+handelClick=({el:{_id}})=>{
+    const{startTestRequest, checkTestRequest}=this.props
+    checkTestRequest({_id})
+    startTestRequest({_id})
+    this.setState({_id:_id})
+}
+componentWillReceiveProps(nextProps) {
+    const{startTest:{data}}=nextProps
+    if(data!==null){
+        this.setState({sessionId:data.sessionId})
+          if(data.finish){
+        this.setState({summary:data.summory,clickModal:true})
+    }
+    }
+
+  
+}
+
+
+    render() {
+        const{ handelClick,closeModal}=this
+        const {sessionId,_id, summary, clickModal} =this.state
+        const{topicTest:{topic},startTest:{data}, checkTestRequest, nextTestRequest, startTestRequest}=this.props;
+
+
+        return (
+            <div className=" profile-page d-flex flex-row font-ci padding  ">
+          
+                <div className='w-25 p-3  border rounded bg-gradient slideRight'  >
+                    {
+                        topic!==null
+                        ?
+                        topic.map(el=>
+                            <button type="button" class="text-center overflow-hidden rounded-pill btn-outline-light btn mb-4 borber bg-rgba border-0  font-ci font-ci-bold "key={el._id} id={el._id} onClick={handelClick.bind(null, { el })}>{el.name}</button>
+                        )
+                        :null
+                    }
+                </div>
+                <div className='w-75 p-3  ml-3 border rounded d-flex flex-row bg-gradient slideLeft'  >
+                    {
+                        data !==null
+                        ?
+                        <Test actions={{checkTestRequest, nextTestRequest, startTestRequest}} handlers={{closeModal}} summary={summary} clickModal={clickModal} sessionId={sessionId} _id={_id} data={data}></Test>
+                           
+                        :
+                        null
+                    } 
+                   
+                   
+                </div>
+            </div>
+
+
+
+        )
+    }
+
+}
+
+const
+    mapStateToProps = state => ({
+topicTest:state.topicTest,
+startTest:state.startTest
+
+    });
+
+const mapDispatchToProps = dispatch => bindActionCreators({getTopicTestRequest,startTestRequest, checkTestRequest, nextTestRequest }, dispatch);
+
+export default connect(mapStateToProps, mapDispatchToProps)(PassingTests);

+ 12 - 0
src/configs/requestsConfigs/index.js

@@ -0,0 +1,12 @@
+export const defaultConfig = {
+    headers: {
+        "Content-Type": "application/json"
+    }
+}
+
+export const makeConfigWithJWT = jwt => ({
+    headers: {
+        "Content-Type": "application/json",
+        "Authorization": `Bearer ${jwt}`
+    }
+})

+ 43 - 8
src/configs/routerConfig.js

@@ -1,17 +1,27 @@
 import React, { lazy } from 'react';
+
+import Landing from './../components/public/landing';
 import * as routes from './../constants/routes';
 
-const ProfilePage = lazy(() => import('../components/user/ProfilePage'))
-const DeleteUser = lazy(()=>import('../components/admin/deleteUser/index'))
-// import SignIn from '../components/public/SignIn';
-const SignIn = lazy(() => import('./../components/public/SignIn'));
-const SignUp = lazy(() => import('./../components/public/SignUp'));
+const ProfilePage = lazy(() => import('../components/user/ProfilePage'));
+const DeleteUser = lazy(()=>import('../components/admin/deleteUser/index'));
+const AddDeleteCategory = lazy(()=> import('../components/admin/addDeleteCategory'));
+const CreateTest = lazy(()=> import('../components/admin/CreateTest'));
+const ChangeTest = lazy(()=>import('../components/admin/getChangeDeleteTest/index'))
+const PassingTests =lazy(()=>import('../components/user/Test/index'))
+const Category =lazy(()=>import('../components/user/Categoty'))
+
+const SignIn = lazy(() => import('../components/public/SignIn/index'));
+const SignUp = lazy(() => import('../components/public/SignUp/index'));
+
+
+const CardsCreator = lazy(() => import('./../components/admin/CardsCreator'))
 
 export default [
     {
         path: routes.LANDING,
         access: 'public',
-        component: () => <div>landing</div>
+        component: Landing
     },
     {
         path: routes.SIGN_IN,
@@ -31,7 +41,7 @@ export default [
     {
         path: routes.CATEGORIES,
         access: 'user-only',
-        component: () => <div>categories</div>
+        component: Category
     },
     {
         path: routes.PROFILE,
@@ -41,13 +51,38 @@ export default [
     {
         path: routes.TESTS,
         access: 'user-only',
-        component: () => <div>test</div>
+        component: PassingTests
+    },
+    {
+        path: '/admin',
+        access: 'admin-only',
+        component: () => <div>Some admin-only component</div>
     },
     {
         path: routes.DELETE_USER,
         access: 'admin-only',
         component: DeleteUser
     },
+    {
+        path: routes.CREATE_CATEGORY,
+        access: 'admin-only',
+        component: AddDeleteCategory
+    },
+    {
+        path: routes.CREATE_TEST,
+        access: 'admin-only',
+        component: CreateTest
+    },
+    {
+        path: routes.CREATE_TEST,
+        access: 'public',
+        component: CardsCreator
+    },
+    {
+        path: routes.CHANGE_TEST,
+        access: 'public',
+        component: ChangeTest
+    },
     {
         access: 'public',
         component: () => <div>404</div>

+ 47 - 0
src/configs/validate.js

@@ -0,0 +1,47 @@
+export default function validate(values) {
+    const { name, email, password, passwordConfirmation } = values;
+        const errors = {};
+    
+        if (!email) {
+            errors.email = "Required";
+        }
+        else if (email.length < 8 || email.length > 20) {
+            errors.email = "Invalid email length: email should be from 8 to 20 symbols";
+        }
+        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(email)) {
+            errors.email = "Invalid email, try another one";
+        }
+    
+        if (!name) {
+            errors.name = "Required";
+        }
+        else if (name.length < 6 || name.length > 10) {
+            errors.name = "Invalid name length: name should be from 6 to 10 symbols";
+        }
+        else if (!/^[_A-z0-9]*((-|\s)*[_A-z0-9])*$/.test(name)) {
+            errors.name = "Invalid name, try another one"
+        }
+        
+        if (!password) {
+            errors.password = "Required"
+        }
+        else if (/[,]/.test(password)) {
+            errors.password = "Invalid symbol: \",\" is not allowed!";
+        }
+        else if (password.length < 8 || password.length > 20) {
+            errors.password = "Invalid password length: password should be from 8 to 20 symbols";
+        }
+        else if (!/^[a-z0-9_-]{8,20}$/i.test(password)) {
+            errors.password = "Invalid password, try another one";
+        }
+    
+        if (!passwordConfirmation) {
+            errors.passwordConfirmation = "Required";
+        }
+        else if (password !== passwordConfirmation) {
+            errors.passwordConfirmation = "Passwords don't match each other!";
+        }
+    
+      return errors;
+    }

+ 83 - 0
src/constants/admin.js

@@ -0,0 +1,83 @@
+export const CREATE_CATEGORY = "https://test-app-a-level.herokuapp.com/category" 
+export const CREATE_CATEGORY_REQUEST = 'CREATE_CATEGORY_REQUEST';
+export const CREATE_CATEGORY_REQUEST_SUCCESS = 'CREATE_CATEGORY_REQUEST_SUCCESS';
+export const CREATE_CATEGORY_REQUEST_FAILURE = 'CREATE_CATEGORY_REQUEST_FAILURE';
+
+export const GET_CATEGORY_REQUEST = 'GET_CATEGORY_REQUEST';
+export const GET_CATEGORY_REQUEST_SUCCESS = 'GET_CATEGORY_REQUEST_SUCCESS';
+export const GET_CATEGORY_REQUEST_FAILURE = 'GET_CATEGORY_REQUEST_FAILURE';
+
+
+export const CHANGE_CATEGORY_REQUEST = 'CHANGE_CATEGORY_REQUEST';
+export const CHANGE_CATEGORY_REQUEST_SUCCESS = 'CHANGE_CATEGORY_REQUEST_SUCCESS';
+export const CHANGE_CATEGORY_REQUEST_FAILURE = 'CHANGE_CATEGORY_REQUEST_FAILURE';
+
+export const DELETE_CATEGORY_REQUEST = 'DELETE_CATEGORY_REQUEST';
+export const DELETE_CATEGORY_REQUEST_SUCCESS = 'DELETE_CATEGORY_REQUEST_SUCCESS';
+export const DELETE_CATEGORY_REQUEST_FAILURE = 'DELETE_CATEGORY_REQUEST_FAILURE';
+
+export const CREATE_TOPICS = "https://test-app-a-level.herokuapp.com/topics";
+export const CREATE_TOPICS_REQUEST = 'CREATE_TOPICS_REQUEST';
+export const CREATE_TOPICS_REQUEST_SUCCESS = 'CREATE_TOPICS_REQUEST_SUCCESS';
+export const CREATE_TOPICS_REQUEST_FAILURE = 'CREATE_TOPICS_REQUEST_FAILURE';
+
+export const CREATE_QUESTIONS = "https://test-app-a-level.herokuapp.com/questions"; 
+export const CREATE_ANSVERS = "https://test-app-a-level.herokuapp.com/answers";
+export const CREATE_TEST_REQUEST = 'CREATE_TEST_REQUEST';
+export const CREATE_QUESTIONS_REQUEST_SUCCESS = 'CREATE_QUESTIONS_REQUEST_SUCCESS';
+export const CREATE_ANSVERS_REQUEST_SUCCESS = 'CREATE_ANSVERS_REQUEST_SUCCESS';
+export const CREATE_TEST_REQUEST_FAILURE = 'CREATE_TEST_REQUEST_FAILURE';
+
+export const MY_USER = "https://test-app-a-level.herokuapp.com/me";
+export const MY_USER_REQUEST = 'MY_USER_REQUEST';
+export const MY_USER_REQUEST_SUCCESS = 'MY_USER_REQUEST_SUCCESS';
+export const MY_USER_REQUEST_FAILURE = 'MY_USER_REQUEST_FAILURE';
+
+export const GET_USERS = "https://test-app-a-level.herokuapp.com/users/list";
+export const GET_USERS_REQUEST = 'GET_USERS_REQUEST';
+export const GET_USERS_REQUEST_SUCCESS = 'GET_USERS_REQUEST_SUCCESS';
+export const GET_USERS_REQUEST_FAILURE = 'GET_USERS_REQUEST_FAILURE';
+
+
+export const CHANGE_USER = "https://test-app-a-level.herokuapp.com/users/";
+export const CHANGE_USER_ROLE = "https://test-app-a-level.herokuapp.com/users/changeRole/";
+
+export const CHANGE_USERS_REQUEST = 'CHANGE_USERS_REQUEST';
+export const CHANGE_USERS_REQUEST_SUCCESS = 'CHANGE_USERS_REQUEST_SUCCESS';
+export const CHANGE_USERS_REQUEST_FAILURE = 'CHANGE_USERS_REQUEST_FAILURE';
+
+export const DELETE_USERS_REQUEST = 'DELETE_USERS_REQUEST';
+export const DELETE_USERS_REQUEST_SUCCESS = 'DELETE_USERS_REQUEST_SUCCESS';
+export const DELETE_USERS_REQUEST_FAILURE = 'DELETE_USERS_REQUEST_FAILURE';
+
+
+export const GET_TOPIC_REQUEST = 'GET_TOPIC_REQUEST';
+export const GET_TOPIC_REQUEST_SUCCESS = 'GET_TOPIC_REQUEST_SUCCESS';
+export const GET_TOPIC_REQUEST_FAILURE = 'GET_TOPIC_REQUEST_FAILURE';
+
+
+export const GET_QUESTIONS_REQUEST = 'GET_QUESTIONS_REQUEST';
+export const GET_QUESTIONS_REQUEST_SUCCESS = 'GET_QUESTIONS_REQUEST_SUCCESS';
+export const GET_QUESTIONS_REQUEST_FAILURE = 'GET_QUESTIONS_REQUEST_FAILURE';
+
+export const DELETE_TOPIC_REQUEST = 'DELETE_TOPIC_REQUEST';
+export const DELETE_TOPIC_REQUEST_SUCCESS = 'DELETE_TOPIC_REQUEST_SUCCESS';
+export const DELETE_TOPIC_REQUEST_FAILURE = 'DELETE_TOPIC_REQUEST_FAILURE';
+
+export const DELETE_QUESTION_REQUEST = 'DELETE_QUESTION_REQUEST';
+export const DELETE_QUESTION_REQUEST_SUCCESS = 'DELETE_QUESTION_REQUEST_SUCCESS';
+export const DELETE_QUESTION_REQUEST_FAILURE = 'DELETE_QUESTION_REQUEST_FAILURE';
+
+export const DELETE_ANSWER_REQUEST = 'DELETE_ANSWER_REQUEST';
+export const DELETE_ANSWER_REQUEST_SUCCESS = 'DELETE_ANSWER_REQUEST_SUCCESS';
+export const DELETE_ANSWER_REQUEST_FAILURE = 'DELETE_ANSWER_REQUEST_FAILURE';
+
+export const GET_ANSWERS_REQUEST = 'GET_ANSWERS_REQUEST';
+export const GET_ANSWERS_REQUEST_SUCCESS = 'GET_ANSWERS_REQUEST_SUCCESS';
+export const GET_ANSWERS_REQUEST_FAILURE = 'GET_ANSWERS_REQUEST_FAILURE';
+
+export const CHANGE_TEST_REQUEST = 'CHANGE_TEST_REQUEST';
+export const CHANGE_TOPIC_REQUEST_SUCCESS = 'CHANGE_TOPIC_REQUEST_SUCCESS';
+export const CHANGE_QUESTIONS_REQUEST_SUCCESS = 'CHANGE_QUESTIONS_REQUEST_SUCCESS';
+export const CHANGE_ANSVERS_REQUEST_SUCCESS = 'CHANGE_ANSVERS_REQUEST_SUCCESS';
+export const CHANGE_TEST_REQUEST_FAILURE = 'CHANGE_TEST_REQUEST_FAILURE';

+ 10 - 1
src/constants/auth.js

@@ -2,8 +2,17 @@ export const SIGN_IN_URL = 'https://test-app-a-level.herokuapp.com/auth/login';
 export const SIGN_IN_REQUEST = 'SIGN_IN_REQUEST';
 export const SIGN_IN_REQUEST_SUCCESS = 'SIGN_IN_REQUEST_SUCCESS';
 export const SIGN_IN_REQUEST_FAILURE = 'SIGN_IN_REQUEST_FAILURE';
+export const SIGN_IN_STATE_ZEROING = 'SIGN_IN_STATE_ZEROING';
 
 export const SIGN_UP_URL = 'https://test-app-a-level.herokuapp.com/auth/register';
 export const SIGN_UP_REQUEST = 'SIGN_UP_REQUEST';
 export const SIGN_UP_REQUEST_SUCCESS = 'SIGN_UP_REQUEST_SUCCESS';
-export const SIGN_UP_REQUEST_FAILURE = 'SIGN_UP_REQUEST_FAILURE';
+export const SIGN_UP_REQUEST_FAILURE = 'SIGN_UP_REQUEST_FAILURE';
+
+export const LOG_OUT_URL = 'https://test-app-a-level.herokuapp.com/auth/logout';
+export const LOG_OUT_REQUEST = 'LOG_OUT_REQUEST';
+export const LOG_OUT_REQUEST_SUCCESS = 'LOG_OUT_REQUEST_SUCCESS';
+export const LOG_OUT_REQUEST_FAILURE = 'LOG_OUT_REQUEST_FAILURE';
+
+export const ACTIVE_TOKEN = 'ACTIVE_TOKEN';
+export const INACTIVE_TOKEN = 'INACTIVE_TOKEN'; 

+ 1 - 0
src/constants/routes.js

@@ -9,6 +9,7 @@ export const CREATE_CATEGORY = '/create-category';
 export const CATEGORIES = '/categories';
 export const PROFILE = '/profile';
 export const CREATE_TEST = '/create-test';
+export const CHANGE_TEST = '/change-test';
 export const DELETE_USER = '/delete-user'
 export const TESTS = '/test';
 export const PASSWORD_FORGET = '/pw-forget';

+ 20 - 1
src/constants/user.js

@@ -9,4 +9,23 @@ export const CHANGE_EMAIL_REQUEST_FAILURE = 'CHANGE_EMAIL_REQUEST_FAILURE';
 
 export const CHANGE_PASSWORD_REQUEST = 'CHANGE_PASSWORD_REQUEST';
 export const CHANGE_PASSWORD_REQUEST_SUCCESS = 'CHANGE_PASSWORD_REQUEST_SUCCESS';
-export const CHANGE_PASSWORD_REQUEST_FAILURE = 'CHANGE_PASSWORD_REQUEST_FAILURE';
+export const CHANGE_PASSWORD_REQUEST_FAILURE = 'CHANGE_PASSWORD_REQUEST_FAILURE';
+
+export const GET_TOPIC_TEST_REQUEST = 'GET_TOPIC_TEST_REQUEST';
+export const GET_TOPIC_TEST_REQUEST_SUCCESS = 'GET_TOPIC_TEST_REQUEST_SUCCESS';
+export const GET_TOPIC_TEST_REQUEST_FAILURE = 'GET_TOPIC_TEST_REQUEST_FAILURE';
+
+export const START_TEST='https://test-app-a-level.herokuapp.com/statistics/start'
+export const START_TEST_REQUEST = 'START_TEST_REQUEST';
+export const START_TEST_REQUEST_SUCCESS = 'START_TEST_REQUEST_SUCCESS';
+export const START_TEST_REQUEST_FAILURE = 'START_TEST_REQUEST_FAILURE';
+
+export const CHECK_TEST='https://test-app-a-level.herokuapp.com/statistics/check'
+export const CHECK_TEST_REQUEST = 'CHECK_TEST_REQUEST';
+export const CHECK_TEST_REQUEST_SUCCESS = 'CHECK_TEST_REQUEST_SUCCESS';
+export const CHECK_TEST_REQUEST_FAILURE = 'CHECK_TEST_REQUEST_FAILURE';
+
+export const NEXT_TEST='https://test-app-a-level.herokuapp.com/statistics/next'
+export const NEXT_TEST_REQUEST = 'NEXT_TEST_REQUEST';
+export const NEXT_TEST_REQUEST_SUCCESS = 'NEXT_TEST_REQUEST_SUCCESS';
+export const NEXT_TEST_REQUEST_FAILURE = 'NEXT_TEST_REQUEST_FAILURE';

+ 43 - 0
src/reducers/admin/changeCategory.js

@@ -0,0 +1,43 @@
+import * as actionTypes from '../../constants/admin';
+import initialState from '../initialState';
+
+export default function changeCategory(state = initialState.changeCategory, {payload, type, error}) {
+
+    switch (type) { // payload.type -> type
+        case 'wtfUpdate': {
+            return initialState.changeCategory
+        }
+        case actionTypes.CHANGE_CATEGORY_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                isFlag:false,
+                data:null,
+                error: null
+            }
+        }
+        case actionTypes.CHANGE_CATEGORY_REQUEST_SUCCESS: {
+            const { data } = payload;
+
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:true,
+                data: data,
+                error: null,
+            }
+        }
+        case actionTypes.CHANGE_CATEGORY_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                data: null,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 42 - 0
src/reducers/admin/createCategory.js

@@ -0,0 +1,42 @@
+import * as actionTypes from '../../constants/admin';
+import initialState from '../initialState';
+
+export default function newCategory(state = initialState.newCategory, {payload, type, error}) {
+
+    switch (type) { // payload.type -> type
+        case 'wtfCreate': { // CREATE_CATEGORY_NULIFY
+            return initialState.newCategory
+        }
+
+        case actionTypes.CREATE_CATEGORY_REQUEST: {
+            
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:false,
+                data:null
+            }
+        }
+        case actionTypes.CREATE_CATEGORY_REQUEST_SUCCESS: {
+            const { data } = payload;
+
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:true,
+                data: data,
+            }
+        }
+        case actionTypes.GET_CATEGORY_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 35 - 0
src/reducers/admin/getCategory.js

@@ -0,0 +1,35 @@
+import * as actionTypes from '../../constants/admin';
+import initialState from './../initialState';
+
+export default function getCategory(state = initialState.category, { payload, type, error }) {
+
+    switch (type) { // payload.type -> type
+        case actionTypes.GET_CATEGORY_REQUEST: {
+            return {
+                ...state,
+                isFetching: true
+            }
+        }
+        case actionTypes.GET_CATEGORY_REQUEST_SUCCESS: {
+            const { data: { category } } = payload;
+
+            return {
+                ...state,
+                isFetching: false,
+                isFlag: true,
+                data: category,
+            }
+        }
+        case actionTypes.GET_CATEGORY_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 33 - 0
src/reducers/admin/getUsers.js

@@ -0,0 +1,33 @@
+import * as actionTypes from '../../constants/admin';
+import initialState from './../initialState';
+
+export default function getUsers(state = initialState.users, { payload, type, error }) {
+
+    switch (type) { // payload.type -> type
+        case actionTypes.GET_USERS_REQUEST: {
+            return {
+                ...state,
+                isFetching: true
+            }
+        }
+        case actionTypes.GET_USERS_REQUEST_SUCCESS: {
+            const {data:{users}}=payload
+            return {
+                ...state,
+                isFetching: false,
+                user:users
+            }
+        }
+        case actionTypes.GET_USERS_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 32 - 0
src/reducers/admin/initialValues.js

@@ -0,0 +1,32 @@
+import * as actionTypes from '../../constants/admin';
+import initialState from './../initialState';
+
+export default function getCategory(state = initialState.initialValues, {payload, type, error}) {
+
+    switch (type) { // payload.type -> type
+        case actionTypes.GET_CATEGORY_REQUEST_SUCCESS: {
+            
+            return {
+                ...state,
+                categoryId:payload
+            }
+        }
+        case actionTypes.GET_TOPIC_REQUEST_SUCCESS: {
+
+            return {
+                ...state,
+                name:payload,
+            }
+        }
+        case actionTypes.GET_QUESTIONS_REQUEST_SUCCESS: {
+
+            return {
+                ...state,
+                question:payload
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 35 - 0
src/reducers/admin/test/changeUser.js

@@ -0,0 +1,35 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function changeUserReducer(state = initialState.changeUser, {  type, payload }) {
+    switch (type) {
+        case actionTypes.CHANGE_USERS_REQUEST: {
+            return {
+                ...state,
+                isFetching: false,
+                payload
+            }
+        }
+        case actionTypes.CHANGE_USERS_REQUEST_SUCCESS: {
+            const { data:{user} } = payload;
+
+            return {
+                ...state,
+                isFetching: true,
+                data:user
+            }
+        }
+        case actionTypes.CHANGE_USERS_REQUEST_FAILURE: {
+            const { error } = payload;
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 34 - 0
src/reducers/admin/test/createTopics.js

@@ -0,0 +1,34 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function topic(state = initialState.topicId, {payload, type, error}) {
+
+    switch (type) { // payload.type -> type
+        case actionTypes.CREATE_TOPICS_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                // payload
+            }
+        }
+        case actionTypes.CREATE_TOPICS_REQUEST_SUCCESS: {
+const {data:{topic}}=payload
+            return {
+                ...state,
+                isFetching: false,
+                topic
+            }
+        }
+        case actionTypes.CREATE_TOPICS_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 34 - 0
src/reducers/admin/test/deleteQuestion.js

@@ -0,0 +1,34 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function deleteQuestion(state = initialState.deleteQuestion, {payload, type, error}) {
+
+    switch (type) { 
+        case actionTypes.DELETE_QUESTION_REQUEST: {
+            return {
+                ...state,
+                isFetching: false,
+                payload
+            }
+        }
+        case actionTypes.DELETE_QUESTION_REQUEST_SUCCESS: {
+
+            return {
+                ...state,
+                isFetching: true,
+                payload
+            }
+        }
+        case actionTypes.DELETE_QUESTION_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 34 - 0
src/reducers/admin/test/deleteTopic.js

@@ -0,0 +1,34 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function deleteTopic(state = initialState.deleteTopic, {payload, type, error}) {
+
+    switch (type) { 
+        case actionTypes.DELETE_TOPIC_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                payload
+            }
+        }
+        case actionTypes.DELETE_TOPIC_REQUEST_SUCCESS: {
+
+            return {
+                ...state,
+                isFetching: false,
+                payload
+            }
+        }
+        case actionTypes.DELETE_TOPIC_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: true,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 36 - 0
src/reducers/admin/test/deleteUsers.js

@@ -0,0 +1,36 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function changeEmailReducer(state = initialState.deleteUsers, {  type, payload }) {
+    switch (type) {
+        case actionTypes.DELETE_USERS_REQUEST: {
+            return {
+                ...state,
+                isFetching: false,
+                payload
+            }
+        }
+        case actionTypes.DELETE_USERS_REQUEST_SUCCESS: {
+            // const { user:{email} } = payload;
+            // console.log(email)
+
+            return {
+                ...state,
+                isFetching: true,
+                data:payload
+            }
+        }
+        case actionTypes.DELETE_USERS_REQUEST_FAILURE: {
+            const { error } = payload;
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 36 - 0
src/reducers/admin/test/getAnswers.js

@@ -0,0 +1,36 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function getAnswers(state = initialState.arrayAnswers, { payload, type, error }) {
+
+    switch (type) {
+        case actionTypes.GET_ANSWERS_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                isFlag: false,
+                payload
+            }
+        }
+        case actionTypes.GET_ANSWERS_REQUEST_SUCCESS: {
+            const {data:{answers}}=payload
+            return {
+                ...state,
+                isFetching: false,
+                isFlag: true,
+                answers:answers
+            }
+        }
+        case actionTypes.GET_ANSWERS_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 36 - 0
src/reducers/admin/test/getQuestions.js

@@ -0,0 +1,36 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function getQuestions(state = initialState.arrayQuestions, { payload, type, error }) {
+
+    switch (type) {
+        case actionTypes.GET_QUESTIONS_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                isFlag: false,
+                payload
+            }
+        }
+        case actionTypes.GET_QUESTIONS_REQUEST_SUCCESS: {
+            const { data: { questions } } = payload
+            return {
+                ...state,
+                isFetching: false,
+                isFlag: true,
+                questions: questions
+            }
+        }
+        case actionTypes.GET_QUESTIONS_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 37 - 0
src/reducers/admin/test/getTopic.js

@@ -0,0 +1,37 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function getTopic(state = initialState.topic, {payload, type, error}) {
+
+    switch (type) { 
+        case actionTypes.GET_TOPIC_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                isFlag:false,
+                payload
+            }
+        }
+        case actionTypes.GET_TOPIC_REQUEST_SUCCESS: {
+const {data:{topics}} =payload
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:true,
+                topics
+            }
+        }
+        case actionTypes.GET_TOPIC_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 34 - 0
src/reducers/admin/test/newTopic.js

@@ -0,0 +1,34 @@
+import * as actionTypes from '../../../constants/admin';
+import initialState from '../../initialState';
+
+export default function newTopic(state = initialState.newTopic, {payload, type, error}) {
+
+    switch (type) { // payload.type -> type
+        case actionTypes.CHANGE_TEST_REQUEST: {
+            return {
+                ...state,
+                isFetching: false,
+                // payload
+            }
+        }
+        case actionTypes.CHANGE_TOPIC_REQUEST_SUCCESS: {
+const {data:{topic}}=payload
+            return {
+                ...state,
+                isFetching: true,
+                data:topic
+            }
+        }
+        // case actionTypes.CREATE_TOPICS_REQUEST_FAILURE: {
+
+        //     return {
+        //         ...state,
+        //         isFetching: false,
+        //         error
+        //     }
+        // }
+        default: {
+            return state;
+        }
+    }
+}

+ 31 - 0
src/reducers/auth/logOut.js

@@ -0,0 +1,31 @@
+import * as actionTypes from './../../constants/auth';
+import initialState from './../initialState';
+
+export default function signInReducer(state = initialState.logOut, {type, error}) {
+
+    switch (type) {
+        case actionTypes.LOG_OUT_REQUEST: {
+            return {
+                ...state,
+                isFetching: true
+            }
+        }
+        case actionTypes.LOG_OUT_REQUEST_SUCCESS: {
+            return {
+                ...state,
+                isFetching: false,
+                isSuccessful: true
+            }
+        }
+        case actionTypes.LOG_OUT_REQUEST_FAILURE: {
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 4 - 3
src/reducers/auth/signIn.js

@@ -11,23 +11,24 @@ export default function signInReducer(state = initialState.signIn, {payload, typ
             }
         }
         case actionTypes.SIGN_IN_REQUEST_SUCCESS: {
-            const { user, token } = payload;
+            const { user } = payload;
 
             return {
                 ...state,
                 isFetching: false,
                 data: user,
-                token
             }
         }
         case actionTypes.SIGN_IN_REQUEST_FAILURE: {
-
             return {
                 ...state,
                 isFetching: false,
                 error
             }
         }
+        case actionTypes.SIGN_IN_STATE_ZEROING: {
+            return initialState.signIn
+        }
         default: {
             return state;
         }

+ 22 - 0
src/reducers/auth/tokenCheckout.js

@@ -0,0 +1,22 @@
+import * as actionTypes from './../../constants/auth';
+import initialState from './../initialState';
+
+export default function signInReducer(state = initialState.tokenCheckout, {type, payload: role, error}) {
+    switch(type) {
+        case actionTypes.ACTIVE_TOKEN: {
+            return {
+                ...state,
+                role
+            }
+        }
+        case actionTypes.INACTIVE_TOKEN: {
+            return {
+                ...state,
+                role: null
+            }
+        }
+        default: {  
+            return state;
+        }
+    }
+}

+ 40 - 1
src/reducers/index.js

@@ -3,15 +3,54 @@ import { reducer as form } from 'redux-form';
 
 import signIn from './auth/signIn';
 import signUp from './auth/signUp';
+import logOut from './auth/logOut';
+import tokenCheckout from './auth/tokenCheckout';
 
+import category from './admin/getCategory';
+import newCategory from './admin/createCategory';
+import topicId from './admin/test/createTopics';
+import topic from './admin/test/getTopic';
+import deleteTopic from './admin/test/deleteTopic';
+import deleteQuestion from './admin/test/deleteQuestion';
+import arrayAnswers from './admin/test/getAnswers'
+import changeUser from './admin/test/changeUser';
+import deleteUsers from './admin/test/deleteUsers';
+import newTopic from './admin/test/newTopic';
+import changeCategory from './admin/changeCategory';
+import arrayQuestions from './admin/test/getQuestions';
+
+
+import topicTest from './user/getTopicTest';
 import chageLoginReducer from './user/chageLogin';
 import changeEmailReducer from './user/changeEmail';
+import myUser from './user/myUser'
+import users from './admin/getUsers'
+import startTest from './user/startTest'
 
 export default combineReducers({
 
+    tokenCheckout,
+    logOut,
+
     signIn,
     signUp,
     chageLoginReducer,
     changeEmailReducer,
-    form
+    form,
+    category,
+    changeCategory,
+    newCategory,
+    topicId,
+    myUser,
+    users,
+    topic,
+    arrayQuestions,
+    deleteTopic,
+    deleteQuestion,
+    arrayAnswers,
+    changeUser,
+    deleteUsers, 
+    newTopic,
+    topicTest,
+    startTest
 })

+ 102 - 4
src/reducers/initialState.js

@@ -1,22 +1,120 @@
 export default {
+
+    users: {
+        isFetching: false,
+        user: null,
+        error: null
+    },
+    changeLogin: {
+        isFetching: false,
+        data: null,
+        error: null
+    },
+    changeEmail: {
+        isFetching: false,
+        data: null,
+        error: null
+    },
+    deleteTopic:{
+        isFetching:true,
+    },
+    deleteQuestion:{
+        isFetching:false,
+    },
+
     signIn: {
         isFetching: false,
         data: null,
-        error: null,
-        token: null
+        error: null
     },
     signUp: {
+        isFetching: false,
+        data: null,
+        error: null
+    },
+    category: {
+        data: null,
+        isFetching: false,
+        error: null,
+        isFlag: false
+    },
+    topicId: {
+        isFetching: false,
+        error: null
+    },
+    topic: {
+        // topic:null,
+        isFetching: true,
+        error: null
+    }
+    ,
+ 
+    newCategory: {
+        data: null,
+        isFetching: false,
+        error: null,
+        isFlag: false
+    },
+    logOut: {
         isFetching: false,
         isSuccessful: null,
         error: null
     },
-    changeLogin:{
+    tokenCheckout: {
+        role: null
+    },
+    myUser: {
+        data: null,
+        isFetching: false,
+        error: null
+    },
+    changeCategory: {
+        isFetching: false,
+        isFlag: false,
+        data: null,
+        error: null
+    }
+    ,
+    arrayQuestions: {
+        isFetching: false,
+        isFlag: false,
+        questions: null,
+        error: null
+    },
+    arrayAnswers: {
+        isFetching: false,
+        isFlag: false,
+        answers: null,
+        error: null
+    }, 
+    changeUser:{
+        data: null,
+        isFetching: false,
+        error: null
+    },
+    deleteUsers:{
+        data: null,
+        isFetching: false,
+        error: null
+    },
+    newTopic:{
+        data: null,
         isFetching: false,
+        error: null
+    },
+    topicTest:{
+        topic:null,
+        isFetching: true,
+        isFlag:false,
+    },
+    newTopic:{
         data: null,
+        isFetching: false,
         error: null
     },
-    changeEmail:{
+    startTest:{
         isFetching: false,
+        isFlag: false,
         data: null,
         error: null
     },

+ 0 - 1
src/reducers/user/chageLogin.js

@@ -4,7 +4,6 @@ import initialState from './../initialState';
 export default function chageLoginReducer(state = initialState.changeLogin, {  type, payload }) {
     switch (type) {
         case actionTypes.CHANGE_LOGIN_REQUEST: {
-            console.log(payload)
             return {
                 ...state,
                 isFetching: true,

+ 0 - 1
src/reducers/user/changeEmail.js

@@ -4,7 +4,6 @@ import initialState from './../initialState';
 export default function changeEmailReducer(state = initialState.changeEmail, {  type, payload }) {
     switch (type) {
         case actionTypes.CHANGE_EMAIL_REQUEST: {
-            console.log(payload)
             return {
                 ...state,
                 isFetching: true,

+ 36 - 0
src/reducers/user/getTopicTest.js

@@ -0,0 +1,36 @@
+import * as actionTypes from '../../constants/user';
+import initialState from '../initialState';
+
+export default function getTopicTest(state = initialState.startTest, {payload, type, error}) {
+
+    switch (type) { 
+        case actionTypes.GET_TOPIC_TEST_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                isFlag:false
+            }
+        }
+        case actionTypes.GET_TOPIC_TEST_REQUEST_SUCCESS: {
+const {data:{topics}} =payload
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:true,
+                topic:topics
+            }
+        }
+        case actionTypes.GET_TOPIC_TEST_REQUEST_FAILURE: {
+
+            return {
+                ...state,
+                isFetching: false,
+                isFlag:false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 33 - 0
src/reducers/user/myUser.js

@@ -0,0 +1,33 @@
+import * as actionTypes from './../../constants/admin';
+import initialState from './../initialState';
+
+export default function myUser(state = initialState.myUser, {  type, payload }) {
+    switch (type) {
+        case actionTypes.MY_USER_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                payload
+            }
+        }
+        case actionTypes.MY_USER_REQUEST_SUCCESS: {
+            const {data} =payload
+            return {
+                ...state,
+                isFetching: false,
+                data:data
+            }
+        }
+        case actionTypes.MY_USER_REQUEST_FAILURE: {
+            const { error } = payload;
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 41 - 0
src/reducers/user/startTest.js

@@ -0,0 +1,41 @@
+import * as actionTypes from '../../constants/user';
+import initialState from '../initialState';
+
+export default function startTest(state = initialState.startTest, {  type, payload }) {
+    switch (type) {
+        case actionTypes.START_TEST_REQUEST: {
+            return {
+                ...state,
+                isFetching: true,
+                payload
+            }
+        }
+        case actionTypes.START_TEST_REQUEST_SUCCESS: {
+            const {data} =payload
+            return {
+                ...state,
+                isFetching: false,
+                data:data
+            }
+        }
+        case actionTypes.NEXT_TEST_REQUEST_SUCCESS: {
+            const {data} =payload
+            return {
+                ...state,
+                isFetching: false,
+                data:data
+            }
+        }
+        case actionTypes.START_TEST_REQUEST_FAILURE: {
+            const { error } = payload;
+            return {
+                ...state,
+                isFetching: false,
+                error
+            }
+        }
+        default: {
+            return state;
+        }
+    }
+}

+ 0 - 0
src/router.js


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików