From 8d73f7cabc05e4864ac9b9fe46a9e5ae0eea7d43 Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 13:50:46 +0700
Subject: [PATCH 01/11] add auth.service

---
 diskuy/src/services/auth.service.js | 31 +++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 diskuy/src/services/auth.service.js

diff --git a/diskuy/src/services/auth.service.js b/diskuy/src/services/auth.service.js
new file mode 100644
index 0000000..6e0af95
--- /dev/null
+++ b/diskuy/src/services/auth.service.js
@@ -0,0 +1,31 @@
+import axios from 'axios'
+
+const API_URL = 'http://localhost:4000/api/auth'
+
+class AuthService {
+    async login(username, password) {
+        const response = await axios.post(`${API_URL}/signin`, {
+            username,
+            password
+        })
+        if (response.data.accessToken)
+            localStorage.setItem('user', JSON.stringify(response.data))
+        
+        return response
+    }
+    logout() {localStorage.removeItem('user')}
+
+    register(username, email, password) {
+        return axios.post(`${API_URL}/signup`, {
+            username,
+            email,
+            password
+        })
+    }
+
+    getCurrentUser() {
+        return JSON.parse(localStorage.getItem('user'))
+    }
+}
+
+export default new AuthService()
\ No newline at end of file
-- 
GitLab


From 1f83d9d30d383ac8516a74da456ed484d18b1e38 Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 13:55:39 +0700
Subject: [PATCH 02/11] add auth-header

---
 diskuy/src/services/auth-header.js | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 diskuy/src/services/auth-header.js

diff --git a/diskuy/src/services/auth-header.js b/diskuy/src/services/auth-header.js
new file mode 100644
index 0000000..e9c1ad4
--- /dev/null
+++ b/diskuy/src/services/auth-header.js
@@ -0,0 +1,7 @@
+export default function authHeader() {
+    const user = JSON.parse(localStorage.getItem('user'))
+
+    if (user && user.accessToken)
+        return { Authorization: 'Bearer' + user.accessToken }
+    else return {}
+}
\ No newline at end of file
-- 
GitLab


From dd3e51dd53193ee604846f80ff5ad03cf0e03e2d Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 14:03:21 +0700
Subject: [PATCH 03/11] add user.service

---
 diskuy/src/services/user.service.js | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 diskuy/src/services/user.service.js

diff --git a/diskuy/src/services/user.service.js b/diskuy/src/services/user.service.js
new file mode 100644
index 0000000..b1bc801
--- /dev/null
+++ b/diskuy/src/services/user.service.js
@@ -0,0 +1,12 @@
+import axios from 'axios'
+import authHeader from './auth-header'
+
+const API_URL = 'http://localhost:4000/api'
+
+class UserService {
+    getProfile() {
+        return axios.get(`${API_URL}/user`, { headers : authHeader()})
+    }
+}
+
+export default new UserService()
\ No newline at end of file
-- 
GitLab


From c7a75d25f151b44b83f0b88800422bd79764160d Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 14:25:46 +0700
Subject: [PATCH 04/11] add react form validator lib

---
 diskuy/package-lock.json | 44 ++++++++++++++++++++++++++++++++++++++++
 diskuy/package.json      |  2 ++
 2 files changed, 46 insertions(+)

diff --git a/diskuy/package-lock.json b/diskuy/package-lock.json
index ce0783d..0221d74 100644
--- a/diskuy/package-lock.json
+++ b/diskuy/package-lock.json
@@ -9681,6 +9681,11 @@
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
     },
+    "lodash.omit": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
+      "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
+    },
     "lodash.sortby": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -12465,6 +12470,35 @@
         "workbox-webpack-plugin": "5.1.4"
       }
     },
+    "react-validation": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
+      "integrity": "sha1-tQcL+KbnN7hw2Hu/tyzMpys/N1A=",
+      "requires": {
+        "lodash.omit": "^4.5.0",
+        "prop-types": "^15.6.0",
+        "react": "^16.0.0",
+        "shallow-equal": "^1.0.0",
+        "uuid": "^3.1.0"
+      },
+      "dependencies": {
+        "react": {
+          "version": "16.14.0",
+          "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
+          "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
+          "requires": {
+            "loose-envify": "^1.1.0",
+            "object-assign": "^4.1.1",
+            "prop-types": "^15.6.2"
+          }
+        },
+        "uuid": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+        }
+      }
+    },
     "read-pkg": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
