This commit is contained in:
2023-11-16 22:57:56 +01:00
commit 237d969e5c
146 changed files with 23818 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
export interface User {
id: number
name: string
email: string
email_verified_at: string | null
password?: string
remember_token?: string | null
roles: Role[]
created_at: string | null
updated_at: string | null
}
export interface Role {
name: 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
const csrf_cookie = useCookie('XSRF-TOKEN')
csrf_cookie.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
}
}

View File

@@ -0,0 +1,4 @@
export default function useEcho() {
const { $echo } = useNuxtApp()
return $echo
}

View 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,
})
}

View File

@@ -0,0 +1,11 @@
export function useRoles() {
const user = useUser()
function hasRole(roleName: string) {
return user.value?.roles?.some(role => role.name === roleName) ?? false
}
return {
hasRole,
}
}

View File

@@ -0,0 +1,63 @@
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,
}
}