77 lines
1.8 KiB
TypeScript
77 lines
1.8 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import type { User, LoginRequest, RegisterRequest } from '~/types'
|
|
|
|
interface AuthState {
|
|
user: User | null
|
|
token: string | null
|
|
loading: boolean
|
|
}
|
|
|
|
export const useAuthStore = defineStore('auth', {
|
|
state: (): AuthState => ({
|
|
user: null,
|
|
token: null,
|
|
loading: false,
|
|
}),
|
|
|
|
getters: {
|
|
isAuthenticated: (state) => !!state.token,
|
|
},
|
|
|
|
actions: {
|
|
async login(email: string, password: string) {
|
|
this.loading = true
|
|
try {
|
|
const api = useApi()
|
|
const response = await api.post<{ access_token: string; user: User }>('/auth/login', { email, password })
|
|
this.token = response.access_token
|
|
this.user = response.user
|
|
await this.fetchUser()
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async register(data: RegisterRequest) {
|
|
this.loading = true
|
|
try {
|
|
const api = useApi()
|
|
const response = await api.post<{ access_token: string; user: User }>('/auth/register', data)
|
|
this.token = response.access_token
|
|
this.user = response.user
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async fetchUser() {
|
|
if (!this.token) return
|
|
try {
|
|
const api = useApi()
|
|
this.user = await api.get<User>('/me')
|
|
} catch {
|
|
this.token = null
|
|
this.user = null
|
|
}
|
|
},
|
|
|
|
async refreshToken(): Promise<boolean> {
|
|
try {
|
|
const api = useApi()
|
|
const response = await api.post<{ access_token: string }>('/auth/refresh')
|
|
this.token = response.access_token
|
|
return true
|
|
} catch {
|
|
this.token = null
|
|
this.user = null
|
|
return false
|
|
}
|
|
},
|
|
|
|
logout() {
|
|
this.token = null
|
|
this.user = null
|
|
},
|
|
},
|
|
})
|