Browse Source

profile changes:added login ahd password

Svetlana 6 years ago
parent
commit
f46920a81d

+ 16 - 0
src/actions/userFields/changeEmail.js

@@ -0,0 +1,16 @@
+import * as types from '../../constants';
+
+export const userChangeRequest = payload => ({
+    type: types.USERS_CHANGE_REQUEST,
+    payload
+})
+
+export const userChangeRequestSucces = payload => ({
+    type: types.USERS_CHANGE_REQUEST_SUCCESS,
+    payload
+})
+
+export const userChangeRequestFailure = error => ({
+    type: types.USERS_CHANGE_REQUEST_FAILURE,
+    error
+})

+ 16 - 0
src/actions/userFields/changePassword.js

@@ -0,0 +1,16 @@
+import * as types from '../../constants';
+
+export const passwordChangeRequest = payload => ({
+    type: types.PASSWORD_CHANGE_REQUEST,
+    payload
+})
+
+export const passwordChangeRequestSucces = payload => ({
+    type: types.PASSWORD_CHANGE_REQUEST_SUCCESS,
+    payload
+})
+
+export const passwordChangeRequestFailure = error => ({
+    type: types.PASSWORD_CHANGE_REQUEST_FAILURE,
+    error
+})

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

@@ -32,9 +32,10 @@ export default class header extends Component {
                     <h1 className="header__logo">Test.<span className="header__logo--i-letter">i</span>o</h1>
                 </Link>
                 <hr className="header__logo--divider" />
-                <span className="header__toggle-trigger" onClick={this.handleToggle} >
+                {/* <span className="header__toggle-trigger" onClick={this.handleToggle} >
                     <span />
-                </span>
+                </span> */}
+                <button style={{ position: "absolute", top: '85px', left: 0 }} onClick={this.handleToggle}>HEADER TOGGLE</button>
                 <div className="header__flex-wrapper">
                     <nav className={`header__nav ${toggleStatus}`}>
                         <ul className="header__nav nav__list"  >

+ 52 - 0
src/components/user-components/profilePage/LoginFild/index.js

@@ -0,0 +1,52 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { Field } from 'redux-form';
+
+import ChangeLoginForm from './loginChangeForm';
+
+export default class ChangeLogin extends React.Component {
+
+    state = {
+        clicked: false,
+        newLogin: null
+    }
+
+    submit = ({ login }) => {
+        console.log('handleSubmit->submit', this.props)
+        const { actions: { userChangeRequest }, user: { data: { id } } } = this.props;
+
+        console.log('id', id);
+
+        userChangeRequest({
+            login,
+            id
+        })
+    }
+
+    handleClick = () => {
+        this.setState((prevState) => ({ clicked: !prevState.clicked }));
+    }
+
+    render() {
+        const { handleClick, submit } = this;
+        const { clicked } = this.state;
+        const { children } = this.props;
+
+        return (
+            !clicked
+                ?
+                (
+                    <React.Fragment>
+                        <div>{children}</div>
+                        <button onClick={handleClick}>Change Email</button>
+                    </React.Fragment>
+                )
+                : (
+                    <React.Fragment>
+                        <div>{children}</div>
+                        <ChangeLoginForm handlers={{ handleClick, submit }} />
+                    </React.Fragment>
+                )
+        )
+    }
+}

+ 34 - 0
src/components/user-components/profilePage/LoginFild/loginChangeForm/index.js

@@ -0,0 +1,34 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { Field, reduxForm } from 'redux-form';
+
+import formInput from '../../../../common/formInput';
+import validate from '../../../../public-components/auth/signUpForm/validate';
+
+class ChangeLoginForm extends React.Component {
+
+    render() {
+        const { children, handleSubmit, handlers: { handleClick, submit } } = this.props;
+        return (
+            <form onSubmit={handleSubmit(submit)} >
+                <Field name="login" type="email" placeholder="Enter new login" component={formInput} />
+                <button
+                    type="button"
+                    onClick={
+                        function() {
+                            handleClick();
+                            handleSubmit(submit)();
+                        }    
+                    }
+                >
+                    Change
+                </button>
+            </form >
+        )
+    }
+}
+
+export default reduxForm({
+    form: "changeLogin",
+    validate
+})(ChangeLoginForm);

+ 25 - 0
src/components/user-components/profilePage/PasswordFields/PasswordChangeForm/index.js

@@ -0,0 +1,25 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { Field, reduxForm } from 'redux-form';
+
+import formInput from '../../../../common/formInput';
+import validate from '../PasswordChangeForm/validate/index';
+
+class ChangePasswordForm extends React.Component {
+
+    render() {
+        const { children, handleSubmit, handlers: { handleClick, submit } } = this.props;
+        return (
+            <form onSubmit={handleSubmit(submit)} >
+                <Field name="passwordConfirmation" type="password" placeholder="Enter password" component={formInput} />
+                <Field name="password" type="password" placeholder="Enter new password" component={formInput} />
+                <button onClick={handleClick}>Change</button>
+            </form >
+        )
+    }
+}
+
+export default reduxForm({
+    form: "changePassword",
+    validate
+})(ChangePasswordForm);

+ 24 - 0
src/components/user-components/profilePage/PasswordFields/PasswordChangeForm/validate/index.js

@@ -0,0 +1,24 @@
+export default function validate(values) {
+    const {  password, passwordConfirmation } = values;
+    const errors = {};
+
+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!";
+}
+    }

