Skip to content

Instantly share code, notes, and snippets.

@hckhanh
Created October 12, 2019 05:21
Show Gist options
  • Save hckhanh/5497a48c5bae9b83ebfb81e0aad1179d to your computer and use it in GitHub Desktop.
Save hckhanh/5497a48c5bae9b83ebfb81e0aad1179d to your computer and use it in GitHub Desktop.
import {
Avatar,
Box,
Button,
Checkbox,
Container,
CssBaseline,
FormControlLabel,
Grid,
Link,
makeStyles,
TextField,
Theme,
Typography
} from "@material-ui/core";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import { RouteComponentProps } from "@reach/router";
import { useMachine } from "@xstate/react";
import get from "lodash.get";
import { useSnackbar } from "notistack";
import React, { FC, useEffect } from "react";
import useForm from "react-hook-form";
import { LoginForm, LoginFormSchema } from "../models/user";
import AuthMachine from "../states/AuthMachine";
import LoginMachine from "../states/LoginMachine";
const Copyright: FC = () => {
return (
<Typography variant="body2" color="textSecondary" align="center">
{"Copyright © "}
<Link color="inherit" href="https://dinovative.com/">
Dinovative
</Link>
{` ${new Date().getFullYear()}.`}
</Typography>
);
};
const useStyles = makeStyles((theme: Theme) => ({
"@global": {
body: {
backgroundColor: theme.palette.common.white
}
},
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center"
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing(1)
},
submit: {
margin: theme.spacing(3, 0, 2)
}
}));
const SignIn: FC<RouteComponentProps> = () => {
const classes = useStyles();
const { enqueueSnackbar } = useSnackbar();
const [current, send] = useMachine(LoginMachine, { devTools: true });
const { register, handleSubmit, errors, setValue } = useForm<LoginForm>({
validationSchema: LoginFormSchema
});
useEffect(() => {
if (current.matches("error")) {
enqueueSnackbar(get(current, "context.error.message"), {
variant: "error"
});
setValue("credentials.password", "");
}
}, [current]);
function handleLogin(data: LoginForm) {
send("LOGIN", data);
}
// console.log(current);
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form
className={classes.form}
onSubmit={handleSubmit(handleLogin)}
noValidate
>
<TextField
name="credentials.account"
margin="normal"
variant="outlined"
label="Username or Email"
autoComplete="email"
inputRef={register}
error={Boolean(get(errors, "credentials.account"))}
helperText={get(errors, ["credentials.account", "message"])}
autoFocus
required
fullWidth
/>
<TextField
name="credentials.password"
margin="normal"
variant="outlined"
label="Password"
type="password"
autoComplete="current-password"
inputRef={register}
error={Boolean(get(errors, "credentials.password"))}
helperText={get(errors, ["credentials.password", "message"])}
fullWidth
required
/>
<FormControlLabel
name="rememberMe"
label="Remember me"
control={
<Checkbox color="primary" inputRef={register} defaultChecked />
}
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
disabled={current.matches("loading")}
aria-disabled={current.matches("loading")}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
);
};
export default SignIn;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment