From 9f7a3199130ccbde2b8baa49ddfcd8d84c6c62da Mon Sep 17 00:00:00 2001 From: Thomas Berrod Date: Wed, 26 Jun 2019 17:28:38 +0200 Subject: [PATCH] register form --- nextjs/actions/user.js | 5 +- nextjs/components/organisms/Register.js | 177 +++++++++++++++------ nextjs/pages/Login.js | 198 +++++++++++++++++++----- nextjs/pages/VerifyEmail.js | 11 ++ nextjs/pages/index.js | 2 - nextjs/reducers/user.js | 2 +- nextjs/rootSaga.js | 4 +- nextjs/sagas/userSaga.js | 10 +- nextjs/server.js | 13 +- webRTC/pages/parametres.js | 1 - 10 files changed, 327 insertions(+), 96 deletions(-) create mode 100644 nextjs/pages/VerifyEmail.js diff --git a/nextjs/actions/user.js b/nextjs/actions/user.js index 398ad6d15..8474b2bb9 100644 --- a/nextjs/actions/user.js +++ b/nextjs/actions/user.js @@ -23,8 +23,9 @@ export const fetchCurrentUserFailure = user => ({ user }); -export const registerUserRequest = () => ({ - type: REQUEST_REGISTER +export const registerUserRequest = (payload) => ({ + type: REQUEST_REGISTER, + payload }); export const registerUserSuccess = () => ({ diff --git a/nextjs/components/organisms/Register.js b/nextjs/components/organisms/Register.js index a3f5699dd..8ef76f874 100644 --- a/nextjs/components/organisms/Register.js +++ b/nextjs/components/organisms/Register.js @@ -1,8 +1,15 @@ -import React from 'react'; -import { TextField, FormGroup, FormControlLabel, Checkbox, Button, Typography, Link } from '@material-ui/core'; +import React, {Fragment} from 'react'; +import { connect } from "react-redux"; +import Validator from "validator"; +import {FormLabel, FormHelperText,InputLabel, Input,TextField, FormGroup, FormControlLabel, Checkbox, Button, Typography, Link } from '@material-ui/core'; +import Visibility from '@material-ui/icons/Visibility'; +import VisibilityOff from '@material-ui/icons/VisibilityOff'; +import IconButton from '@material-ui/core/IconButton'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import FormControl from '@material-ui/core/FormControl'; import { withStyles } from '@material-ui/core/styles'; - +import { registerUserRequest, subscribeToNewsletterRequest } from "../../actions/user" const styles = theme => ({ container: { @@ -20,22 +27,84 @@ const styles = theme => ({ input50: { width: '50%', }, + checkboxError:{ + color:'red' + } }); class Register extends React.Component { state = { - prenom:'', - nom:'', - email:'', - password:'', - checkNewsletter:false, - checkCGU:false - + data: { + prenom: '', + nom: '', + email: '', + password: '', + checkNewsletter: false, + checkCGU: false, + }, + errors: {}, + loading: false, + showPassword:false } + validate = data => { + const errors = {}; + if (!Validator.isEmail(data.email)) errors.email = "Email invalide"; + if (!!!data.password) errors.password = "Requis"; + if (!!!data.prenom) errors.prenom = "Requis"; + if (!!!data.nom) errors.nom = "Requis"; + if (!data.checkCGU) errors.checkCGU = "Requis"; + + return errors; + }; + + onRegister = e => { + e.preventDefault(); + const errors = this.validate(this.state.data); + console.log('onSubmit') + console.log(errors) + this.setState({ errors: errors }); + + if (Object.keys(errors).length === 0) { + this.setState({ loading: true }); + + this.props.registerUserRequest(this.state.data) + + if (this.state.data.checkNewsletter) + this.props.subscribeToNewsletterRequest({ email: this.state.data.email }) + } + + }; + + componentWillReceiveProps(nextProps) { + this.setState({ + errors: nextProps.errors, + loading: nextProps.loading + }) + } + onChange = e => + this.setState({ + data: { ...this.state.data, [e.target.name]: e.target.value } + }); + handleCheckBoxChange = name => event => { + this.setState({data:{ ...this.state.data, [name]: event.target.checked }}); + }; + + handleChangePasswordVisibility = prop => event => { + this.setState({ [prop]: event.target.value }); + }; + + handleClickShowPassword = () => { + this.setState({ showPassword: !this.state.showPassword }); + }; + render() { const { classes } = this.props; + const { data, errors } = this.state; + console.log('render errors'); + console.log(errors); + console.log(this.state); return (
@@ -43,77 +112,86 @@ class Register extends React.Component {
- - + + Password * + + + {this.state.showPassword ? : } + + + } + autoComplete="current-password" + error={!!errors.password} + /> + } label="Je souhaite recevoir la newsletter de Talents Tube" + /> + } - label="Je déclare avoir pris connaissance et accepte les termes et les CGU" + label="Je déclare avoir pris connaissance et accepte les termes et les CGU*" required - error={this.state.checkCGU === false} - helperText={this.state.checkCGU === "" ? 'Ce champ est requis!' : ' '} /> - - @@ -123,10 +201,10 @@ class Register extends React.Component { >Ou - -
@@ -145,4 +223,11 @@ class Register extends React.Component { } } -export default withStyles(styles)(Register); \ No newline at end of file +function mapStateToProps(state) { + return { + loading: !!state.user.loading, + errors: state.user.errors + }; +} + +export default withStyles(styles)(connect(mapStateToProps, { registerUserRequest, subscribeToNewsletterRequest })(Register)); \ No newline at end of file diff --git a/nextjs/pages/Login.js b/nextjs/pages/Login.js index d6d4a01b1..1f7292fab 100644 --- a/nextjs/pages/Login.js +++ b/nextjs/pages/Login.js @@ -12,9 +12,53 @@ import Validator from "validator"; import Tabs from '@material-ui/core/Tabs'; import Tab from '@material-ui/core/Tab'; import Router from 'next/router' - +import Register from '../components/organisms/Register'; +import Snackbar from '@material-ui/core/Snackbar'; +import SnackbarContent from '@material-ui/core/SnackbarContent'; import { requestLogin, requestOauthLogin,requestLoginFailure } from "../actions/auth"; +import { makeStyles } from '@material-ui/core/styles'; +import clsx from 'clsx'; +import CheckCircleIcon from '@material-ui/icons/CheckCircle'; +import IconButton from '@material-ui/core/IconButton'; +import ErrorIcon from '@material-ui/icons/Error'; +import InfoIcon from '@material-ui/icons/Info'; +import CloseIcon from '@material-ui/icons/Close'; +import WarningIcon from '@material-ui/icons/Warning'; +import { amber, green } from '@material-ui/core/colors'; +import _ from "lodash" +const variantIcon = { + success: CheckCircleIcon, + warning: WarningIcon, + error: ErrorIcon, + info: InfoIcon, + }; + + const useStyles1 = makeStyles(theme => ({ + success: { + backgroundColor: green[600], + }, + error: { + backgroundColor: theme.palette.error.dark, + }, + info: { + backgroundColor: theme.palette.primary.main, + }, + warning: { + backgroundColor: amber[700], + }, + icon: { + fontSize: 20, + }, + iconVariant: { + opacity: 0.9, + marginRight: theme.spacing(1), + }, + message: { + display: 'flex', + alignItems: 'center', + }, + })); function TabContainer({ children, dir }) { return ( @@ -55,13 +99,37 @@ class LoginPage extends React.Component { }, errors: {}, loading: false, - tabIndex:0 + tabIndex:0, + openSnack:false }; + + static getInitialProps({query}) { + + const { error } = query + console.log("LoginPage getInitialProps") + console.log(error) + console.log("LoginPage getInitialProps") + return { errors: {message:error}, openSnack:!!error }; + } + componentWillReceiveProps(nextProps) { + console.log("LoginPage componentWillReceiveProps") + console.log(nextProps) + console.log(!!nextProps.errors) + console.log("LoginPage componentWillReceiveProps") this.setState({ errors: nextProps.errors, - loading: nextProps.loading + loading: nextProps.loading, + openSnack: _.isEmpty(nextProps.errors) }) + console.log("LoginPage componentWillReceiveProps 2") + console.log(nextProps) + console.log("LoginPage componentWillReceiveProps 2") + } + + componentDidMount() + { + } onChange = e => @@ -104,43 +172,55 @@ class LoginPage extends React.Component { Router.push('/auth/facebook') } - handleChange= (event, newValue) => { + handleChange = (event, newValue) => { console.log('handleChange') this.setState({ tabIndex: newValue }); } - handleChangeIndex= (index) =>{ + handleChangeIndex = (index) => { console.log('handleChangeIndex') this.setState({ tabIndex: index }); } + + handleClose = (event, reason) => { + // if (reason === 'clickaway') { + // return; + // } + + this.setState({ openSnack: false }); + } render() { const { classes } = this.props; - const { data, errors, loading } = this.state; + const { data, errors, loading, openSnack } = this.state; + + console.log("render this.state") + console.log(this.state) + console.log("this.state") return (
- {!!errors && ( -
{errors.message}
- )} + {/* {!!errors && ( +
{errors && errors.message}
+ )} */} {loading && (
Chargement...
)} {!loading && ( - - - - - - - + + + + + + + @@ -208,32 +288,78 @@ class LoginPage extends React.Component { Je ne possède pas de compte Talents Tube ? - + >Je ne possède pas de compte Talents Tube ? + this.handleChangeIndex(1)} className={classes.link}> S'inscrire - +
+
{this.state.openSnack} +
- - Item Two - - - + + + + + + )}
+ + + + ); } } -function mapStateToProps(state) { +function mapStateToProps(state,ownProps) { return { + openSnack:!_.isEmpty(ownProps.errors), loading: !!state.user.loading, - errors: state.user.errors + errors: state.user.errors || ownProps.errors }; } +function MySnackbarContentWrapper(props) { + const classes = useStyles1(); + const { className, message, onClose, variant, ...other } = props; + const Icon = variantIcon[variant]; + + return ( + + + {message} + + } + action={[ + + + , + ]} + {...other} + /> + ); + } export default withStyles(styles)(connect(mapStateToProps, { requestLogin, requestOauthLogin, requestLoginFailure })(LoginPage)); \ No newline at end of file diff --git a/nextjs/pages/VerifyEmail.js b/nextjs/pages/VerifyEmail.js new file mode 100644 index 000000000..518352165 --- /dev/null +++ b/nextjs/pages/VerifyEmail.js @@ -0,0 +1,11 @@ +import React, { Component } from 'react' + +export default class VerifyEmail extends Component { + render() { + return ( +
+ Vérifiez vos email pour confirmer votre inscription. +
+ ) + } +} diff --git a/nextjs/pages/index.js b/nextjs/pages/index.js index 891934c1a..603aa4590 100644 --- a/nextjs/pages/index.js +++ b/nextjs/pages/index.js @@ -104,8 +104,6 @@ class Index extends React.Component { - - diff --git a/nextjs/reducers/user.js b/nextjs/reducers/user.js index 7ac03874b..0ac854ac9 100644 --- a/nextjs/reducers/user.js +++ b/nextjs/reducers/user.js @@ -42,7 +42,7 @@ export function user(state = { case REQUEST_LOGIN_FAILURE: return { loading: false, - errors: { ...action.data.message }, + errors: { ...action.message }, } case FETCH_CURRENT_USER_REQUEST: return { diff --git a/nextjs/rootSaga.js b/nextjs/rootSaga.js index d973fe836..84833affa 100644 --- a/nextjs/rootSaga.js +++ b/nextjs/rootSaga.js @@ -3,13 +3,14 @@ import { all, call, delay, put, take, takeLatest } from 'redux-saga/effects' import es6promise from 'es6-promise' -import { requestLoginSaga, requestUserSaga, requestLogoutSaga, requestNewsletterSubscribitionSaga} from './sagas/userSaga.js' +import { requestLoginSaga, requestUserSaga, requestRegisterSaga, requestLogoutSaga, requestNewsletterSubscribitionSaga} from './sagas/userSaga.js' import { requestAdsSaga, requestAdSaga, requestPromotedAdsSaga } from './sagas/offreSaga.js' import {requestCompaniesSaga} from './sagas/companySaga.js' import { REQUEST_LOGIN, REQUEST_LOGOUT, + REQUEST_REGISTER, FETCH_CURRENT_USER_REQUEST, FETCH_ADS_REQUEST, FETCH_AD_REQUEST, @@ -26,6 +27,7 @@ function* rootSaga() { yield all([ takeLatest(REQUEST_LOGIN, requestLoginSaga), takeLatest(REQUEST_LOGOUT, requestLogoutSaga), + takeLatest(REQUEST_REGISTER, requestRegisterSaga), takeLatest(FETCH_CURRENT_USER_REQUEST, requestUserSaga), takeLatest(SUBSCRIBE_NEWSLETTER_REQUEST, requestNewsletterSubscribitionSaga), takeLatest(FETCH_ADS_REQUEST, requestAdsSaga), diff --git a/nextjs/sagas/userSaga.js b/nextjs/sagas/userSaga.js index ed458ffdb..946db89b6 100644 --- a/nextjs/sagas/userSaga.js +++ b/nextjs/sagas/userSaga.js @@ -1,8 +1,11 @@ import { call, put } from "redux-saga/effects"; -import { userLoggedIn, requestLoginFailure,userLoggedOut } from "../actions/auth"; -import { fetchCurrentUserSuccess, fetchCurrentUserFailure, - subscribeToNewsletterSuccess,subscribeToNewsletterFailure } from "../actions/user"; +import { userLoggedIn, requestLoginFailure, userLoggedOut } from "../actions/auth"; +import { + fetchCurrentUserSuccess, fetchCurrentUserFailure, + subscribeToNewsletterSuccess, subscribeToNewsletterFailure, + registerUserSuccess, registerUserFailure +} from "../actions/user"; import setAuthorizationHeader from "../data/setAuthorizationHeader"; import api from "../data/api"; @@ -100,6 +103,7 @@ export function* requestRegisterSaga(action) { if (res.data.success === true) { yield put(registerUserSuccess(res)); + Router.push('/VerifyEmail'); } else throw new Error("not subscribed") diff --git a/nextjs/server.js b/nextjs/server.js index efd9aea50..654f73f34 100644 --- a/nextjs/server.js +++ b/nextjs/server.js @@ -70,12 +70,13 @@ app.prepare() server.use(passport.initialize()); server.get('/auth/facebook', - passport.authorize('facebook', { scope: ['email', 'public_profile'], session: false })); + passport.authorize('facebook', { scope: ['email', 'public_profile'], session: false, failureRedirect: '/login'})); server.get('/auth/facebook/callback', passport.authorize('facebook', { failureRedirect: '/login', session: false }), (req, res) => { - // Successful authentication, redirect home. + + console.log('facebookcallback') console.log(req.account)//don't understand why ! // console.log(req.accessToken) @@ -91,11 +92,15 @@ app.prepare() }) server.get('/auth/linkedin', - passport.authorize('linkedin', { scope: ['r_basicprofile', 'r_emailaddress', 'r_liteprofile'], session: false })); + passport.authorize('linkedin', { scope: ['r_basicprofile', 'r_emailaddress', 'r_liteprofile'], session: false , failureRedirect: '/login'})); server.get('/auth/linkedin/callback', passport.authorize('linkedin', { failureRedirect: '/login', session: false }), - function (req, res) { + function (error, req, res, next) { + if (error) { + console.log(error) + return res.redirect('/login?error='+error.message) + } // Successful authentication, redirect home. console.log('linkedincallback') console.log(req.accessToken) diff --git a/webRTC/pages/parametres.js b/webRTC/pages/parametres.js index 7316156d2..b6483e661 100644 --- a/webRTC/pages/parametres.js +++ b/webRTC/pages/parametres.js @@ -119,7 +119,6 @@ class parametres extends Component { const topicsTemp = cloneDeep(this.state.topics) topicsTemp.map(temp => temp.value = !!topics[temp.key] - ) this.setState({ topics: topicsTemp }) }