+ 52 - 0
src/components/user-components/profilePage/PasswordFields/index.js

@@ -0,0 +1,52 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { Field } from 'redux-form';
+
+import ChangePasswordForm from './PasswordChangeForm'
+
+export default class ChangePassword extends React.Component {
+
+    state = {
+        clicked: false,
+    }
+    
+    submit = ({ password }) => {
+        console.log('handleSubmit->submit', this.props)
+        const { actions: { passwordChangeRequest }, user: { data: { id } } } = this.props;
+
+        console.log('id', id);
+
+         passwordChangeRequest({
+            password,
+            id
+        })
+    }
+
+    handleClick = () => {
+        this.setState((prevState) => ({ clicked: !prevState.clicked }));
+    }
+
+    render() {
+        const { handleClick, submit } = this;
+        const { clicked } = this.state;
+        const { children } = this.props;
+
+        return (
+            !clicked
+                ?
+                (
+                    <React.Fragment>
+                        <div>{children}</div>
+                        <button onClick={handleClick}>Change password</button>
+                    </React.Fragment>
+                    
+                )
+                : (
+                    <React.Fragment>
+                        <div>{children}</div>
+                        <ChangePasswordForm handlers={{ handleClick, submit }} />
+                    </React.Fragment>
+                )
+        )
+    }
+}

+ 44 - 22
src/components/user-components/profilePage/index.js

@@ -1,52 +1,73 @@
 import React from 'react';
 import { connect } from 'react-redux';
-// import { bindActionCreators } from 'redux'
+import { bindActionCreators } from 'redux'
 // import {} from './../../../actions'
 import axios from 'axios';
