I want save value for date from this code, I use vscode and reactjs and Material package.
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap',
},
textField: {
marginLeft: theme.spacing.unit,
marginRight: theme.spacing.unit,
width: 200,
},
});
function DatePickers(props) {
const { classes } = props;
//console.log(props)
return (
<form className={classes.container} noValidate>
<TextField
id="date"
label="Birthday"
type="date"
defaultValue="2017-05-24"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
/>
</form>
);
}
DatePickers.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(DatePickers);
In order to save the selected date, your code should look something like this,
import React, { Component } from "react";
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const styles = theme => ({
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing.unit,
marginRight: theme.spacing.unit,
width: 200
}
});
class DatePickers extends Component {
state = {
date: "2017-05-24"
};
handleChange = event => {
this.setState({ date: event.target.value });
};
render() {
const { classes } = this.props;
console.log(this.state);
return (
<form className={classes.container} noValidate>
<TextField
id="date"
label="Birthday"
type="date"
value={this.state.date}
onChange={this.handleChange}
className={classes.textField}
InputLabelProps={{
shrink: true
}}
/>
</form>
);
}
}
DatePickers.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(DatePickers);
Related
I have
import CaretDownIcon from 'src/../public/images/svg/caret-down.svg';
<Select
className={selectClassName}
data-testid={testId}
// IconComponent={<SvgIcon>{CaretDownIcon}</SvgIcon>}
// IconComponent={CaretDownIcon}
inputProps={{
name,
id: labelId,
}}
{...rest}
>
I tried both of those commented lines, but no dice. What's the right way?
You need to create a component for your custom svg icon. Copy the path from the svg file to make a component as shown below:
function CustomSvgIcon(props) {
return (
<SvgIcon {...props}>
<path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" />
</SvgIcon>
);
}
then you can use that with IconComponent={CustomSvgIcon}.
Here's a full working example:
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormControl from "#material-ui/core/FormControl";
import Select from "#material-ui/core/Select";
import SvgIcon from "#material-ui/core/SvgIcon";
const styles = (theme) => ({
root: {
display: "flex",
flexWrap: "wrap"
},
formControl: {
margin: theme.spacing.unit,
minWidth: 120
},
selectEmpty: {
marginTop: theme.spacing.unit * 2
}
});
function CustomSvgIcon(props) {
return (
<SvgIcon {...props}>
<path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" />
</SvgIcon>
);
}
class SimpleSelect extends React.Component {
state = {
age: "",
name: "hai"
};
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
render() {
const { classes } = this.props;
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.formControl}>
<InputLabel htmlFor="age-simple">Age</InputLabel>
<Select
value={this.state.age}
onChange={this.handleChange}
inputProps={{
name: "age",
id: "age-simple"
}}
IconComponent={CustomSvgIcon}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</form>
);
}
}
SimpleSelect.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(SimpleSelect);
It is also possible to create a React component from an imported SVG file, but this is dependent on your build configuration. If you are using create-react-app then this will work (see this article for details).
Below is an example using the import approach. This uses import { ReactComponent as TestSvgAsComponent } from "./test.svg"; to get a React component from the SVG file. The other step necessary is to add in the styles that would be applied by SvgIcon (classes.icon from useIconStyles in the example).
import React from "react";
import PropTypes from "prop-types";
import { withStyles, makeStyles } from "#material-ui/core/styles";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormControl from "#material-ui/core/FormControl";
import Select from "#material-ui/core/Select";
import { ReactComponent as TestSvgAsComponent } from "./test.svg";
import clsx from "clsx";
const styles = (theme) => ({
root: {
display: "flex",
flexWrap: "wrap"
},
formControl: {
margin: theme.spacing.unit,
minWidth: 120
},
selectEmpty: {
marginTop: theme.spacing.unit * 2
}
});
const useIconStyles = makeStyles({
// This is a copy of the styles from https://github.com/mui-org/material-ui/blob/v4.12.3/packages/material-ui/src/SvgIcon/SvgIcon.js#L10
icon: {
fill: "currentColor",
width: "1em",
height: "1em",
display: "inline-block",
fontSize: "1.5rem",
transition: "fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
flexShrink: 0,
userSelect: "none"
}
});
function CustomSvgIcon({ className, ...other }) {
const classes = useIconStyles();
return (
<TestSvgAsComponent className={clsx(classes.icon, className)} {...other} />
);
}
class SimpleSelect extends React.Component {
state = {
age: "",
name: "hai"
};
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
render() {
const { classes } = this.props;
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.formControl}>
<InputLabel htmlFor="age-simple">Age</InputLabel>
<Select
value={this.state.age}
onChange={this.handleChange}
inputProps={{
name: "age",
id: "age-simple"
}}
IconComponent={CustomSvgIcon}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</form>
);
}
}
SimpleSelect.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(SimpleSelect);
Related documentation:
https://material-ui.com/components/icons/#svgicon
Related answer:
Select is not working onClick IconComponent(dropdown-arrow) in react material ui
I am going through trouble to connectand dispatch in function based component. I know how to connect and dispatch class based component.
This is my code;
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
import Button from '#material-ui/core/Button';
import SaveIcon from '#material-ui/icons/Save';
import { connect } from "react-redux";
const useStyles = makeStyles(theme => ({
container: {
display: 'flex',
flexWrap: 'wrap',
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
},
dense: {
marginTop: 19,
},
menu: {
width: 200,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
button: {
margin: theme.spacing(1),
},
}));
export default function TextFields() {
const classes = useStyles();
const [values, setValues] = React.useState({
ssn: '',
phone: '',
email: '',
multiline: 'Controlled',
});
const handleChange = name => event => {
setValues({ ...values, [name]: event.target.value });
};
const onSubmit = () => {
const data = {
ssn: values.ssn,
phone: values.phone,
email: values.email
}
console.log(data)
this.props.dispatch({type: 'SUBMIT', data})
}
return (
<React.Fragment>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<form className={classes.container} noValidate autoComplete="off">
<TextField
id=""
label="SSN"
value={values.ssn}
onChange={handleChange('ssn')}
type="number"
className={classes.textField}
name='ssn'
margin="normal"
/>
<TextField
id=""
label="Phone"
value={values.phone}
onChange={handleChange('phone')}
type="number"
className={classes.textField}
name='phone'
margin="normal"
/>
<TextField
id=""
label="Email"
value={values.email}
onChange={handleChange('email')}
type="email"
className={classes.textField}
margin="normal"
name='email'
/>
<Button
onClick={() => onSubmit()}
variant="contained"
color="primary"
size="small"
className={classes.button}
startIcon={<SaveIcon />}
>
Save
</Button>
</form>
</React.Fragment>
);
}
Can anyone help me to dispatch the data or connect ? THANKS IN ADVANCE
I am new to Material UI. So, here i am using a Textfield type Date. By defaut in the textfield it shows "dd-mm-yyyy". But, i want to show an string value by default, like this "Add DOB (MM/DD/YYYY)". I tried some ways, its not taking the string value. Please let me know, how can i achieve this.
import React from 'react';
import { render } from 'react-dom';
import TextField from 'material-ui/TextField';
const App = () => (
<div style={styles}>
<TextField
id="date"
label="Add Date of Birth"
type="date"
name="DateOfBirth"
defaultValue="Add DOB"
className="form-field"
InputLabelProps={{
shrink: true,
}}
/>
</div>
);
render(<App />, document.getElementById('root'));
I'm not sure what default you are asking. I am assuming two things here: default value for the date or some kind of text accompanying the date.
If you want to set default value for the TextField it is best to set the value prop for the component with a state as in value={stateValue}. If you want to add some text to accompany the date you can try Input Adornments in the Material UI.
Code example for this:
import React from "react";
import InputAdornment from "#material-ui/core/InputAdornment";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
const useStyles = makeStyles(theme => ({
container: {
display: "flex",
flexDirection: "column",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200
},
adornment: {
width: 110
},
dense: {
marginTop: 19
},
menu: {
width: 200
}
}));
export default function TextFields() {
const classes = useStyles();
const [values, setValues] = React.useState({
date: "1993-11-01"
});
const handleChange = name => event => {
console.log(event.target.value);
setValues({ ...values, [name]: event.target.value });
};
return (
<form className={classes.container} noValidate autoComplete="off">
<TextField
id="date"
label="Add Date of Birth"
type="date"
name="DateOfBirth"
// defaultValue="Add DOB"
InputProps={{
startAdornment: (
<InputAdornment className={classes.adornment} position="start">
Add DOB
</InputAdornment>
)
}}
value={values.date}
className={classes.textField}
onChange={handleChange("date")}
InputLabelProps={{
shrink: true
}}
/>
<TextField
id="standard-name"
label="Date Text"
className={classes.textField}
value={values.date}
onChange={handleChange("date")}
margin="normal"
/>
</form>
);
}
Demo Codesandbox: TextField - date
I am trying to create a sample login form in React using material-ui through graphql mutation. But the login form is not working as expected.
i am able to log in only some times, but even in those times, I do not see any data being passed via loginMutation props in console. Could some one please tell me what am i doing wrong here?
Here is the Login Component that I am trying to create
import React, { Component } from 'react';
import { AUTH_TOKEN } from '../constants';
import { graphql, compose } from 'react-apollo';
import {LOGIN_MUTATION} from "../gql/loginGQL";
import Paper from '#material-ui/core/Paper';
import Button from '#material-ui/core/Button';
import TextField from '#material-ui/core/TextField'
import PropTypes from 'prop-types';
import Avatar from '#material-ui/core/Avatar';
import CssBaseline from '#material-ui/core/CssBaseline';
import FormControl from '#material-ui/core/FormControl';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
//import Input from '#material-ui/core/Input';
//import InputLabel from '#material-ui/core/InputLabel';
import LockIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
layout: {
width: 'auto',
display: 'block', // Fix IE11 issue.
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
width: 400,
marginLeft: 'auto',
marginRight: 'auto',
},
},
paper: {
marginTop: theme.spacing.unit * 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`,
},
avatar: {
margin: theme.spacing.unit,
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
});
class Login extends Component {
state = {
email: '',
password: '',
errors: null
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockIcon />
</Avatar>
<Typography variant="headline">Sign in</Typography>
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<TextField
id='email'
value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}
type='text'
label='Your email address'
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<TextField
id='password'
value={this.state.password}
onChange={e => this.setState({ password: e.target.value })}
type='password'
label='Password'
/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
id="submit"
type="submit"
fullWidth
variant="raised"
color="primary"
className={classes.submit}
onClick={() => this._confirm()}
>
Sign in
</Button>
</form>
</Paper>
</main>
</React.Fragment>
);
}
_confirm = async () => {
const { email, password } = this.state
try{
const result = await this.props.loginMutation({
variables: {
email,
password,
},
});
console.log(result); // Here no data is being displayed !
const { jwt } = result.data.signInUser;
this._saveUserData(jwt);
this.props.history.push(`/`)
} catch(error) {
const errors = error.graphQLErrors.map(error => error.message);
this.setState({ errors });
}
}
_saveUserData = (token) => {
localStorage.setItem(AUTH_TOKEN, token)
}
}
Login.propTypes = {
classes: PropTypes.object.isRequired,
};
export default compose(
graphql(LOGIN_MUTATION, { name: 'loginMutation' }),
withStyles(styles),
)(Login)
The error was being occurred due to the Button tag. Although, it had type="submit", the form was still not being submitted due to which the input data was not being appearing in the "_confirm". I am wondering why, I must have missed something here.
For now, I created a div tag inside the Button and added onClick handler there instead of Button tag.
So, the edited code just have this small change
<Button color="primary" className = {classes.submit} variant="raised" fullWidth>
<div className="test" onClick={() => this._confirm()} >
Sign in
</div>
</Button>
Here is the full source code:
import React, { Component } from 'react';
import { AUTH_TOKEN } from '../constants';
import { graphql, compose } from 'react-apollo';
import {LOGIN_MUTATION} from "../gql/loginGQL";
import Paper from '#material-ui/core/Paper';
import Button from '#material-ui/core/Button';
import TextField from '#material-ui/core/TextField'
import PropTypes from 'prop-types';
import Avatar from '#material-ui/core/Avatar';
import CssBaseline from '#material-ui/core/CssBaseline';
import FormControl from '#material-ui/core/FormControl';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
//import Input from '#material-ui/core/Input';
//import InputLabel from '#material-ui/core/InputLabel';
import LockIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
layout: {
width: 'auto',
display: 'block', // Fix IE11 issue.
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
width: 400,
marginLeft: 'auto',
marginRight: 'auto',
},
},
paper: {
marginTop: theme.spacing.unit * 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px`,
},
avatar: {
margin: theme.spacing.unit,
backgroundColor: theme.palette.secondary.main,
},
form: {
width: '100%', // Fix IE11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
});
class Login extends Component {
state = {
email: '',
password: '',
errors: null
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<Paper className={classes.paper}>
<Avatar className={classes.avatar}>
<LockIcon />
</Avatar>
<Typography variant="headline">Sign in</Typography>
<form className={classes.form}>
<FormControl margin="normal" required fullWidth>
<TextField
id='email'
value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}
type='text'
label='Your email address'
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<TextField
id='password'
value={this.state.password}
onChange={e => this.setState({ password: e.target.value })}
type='password'
label='Password'
/>
</FormControl>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
// Here is the change
<Button color="primary" className = {classes.submit}
variant="raised"fullWidth >
<div className="test" onClick={() => this._confirm()} >
Sign in
</div>
</Button>
// Change ends here
</form>
</Paper>
</main>
</React.Fragment>
);
}
_confirm = async () => {
const { email, password } = this.state
try{
const result = await this.props.loginMutation({
variables: {
email,
password,
},
});
console.log(result); // Here no data is being displayed !
const { jwt } = result.data.signInUser;
this._saveUserData(jwt);
this.props.history.push(`/`)
} catch(error) {
const errors = error.graphQLErrors.map(error => error.message);
this.setState({ errors });
}
}
_saveUserData = (token) => {
localStorage.setItem(AUTH_TOKEN, token)
}
}
Login.propTypes = {
classes: PropTypes.object.isRequired,
};
export default compose(
graphql(LOGIN_MUTATION, { name: 'loginMutation' }),
withStyles(styles),
)(Login)
I have created a user register page on the react-admin template, but when it's rendered, the sidebar and appbar are being rendered as well.
The default login page in the template gets rendered without these 2 components.
How do I configure the app so that the register page also gets rendered without the sidebar and appbar?
MyLayout.js
// in src/MyLayout.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withStyles, MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import {
AppBar,
Menu,
Notification,
Sidebar,
setSidebarVisibility,
} from 'react-admin';
const styles = theme => ({
root: {
display: 'flex',
flexDirection: 'column',
zIndex: 1,
minHeight: '100vh',
backgroundColor: theme.palette.background.default,
position: 'relative',
},
appFrame: {
display: 'flex',
flexDirection: 'column',
overflowX: 'auto',
},
contentWithSidebar: {
display: 'flex',
flexGrow: 1,
},
content: {
display: 'flex',
flexDirection: 'column',
flexGrow: 2,
padding: theme.spacing.unit * 3,
marginTop: '4em',
paddingLeft: 5,
},
});
class MyLayout extends Component {
componentWillMount() {
this.props.setSidebarVisibility(true);
}
render() {
const {
children,
classes,
dashboard,
isLoading,
logout,
open,
title,
} = this.props;
return (
<div className={classes.root}>
<div className={classes.appFrame}>
<AppBar title={title} open={open} logout={logout} color="primary"/>
<main className={classes.contentWithSidebar}>
<Sidebar>
<Menu logout={logout} hasDashboard={!!dashboard} />
</Sidebar>
<div className={classes.content}>
{children}
</div>
</main>
<Notification />
</div>
</div>
);
}
}
MyLayout.propTypes = {
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
dashboard: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string,
]),
isLoading: PropTypes.bool.isRequired,
logout: 'componentPropType',
setSidebarVisibility: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
};
const mapStateToProps = state => ({ isLoading: state.admin.loading > 0 });
export default connect(mapStateToProps, { setSidebarVisibility })(withStyles(styles)(MyLayout));
register.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 { Notification, translate, userLogin } from 'react-admin';
import { Link } from 'react-router-dom';
import dataProvider from './dataProvider';
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 Register extends Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
email: '',
password: '',
submitted: false
};
//this.handleSubmit = this.handleSubmit.bind(this);
this.handleFirstNameChange = this.handleFirstNameChange.bind(this);
this.handleLastNameChange = this.handleLastNameChange.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
}
handleFirstNameChange(e){
this.setState({firstName:e.target.value});
}
handleLastNameChange(e) {
this.setState({ lastName: e.target.value });
}
handleEmailChange(e) {
this.setState({ email: e.target.value });
}
handlePasswordChange(e) {
this.setState({ password: e.target.value });
}
register = () => {
this.setState({ submitted: true });
const { firstName, lastName, email, password } = this.state;
//console.log(data);
//console.log(firstName);
dataProvider('CREATE', 'user/register', { 'data': { 'fname': firstName, 'lname': lastName, 'email': email, 'password': password } });
/*dataProvider('CREATE', 'user/register', { data: {
fname: 1, lname: 5, email: test, password: 1234
} });*/
}
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.register)}>
<div className={classes.hint}></div>
<div className={classes.form}>
<div className={classes.input}>
<Field
name="firstName"
component={renderInput}
label={'First Name'}
disabled={isLoading}
value={this.state.firstName}
onChange={this.handleFirstNameChange}
/>
</div>
<div className={classes.input}>
<Field
name="lastName"
component={renderInput}
label={'Last Name'}
disabled={isLoading}
value={this.state.lastName}
onChange={this.handleLastNameChange}
/>
</div>
<div className={classes.input}>
<Field
name="email"
component={renderInput}
label={'Email'}
disabled={isLoading}
value={this.state.email}
onChange={this.handleEmailChange}
/>
</div>
<div className={classes.input}>
<Field
name="password"
component={renderInput}
label={translate('ra.auth.password')}
type="password"
disabled={isLoading}
value={this.state.password}
onChange={this.handlePasswordChange}
/>
</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} />
)}
{'Register'}
</Button>
</CardActions>
<CardActions className={classes.actions}>
<Button
variant="raised"
color="secondary"
disabled={isLoading}
className={classes.button}
fullWidth
>
<Link to={{pathname: "/login"}} style={{textDecoration: 'none', color:'#fff'}} >Sign In</Link>
</Button>
</CardActions>
</form>
</Card>
<Notification />
</div>
);
}
}
Register.propTypes = {
...propTypes,
authProvider: PropTypes.func,
classes: PropTypes.object,
previousRoute: PropTypes.string,
translate: PropTypes.func.isRequired,
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.fname) {
errors.fname = translate('ra.validation.required');
}
if (!values.lname) {
errors.lname = translate('ra.validation.required');
}
if (!values.email) {
errors.email = translate('ra.validation.required');
}
if (!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) {
errors.email = 'A valid email is required';
}
if (!values.password) {
errors.password = translate('ra.validation.required');
}
return errors;
},
}),
connect(
mapStateToProps,
{ userLogin }
),
withStyles(styles)
);
export default enhance(Register);
I believe you will use a customRoute to add your register page to router. You can add a 'noLayout' for not displaying appbar and sidebar
https://github.com/marmelab/react-admin/blob/master/docs/Admin.md#customroutes