69 lines
1.6 KiB
TypeScript
69 lines
1.6 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
import { AUTH_TOKEN_KEY, api } from '../lib/api'
|
|
import type { AuthSession, LoginPayload } from '../types/awards'
|
|
|
|
function readStoredToken() {
|
|
if (typeof window === 'undefined') return null
|
|
return window.localStorage.getItem(AUTH_TOKEN_KEY)
|
|
}
|
|
|
|
function writeStoredToken(token: string | null) {
|
|
if (typeof window === 'undefined') return
|
|
|
|
if (token) {
|
|
window.localStorage.setItem(AUTH_TOKEN_KEY, token)
|
|
} else {
|
|
window.localStorage.removeItem(AUTH_TOKEN_KEY)
|
|
}
|
|
}
|
|
|
|
export const useAuthStore = defineStore('auth', {
|
|
state: () => ({
|
|
session: null as AuthSession | null,
|
|
hydrated: false,
|
|
loading: false,
|
|
}),
|
|
getters: {
|
|
isLoggedIn: (state) => Boolean(state.session),
|
|
isAdmin: (state) => state.session?.role === 'admin',
|
|
},
|
|
actions: {
|
|
async hydrate() {
|
|
if (!readStoredToken()) {
|
|
this.hydrated = true
|
|
return
|
|
}
|
|
|
|
try {
|
|
this.session = await api.getSession()
|
|
} catch {
|
|
this.session = null
|
|
writeStoredToken(null)
|
|
} finally {
|
|
this.hydrated = true
|
|
}
|
|
},
|
|
async login(payload: LoginPayload) {
|
|
this.loading = true
|
|
try {
|
|
const session = await api.login(payload)
|
|
this.session = session
|
|
writeStoredToken(session.sessionToken)
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
async logout() {
|
|
this.loading = true
|
|
try {
|
|
await api.logout()
|
|
} finally {
|
|
this.session = null
|
|
writeStoredToken(null)
|
|
this.loading = false
|
|
}
|
|
},
|
|
},
|
|
})
|