+import { userChangeRequest } from '../../../actions/userFields/changeEmail'
+import {passwordChangeRequest} from '../../../actions/userFields/changePassword'
+
+import ChangeLogin from './LoginFild';
+import ChangePassword from './PasswordFields'
 
 // redux-connected container
 
 class profilePage extends React.Component {
 
     state = {
-        user: {}
+        files: null,
+        photo: null
     }
+    change = e => {
+        const reader = new FileReader();
+
+        const file = e.target.files[0];
+        this.setState({ file });
+
+        reader.onloadend = () => {
+            this.setState({
+                photo: reader.result
+            });
+        };
+        reader.readAsDataURL(file);
+    };
 
-    getUser = () => {
-        const randomUserId = Math.ceil(Math.random() * 10);
+    post = () => {
+        const file = new FormData();
 
-        axios.post(`https://quiz.maxcrc.de/api/v1/user`,{
-            "login": 'ddd',
-            "password":"jhgfhgg"
+        file.append("profilePhoto", this.state.file);
+    };
 
+    lol = () => {
+        const { user: { data: { id } }, userChangeRequest } = this.props;
+
+        userChangeRequest({
+            id,
+            login: "lol wtf"
         })
-            .then(({ data }) => this.setState({
-                user: data
-            }))
-            .catch(({ message }) => console.warn(message))
     }
 
-    componentDidMount() {
-        this.getUser();
-    }
 
     render() {
-        const { user } = this.state;
+        const { user, userChangeRequest } = this.props;
 
-        console.log(user);
+        // console.log('User', user);
+        // console.log('Props', this.props);
+        // console.log('State', this.state);
 
         return (
             <div className="page page--bottom-only profile-page">
                 <section className="container section section--about">
+                    <button onClick={this.lol}>adlkasjdakl</button>
                     <h2 className="section__element section__element--header">{user.login}</h2>
                     <img className="section__element section__element--image" src={user.avatar} alt="avatar" />
                     <div className="sedtion__element section__element--login">
                         <h3>Login</h3>
-                        <p>{user.login}<button className="link link--btn right">Change login</button></p>
+                        {/* <p>{user.login}<button className="link link--btn right" >Change login</button></p> */}
+                        <ChangeLogin className="link link--btn right" user={user} actions={{ userChangeRequest }}>{user.login}</ChangeLogin>
                     </div>
                     <div className="section__element section__element--">
-                        <h3>E-mail</h3>
-                        <p>{user.email}<button className="link link--btn right">Change e-mail</button></p>
+                        <h3>Password</h3>
+                        <ChangePassword className="link link--btn right" user={user} actions={{ passwordChangeRequest }}>{user.password}</ChangePassword>
                     </div>
                     <div className="section__element section__element--">
                         <h3>Status</h3>
@@ -82,8 +103,9 @@ class profilePage extends React.Component {
 const
     mapStateToProps = state => ({
         user: state.user
-    })
-// mapDispatchToProps = dispatch => bindActionCreators({}, dispatch)
+    });
+
+const mapDispatchToProps = dispatch => bindActionCreators({ userChangeRequest, passwordChangeRequest }, dispatch);
 
-export default connect(mapStateToProps)(profilePage);
+export default connect(mapStateToProps, mapDispatchToProps)(profilePage);
 

+ 8 - 0
src/constants/index.js

@@ -19,3 +19,11 @@ export const USERS_GET_REQUEST_SUCCESS_FAILURE = 'USERS_GET_REQUEST_FAILURE';
 
 export const TOKEN_AUTH = 'TOKEN_AUTH';
 
+export const USERS_CHANGE_URL = 'https://quiz.maxcrc.de/api/v1/user/';
+export const USERS_CHANGE_REQUEST = 'USERS_CHANGE_REQUEST';
+export const USERS_CHANGE_REQUEST_SUCCESS = 'USERS_CHANGE_REQUEST_SUCCESS';
+export const USERS_CHANGE_REQUEST_FAILURE = 'USERS_CHANGE_REQUEST_FAILURE';
+
+export const PASSWORD_CHANGE_REQUEST = 'PASSWORD_CHANGE_REQUEST';
+export const PASSWORD_CHANGE_REQUEST_SUCCESS = 'PASSWORD_CHANGE_REQUEST_SUCCESS';
+export const PASSWORD_CHANGE_REQUEST_FAILURE = 'PASSWORD_CHANGE_REQUEST_FAILURE';

+ 9 - 1
src/reducers/index.js

@@ -4,11 +4,19 @@ import { combineReducers } from 'redux';
 
 
 import user from './user';
+
+import changeEmail from './userFields/changeEmail/index';
+import changePassword from './userFields/changePassword/index'
+
 import { reducer as form } from 'redux-form';
 
+
+
 const combinedReducers = combineReducers({
     form,
-    user
+    user,
+    changeEmail,
+    changePassword
 })
 
 export default combinedReducers;

+ 7 - 1
src/reducers/initialState/index.js

@@ -1,9 +1,15 @@
 export default {
     user: {
-        
         data: null,
         error: null,
         gettingUser: null,
         isAdmin: null
+    },
+    changeEmail: {
+        login: null
+    },
+    
+    changePassword: {
+        password: null
     }
 }

+ 25 - 0
src/reducers/userFields/changeEmail/index.js

@@ -0,0 +1,25 @@
+import * as types from "../../../constants";
+import initialState from '../../initialState';
+
+export default function changeEmail(state = initialState.changeEmail, {type, payload: login, error }) {
+    switch (type) {
+        case types.USERS_CHANGE_REQUEST: {
+            return state
+        }
+        case types.USERS_CHANGE_REQUEST_SUCCESS: {
+            return {
+                ...state,
+                login
+            }
+        }
+        case types.USERS_CHANGE_REQUEST_FAILURE: {
+            return {
+                ...state,
+                error
+            }
+        }
+        default: {
+            return state
+        }
+    }
+}

+ 25 - 0
src/reducers/userFields/changePassword/index.js

@@ -0,0 +1,25 @@
+import * as types from "../../../constants";
+import initialState from '../../initialState';
+
+export default function changePassword(state = initialState.changePassword, {type, payload: password, error }) {
+    switch (type) {
+        case types.PASSWORD_CHANGE_REQUEST: {
+            return state
+        }
+        case types.PASSWORD_CHANGE_REQUEST_SUCCESS: {
+            return {
+                ...state,
+                password
+            }
+        }
+        case types.PASSWORD_CHANGE_REQUEST_FAILURE: {
+            return {
+                ...state,
+                error
+            }
+        }
+        default: {
+            return state
+        }
+    }
+}

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

@@ -8,12 +8,10 @@ import { SIGN_IN_URL} from '../../../constants/index'
 
 export default function* ({ payload: requestBody } ) {
     try {
-        // console.log('received request body from sign-in worker saga', requestBody);
         const payload = yield call(() =>
             axios.post(SIGN_IN_URL, {...requestBody})
                 .then(({ data }) => data)
         );
-        // console.log("Payload", payload);
         yield put(actions.signInRequestSucces(payload));
     }
     catch ({ message }) {

+ 7 - 2
src/saga/index.js

@@ -1,8 +1,13 @@
 import { fork } from "redux-saga/effects";
 import auth from './auth'
+import userFields from './userFields/index';
+import changePassworde from './userFields/index'
 
 
 export default function*() {
-    yield fork(auth);
-
+    yield [
+        fork(auth),
+        fork(userFields),
+        fork(changePassworde)
+    ];
 }

+ 18 - 0
src/saga/userFields/changeEmail/index.js

@@ -0,0 +1,18 @@
+import { put, call } from "redux-saga/effects";
+import * as actions from './../../../actions/userFields/changeEmail'
+import axios from 'axios';
+import { USERS_CHANGE_URL } from '../../../constants/index'
+
+export default function* ({payload}) {
+    try {
+        console.log("payload inside the saga", payload);
+        const payloads = yield call(() =>
+            axios.put(`${USERS_CHANGE_URL}${payload.id}`, payload.login)
+                .then(({ data }) => data)
+        );
+        yield put(actions.userChangeRequestSucces(payload));
+    }
+    catch ({ message }) {
+        yield put(actions.userChangeRequestFailure(message))
+    }
+}

+ 18 - 0
src/saga/userFields/changePassword/index.js

@@ -0,0 +1,18 @@
+import { put, call } from "redux-saga/effects";
+import * as actions from './../../../actions/userFields/changePassword'
+import axios from 'axios';
+import { USERS_CHANGE_URL } from '../../../constants/index'
+
+export default function* ({payload}) {
+    try {
+        console.log("payload inside the saga", payload);
+        const payloads = yield call(() =>
+            axios.put(`${USERS_CHANGE_URL}${payload.id}`, payload.password)
+                .then(({ data }) => data)
+        );
+        yield put(actions.passwordChangeRequestSucces(payloads));
+    }
+    catch ({ message }) {
+        yield put(actions.passwordChangeRequestFailure(message))
+    }
+}

+ 11 - 0
src/saga/userFields/index.js

@@ -0,0 +1,11 @@
+import { takeEvery } from "redux-saga/effects";
+import * as types from "./../../constants"
+
+import changeEmail from './changeEmail/index';
+import changePassword from "./changePassword";
+
+
+export default function*() {
+    yield takeEvery(types.USERS_CHANGE_REQUEST, changeEmail);
+    yield takeEvery(types.PASSWORD_CHANGE_REQUEST, changePassword)
+}