@@ -13513,6 +13547,11 @@
         "kind-of": "^6.0.2"
       }
     },
+    "shallow-equal": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
+      "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
+    },
     "shebang-command": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -15007,6 +15046,11 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "validator": {
+      "version": "13.5.2",
+      "resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz",
+      "integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ=="
+    },
     "value-equal": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
diff --git a/diskuy/package.json b/diskuy/package.json
index 3c8f1e3..41b045f 100644
--- a/diskuy/package.json
+++ b/diskuy/package.json
@@ -11,6 +11,8 @@
     "react-dom": "^17.0.1",
     "react-router-dom": "^5.2.0",
     "react-scripts": "4.0.1",
+    "react-validation": "^3.0.7",
+    "validator": "^13.5.2",
     "web-vitals": "^0.2.4"
   },
   "scripts": {
-- 
GitLab


From de53e193e291af0a5991d599dce50db78cd9012a Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 14:26:18 +0700
Subject: [PATCH 05/11] add Login component pre req

---
 diskuy/src/Login.js | 48 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 diskuy/src/Login.js

diff --git a/diskuy/src/Login.js b/diskuy/src/Login.js
new file mode 100644
index 0000000..ac7c150
--- /dev/null
+++ b/diskuy/src/Login.js
@@ -0,0 +1,48 @@
+import React from 'react'
+import Form from "react-validation/bulid/form"
+import Input from "react-validation/bulid/input"
+import CheckButton from "react-validation/bulid/button"
+import { isEmail } from 'validator'
+import { useInput } from './hooks/input-hook';
+import { useState } from "react";
+
+import AuthService from './services/auth.service'
+
+const required = value => {
+    if (!value) {
+        return (
+            <div className='alert alert-danger' role='alert'>
+                This field is required!
+            </div>
+        )
+    }
+}
+
+export default function Login(props){
+    const [username, bindUsername, resetUsername] = useInput('')
+    const [password, bindPassword, resetPassword] = useInput('')
+    const [loading, setLoading] = useState(false)
+    const [message, setMessage] = useState('')
+
+    const handleLogin = async event => {
+        event.preventDefault()
+        setLoading(true)
+
+        this.form.validateAll()
+
+        if (this.checkBtn.context._errors.length === 0) {
+            try {
+                await AuthService.login(username, password)
+                // ? this.props.history.push('/profile')
+                // ? window.location.reload()
+            }
+            catch(error) {
+                const responseMessage =
+                    (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
+                
+                setMessage(responseMessage)
+            }
+        }
+        setLoading(false)
+    }
+}
-- 
GitLab


From 90310fdff1e8b12c89c21e401563f555d889923b Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 14:38:17 +0700
Subject: [PATCH 06/11] add login route

---
 diskuy/src/App.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/diskuy/src/App.js b/diskuy/src/App.js
index 0f77f60..9a907b8 100644
--- a/diskuy/src/App.js
+++ b/diskuy/src/App.js
@@ -5,6 +5,7 @@ import Navbar from './Navbar';
 import Profile from './Profile/Profile';
 import ListThreads from './Threads/ListThreads';
 import Form from './Form';
+import Login from './Login'
 import TopicList from './TopicList';
 import {
   BrowserRouter as Router,
@@ -19,6 +20,7 @@ function App() {
       <Navbar />
       <Route exact path='/' component={TopicList} />
       <Route exact path='/profile' component={Profile} />
+      <Route exact path='/login' component={Login} />
       <Route exact path='/topic/:topic/thread/create' component={Form} />
       <Route exact path='/topic/:topic/:thread' component={Thread} />
       <Route exact path='/topic/:topic' component={Topic} />
-- 
GitLab


From c93b04d75167c0bd06febd599ae401e332dd5513 Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 14:38:40 +0700
Subject: [PATCH 07/11] add Login page render

---
 diskuy/src/Login.js | 52 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/diskuy/src/Login.js b/diskuy/src/Login.js
index ac7c150..442dcc0 100644
--- a/diskuy/src/Login.js
+++ b/diskuy/src/Login.js
@@ -39,10 +39,60 @@ export default function Login(props){
             catch(error) {
                 const responseMessage =
                     (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
-                
                 setMessage(responseMessage)
             }
         }
         setLoading(false)
     }
+
+    return (
+        <div>
+            <Form
+                onSubmit={handleLogin}
+                ref={c => {this.form = c}}
+            >
+                <div className='form-group'>
+                    <label htmlFor='username'>Username</label>
+                    <Input
+                        type='text'
+                        className='form-control'
+                        name='username'
+                        {...bindUsername}
+                        validations={[required]}
+                    />
+                </div>
+                <div className='form-group'>
+                    <label htmlFor='password'>Password</label>
+                    <Input
+                        type='password'
+                        className='form-control'
+                        name='password'
+                        {...bindPassword}
+                        validations={[required]} 
+                    />
+                </div>
+
+                <div className='form-group'>
+                    <button className='btn btn-primary btn-block' disabled={loading}>
+                        {loading && (
+                            <span className='spinner-border spinner-border-sm'></span>
+                        )}
+                        <span>Login</span>
+                    </button>
+                </div>
+
+                {message && (
+                    <div className='form-group'>
+                        <div className='alert alert-danger' role='alert'>
+                            {message}
+                        </div>
+                    </div>
+                )}
+                <CheckButton
+                    style={{ display: 'none' }}
+                    ref={c => {this.checkBtn = c}}
+                />
+            </Form>
+        </div>
+    )
 }
-- 
GitLab


From 236d55d0f228c34922f1b5668ec3c8c866825ffc Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 14:49:51 +0700
Subject: [PATCH 08/11] fix react-validation import

---
 diskuy/src/Login.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/diskuy/src/Login.js b/diskuy/src/Login.js
index 442dcc0..a80d647 100644
--- a/diskuy/src/Login.js
+++ b/diskuy/src/Login.js
@@ -1,13 +1,13 @@
 import React from 'react'
-import Form from "react-validation/bulid/form"
-import Input from "react-validation/bulid/input"
-import CheckButton from "react-validation/bulid/button"
+import { form, input, button } from 'react-validation'
 import { isEmail } from 'validator'
 import { useInput } from './hooks/input-hook';
 import { useState } from "react";
 
 import AuthService from './services/auth.service'
 
+const [Form, Input, CheckButton] = [form, input, button]
+
 const required = value => {
     if (!value) {
         return (
-- 
GitLab


From 5369e73372a3e15c654efdb872bf867a8fe97eb2 Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 15:10:35 +0700
Subject: [PATCH 09/11] remove react-validation, resolve LoginForm errors

---
 diskuy/package-lock.json | 39 ----------------
 diskuy/package.json      |  1 -
 diskuy/src/App.js        |  4 +-
 diskuy/src/Login.js      | 98 ----------------------------------------
 diskuy/src/LoginForm.js  | 82 +++++++++++++++++++++++++++++++++
 5 files changed, 84 insertions(+), 140 deletions(-)
 delete mode 100644 diskuy/src/Login.js
 create mode 100644 diskuy/src/LoginForm.js

diff --git a/diskuy/package-lock.json b/diskuy/package-lock.json
index 0221d74..1182450 100644
--- a/diskuy/package-lock.json
+++ b/diskuy/package-lock.json
@@ -9681,11 +9681,6 @@
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
     },
-    "lodash.omit": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
-      "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
-    },
     "lodash.sortby": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@@ -12470,35 +12465,6 @@
         "workbox-webpack-plugin": "5.1.4"
       }
     },
-    "react-validation": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
-      "integrity": "sha1-tQcL+KbnN7hw2Hu/tyzMpys/N1A=",
-      "requires": {
-        "lodash.omit": "^4.5.0",
-        "prop-types": "^15.6.0",
-        "react": "^16.0.0",
-        "shallow-equal": "^1.0.0",
-        "uuid": "^3.1.0"
-      },
-      "dependencies": {
-        "react": {
-          "version": "16.14.0",
-          "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
-          "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
-          "requires": {
-            "loose-envify": "^1.1.0",
-            "object-assign": "^4.1.1",
-            "prop-types": "^15.6.2"
-          }
-        },
-        "uuid": {
-          "version": "3.4.0",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
-        }
-      }
-    },
     "read-pkg": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
@@ -13547,11 +13513,6 @@
         "kind-of": "^6.0.2"
       }
     },
