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',