API & Client: registration controls
This commit is contained in:
@ -7,6 +7,7 @@
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-key-index": "^0.1.1",
|
||||
"react-redux": "^5.0.6",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^5.0.0-alpha.9",
|
||||
|
@ -1,9 +1,14 @@
|
||||
import keyIndex from 'react-key-index'
|
||||
import mpwoApi from '../mpwoApi'
|
||||
|
||||
function AuthError(message) {
|
||||
return { type: 'AUTH_ERROR', message }
|
||||
}
|
||||
|
||||
function AuthErrors(messages) {
|
||||
return { type: 'AUTH_ERRORS', messages }
|
||||
}
|
||||
|
||||
function ProfileSuccess(message) {
|
||||
return { type: 'PROFILE_SUCCESS', message }
|
||||
}
|
||||
@ -27,6 +32,11 @@ const updateFormDataPassword = value => ({
|
||||
password: value,
|
||||
})
|
||||
|
||||
const updateFormDataPasswordConf = value => ({
|
||||
type: 'UPDATE_FORMDATA_PASSWORD_CONF',
|
||||
passwordConf: value,
|
||||
})
|
||||
|
||||
export function getProfile(dispatch) {
|
||||
return mpwoApi
|
||||
.getProfile()
|
||||
@ -46,7 +56,11 @@ export function getProfile(dispatch) {
|
||||
export function register(formData) {
|
||||
return function(dispatch) {
|
||||
return mpwoApi
|
||||
.register(formData.username, formData.email, formData.password)
|
||||
.register(
|
||||
formData.username,
|
||||
formData.email,
|
||||
formData.password,
|
||||
formData.passwordConf)
|
||||
.then(ret => {
|
||||
if (ret.status === 'success') {
|
||||
window.localStorage.setItem('authToken', ret.auth_token)
|
||||
@ -92,6 +106,20 @@ export function logout() {
|
||||
return { type: 'LOGOUT' }
|
||||
}
|
||||
|
||||
function RegisterFormControl (formData) {
|
||||
const errMsg = []
|
||||
if (formData.username.length < 3 || formData.username.length > 12) {
|
||||
errMsg.push('Username: 3 to 12 characters required.')
|
||||
}
|
||||
if (formData.password !== formData.passwordConf) {
|
||||
errMsg.push('Password and password confirmation don\'t match.')
|
||||
}
|
||||
if (formData.password.length < 8) {
|
||||
errMsg.push('Password: 8 characters required.')
|
||||
}
|
||||
return errMsg
|
||||
}
|
||||
|
||||
export function handleUserFormSubmit(event, formType) {
|
||||
event.preventDefault()
|
||||
return (dispatch, getState) => {
|
||||
@ -101,7 +129,12 @@ export function handleUserFormSubmit(event, formType) {
|
||||
if (formType === 'Login') {
|
||||
dispatch(login(formData.formData))
|
||||
} else { // formType === 'Register'
|
||||
dispatch(register(formData.formData))
|
||||
const ret = RegisterFormControl(formData.formData)
|
||||
if (ret.length === 0) {
|
||||
dispatch(register(formData.formData))
|
||||
} else {
|
||||
dispatch(AuthErrors(keyIndex(ret, 1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,7 +145,9 @@ export const handleFormChange = event => dispatch => {
|
||||
return dispatch(updateFormDataEmail(event.target.value))
|
||||
case 'username':
|
||||
return dispatch(updateFormDataUsername(event.target.value))
|
||||
default: // case 'password':
|
||||
case 'password':
|
||||
return dispatch(updateFormDataPassword(event.target.value))
|
||||
default: // case 'password-conf':
|
||||
return dispatch(updateFormDataPasswordConf(event.target.value))
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
.App {
|
||||
/*text-align: center;*/
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
@ -27,6 +27,10 @@
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.card {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 2em;
|
||||
margin: 1em;
|
||||
|
@ -1,10 +1,13 @@
|
||||
import React from 'react'
|
||||
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
||||
export default function Form (props) {
|
||||
return (
|
||||
<div>
|
||||
<h1>{props.formType}</h1>
|
||||
<Helmet>
|
||||
<title>mpwo - {props.formType}</title>
|
||||
</Helmet>
|
||||
<h1 className="page-title">{props.formType}</h1>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-md-3" />
|
||||
@ -13,7 +16,7 @@ export default function Form (props) {
|
||||
<form onSubmit={event =>
|
||||
props.handleUserFormSubmit(event, props.formType)}
|
||||
>
|
||||
{props.formType === 'Register' &&
|
||||
{props.formType === 'Register' &&
|
||||
<div className="form-group">
|
||||
<input
|
||||
name="username"
|
||||
@ -24,16 +27,16 @@ export default function Form (props) {
|
||||
onChange={props.onHandleFormChange}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
<div className="form-group">
|
||||
<input
|
||||
name="email"
|
||||
className="form-control input-lg"
|
||||
type="email"
|
||||
placeholder="Enter an email address"
|
||||
required
|
||||
onChange={props.onHandleFormChange}
|
||||
/>
|
||||
}
|
||||
<div className="form-group">
|
||||
<input
|
||||
name="email"
|
||||
className="form-control input-lg"
|
||||
type="email"
|
||||
placeholder="Enter an email address"
|
||||
required
|
||||
onChange={props.onHandleFormChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<input
|
||||
@ -45,6 +48,18 @@ export default function Form (props) {
|
||||
onChange={props.onHandleFormChange}
|
||||
/>
|
||||
</div>
|
||||
{props.formType === 'Register' &&
|
||||
<div className="form-group">
|
||||
<input
|
||||
name="password-conf"
|
||||
className="form-control input-lg"
|
||||
type="password"
|
||||
placeholder="Enter password confirmation"
|
||||
required
|
||||
onChange={props.onHandleFormChange}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary btn-lg btn-block"
|
||||
|
@ -11,7 +11,7 @@ class Logout extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<p className="App-center">
|
||||
You are now logged out.
|
||||
Click <Link to="/login">here</Link> to log back in.</p>
|
||||
</div>
|
||||
|
@ -16,6 +16,17 @@ function UserForm(props) {
|
||||
{ props.message !== '' && (
|
||||
<code>{props.message}</code>
|
||||
)}
|
||||
{ props.messages.length > 0 && (
|
||||
<code>
|
||||
<ul>
|
||||
{props.messages.map(msg => (
|
||||
<li key={msg.id}>
|
||||
{msg.value}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</code>
|
||||
)}
|
||||
<Form
|
||||
formType={props.formType}
|
||||
userForm={props.formData}
|
||||
@ -32,6 +43,7 @@ export default connect(
|
||||
state => ({
|
||||
formData: state.formData,
|
||||
message: state.message,
|
||||
messages: state.messages,
|
||||
}),
|
||||
dispatch => ({
|
||||
onHandleFormChange: event => {
|
||||
|
@ -17,7 +17,7 @@ export default class MpwoApi {
|
||||
.then(response => response.json())
|
||||
.catch(error => error)
|
||||
}
|
||||
static register(username, email, password) {
|
||||
static register(username, email, password, passwordConf) {
|
||||
const request = new Request(`${apiUrl}auth/register`, {
|
||||
method: 'POST',
|
||||
headers: new Headers({
|
||||
@ -27,6 +27,7 @@ export default class MpwoApi {
|
||||
username: username,
|
||||
email: email,
|
||||
password: password,
|
||||
password_conf: passwordConf,
|
||||
}),
|
||||
})
|
||||
return fetch(request)
|
||||
|
@ -2,20 +2,70 @@ import { combineReducers } from 'redux'
|
||||
|
||||
import initial from './initial'
|
||||
|
||||
const formData = (state = initial.formData, action) => {
|
||||
switch (action.type) {
|
||||
case 'UPDATE_FORMDATA_EMAIL':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
email: action.email
|
||||
},
|
||||
}
|
||||
case 'UPDATE_FORMDATA_USERNAME':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
username: action.username
|
||||
},
|
||||
}
|
||||
case 'UPDATE_FORMDATA_PASSWORD':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
password: action.password
|
||||
},
|
||||
}
|
||||
case 'UPDATE_FORMDATA_PASSWORD_CONF':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
passwordConf: action.passwordConf
|
||||
},
|
||||
}
|
||||
case 'PROFILE_SUCCESS':
|
||||
return initial.formData
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
const message = (state = initial.message, action) => {
|
||||
switch (action.type) {
|
||||
case 'AUTH_ERROR':
|
||||
case 'PROFILE_ERROR':
|
||||
return action.message
|
||||
case 'LOGOUT':
|
||||
return ''
|
||||
case 'PROFILE_SUCCESS':
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
return ''
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
const messages = (state = initial.messages, action) => {
|
||||
switch (action.type) {
|
||||
case 'AUTH_ERRORS':
|
||||
return action.messages
|
||||
case 'LOGOUT':
|
||||
case 'PROFILE_SUCCESS':
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
return []
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
const user = (state = initial.user, action) => {
|
||||
switch (action.type) {
|
||||
case 'AUTH_ERROR':
|
||||
@ -37,40 +87,11 @@ const user = (state = initial.user, action) => {
|
||||
}
|
||||
}
|
||||
|
||||
const formData = (state = initial.formData, action) => {
|
||||
switch (action.type) {
|
||||
case 'UPDATE_FORMDATA_EMAIL':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
email: action.email
|
||||
},
|
||||
}
|
||||
case 'UPDATE_FORMDATA_USERNAME':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
username: action.username
|
||||
},
|
||||
}
|
||||
case 'UPDATE_FORMDATA_PASSWORD':
|
||||
return {
|
||||
formData: {
|
||||
...state.formData,
|
||||
password: action.password
|
||||
},
|
||||
}
|
||||
case 'PROFILE_SUCCESS':
|
||||
return initial.formData
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
const reducers = combineReducers({
|
||||
message,
|
||||
user,
|
||||
formData,
|
||||
message,
|
||||
messages,
|
||||
user,
|
||||
})
|
||||
|
||||
export default reducers
|
||||
|
@ -1,5 +1,6 @@
|
||||
export default {
|
||||
message: '',
|
||||
messages: [],
|
||||
user: {
|
||||
id: '',
|
||||
username: '',
|
||||
@ -12,7 +13,8 @@ export default {
|
||||
formData: {
|
||||
username: '',
|
||||
email: '',
|
||||
password: ''
|
||||
password: '',
|
||||
passwordConf: '',
|
||||
}
|
||||
},
|
||||
}
|
||||
|
Reference in New Issue
Block a user