Added auth to frontend
parent
87776fdbe7
commit
00fcc17b5d
@ -0,0 +1,8 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const request = axios.create({
|
||||||
|
baseURL: 'http://localhost:8000',
|
||||||
|
withCredentials: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
export { request }
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
const userSchema = z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
password: z.string().min(6),
|
||||||
|
})
|
||||||
|
|
||||||
|
const userLogin = async (email: String, password: String) => {
|
||||||
|
await getUser()
|
||||||
|
if (useUser().value) return
|
||||||
|
|
||||||
|
const user = userSchema.safeParse({ email, password })
|
||||||
|
|
||||||
|
if (!user.success) return user.error.format()
|
||||||
|
|
||||||
|
await request.get('/sanctum/csrf-cookie')
|
||||||
|
await request.post('/login', user.data)
|
||||||
|
|
||||||
|
await getUser()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUser = async () => {
|
||||||
|
await request
|
||||||
|
.get('/api/user')
|
||||||
|
.then(({ data }) => {
|
||||||
|
const parsed = loggedInUserSchema.safeParse(data)
|
||||||
|
if (!parsed.success) return
|
||||||
|
useUser().value = parsed.data.name
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const loggedInUserSchema = z.object({
|
||||||
|
name: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
const useUser = () => useState<String>('user', () => '')
|
||||||
|
|
||||||
|
export { userLogin, useUser, getUser }
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
|
const user = useUser()
|
||||||
|
await getUser()
|
||||||
|
|
||||||
|
if (!user.value && to.path !== '/login' && to.path.startsWith('/')) {
|
||||||
|
return navigateTo('/login')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.value && to.path === '/login') {
|
||||||
|
return navigateTo('/')
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
middleware: ['auth'],
|
||||||
|
})
|
||||||
|
|
||||||
|
const user = useUser()
|
||||||
|
|
||||||
|
const userCredential = reactive({
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const isSigningIn = ref<Boolean>(false)
|
||||||
|
|
||||||
|
const errors = reactive({
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
user: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const login = async () => {
|
||||||
|
isSigningIn.value = true
|
||||||
|
const error = await userLogin(userCredential.email, userCredential.password)
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
errors.email = error.email ? error.email._errors.join(',') : ''
|
||||||
|
errors.password = error.password ? error.password._errors.join(',') : ''
|
||||||
|
// errors.user = error.user ? error.user._errors.join(',') : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => (isSigningIn.value = false), 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
const logoutAxios = async () => {
|
||||||
|
await request.post('/logout')
|
||||||
|
user.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => user.value,
|
||||||
|
() => {
|
||||||
|
if (user.value) useRouter().push('/')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="absolute flex w-96 flex-col items-center justify-center gap-2 rounded-xl border border-lightgray bg-secondary p-6">
|
||||||
|
<label class="mt-2 w-full"> Email </label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="userCredential.email"
|
||||||
|
class="w-full rounded-md border border-lightgray p-2" />
|
||||||
|
<span
|
||||||
|
v-if="errors.email"
|
||||||
|
class="w-full text-red-400">
|
||||||
|
{{ errors.email }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<label class="mt-2 w-full"> Password </label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
v-model="userCredential.password"
|
||||||
|
class="w-full rounded-md border border-lightgray p-2" />
|
||||||
|
<span
|
||||||
|
v-if="errors.password"
|
||||||
|
class="w-full text-red-400">
|
||||||
|
{{ errors.password }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="errors.user"
|
||||||
|
class="mt-4 text-red-400">
|
||||||
|
{{ errors.user }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click="login()"
|
||||||
|
class="mt-6 flex gap-2 rounded-full border border-lightgray bg-blue-500 px-6 py-2">
|
||||||
|
<Icon
|
||||||
|
v-if="isSigningIn"
|
||||||
|
name="loading" />
|
||||||
|
<div> Sign In </div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
Loading…
Reference in New Issue