I want to clear textbox fields on success or error. how can I do that.?
On success or error, calling a function to show the snack bar. Within that, I'm updating the state. but it is not working fine.
any help appreciated.!
function
openSnackbar = ({ message }) => {
this.setState({
open: true,
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: '',
message
});
};
textfield
<TextField
id="cp_currentPassword"
label="Current Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_currentPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>;
component
import React, { Component } from 'react'
import withStyles from "#material-ui/core/styles/withStyles";
import CircularProgress from '#material-ui/core/CircularProgress';
import TextField from '#material-ui/core/TextField';
import GridItem from "../uiComponents/Grid/GridItem.jsx";
import GridContainer from "../uiComponents/Grid/GridContainer.jsx";
import Button from "../uiComponents/CustomButtons/Button.jsx";
import Card from "../uiComponents/Card/Card.jsx";
import CardHeader from "../uiComponents/Card/CardHeader.jsx";
import CardBody from "../uiComponents/Card/CardBody.jsx";
import CardFooter from "../uiComponents/Card/CardFooter.jsx";
import Snackbar from '#material-ui/core/Snackbar';
import CloseIcon from '#material-ui/icons/Close';
import { Redirect } from 'react-router-dom'
import IconButton from '#material-ui/core/IconButton';
import { connect } from 'react-redux'
import { compose } from 'redux'
import { changePassword } from '../../store/actions/auth'
const styles = {
textField: {
fontSize: '5px'
},
};
class ChangePassword extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
open: false,
message: '',
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: ''
}
}
componentDidUpdate = (prevProps) => {
const { authError } = this.props;
console.log(authError)
if (authError != prevProps.authError) {
this.setState(
{
loading: false,
message: authError,
open: true
})
}
};
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value
})
}
openSnackbar = ({ message }) => {
this.setState({
open: true,
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: '',
message
});
};
handleSubmit = (e) => {
e.preventDefault();
let curpass = this.state.cp_currentPassword
let newpass = this.state.cp_newPassword
this.setState({ loading: true });
this.props.changePassword(curpass, newpass, this.passwordUpdated)
}
passwordUpdated = () => {
this.setState({
message: 'Password changed Successfully.!',
open: true,
loading: false,
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: ''
});
};
render() {
const { classes, auth, authError } = this.props;
console.log(authError)
const { loading } = this.state;
const message = (
<span
id="snackbar-message-id"
dangerouslySetInnerHTML={{ __html: this.state.message }}
/>
);
if (!auth.uid) return <Redirect to='/signin' />
return (
<div>
{/* {authError ? this.openSnackbar({ message: '{authError}' }) : null} */}
{/* {authError && !this.state.open ? this.openSnackbar({ message: '{authError}' }) : null} */}
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<Card>
<CardHeader color="warning">
<h4 className={classes.cardTitleWhite}>Change Password</h4>
</CardHeader>
<form >
<GridContainer>
<GridItem xs={12} sm={12} md={6}>
<CardBody>
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_currentPassword"
label="Current Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_currentPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_newPassword"
label="New Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_newPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_confirmPassword"
label="Confirm Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_confirmPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
</GridContainer>
</CardBody>
<CardFooter>
<Button color="warning" onClick={(e) => this.handleSubmit(e)} disabled={loading}>
{loading && <CircularProgress style={{ color: 'white', height: '20px', width: '20px', marginRight: '10px' }} />}
Change Password
</Button>
</CardFooter>
</GridItem>
</GridContainer>
</form>
</Card>
</GridItem>
</GridContainer>
<Snackbar
open={this.state.open}//{!!this.props.authError}//
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
message={message}
variant="error"
onClose={() => this.setState({ open: false, message: '' })}
action={
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={() =>
// clearAuthError
this.setState({ open: false, message: '' })
}
>
<CloseIcon className={classes.icon} />
</IconButton>
}
autoHideDuration={3000}
/>
</div>
)
}
}
const mapstateToProps = (state) => {
return {
auth: state.firebase.auth,
authError: state.authroot.autherr
}
}
const mapDispatchtoProps = (dispatch, getState) => {
return {
changePassword: (currentPassword, newPassword, passwordUpdated) => { dispatch(changePassword(currentPassword, newPassword, passwordUpdated)) },
}
}
export default compose(
withStyles(styles),
connect(mapstateToProps, mapDispatchtoProps)
)(ChangePassword);
In your handleSubmit function don't pass this.passwordUpdated
handleSubmit = (e) => {
e.preventDefault();
let curpass = this.state.cp_currentPassword
let newpass = this.state.cp_newPassword
this.setState({ loading: true });
this.props.changePassword(curpass, newpass, this.passwordUpdated) //Remove this.passwordUpdated from here
}
Instead of ComponentDidUpdate method you should use ComponentWillReceiveProps
componentWillReceiveProps(nextProps) {
console.log('componentWillReceiveProps', nextProps);
if (this.props.authError !== nextProps.authError) {
// here you can make your textbox empty
this.setState({
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: ''
});
}
}
Note: In new version of react you must use static getDerivedStateFromProps() instead of componentWillReceiveProps.
Related
If something is written on the required TextField then everything will be okay but if the required TextField is blank then it will show me an error message on a helperText. But the problem is I can't use lenth on a if condition where I have set an onClick handler or method but I can use lenth on an onChange handler or method. If I can't use lenth then how will I know that something is written on required TextField. Here is my code:
import React, { Component } from 'react';
import { Container, Grid, Typography, TextField, Button } from '#material-ui/core';
import { withStyles } from "#material-ui/core/styles";
const styles = theme => ({
mT: {
marginTop: theme.spacing(1)
},
mR: {
marginRight: theme.spacing(3)
}
});
class Account extends Component {
constructor(){
super()
this.state={
accname: '',
helperText: '',
error: false
}
this.onChange = this.onChange.bind(this);
this.onClick = this.onClick.bind(this);
}
onChange = (event) => {
this.setState({[event.target.name]:event.target.value})
}
onClick = (event) => {
if (event.target.required > 0) {
this.setState({ helperText: '', error: false });
} else {
this.setState({ helperText: 'Invalid format', error: true });
}
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<Container>
<Grid container
spacing={2}>
<Grid item
xs={12}
sm={12}
md={12}
lg={12}
xl={12}>
<Typography className={classes.mT}
variant="h4"
color="textPrimary">
Add Account
</Typography>
</Grid>
<Grid item
xs={12}
sm={12}
md={12}
lg={12}
xl={12}>
<TextField className={classes.mR}
label="Account Name"
name="accname"
type="text"
helperText={this.state.helperText}
onChange={this.onChange}
value={this.state.accname}
error={this.state.error}
variant="outlined"
color="primary"
size="small"
autoFocus
required />
<Button variant="contained"
color="primary"
onClick={this.onClick} >
Submit
</Button>
</Grid>
</Grid>
</Container>
</React.Fragment>
);
}
}
export default withStyles(styles, { withTheme: true })(Account);
onClick = () => {
if(
this.state.accname.trim() != '' &&
this.state.firstName.trim() != '' &&
this.state.lastName.trim() != ''
){
//Your API call here
}
else{
alert("fill the empty spaces!");
}
Whenever I'm trying to post new Screams in my page. I'm not getting the image, title and content of the card. I need to reload to get that.
It is saying failed prop types means after posting a scream I'm not getting the value from prop types but after a reload, everything seems to be fine. I don't know what is wrong is going. Please have a look at my code.
This is my Screams.js from where i'm showing my Screams
Scream.js
const styles = {
card: {
position: "relative",
display: "flex",
marginBottom: 20,
},
image: {
minWidth: 150,
},
content: {
padding: 25,
objectFit: "cover",
},
};
class Scream extends Component {
render() {
dayjs.extend(relativeTime);
const {
classes,
scream: {
body,
createdAt,
userImage,
userHandle,
screamId,
likeCount,
commentCount,
},
user: {
authenticated,
credentials: { handle },
},
} = this.props;
const deleteButton =
authenticated && userHandle === handle ? (
<DeleteScream screamId={screamId} />
) : null;
const likeButton = !authenticated ? (
<Link to="/login">
<MyButton tip="Like">
<FavoriteBorder color="primary" />
</MyButton>
</Link>
) : this.likedScream() ? (
<MyButton tip="Undo like" onClick={this.unlikeScream}>
<FavoriteIcon color="primary" />
</MyButton>
) : (
<MyButton tip="Like" onClick={this.likeScream}>
<FavoriteBorder color="primary" />
</MyButton>
);
return (
<Card className={classes.card}>
<CardMedia
image={userImage}
title="Profile Image"
className={classes.image}
/>
<CardContent className={classes.content}>
<Typography variant="h5" component={Link} to={`/users/${userHandle}`}>
{userHandle}
</Typography>
{deleteButton}
<Typography variant="body2" color="textSecondary">
{dayjs(createdAt).fromNow()}
</Typography>
<Typography variant="body1">{body}</Typography>
{likeButton}
<span> {likeCount} Likes </span>
<MyButton tip="comments">
<ChatIcon color="primary" />
</MyButton>
<span> {commentCount} Comments </span>
</CardContent>
</Card>
);
}
}
Scream.propTypes = {
likeScream: PropTypes.func.isRequired,
unlikeScream: PropTypes.func.isRequired,
user: PropTypes.object.isRequired,
scream: PropTypes.object.isRequired,
classes: PropTypes.object.isRequired,
};
const mapStateToprops = (state) => ({
user: state.user,
});
const mapActionToProps = {
likeScream,
unlikeScream,
};
export default connect(
mapStateToprops,
mapActionToProps
)(withStyles(styles)(Scream));
As u can see i have userImage, userHandle and body of the card in the props and it is showing it on my page.
But after posting a new Scream, i'm not getting the image, userHandle and body of the new Scream unless and until reload it.
PostScream.js
class PostScream extends Component {
state = {
open: false,
body: "",
errors: {}
}
componentWillReceiveProps(nextProps) {
if(nextProps.UI.errors) {
this.setState({
errors: nextProps.UI.errors
});
}
if(!nextProps.UI.errors && !nextProps.UI.loading) {
this.setState({
body: "",
open: false,
errors: {}
})
}
}
handleOpen = () => {
this.setState({ open: true })
};
handleClose = () => {
this.props.clearErrors();
this.setState({ open: false, errors: {} });
};
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value })
}
handleSubmit = (event) => {
event.preventDefault();
this.props.postScream({ body: this.state.body })
}
render() {
const { errors } = this.state;
const { classes, UI: { loading }} = this.props;
return (
<Fragment>
<MyButton onClick= { this.handleOpen } tip="Post a Scream!">
<AddIcon />
</MyButton>
<Dialog
open= { this.state.open }
onClose= { this.handleClose }
fullWidth
maxWidth = "sm"
>
<MyButton
tip="Close"
onClick={this.handleClose}
tipClassName={classes.closeButton}
>
<CloseIcon />
</MyButton>
<DialogTitle> Post a new Scream </DialogTitle>
<DialogContent>
<form onSubmit= { this.handleSubmit }>
<TextField
name="body"
type="text"
label="SCREAM!"
multiline
rows="3"
placeholder= "What's on your mind!"
error={ errors.body ? true: false }
helperText={ errors.body }
className={classes.TextField}
onChange={ this.handleChange }
fullWidth
/>
<Button
type="submit"
variant="contained"
color="primary"
className={classes.submitButton}
disabled={ loading }
>
Submit
{loading && (
<CircularProgress size={30} className={ classes.progressSpinner } />
)}
</Button>
</form>
</DialogContent>
</Dialog>
</Fragment>
)
}
}
PostScream.propTypes = {
postScream: PropTypes.func.isRequired,
clearErrors: PropTypes.func.isRequired,
UI: PropTypes.object.isRequired
}
const mapStateToProps = (state) => ({
UI: state.UI
});
export default connect(
mapStateToProps,
{ postScream, clearErrors }
)(withStyles(styles)(PostScream));
After posting a new Scream, i am getting Scream like this:-
I was having the same issue, I was able to fix it by adding component='img' to my CardMedia.
<CardMedia
image={userImage}
title="Profile Image"
className={classes.image}
component='img'
/>
Specifying the component as an img "Hides" the images since CardMedia is a div and your css is applied to the div. Add component = "div" to CardMedia.
<CardMedia
image={userImage}
title="Profile Image"
className={classes.image}
component='div'
/>
I'm performing a change password, for authError I'm getting the following error..
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
changepassword.js
import React, { Component } from 'react'
import withStyles from "#material-ui/core/styles/withStyles";
import { Redirect } from 'react-router-dom'
import IconButton from '#material-ui/core/IconButton';
import { connect } from 'react-redux'
import { compose } from 'redux'
import {changePassword } from '../../store/actions/auth'
const styles = {
textField: {
fontSize: '5px'
},
};
class ChangePassword extends Component {
state = {
loading: false,
open:false,
message:'',
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: ''
}
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value
})
}
openSnackbar = ({ message }) => {
this.setState({
open: true,
message,
});
};
handleSubmit = (e) => {
e.preventDefault();
let curpass=this.state.cp_currentPassword
let newpass=this.state.cp_newPassword
this.setState({loading:true});
this.props.changePassword(curpass,newpass)
this.openSnackbar({ message: 'Password changed Successfully.!' })
}
render() {
const { classes, auth, authError } = this.props;
const { loading } = this.state;
const message = (
<span
id="snackbar-message-id"
dangerouslySetInnerHTML={{ __html: this.state.message }}
/>
);
if (!auth.uid) return <Redirect to='/signin' />
return (
<div>
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<Card>
<CardHeader color="warning">
<h4 className={classes.cardTitleWhite}>Change Password</h4>
</CardHeader>
<form >
<GridContainer>
<GridItem xs={12} sm={12} md={6}>
<CardBody>
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_currentPassword"
label="Current Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_currentPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_newPassword"
label="New Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_newPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_confirmPassword"
label="Confirm Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_confirmPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
</GridContainer>
</CardBody>
<CardFooter>
<Button color="warning" onClick={this.handleSubmit} disabled={loading}>
{loading && <CircularProgress style={{ color: 'white', height: '20px', width: '20px', marginRight: '10px' }} />}
Change Password
</Button>
</CardFooter>
</GridItem>
</GridContainer>
</form>
</Card>
</GridItem>
</GridContainer>
{authError ? this.openSnackbar({ message: '{authError}' }) : null}
<Snackbar
open={this.state.open}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
message={message}
variant="error"
onClose={() => this.setState({ open: false, message: '' })}
action={
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={() => this.setState({ open: false, message: '' })}
>
<CloseIcon className={classes.icon} />
</IconButton>
}
autoHideDuration={3000}
/>
</div>
)
}
}
const mapstateToProps = (state) => {
return {
auth: state.firebase.auth,
authError: state.authroot.autherr
}
}
const mapDispatchtoProps = (dispatch) => {
return {
changePassword: (currentPassword,newPassword) => { dispatch(changePassword(currentPassword,newPassword)) }
}
}
export default compose(
withStyles(styles),
connect(mapstateToProps,mapDispatchtoProps)
)(ChangePassword);
change password action
export const changePassword = (currentPassword, newPassword) => {
return (dispatch, getState, { getFirebase }) => {
const firebase = getFirebase();
console.log(currentPassword);
console.log(newPassword);
var user = firebase.auth().currentUser;
user.updatePassword(newPassword).then(() => {
console.log("Password updated!");
}).catch((error) => {
dispatch({ type: 'CHANGEPASSWORD_ERR', error })});
}
}
You are updating state here
{authError ? this.openSnackbar({ message: '{authError}' }) : null
that line runs multiple times, as it checks if there was auth error, if there was call openSnackBar, openSnackBar update state, which cause the component to re-render, after re-render the check happens again etc, which causes a loop. change it to the following and only call openSnackBar when state.open is false.
{authError && !this.state.open ? this.openSnackbar({ message: '{authError}' }) : null}
EDIT
remove authError from render and check in componentDidMount
componentDidMount = () => {
const { authError } = this.props;
if (authError) {
this.openSnackbar({ message: '{authError}' });
}
};
I am completely new to both react and testing and am a bit stumped.
I was just wondering if someone could tell me why my test fails. I assume I making a basic mistake in how this should work.
I am trying to test a log in page. At the moment I am just trying to get my test to fire an onclick from a button and check that that a function has been called.
The log in component code can be seen below.
import React, { Component, Fragment } from "react";
import { Redirect } from "react-router-dom";
// Resources
//import logo from "assets/img/white-logo.png";
//import "./Login.css";
// Material UI
import {
withStyles,
MuiThemeProvider,
createMuiTheme
} from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
import TextField from "#material-ui/core/TextField";
import Person from "#material-ui/icons/Person";
import InputAdornment from "#material-ui/core/InputAdornment";
// Custom Components
import Loading from "components/Loading/Loading.jsx";
// bootstrat 1.0
import { Alert, Row } from "react-bootstrap";
// MUI Icons
import LockOpen from "#material-ui/icons/LockOpen";
// remove
import axios from "axios";
// API
import api2 from "../../helpers/api2";
const styles = theme => ({
icon: {
color: "#fff"
},
cssUnderline: {
color: "#fff",
borderBottom: "#fff",
borderBottomColor: "#fff",
"&:after": {
borderBottomColor: "#fff",
borderBottom: "#fff"
},
"&:before": {
borderBottomColor: "#fff",
borderBottom: "#fff"
}
}
});
const theme = createMuiTheme({
palette: {
primary: { main: "#fff" }
}
});
class Login extends Component {
constructor(props, context) {
super(props, context);
this.state = {
username: "",
password: "",
isAuthenticated: false,
error: false,
toggle: true,
// loading
loading: false
};
}
openLoading = () => {
this.setState({ loading: true });
};
stopLoading = () => {
this.setState({ loading: false });
};
toggleMode = () => {
this.setState({ toggle: !this.state.toggle });
};
handleReset = e => {
const { username } = this.state;
this.openLoading();
api2
.post("auth/admin/forgotPassword", { email: username })
.then(resp => {
this.stopLoading();
console.log(resp);
})
.catch(error => {
this.stopLoading();
console.error(error);
});
};
handleSubmit = event => {
event.preventDefault();
localStorage.clear();
const cred = {
username: this.state.username,
password: this.state.password
};
api2
.post("auth/admin", cred)
.then(resp => {
console.log(resp);
localStorage.setItem("api_key", resp.data.api_key);
localStorage.setItem("username", cred.username);
return this.setState({ isAuthenticated: true });
})
.catch(error => {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
console.log(error.request);
} else {
console.log("Error", error.message);
}
console.log(error.config);
return this.setState({ error: true });
});
};
handleInputChange = event => {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
};
forgotPassword = () => {
console.log("object");
};
render() {
const { error } = this.state;
const { isAuthenticated } = this.state;
const { classes } = this.props;
if (isAuthenticated) {
return <Redirect to="/home/dashboard" />;
}
return (
<div className="login-page">
<video autoPlay muted loop id="myVideo">
<source
src=""
type="video/mp4"
/>
</video>
<div className="videoOver" />
<div className="midl">
<Row className="d-flex justify-content-center">
<img src={''} className="Login-logo" alt="logo" />
</Row>
<br />
<Row className="d-flex justify-content-center">
{error && (
<Alert style={{ color: "#fff" }}>
The username/password entered is incorrect. Try again!
</Alert>
)}
</Row>
<MuiThemeProvider theme={theme}>
<Row className="d-flex justify-content-center">
<TextField
id="input-username"
name="username"
type="text"
label="username"
value={this.state.username}
onChange={this.handleInputChange}
InputProps={{
className: classes.icon,
startAdornment: (
<InputAdornment position="start">
<Person className={classes.icon} />
</InputAdornment>
)
}}
/>
</Row>
{this.state.toggle ? (
<Fragment>
<br />
<Row className="d-flex justify-content-center">
<TextField
id="input-password"
name="password"
type="password"
label="pasword"
value={this.state.password}
onChange={this.handleInputChange}
className={classes.cssUnderline}
InputProps={{
className: classes.icon,
startAdornment: (
<InputAdornment position="start">
<LockOpen className={classes.icon} />
</InputAdornment>
)
}}
/>
</Row>
</Fragment>
) : (
""
)}
</MuiThemeProvider>
<br />
<Row className="d-flex justify-content-center">
{this.state.toggle ? (
<Button
className="button login-button"
data-testid='submit'
type="submit"
variant="contained"
color="primary"
onClick={this.handleSubmit}
name = "logIn"
>
Login
</Button>
) : (
<Button
className="button login-button"
type="submit"
variant="contained"
color="primary"
onClick={this.handleReset}
>
Reset
</Button>
)}
</Row>
<Row className="d-flex justify-content-center">
<p onClick={this.toggleMode} className="text-link">
{this.state.toggle ? "Forgot password?" : "Login"}
</p>
</Row>
</div>
<Loading open={this.state.loading} onClose={this.handleClose} />
</div>
);
}
}
export default withStyles(styles)(Login);
My current test which fails.
import React from 'react'
import {render, fireEvent, getByTestId} from 'react-testing-library'
import Login from './login'
describe('<MyComponent />', () => {
it('Function should be called once', () => {
const functionCalled = jest.fn()
const {getByTestId} = render(<Login handleSubmit={functionCalled} />)
const button = getByTestId('submit');
fireEvent.click(button);
expect(functionCalled).toHaveBeenCalledTimes(1)
});
});
I'm also fairly new to React Testing Library, but it looks like your button is using this.handleSubmit, so passing your mock function as a prop won't do anything. If you were to pass handleSubmit in from some container, then I believe your tests, as you currently have them, would pass.
I get an error message I didn't figure out how to get rid off:
yup__WEBPACK_IMPORTED_MODULE_12__.object(...).shap is not a function
import React from 'react'
import Button from '#material-ui/core/Button'
import Dialog from '#material-ui/core/Dialog'
import DialogActions from '#material-ui/core/DialogActions'
import DialogContent from '#material-ui/core/DialogContent'
import DialogContentText from '#material-ui/core/DialogContentText'
import DialogTitle from '#material-ui/core/DialogTitle'
import TextField from '#material-ui/core/TextField'
import { Link } from 'gatsby'
import DisplayOutput from '../pages/DisplayOutput'
import { Formik, Field, Form, ErrorMessage } from 'formik'
import * as Yup from 'yup'
class DialogFormWithFormik extends React.Component {
constructor(props) {
super(props)
this.state = {
open: false,
dialogModal: 'none',
}
}
handleClickOpen = () => {
this.setState({ open: true })
this.setState({ dialogModal: 'login' })
}
handleRegisterClickOpen = () => {
this.setState({ open: true })
this.setState({ dialogModal: 'register' })
}
handleClose = () => {
this.setState({ dialogModal: false })
}
onSubmit = values => {
console.log(values)
alert('values submitted')
}
form = props => {
return (
<div>
<Button
variant="outlined"
color="primary"
onClick={() => this.handleClickOpen()}
>
Login
</Button>
<Button
variant="outlined"
color="primary"
onClick={() => this.handleRegisterClickOpen()}
>
Register
</Button>
<Dialog
onClose={() => this.handleClose()}
aria-labelledby="customized-dialog-title"
open={this.state.dialogModal === 'login'}
>
<DialogTitle id="form-dialog-title">
To Display Student Data
</DialogTitle>
<DialogContent />
<form onSubmit={props.handleSubmit}>
<TextField
label="Username"
type="text"
margin="normal"
name="userName"
/>
<ErrorMessage name="userName" />
<br />
<TextField
label="Password"
type="password"
autoComplete="current-password"
margin="normal"
/>
<ErrorMessage name="password" />
<DialogActions>
<nav>
<Button color="primary">Login</Button>
</nav>
<br />
<Button onClick={() => this.handleClose()}>Cancel</Button>
</DialogActions>
</form>
</Dialog>
</div>
)
}
schema = () => {
const schema = Yup.object().shap({
userName: Yup.string().required(),
password: Yup.string().required(),
})
return schema
}
render() {
return (
<div align="center">
<Formik
initialValues={{
userName: '',
password: '',
}}
onSubmit={this.onSubmit}
render={this.form}
validationSchema={this.schema()}
/>
</div>
)
}
}
export default DialogFormWithFormik