diff --git a/package-lock.json b/package-lock.json
index ec7781c302f15eadbd792aca10acf84155e8aec2..13345a1690bc62dc989cfe346b17e7e1bca1c104 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11925,6 +11925,11 @@
         "setimmediate": "^1.0.4"
       }
     },
+    "tiny-cookie": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tiny-cookie/-/tiny-cookie-1.0.1.tgz",
+      "integrity": "sha1-dTeGB5xkKjw9CyrMrWAPjeEZrCo="
+    },
     "to-arraybuffer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
@@ -12437,6 +12442,14 @@
       "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
       "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
     },
+    "vue-cookie": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/vue-cookie/-/vue-cookie-1.1.4.tgz",
+      "integrity": "sha1-uLRtESvan5Oi9HAXwu1SgtIGT9o=",
+      "requires": {
+        "tiny-cookie": "^1.0"
+      }
+    },
     "vue-functional-data-merge": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-2.0.7.tgz",
diff --git a/package.json b/package.json
index e5a3e9fe861c29905ba1ecca04f1d946b77debcc..c3aebd5ea1cab5070a40af3fb867fba5963ca77b 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
     "bootstrap-vue": "^2.0.0-rc.15",
     "d3": "^5.9.2",
     "vue": "^2.6.10",
+    "vue-cookie": "^1.1.4",
     "vue-router": "^3.0.1",
     "vuex": "^3.1.0"
   },
diff --git a/src/App.vue b/src/App.vue
index 59d58953655dfcfe93318f114bfe64e1a9d82d9a..63bc9bf1a37c6eb767caf827e11cc85bd191b7e6 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -17,6 +17,31 @@ export default {
   components: {
     'app-navbar': navbar,
   },
+  mounted() {
+    if(this.$cookie.get('token')) {
+      let fetchData = {
+        method: 'POST',
+        headers: {
+          "Authorization": this.$cookie.get('token'),
+        }
+      }
+
+      fetch(`${this.$store.state.baseUrl}/api/get-user`, fetchData)
+      .then(response => response.json())
+      .then(response => {
+        if(response.status === 200) {
+          let data = {
+            'token': this.$cookie.get('token'),
+            'id': response.data._id,
+            'name': response.data.name,
+            'role': response.data.role,
+            'pageList': response.data.page_list
+          }
+          this.$store.commit('setUser', data)
+        }
+      })
+    }
+  }
 }
 
 </script>
diff --git a/src/components/pages/LoginPage.vue b/src/components/pages/LoginPage.vue
index 2d16827da9a70bf8421b7fa725c5a8ff8c613368..778a6ed3aaf8c79e6459ea42f3a0c73a21399513 100644
--- a/src/components/pages/LoginPage.vue
+++ b/src/components/pages/LoginPage.vue
@@ -4,6 +4,15 @@
       <b-card no-body>
         <b-tabs card>
           <b-tab title="Masuk" active>
+            <b-alert
+              :show="dismissCountDown"
+              dismissible
+              variant="warning"
+              @dismissed="dismissCountDown=0"
+              @dismiss-count-down="countdownCallback"
+            >
+              {{ errorMessage }}
+            </b-alert>
             <b-form @submit.prevent="submitLogin">
               <b-form-group label="Nama Pengguna:">
                 <b-form-input
@@ -25,6 +34,15 @@
             </b-form>
           </b-tab>
           <b-tab title="Daftar">
+            <b-alert
+              :show="dismissCountDown"
+              dismissible
+              variant="warning"
+              @dismissed="dismissCountDown=0"
+              @dismiss-count-down="countdownCallback"
+            >
+              {{ errorMessage }}
+            </b-alert>
             <b-form>
               <b-form-group label="NIK/NIP:">
                 <b-form-input
