Init
This commit is contained in:
112
composables/useAuth.ts
Normal file
112
composables/useAuth.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
export interface User {
|
||||
name: string
|
||||
email?: string
|
||||
}
|
||||
|
||||
export interface LoginCredentials {
|
||||
email: string
|
||||
password: string
|
||||
remember?: boolean
|
||||
}
|
||||
|
||||
export interface RegisterCredentials {
|
||||
name: string
|
||||
email: string
|
||||
password: string
|
||||
password_confirmation: string
|
||||
}
|
||||
|
||||
export interface ResetPasswordCredentials {
|
||||
email: string
|
||||
password: string
|
||||
password_confirmation: string
|
||||
token: string
|
||||
}
|
||||
|
||||
// Value is initialized in: ~/plugins/auth.ts
|
||||
export function useUser<T = User>() {
|
||||
return useState<T | undefined | null>('user', () => undefined)
|
||||
}
|
||||
|
||||
export function useAuth<T = User>() {
|
||||
const router = useRouter()
|
||||
|
||||
const user = useUser<T>()
|
||||
const isLoggedIn = computed(() => !!user.value)
|
||||
|
||||
async function refresh() {
|
||||
try {
|
||||
user.value = await fetchCurrentUser()
|
||||
}
|
||||
catch {
|
||||
user.value = null
|
||||
}
|
||||
}
|
||||
|
||||
async function login(credentials: LoginCredentials) {
|
||||
if (isLoggedIn.value) { return }
|
||||
|
||||
await $larafetch('/login', { method: 'post', body: credentials })
|
||||
await refresh()
|
||||
}
|
||||
|
||||
async function register(credentials: RegisterCredentials) {
|
||||
await $larafetch('/register', { method: 'post', body: credentials })
|
||||
await refresh()
|
||||
}
|
||||
|
||||
async function resendEmailVerification() {
|
||||
return await $larafetch<{ status: string }>(
|
||||
'/email/verification-notification',
|
||||
{
|
||||
method: 'post',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
if (!isLoggedIn.value) { return }
|
||||
|
||||
await $larafetch('/logout', { method: 'post' })
|
||||
user.value = null
|
||||
|
||||
await router.push('/login')
|
||||
}
|
||||
|
||||
async function forgotPassword(email: string) {
|
||||
return await $larafetch<{ status: string }>('/forgot-password', {
|
||||
method: 'post',
|
||||
body: { email },
|
||||
})
|
||||
}
|
||||
|
||||
async function resetPassword(credentials: ResetPasswordCredentials) {
|
||||
return await $larafetch<{ status: string }>('/reset-password', {
|
||||
method: 'post',
|
||||
body: credentials,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
user,
|
||||
isLoggedIn,
|
||||
login,
|
||||
register,
|
||||
resendEmailVerification,
|
||||
logout,
|
||||
forgotPassword,
|
||||
resetPassword,
|
||||
refresh,
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchCurrentUser<T = User>() {
|
||||
try {
|
||||
return await $larafetch<T>('/api/user')
|
||||
}
|
||||
catch (error: any) {
|
||||
if ([401, 419].includes(error?.response?.status)) { return null }
|
||||
if (error?.response?.status === undefined) { return null }
|
||||
throw error
|
||||
}
|
||||
}
|
||||
25
composables/useLarafetch.ts
Normal file
25
composables/useLarafetch.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import type { UseFetchOptions } from 'nuxt/app'
|
||||
|
||||
export function useLarafetch<T>(
|
||||
url: string | (() => string),
|
||||
options: UseFetchOptions<T> = {},
|
||||
) {
|
||||
return useFetch(url, {
|
||||
$fetch: $larafetch,
|
||||
async onResponseError({ response }) {
|
||||
const status = response.status
|
||||
if ([500].includes(status)) {
|
||||
console.error('[Laravel Error]', response.statusText, response._data)
|
||||
}
|
||||
|
||||
if ([401, 419].includes(status)) {
|
||||
navigateTo('/login')
|
||||
}
|
||||
|
||||
if ([409].includes(status)) {
|
||||
navigateTo('/verify-email')
|
||||
}
|
||||
},
|
||||
...options,
|
||||
})
|
||||
}
|
||||
61
composables/useSubmit.ts
Normal file
61
composables/useSubmit.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { FormError } from '@nuxt/ui/dist/runtime/types'
|
||||
|
||||
export interface UseSubmitOptions {
|
||||
onSuccess?: (result: any) => any
|
||||
onError?: (error: Error) => any
|
||||
}
|
||||
|
||||
export function useSubmit<T>(
|
||||
fetchable: () => Promise<T>,
|
||||
options: UseSubmitOptions = {},
|
||||
) {
|
||||
const validationErrors = ref<FormError[]>([])
|
||||
const error = ref<Error | null>(null)
|
||||
const inProgress = ref(false)
|
||||
const succeeded = ref<boolean | null>(null)
|
||||
|
||||
async function submit() {
|
||||
validationErrors.value = []
|
||||
error.value = null
|
||||
inProgress.value = true
|
||||
succeeded.value = null
|
||||
|
||||
try {
|
||||
const data = await fetchable()
|
||||
succeeded.value = true
|
||||
options?.onSuccess?.(data)
|
||||
return data
|
||||
}
|
||||
catch (e: any) {
|
||||
error.value = e
|
||||
succeeded.value = false
|
||||
options?.onError?.(e)
|
||||
if (e.data?.errors) {
|
||||
const errorsArray: FormError[] = []
|
||||
for (const path in e.data.errors) {
|
||||
const messages = e.data.errors[path]
|
||||
messages.forEach((message: string) => {
|
||||
errorsArray.push({ path, message })
|
||||
})
|
||||
}
|
||||
validationErrors.value = errorsArray
|
||||
}
|
||||
else {
|
||||
validationErrors.value = []
|
||||
}
|
||||
|
||||
if (e.response?.status !== 422) { throw e }
|
||||
}
|
||||
finally {
|
||||
inProgress.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
submit,
|
||||
inProgress,
|
||||
succeeded,
|
||||
validationErrors,
|
||||
error,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user