-    "shallow-equal": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
-      "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
-    },
     "shebang-command": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
diff --git a/diskuy/package.json b/diskuy/package.json
index 41b045f..3d5998a 100644
--- a/diskuy/package.json
+++ b/diskuy/package.json
@@ -11,7 +11,6 @@
     "react-dom": "^17.0.1",
     "react-router-dom": "^5.2.0",
     "react-scripts": "4.0.1",
-    "react-validation": "^3.0.7",
     "validator": "^13.5.2",
     "web-vitals": "^0.2.4"
   },
diff --git a/diskuy/src/App.js b/diskuy/src/App.js
index 9a907b8..c45caf6 100644
--- a/diskuy/src/App.js
+++ b/diskuy/src/App.js
@@ -5,7 +5,7 @@ import Navbar from './Navbar';
 import Profile from './Profile/Profile';
 import ListThreads from './Threads/ListThreads';
 import Form from './Form';
-import Login from './Login'
+import LoginForm from './LoginForm'
 import TopicList from './TopicList';
 import {
   BrowserRouter as Router,
@@ -20,7 +20,7 @@ function App() {
       <Navbar />
       <Route exact path='/' component={TopicList} />
       <Route exact path='/profile' component={Profile} />
-      <Route exact path='/login' component={Login} />
+      <Route exact path='/login' component={LoginForm} />
       <Route exact path='/topic/:topic/thread/create' component={Form} />
       <Route exact path='/topic/:topic/:thread' component={Thread} />
       <Route exact path='/topic/:topic' component={Topic} />
diff --git a/diskuy/src/Login.js b/diskuy/src/Login.js
deleted file mode 100644
index a80d647..0000000
--- a/diskuy/src/Login.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import React from 'react'
-import { form, input, button } from 'react-validation'
-import { isEmail } from 'validator'
-import { useInput } from './hooks/input-hook';
-import { useState } from "react";
-
-import AuthService from './services/auth.service'
-
-const [Form, Input, CheckButton] = [form, input, button]
-
-const required = value => {
-    if (!value) {
-        return (
-            <div className='alert alert-danger' role='alert'>
-                This field is required!
-            </div>
-        )
-    }
-}
-
-export default function Login(props){
-    const [username, bindUsername, resetUsername] = useInput('')
-    const [password, bindPassword, resetPassword] = useInput('')
-    const [loading, setLoading] = useState(false)
-    const [message, setMessage] = useState('')
-
-    const handleLogin = async event => {
-        event.preventDefault()
-        setLoading(true)
-
-        this.form.validateAll()
-
-        if (this.checkBtn.context._errors.length === 0) {
-            try {
-                await AuthService.login(username, password)
-                // ? this.props.history.push('/profile')
-                // ? window.location.reload()
-            }
-            catch(error) {
-                const responseMessage =
-                    (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
-                setMessage(responseMessage)
-            }
-        }
-        setLoading(false)
-    }
-
-    return (
-        <div>
-            <Form
-                onSubmit={handleLogin}
-                ref={c => {this.form = c}}
-            >
-                <div className='form-group'>
-                    <label htmlFor='username'>Username</label>
-                    <Input
-                        type='text'
-                        className='form-control'
-                        name='username'
-                        {...bindUsername}
-                        validations={[required]}
-                    />
-                </div>
-                <div className='form-group'>
-                    <label htmlFor='password'>Password</label>
-                    <Input
-                        type='password'
-                        className='form-control'
-                        name='password'
-                        {...bindPassword}
-                        validations={[required]} 
-                    />
-                </div>
-
-                <div className='form-group'>
-                    <button className='btn btn-primary btn-block' disabled={loading}>
-                        {loading && (
-                            <span className='spinner-border spinner-border-sm'></span>
-                        )}
-                        <span>Login</span>
-                    </button>
-                </div>
-
-                {message && (
-                    <div className='form-group'>
-                        <div className='alert alert-danger' role='alert'>
-                            {message}
-                        </div>
-                    </div>
-                )}
-                <CheckButton
-                    style={{ display: 'none' }}
-                    ref={c => {this.checkBtn = c}}
-                />
-            </Form>
-        </div>
-    )
-}
diff --git a/diskuy/src/LoginForm.js b/diskuy/src/LoginForm.js
new file mode 100644
index 0000000..3a5f873
--- /dev/null
+++ b/diskuy/src/LoginForm.js
@@ -0,0 +1,82 @@
+import React from 'react'
+import { isEmail } from 'validator'
+import { useInput } from './hooks/input-hook';
+import { useState } from "react";
+
+import AuthService from './services/auth.service'
+
+const required = value => {
+    if (!value) {
+        return (
+            <div className='alert alert-danger' role='alert'>
+                This field is required!
+            </div>
+        )
+    }
+}
+
+export default function LoginForm(){
+
+    const { value: username, bind: bindUsername, reset: resetUsername } = useInput('')
+    const { value: password, bind: bindPassword, reset: resetPassword } = useInput('')
+    const [loading, setLoading] = useState(false)
+    const [message, setMessage] = useState('')
+
+    const handleLogin = async event => {
+        event.preventDefault()
+        setLoading(true)
+
+        try {
+            await AuthService.login(username, password)
+            // ? this.props.history.push('/profile')
+            // ? window.location.reload()
+        }
+        catch(error) {
+            const responseMessage =
+                (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
+            setMessage(responseMessage)
+        }
+        setLoading(false)
+    }
+
+    return (
+        <div>
+            <form onSubmit={handleLogin}>
+                <label htmlFor='username'>Username</label>
+                <input
+                    type='text'
+                    name='username'
+                    {...bindUsername}
+                    validations={[required]}
+                />
+
+                <label htmlFor='password'>Password</label>
+                <input
+                    type='password'
+                    name='password'
+                    {...bindPassword}
+                    validations={[required]} 
+                />
+
+                <button className='btn btn-primary' disabled={loading}>
+                    {loading && (
+                        <span className='spinner-border spinner-border-sm'></span>
+                    )}
+                    <span>Login</span>
+                </button>
+
+                {message && (
+                    <div className='form-group'>
+                        <div className='alert alert-danger' role='alert'>
+                            {message}
+                        </div>
+                    </div>
+                )}
+                <button
+                    style={{ display: 'none' }}
+                    // ref={c => {this.checkBtn = c}}
+                />
+            </form>
+        </div>
+    )
+}
-- 
GitLab


From 6e7e82e690d32d7f0e1fbc6d583625ade8caf215 Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 15:11:25 +0700
Subject: [PATCH 10/11] redirect after successful login

---
 diskuy/src/LoginForm.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/diskuy/src/LoginForm.js b/diskuy/src/LoginForm.js
index 3a5f873..9caa864 100644
--- a/diskuy/src/LoginForm.js
+++ b/diskuy/src/LoginForm.js
@@ -28,8 +28,7 @@ export default function LoginForm(){
 
         try {
             await AuthService.login(username, password)
-            // ? this.props.history.push('/profile')
-            // ? window.location.reload()
+            this.props.history.push('/topics')
         }
         catch(error) {
             const responseMessage =
-- 
GitLab


From 7d5e7de0cb1861b3aa075408144a3eef86b4c76c Mon Sep 17 00:00:00 2001
From: FadhilP <fadhilpradipta0@gmail.com>
Date: Thu, 7 Jan 2021 15:13:00 +0700
Subject: [PATCH 11/11] reset field when error, remove unnecessary component in
 render

---
 diskuy/src/LoginForm.js | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/diskuy/src/LoginForm.js b/diskuy/src/LoginForm.js
index 9caa864..8dec4cc 100644
--- a/diskuy/src/LoginForm.js
+++ b/diskuy/src/LoginForm.js
@@ -34,6 +34,8 @@ export default function LoginForm(){
             const responseMessage =
                 (error.response && error.response.data && error.response.data.message) || error.message || error.toString()
             setMessage(responseMessage)
+            resetPassword()
+            resetUsername()
         }
         setLoading(false)
     }
@@ -71,10 +73,6 @@ export default function LoginForm(){
                         </div>
                     </div>
                 )}
-                <button
-                    style={{ display: 'none' }}
-                    // ref={c => {this.checkBtn = c}}
-                />
             </form>
         </div>
     )
-- 
GitLab