Files
mykopkb-fe/src/modules/auth/pages/Login.vue
T

151 lines
6.4 KiB
Vue

<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Box } from '@/components/ui/box'
import { Button } from '@/components/ui/button'
import { CheckboxRoot, CheckboxControl, CheckboxLabel } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
import { AlertRoot, AlertTitle, AlertDescription } from '@/components/ui/alert'
import { PasswordInput } from '@/components/ui/password-input'
import {
getAuthErrorMessage,
login,
resolvePostAuthRoute,
} from '@/modules/auth'
import { useAuthStore } from '@/stores/auth'
import illustrationUrl from '@/assets/images/logo.svg'
const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()
const email = ref('')
const password = ref('')
const remember = ref(false)
const loading = ref(false)
const errorMessage = ref('')
const successMessage = ref('')
onMounted(() => {
if (route.query.reset === 'success') {
const message = route.query.message
successMessage.value = typeof message === 'string' && message
? message
: 'Kata laluan anda telah berjaya ditetapkan semula. Sila log masuk.'
}
})
const handleLogin = async () => {
errorMessage.value = ''
successMessage.value = ''
loading.value = true
try {
const response = await login({
email: email.value,
password: password.value,
remember: remember.value,
})
const loginData = response.data
if ('requires_email_verification' in loginData) {
await router.push({
name: 'verify-email',
query: { email: loginData.email },
})
return
}
authStore.setSession(loginData.user, response.active_role ?? null, response.can_switch_role ?? false)
await router.push(resolvePostAuthRoute(loginData.user, response.redirect_path))
} catch (error) {
errorMessage.value = getAuthErrorMessage(error)
} finally {
loading.value = false
}
}
const appName = import.meta.env.VITE_APP_NAME
const appVersion = import.meta.env.VITE_APP_VERSION
</script>
<template>
<div :class="[
'relative h-screen lg:overflow-hidden bg-primary bg-noise xl:bg-background xl:bg-none',
'before:hidden before:xl:block before:content-[\'\'] before:w-[57%] before:mt-[-28%] before:mb-[-16%] before:ml-[-12%] before:absolute before:inset-y-0 before:left-0 before:transform before:rotate-6 before:bg-primary/95 before:bg-noise before:rounded-[35%]',
'after:hidden after:xl:block after:content-[\'\'] after:w-[57%] after:mt-[-28%] after:mb-[-16%] after:ml-[-12%] after:absolute after:inset-y-0 after:left-0 after:transform after:rotate-6 after:border after:bg-accent after:bg-cover after:blur-xl after:rounded-[35%] after:border-primary',
]">
<div :class="[
'p-3 sm:px-8 relative h-full',
'before:hidden before:xl:block before:w-[57%] before:mt-[-20%] before:mb-[-13%] before:ml-[-12%] before:absolute before:inset-y-0 before:left-0 before:transform before:-rotate-6 before:bg-primary/40 before:bg-noise before:border before:border-primary/50 before:opacity-60 before:rounded-[20%]',
]">
<div class="container relative z-10 mx-auto sm:px-20">
<div class="block grid-cols-2 gap-4 xl:grid">
<!-- BEGIN: Login Info -->
<div class="hidden min-h-screen flex-col xl:flex">
<div class="my-auto">
<img class="-mt-16 w-1/2" :src="illustrationUrl" alt="logo-RAJD" />
<div class="mt-10 text-4xl font-medium leading-tight text-white">
Selamat Datang
</div>
<div class="mt-5 text-lg text-white opacity-60">
Sistem Informasi Koperasi Online (MyKOPKB) 1.0
</div>
</div>
</div>
<!-- END: Login Info -->
<!-- BEGIN: Login Form -->
<div class="my-10 flex h-screen py-5 xl:my-0 xl:h-auto xl:py-0">
<Box raised="double"
class="mx-auto my-auto w-full px-5 py-8 sm:w-3/4 sm:px-8 lg:w-2/4 xl:ml-24 xl:w-auto xl:p-0 xl:before:hidden xl:after:hidden xl:shadow-none xl:border-none xl:bg-none">
<h2 class="text-center text-2xl font-semibold xl:text-left xl:text-3xl">Log Masuk</h2>
<div class="mt-2 text-center opacity-70 xl:hidden">
Selamat Datang
</div>
<AlertRoot v-if="successMessage" class="mt-6" variant="primary">
<AlertDescription>{{ successMessage }}</AlertDescription>
</AlertRoot>
<AlertRoot v-if="errorMessage" class="mt-6" variant="danger">
<AlertTitle>Login failed</AlertTitle>
<AlertDescription>{{ errorMessage }}</AlertDescription>
</AlertRoot>
<form class="mt-8 flex flex-col gap-5" @submit.prevent="handleLogin">
<Input v-model="email" class="box block min-w-full px-5 py-6 xl:min-w-md" type="email"
placeholder="Email" autocomplete="email" required />
<PasswordInput v-model="password" class="box block min-w-full px-5 py-6 xl:min-w-md"
placeholder="Kata Laluan" autocomplete="current-password" required />
<div class="flex text-xs sm:text-sm">
<div class="mr-auto flex-row items-center">
<CheckboxRoot :checked="remember" @checked-change="({ checked }) => (remember = checked === true)">
<CheckboxControl />
<CheckboxLabel>Ingat saya</CheckboxLabel>
</CheckboxRoot>
</div>
<button type="button" class="opacity-70 hover:opacity-100"
@click="router.push({ name: 'forgot-password' })">
Lupa Kata Laluan?
</button>
</div>
<div class="mt-5 text-center xl:mt-10 xl:text-left">
<Button class="login-button box w-full px-4 py-5" variant="primary" type="submit" :disabled="loading">
{{ loading ? 'Log masuk...' : 'Log masuk' }}
</Button>
<Button class="box mt-4 w-full px-4 py-5" look="outline" type="button"
@click="router.push({ name: 'register' })">
Daftar
</Button>
</div>
</form>
</Box>
</div>
<!-- END: Login Form -->
</div>
</div>
</div>
</div>
</template>