From bf7c63cd53dde93bffe24eb1426b8bfc2037646b Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sat, 29 Aug 2020 15:30:48 +0300
Subject: feat: use Formik in Login form

---
 src/containers/Login/Login.tsx | 104 +++++++++++++++++++++++++++--------------
 1 file changed, 68 insertions(+), 36 deletions(-)

(limited to 'src/containers/Login/Login.tsx')

diff --git a/src/containers/Login/Login.tsx b/src/containers/Login/Login.tsx
index bec0db5..9814d01 100644
--- a/src/containers/Login/Login.tsx
+++ b/src/containers/Login/Login.tsx
@@ -1,14 +1,24 @@
-import React, { useState, useRef } from 'react';
+import React, { useState } from 'react';
 import { useHistory } from 'react-router-dom';
+import { Formik, Form, Field } from 'formik';
 import { makeStyles } from '@material-ui/core/styles';
 import {
   TextField,
   Button,
   FormControlLabel,
-  Switch
+  Switch,
+  InputAdornment,
+  IconButton
 } from '@material-ui/core';
+import { Visibility, VisibilityOff } from '@material-ui/icons';
 import { useAuth } from '../../hooks/useAuth';
 
+interface Fields {
+  username: string;
+  password: string;
+  remember: boolean;
+}
+
 const useStyles = makeStyles(theme => ({
   root: {
     '& > *': {
@@ -37,54 +47,76 @@ const useStyles = makeStyles(theme => ({
 
 const Login: React.FC = () => {
   const [error, setError] = useState<boolean>(false);
-  const [remember, setRemember] = useState<boolean>(true);
+  const [showPassword, setShowPassword] = useState<boolean>(false);
   const classes = useStyles();
-  const nameRef = useRef<HTMLInputElement>();
-  const passwordRef = useRef<HTMLInputElement>();
   const { login } = useAuth();
   const history = useHistory();
 
-  const handleCheck = () => {
-    setRemember(!remember);
-  };
-
-  const handleSubmit = async () => {
-    const name = nameRef.current?.value?.toLowerCase();
-    const password = passwordRef.current?.value;
-    if (name && password) {
-      login(name, password, remember).then(success => {
-        if (success) history.push(`/profile/${name}`);
+  const handleSubmit = async ({ username, password, remember }: Fields) => {
+    console.log({ username, password, remember })
+    if (username && password) {
+      login(username, password, remember).then(success => {
+        if (success) history.push(`/profile/${username}`);
         else setError(true);
       });
-    }
+    } else setError(true);
   };
-
   const handleRegistration = () => {
     history.push('/registration');
   };
 
+  const toggleShowPassword = () => {
+    setShowPassword(prevState => !prevState);
+  };
+
   return (
     <>
       <div className={classes.formHeader}>Sign In</div>
-      <form className={classes.root} noValidate autoComplete="off">
-        <TextField
-          inputRef={nameRef}
-          error={error}
-          label="Login"
-        />
-        <TextField
-          inputRef={passwordRef}
-          error={error}
-          helperText={error && 'Invalid credentials'}
-          label="Password"
-          type="password"
-        />
-        <FormControlLabel
-          control={<Switch color="primary" onClick={handleCheck} checked={remember} size="small" />}
-          label="Remember me"
-        />
-        <Button variant="contained" onClick={handleSubmit}>submit</Button>
-      </form>
+      <Formik
+        initialValues={{ username: '', password: '', remember: true }}
+        onSubmit={handleSubmit}
+      >
+        {({ values, touched, isSubmitting }) => (
+          <Form className={classes.root} autoComplete="off">
+            <Field
+              name="username"
+              label="Login"
+              value={values.username}
+              error={error}
+              as={TextField}
+            />
+            <Field
+              name="password"
+              label="Password"
+              as={TextField}
+              value={values.password}
+              error={error}
+              helperText={error && 'Invalid credentials'}
+              type={showPassword ? 'text' : 'password'}
+              InputProps={{
+                endAdornment: (
+                  <InputAdornment position="end">
+                    <IconButton
+                      size="small"
+                      aria-label="toggle password visibility"
+                      onClick={toggleShowPassword}
+                    >
+                      {showPassword ? <Visibility /> : <VisibilityOff />}
+                    </IconButton>
+                  </InputAdornment>
+                )
+              }}
+            />
+            <Field
+              name="remember"
+              label="Remember me"
+              as={FormControlLabel}
+              control={<Switch color="primary" checked={values.remember} size="small" />}
+            />
+            <Button variant="contained" type="submit" disabled={isSubmitting}>submit</Button>
+          </Form>
+        )}
+      </Formik>
       <div className={classes.formTransfer}>
         <div>{'Don\'t have an account?'}</div>
         <span
-- 
cgit v1.2.3

