我需要在“登录”页面中再插入一个字段,因此,在JSON登录请求中还要再插入一个条目,尽管我设法在登录页面中插入了该字段(作为{{1}的FormControl
}} s),在将所选选项插入JSON请求时遇到了麻烦。
Select
:
login.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { propTypes, reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CircularProgress from '@material-ui/core/CircularProgress';
import TextField from '@material-ui/core/TextField';
import { withStyles } from '@material-ui/core/styles';
import LockIcon from '@material-ui/icons/Lock';
import { MenuItem, Select, FormControl, InputLabel } from '@material-ui/core';
import { Notification, translate, userLogin } from 'react-admin';
import InstitutionSelect from "./InstitutionSelect";
const styles = theme => ({
main: {
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
alignItems: 'center',
justifyContent: 'flex-start',
background: 'url(https://source.unsplash.com/random/1600x900)',
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
},
card: {
minWidth: 300,
marginTop: '6em',
},
avatar: {
margin: '1em',
display: 'flex',
justifyContent: 'center',
},
icon: {
backgroundColor: theme.palette.secondary.main,
},
hint: {
marginTop: '1em',
display: 'flex',
justifyContent: 'center',
color: theme.palette.grey[500],
},
form: {
padding: '0 1em 1em 1em',
},
input: {
marginTop: '1em',
},
actions: {
padding: '0 1em 1em 1em',
},
});
// see http://redux-form.com/6.4.3/examples/material-ui/
const renderInput = ({
meta: { touched, error } = {},
input: { ...inputProps },
...props
}) => (
<TextField
error={!!(touched && error)}
helperText={touched && error}
{...inputProps}
{...props}
fullWidth
/>
);
class Login extends Component {
login = auth =>
this.props.userLogin(
auth,
this.props.location.state
? this.props.location.state.nextPathname
: '/'
);
render() {
const { classes, handleSubmit, isLoading, translate } = this.props;
return (
<div className={classes.main}>
<Card className={classes.card}>
<div className={classes.avatar}>
<Avatar className={classes.icon}>
<LockIcon />
</Avatar>
</div>
<form onSubmit={handleSubmit(this.login)}>
<div className={classes.form}>
<div className={classes.input}>
<InstitutionSelect
name="institution"
disabled={isLoading}
/>
</div>
<div className={classes.input}>
<Field
name="username"
component={renderInput}
label={translate('ra.auth.username')}
disabled={isLoading}
/>
</div>
<div className={classes.input}>
<Field
name="password"
component={renderInput}
label={translate('ra.auth.password')}
type="password"
disabled={isLoading}
/>
</div>
</div>
<CardActions className={classes.actions}>
<Button
variant="raised"
type="submit"
color="primary"
disabled={isLoading}
className={classes.button}
fullWidth
>
{isLoading && (
<CircularProgress size={25} thickness={2} />
)}
{translate('ra.auth.sign_in')}
</Button>
</CardActions>
</form>
</Card>
<Notification />
</div>
);
}
}
Login.propTypes = {
...propTypes,
authProvider: PropTypes.func,
classes: PropTypes.object,
previousRoute: PropTypes.string,
translate: PropTypes.func.isRequired,
// Insert Institution here?
userLogin: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({ isLoading: state.admin.loading > 0 });
const enhance = compose(
translate,
reduxForm({
form: 'signIn',
validate: (values, props) => {
const errors = {};
const { translate } = props;
if (!values.institution) {
errors.institution = translate('ra.validation.required');
}
if (!values.username) {
errors.username = translate('ra.validation.required');
}
if (!values.password) {
errors.password = translate('ra.validation.required');
}
return errors;
},
}),
connect(
mapStateToProps,
{ userLogin }
),
withStyles(styles)
);
export default enhance(Login);
:
authProvider.js
import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'react-admin';
export default (type, params) => {
// called when the user attempts to log in
if (type === AUTH_LOGIN) {
const { institution, username, password } = params;
localStorage.setItem('username', username);
const request = new Request('194.117.29.119:3000/api/users/login', {
method: 'POST',
body: JSON.stringify({
institution,
username,
password
}),
headers: new Headers({ 'Content-Type': 'application/json' }),
})
return fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
localStorage.setItem('token', token);
});
}
// called when the user clicks on the logout button
if (type === AUTH_LOGOUT) {
localStorage.removeItem('username');
return Promise.resolve();
}
// called when the API returns an error
if (type === AUTH_ERROR) {
const { status } = params;
if (status === 401 || status === 403) {
localStorage.removeItem('username');
return Promise.reject();
}
return Promise.resolve();
}
// called when the user navigates to a new location
if (type === AUTH_CHECK) {
return localStorage.getItem('username')
? Promise.resolve()
: Promise.reject();
}
return Promise.reject('Unknown method');
};
:
InstitutionSelect.js