Next.js template
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LoginForm.jsx 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import {
  2. Box,
  3. Button,
  4. Container,
  5. Grid,
  6. IconButton,
  7. InputAdornment,
  8. TextField,
  9. Typography,
  10. } from '@mui/material';
  11. import { useFormik } from 'formik';
  12. import { signIn } from 'next-auth/react';
  13. import Link from 'next/link';
  14. import { useRouter } from 'next/router';
  15. import { useState } from 'react';
  16. import {
  17. BASE_PAGE,
  18. FORGOT_PASSWORD_PAGE,
  19. REGISTER_PAGE,
  20. } from '../../../constants/pages';
  21. import { loginSchema } from '../../../schemas/loginSchema';
  22. import ErrorMessageComponent from '../../mui/ErrorMessageComponent';
  23. const LoginForm = () => {
  24. const [showPassword, setShowPassword] = useState(false);
  25. const handleClickShowPassword = () => setShowPassword(!showPassword);
  26. const handleMouseDownPassword = () => setShowPassword(!showPassword);
  27. const router = useRouter();
  28. const [error, setError] = useState({ hasError: false, errorMessage: '' });
  29. const submitHandler = async (values) => {
  30. const result = await signIn('credentials', {
  31. redirect: false,
  32. username: values.username,
  33. password: values.password,
  34. });
  35. if (!result.error) {
  36. router.replace(BASE_PAGE);
  37. } else {
  38. setError({ hasError: true, errorMessage: result.error });
  39. }
  40. };
  41. const formik = useFormik({
  42. initialValues: {
  43. username: '',
  44. password: '',
  45. },
  46. validationSchema: loginSchema,
  47. onSubmit: submitHandler,
  48. validateOnBlur: true,
  49. enableReinitialize: true,
  50. });
  51. return (
  52. <Container component="main" maxWidth="md">
  53. <Box
  54. sx={{
  55. marginTop: 32,
  56. display: 'flex',
  57. flexDirection: 'column',
  58. alignItems: 'center',
  59. }}
  60. >
  61. <Typography component="h1" variant="h5">
  62. Login
  63. </Typography>
  64. {error.hasError && <ErrorMessageComponent error={error.errorMessage} />}
  65. <Box
  66. component="form"
  67. onSubmit={formik.handleSubmit}
  68. sx={{ position: 'relative', mt: 1, p: 1 }}
  69. >
  70. <TextField
  71. name="username"
  72. label="Username"
  73. margin="normal"
  74. value={formik.values.username}
  75. onChange={formik.handleChange}
  76. error={formik.touched.username && Boolean(formik.errors.username)}
  77. helperText={formik.touched.username && formik.errors.username}
  78. autoFocus
  79. fullWidth
  80. />
  81. <TextField
  82. name="password"
  83. label="Password"
  84. margin="normal"
  85. type={showPassword ? 'text' : 'password'}
  86. value={formik.values.password}
  87. onChange={formik.handleChange}
  88. error={formik.touched.password && Boolean(formik.errors.password)}
  89. helperText={formik.touched.password && formik.errors.password}
  90. fullWidth
  91. InputProps={{
  92. endAdornment: (
  93. <InputAdornment position="end">
  94. <IconButton
  95. onClick={handleClickShowPassword}
  96. onMouseDown={handleMouseDownPassword}
  97. ></IconButton>
  98. </InputAdornment>
  99. ),
  100. }}
  101. />
  102. <Button
  103. type="submit"
  104. variant="contained"
  105. sx={{ mt: 3, mb: 2 }}
  106. fullWidth
  107. >
  108. Login
  109. </Button>
  110. <Grid container>
  111. <Grid
  112. item
  113. xs={12}
  114. md={6}
  115. sx={{ textAlign: { xs: 'center', md: 'left' } }}
  116. >
  117. <Link href={FORGOT_PASSWORD_PAGE}>Forgot your password?</Link>
  118. </Grid>
  119. <Grid
  120. item
  121. xs={12}
  122. md={6}
  123. sx={{ textAlign: { xs: 'center', md: 'right' } }}
  124. >
  125. <Link href={REGISTER_PAGE}>Dont have an account?</Link>
  126. </Grid>
  127. </Grid>
  128. </Box>
  129. </Box>
  130. </Container>
  131. );
  132. };
  133. export default LoginForm;