@@ -93,23 +111,135 @@ export default {
         username: '',
         password: '',
         confirmPassword: ''
-      }
+      },
+      errorMessage: '',
+      dismissSecs: 5,
+      dismissCountDown: 0
     }
   },
   created : function() {
     this.$store.commit('changed','Jenis Anggaran')
   },
   methods: {
-    submitLogin: function(event) {
-      // TODO: Create function to log in the user
-      var data = {token: 'ABCD', id: 1, name: this.login.username}
-      this.$store.commit('setUser', data)
-      this.$router.push('/')
+    submitLogin() {
+      if (this.login.username.length == 0 || this.login.password.length == 0) {
+        this.setErrorMessage("Kata pengguna/sandi wajib diisi")
+        return
+      }
+
+      let fetchData = {
+        method: 'POST',
+        body: JSON.stringify(
+          {
+            username: this.login.username,
+            password: this.login.password,
+          }
+        ),
+        headers: {
+          "Content-Type": "application/json",
+        }
+      }
+
+      fetch(`${this.$store.state.baseUrl}/api/login`, fetchData)
+      .then(response => response.json())
+      .then(response => {
+        if(response.status === 200) {
+          this.$cookie.set('token', response.data.token)
+          let data = {
+            'token': response.data.token,
+            'id': response.data.user._id,
+            'name': response.data.user.name,
+            'role': response.data.user.role,
+            'pageList': response.data.user.page_list
+          }
+          this.$store.commit('setUser', data)
+          this.$router.push({name: 'LandingPage'})
+        } else if(response.status === 404) {
+          this.setErrorMessage('Kata pengguna/sandi salah.')
+        } else {
+          this.setErrorMessage('Tidak dapat masuk. Silakan coba lagi.')
+        }
+      })
+      .catch(error => {
+        this.setErrorMessage('Tidak dapat terhubung dengan server. Mohon periksa koneksi internet dan cobalah beberapa saat lagi.')
+      })
+    },
+    submitRegister() {
+      if (this.register.username.length === 0) {
+        this.setErrorMessage("Kata pengguna wajib diisi")
+        return
+      }
+      if (this.register.nik.length === 0) {
+        this.setErrorMessage("NIK wajib diisi")
+        return
+      }
+      if (this.register.name.length === 0) {
+        this.setErrorMessage("Nama lengkap wajib diisi")
+        return
+      }
+      if (this.register.password.length === 0) {
+        this.setErrorMessage("Kata sandi wajib diisi")
+        return
+      }
+      if (this.register.password !== this.register.confirmPassword) {
+        this.setErrorMessage("Kata sandi tidak cocok")
+        return
+      }
+      if (this.register.password !== this.register.confirmPassword) {
+        this.setErrorMessage("Kata sandi tidak cocok")
+        return
+      }
+      
+      let role = 0
+      if (this.register.nik.length === 18)
+        role = 1
+
+      let fetchData = {
+        method: 'POST',
+        body: JSON.stringify(
+          {
+            username: this.register.username,
+            password: this.register.password,
+            user_id: this.register.nik,
+            name: this.register.name,
+            role: role
+          }
+        ),
+        headers: {
+          "Content-Type": "application/json",
+        }
+      };
+
+      fetch(`${this.$store.state.baseUrl}/api/register`, fetchData)
+      .then(response => response.json())
+      .then(response => {
+        if(response.status === 200) {
+          this.$cookie.set('token', response.data.token)
+          let data = {
+            'token': response.data.token,
+            'id': this.register.nik,
+            'name': this.register.name,
+            'role': role,
+            'pageList': []
+          }
+          this.$store.commit('setUser', data)
+          this.$router.push({name: 'LandingPage'})
+        } else if (response.status === 500) {
+          this.setErrorMessage('Akun dengan NIK ini sudah dibuat.')
+        } else {
+          this.setErrorMessage('Terjadi kesalahan. Kesalahan: ' + response.message)
+        }
+      })
+      .catch(error => {
+        this.setErrorMessage('Tidak dapat terhubung dengan server. Mohon periksa koneksi internet dan cobalah beberapa saat lagi.')
+      })
+    },
+    countdownCallback(dismissCountDown) {
+      this.dismissCountDown = dismissCountDown
     },
-    submitRegister: function(event) {
-      // TODO: Create function to register new user
-      this.$store.commit('setUser', 'ABCD', 1, this.register.username)
-      this.$router.push('/')
+    setErrorMessage(message) {
+      this.errorMessage = message
+      this.dismissCountDown = this.dismissSecs
     }
   }
 }
diff --git a/src/components/partials/Navbar.vue b/src/components/partials/Navbar.vue
index 97942b30c1e1f50c1c6981e92ac06dee4f13b4c4..25254753349f4fbb29d7f8ea46c7bf0a95599b5b 100644
--- a/src/components/partials/Navbar.vue
+++ b/src/components/partials/Navbar.vue
@@ -12,7 +12,7 @@
       <b-collapse is-nav id="nav_collapse">
       <!-- Right aligned nav items -->
       <b-navbar-nav>
-        <b-nav-item-dropdown v-bind:text=pilihan left>
+        <b-nav-item-dropdown v-bind:text=state left>
           <b-dropdown-item v-on:click="gotoPage('semua-anggaran')">
             Semua Anggaran
           </b-dropdown-item>
@@ -38,11 +38,11 @@
           </b-nav-item>
         </div>
         <div v-else>
-          <b-nav-item-dropdown v-bind:text=nama right>
+          <b-nav-item-dropdown v-bind:text=name right>
             <b-dropdown-item v-on:click="gotoPage('semua-anggaran')">
               Pengaturan
             </b-dropdown-item>
-            <b-dropdown-item v-on:click="gotoPage('pendapatan')">
+            <b-dropdown-item v-on:click="logOut()">
               Keluar
             </b-dropdown-item>
           </b-nav-item-dropdown>
@@ -61,29 +61,27 @@ export default {
   name: 'Navbar',
   data () {
     return {
-      pilihan : this.$store.state.pilihan,
-      nama : this.$store.state.user.name,
+      
     }
   },
   computed : {
-    state_watcher () {
+    state() {
       return this.$store.state.pilihan
+    },
+    name() {
+      return this.$store.state.user.name
     }
   },
   methods : {
-    gotoPage : function(page) {
+    gotoPage(page) {
       this.$router.push(page)
+    },
+    logOut() {
+      this.$cookie.set('token', "");
+      this.$store.commit('clearUser')
+      this.$router.push({name: 'LandingPage'});
     }
   },
-  created : function() {
-    this.pilihan = this.$store.state.pilihan
-  },
-  watch : {
-    state_watcher(newPilihan, oldPilihan) {
-      //   console.log("lama : " + oldPilihan + ", baru :" +newPilihan)
-        this.pilihan = newPilihan
-    }
-  }
 }
 </script>
 
diff --git a/src/components/store/Store.js b/src/components/store/Store.js
index 968e617040b987fed2319979519755646f4532ed..47416af30db77b1a775b6b3a15f5a624f3f75986 100644
--- a/src/components/store/Store.js
+++ b/src/components/store/Store.js
@@ -9,10 +9,13 @@ export const store = new Vuex.Store({
     count : 0,
     year : '',
     user : {
-      token : '',
-      id : -1,
-      name : 'dummy'
-    }
+      token: '',
+      id: -1,
+      name: '',
+      role: -1,
+      pageList: []
+    },
+    baseUrl: 'http://localhost:5000'
   },
   computed: {
     pilihan() {
@@ -30,7 +33,16 @@ export const store = new Vuex.Store({
       state.user.token = data.token
       state.user.id = data.id
       state.user.name = data.name
+      state.user.role = data.role
+      state.user.pageList = data.pageList
     },
+    clearUser(state) {
+      state.user.token = '',
+      state.user.id = -1,
+      state.user.name = '',
+      state.user.role = -1,
+      state.user.pageList = []
+    }
   },
   getters : {
     pilihan : (state) => {
diff --git a/src/main.js b/src/main.js
index 9d4ab8846d9f4d49fae15007603ed7f9b7ec9d6f..44488f4ae3b2fc2fa48abc7526cd69167af0f869 100644
--- a/src/main.js
+++ b/src/main.js
@@ -5,6 +5,7 @@ import Vuex from 'vuex'
 import App from './App'
 import router from './router'
 import BootstrapVue from 'bootstrap-vue'
+import VueCookie from 'vue-cookie'
 import {store} from './components/store/store'
  
 import 'bootstrap/dist/css/bootstrap.css'
@@ -13,6 +14,8 @@ import 'bootstrap-vue/dist/bootstrap-vue.css'
 Vue.config.productionTip = false
 Vue.use(BootstrapVue)
 Vue.use(Vuex)
+Vue.use(VueCookie)
+
 /* eslint-disable no-new */
 new Vue({
   el: '#app',