This commit is contained in:
Dede Fuji Abdul
2023-10-16 14:29:26 +07:00
parent 4ee87a0aa9
commit d80e8d2b5a
9 changed files with 979 additions and 96 deletions

View File

@ -762,6 +762,10 @@ select {
left: -0.5rem;
}
.bottom-0 {
bottom: 0px;
}
.left-0 {
left: 0px;
}
@ -802,34 +806,6 @@ select {
top: 100%;
}
.top-\[50\%\] {
top: 50%;
}
.bottom-0 {
bottom: 0px;
}
.\!bottom-0 {
bottom: 0px !important;
}
.\!right-0 {
right: 0px !important;
}
.\!top-0 {
top: 0px !important;
}
.bottom-auto {
bottom: auto;
}
.top-auto {
top: auto;
}
.z-10 {
z-index: 10;
}
@ -867,6 +843,11 @@ select {
margin-right: 0.5rem;
}
.mx-3 {
margin-left: 0.75rem;
margin-right: 0.75rem;
}
.mx-auto {
margin-left: auto;
margin-right: auto;
@ -887,26 +868,6 @@ select {
margin-bottom: auto;
}
.mx-4 {
margin-left: 1rem;
margin-right: 1rem;
}
.mx-3 {
margin-left: 0.75rem;
margin-right: 0.75rem;
}
.\!mx-3 {
margin-left: 0.75rem !important;
margin-right: 0.75rem !important;
}
.\!my-auto {
margin-top: auto !important;
margin-bottom: auto !important;
}
.\!mt-0 {
margin-top: 0px !important;
}
@ -1107,6 +1068,11 @@ select {
height: 74vh;
}
.h-fit {
height: -moz-fit-content;
height: fit-content;
}
.h-full {
height: 100%;
}
@ -1115,11 +1081,6 @@ select {
height: 80vh;
}
.h-fit {
height: -moz-fit-content;
height: fit-content;
}
.max-h-0 {
max-height: 0px;
}
@ -1498,10 +1459,6 @@ select {
--tw-divide-opacity: 0.1;
}
.justify-self-center {
justify-self: center;
}
.overflow-hidden {
overflow: hidden;
}

View File

@ -12,7 +12,7 @@ const router = createRouter({
linkActiveClass: 'active',
routes: [
{
path: '/',
path: '/home',
name: 'Home',
'meta': { requiresAuth: true },
component: HomeView,
@ -295,9 +295,9 @@ const router = createRouter({
path: '/logout',
name: 'Logout',
beforeEnter(to, from, next) {
const auth = useAuthStore();
auth.logout();
next('/login');
const auth = useAuthStore()
auth.logout()
next('/login')
},
redirect: '/logout'
},
@ -319,26 +319,36 @@ const router = createRouter({
]
})
router.beforeEach((to, _from) => {
router.beforeEach((to, from, next) => {
// redirect to login page if not logged in and trying to access a restricted page
const publicPages = ['/login'];
const authRequired = !publicPages.includes(to.path);
const auth = useAuthStore();
// if to is not found, redirect to 404
if (to.matched.length === 0) {
return '/404';
} else {
// if to is not login and user is not logged in, redirect to login
if (!auth.isLoggedIn) {
// if to is 404, redirect to 404
if (to.path !== '/404' && to.path !== '/login') {
return '/login';
if (to.path === '/') {
if (auth.isLoggedIn) {
next('/home')
} else {
next('/login')
}
} else {
next('/404')
}
} else {
// if to is not login and user is not logged in, redirect to login
if (auth.isLoggedIn) {
// if to is login and user is logged in, redirect to home
if (to.path === '/login') {
return '/';
next('/home')
} else {
next()
}
} else {
// if to is 404, redirect to 404
if (to.path !== '/404' && to.path !== '/login') {
next('/login')
} else {
next()
}
}
}

View File

@ -1,11 +1,12 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { dispatchNotification } from '@/components/Notification'
import { readData, removeData, writeData } from './storage'
import router from '@/router'
export const useAuthStore = defineStore('auth', () => {
// token from localStorage
const token = ref(localStorage.getItem('token') || '')
const token = ref(readData('token') || '')
// create a shared state
const username = ref('')
const password = ref('')
@ -13,7 +14,7 @@ export const useAuthStore = defineStore('auth', () => {
const isLoggedIn = computed(() => token.value !== '')
// define your actions
function login() {
const login = () => {
if (username.value == '' || password.value == '') {
dispatchNotification({ title: 'Perhatian', content: 'Username atau password tidak boleh kosong', type: 'warning' })
} else {
@ -22,11 +23,10 @@ export const useAuthStore = defineStore('auth', () => {
isLoading.value = false
if (username.value == 'demo' && password.value == 'demo') {
// store token in localStorage
localStorage.setItem('token', 'secret-token')
writeData('token', 'secret-token')
dispatchNotification({ title: 'Berhasil', content: 'Login berhasil, selamat datang kembali!', type: 'success' })
// redirect to home page after login
// router.replace('/')
router.go(0)
router.push('/home')
} else {
dispatchNotification({ title: 'Login Gagal', content: 'Username atau password salah', type: 'error' })
}
@ -34,10 +34,15 @@ export const useAuthStore = defineStore('auth', () => {
}
}
function logout() {
localStorage.removeItem('token')
}
const logout = () => removeData('token')
// expose everything
return { token, username, password, isLoggedIn, login, logout, isLoading }
return {
token,
username,
password,
isLoggedIn,
isLoading,
login,
logout,
}
})

28
src/stores/storage.ts Normal file
View File

@ -0,0 +1,28 @@
import { EncryptStorage } from 'encrypt-storage'
const encryptStorage = new EncryptStorage('qwertyuiopasdfghjklzxcvbnm-1234567890')
const writeData = (key: string, data: any) => encryptStorage.setItem(key, data)
const writeDataJson = (key: string, data: any) => encryptStorage.setItem(key, JSON.stringify(data))
const removeData = (key: string) => encryptStorage.removeItem(key)
const readData = (key: string) => {
try {
return encryptStorage.getItem(key)
} catch (error) {
return undefined
}
}
const readDataJson = (key: string) => {
try {
return encryptStorage.getItem(key)
} catch (error) {
return undefined
}
}
export {
removeData,
writeData,
writeDataJson,
readData,
readDataJson
}

View File

@ -1,11 +1,16 @@
<script setup lang="ts">
import { useAuthStore } from '@/stores/auth';
import Icon from '@/assets/images/pln-with-text.png';
import Hero from '@/assets/images/hero.png';
import Button from '@/components/ButtonPrimary.vue';
import InputText from '@/components/InputText.vue';
import { useAuthStore } from '@/stores/auth'
import Icon from '@/assets/images/pln-with-text.png'
import Hero from '@/assets/images/hero.png'
import Button from '@/components/ButtonPrimary.vue'
import InputText from '@/components/InputText.vue'
import { onMounted } from 'vue'
const authStore = useAuthStore();
const authStore = useAuthStore()
onMounted(() => {
window.document.title = `Login - ${import.meta.env.VITE_APP_NAME}`
})
</script>
<template>
@ -35,7 +40,6 @@ const authStore = useAuthStore();
<img :src="Hero" alt="logo" class="h-full" />
</div>
</div>
</div>
</div>
</template>