Refactor user store to use apiClient instead of direct fetch
- Replace manual fetch calls with apiClient.get() and apiClient.patch() - Remove manual token handling (apiClient handles this automatically) - Add typed UserProfileResponse interface for API response - Improve error handling with ApiError type checking - Gains automatic token refresh on 401 with retry logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ca3aca2b38
commit
6bfc928169
@ -7,7 +7,8 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { config } from '@/config'
|
||||
import { apiClient } from '@/api/client'
|
||||
import { ApiError } from '@/api/types'
|
||||
import { useAuthStore } from './auth'
|
||||
|
||||
export interface LinkedAccount {
|
||||
@ -38,14 +39,28 @@ export const useUserStore = defineStore('user', () => {
|
||||
const hasStarterDeck = computed(() => profile.value?.hasStarterDeck ?? false)
|
||||
const linkedAccounts = computed(() => profile.value?.linkedAccounts ?? [])
|
||||
|
||||
/** API response type for user profile */
|
||||
interface UserProfileResponse {
|
||||
id: string
|
||||
display_name: string
|
||||
avatar_url: string | null
|
||||
has_starter_deck: boolean
|
||||
created_at: string
|
||||
linked_accounts?: Array<{
|
||||
provider: string
|
||||
provider_user_id: string
|
||||
email: string | null
|
||||
linked_at: string
|
||||
}>
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current user's profile from the API.
|
||||
*/
|
||||
async function fetchProfile(): Promise<boolean> {
|
||||
const auth = useAuthStore()
|
||||
const token = await auth.getValidToken()
|
||||
|
||||
if (!token) {
|
||||
if (!auth.isAuthenticated) {
|
||||
error.value = 'Not authenticated'
|
||||
return false
|
||||
}
|
||||
@ -54,25 +69,16 @@ export const useUserStore = defineStore('user', () => {
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await fetch(`${config.apiBaseUrl}/api/users/me`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
},
|
||||
})
|
||||
const data = await apiClient.get<UserProfileResponse>('/api/users/me')
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch profile')
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
profile.value = {
|
||||
id: data.id,
|
||||
displayName: data.display_name,
|
||||
avatarUrl: data.avatar_url,
|
||||
hasStarterDeck: data.has_starter_deck,
|
||||
createdAt: data.created_at,
|
||||
linkedAccounts: data.linked_accounts?.map((acc: Record<string, unknown>) => ({
|
||||
provider: acc.provider,
|
||||
linkedAccounts: data.linked_accounts?.map((acc) => ({
|
||||
provider: acc.provider as 'google' | 'discord',
|
||||
providerUserId: acc.provider_user_id,
|
||||
email: acc.email,
|
||||
linkedAt: acc.linked_at,
|
||||
@ -89,7 +95,11 @@ export const useUserStore = defineStore('user', () => {
|
||||
|
||||
return true
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError) {
|
||||
error.value = e.detail || e.message
|
||||
} else {
|
||||
error.value = e instanceof Error ? e.message : 'Failed to fetch profile'
|
||||
}
|
||||
return false
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
@ -101,9 +111,8 @@ export const useUserStore = defineStore('user', () => {
|
||||
*/
|
||||
async function updateDisplayName(newName: string): Promise<boolean> {
|
||||
const auth = useAuthStore()
|
||||
const token = await auth.getValidToken()
|
||||
|
||||
if (!token) {
|
||||
if (!auth.isAuthenticated) {
|
||||
error.value = 'Not authenticated'
|
||||
return false
|
||||
}
|
||||
@ -112,24 +121,17 @@ export const useUserStore = defineStore('user', () => {
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const response = await fetch(`${config.apiBaseUrl}/api/users/me`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ display_name: newName }),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update profile')
|
||||
}
|
||||
await apiClient.patch('/api/users/me', { display_name: newName })
|
||||
|
||||
// Refetch to get updated data
|
||||
await fetchProfile()
|
||||
return true
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError) {
|
||||
error.value = e.detail || e.message
|
||||
} else {
|
||||
error.value = e instanceof Error ? e.message : 'Failed to update profile'
|
||||
}
|
||||
return false
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
|
||||
Loading…
Reference in New Issue
Block a user