import { defineStore } from 'pinia' import { ref } from 'vue' export interface Objective { objectiv_id: string display_string: string first_seen_at: string | null count: number max_count: number seed: string | null points_per_objectiv: number total_points: number } interface UserInfo { username: string rank: number | null score: number runsSubmitted: number deathsCount: number isStaff: boolean } interface LeaderboardEntry { rank: number username: string total_score: number objectives_count: number deaths_count: number is_staff: boolean } export const useNoitaStore = defineStore('noita', () => { // State const userInfo = ref({ username: 'Player', rank: null, score: 0, runsSubmitted: 0, deathsCount: 0, isStaff: false, }) const objectives = ref([]) const leaderboard = ref([]) const isLoadingLeaderboard = ref(false) const isUploading = ref(false) const error = ref('') // Actions const fetchUserResults = async () => { try { const response = await fetch('/api/noita/results') if (!response.ok) throw new Error('Failed to fetch results') const results = await response.json() userInfo.value.score = results.total_score userInfo.value.deathsCount = results.deaths_count userInfo.value.runsSubmitted = results.objectives.length objectives.value = results.objectives } catch (err) { error.value = 'Failed to fetch user results' console.error('Error fetching results:', err) } } const fetchLeaderboard = async () => { isLoadingLeaderboard.value = true try { const response = await fetch('/api/noita/leaderboard') if (!response.ok) throw new Error('Failed to fetch leaderboard') const data = await response.json() leaderboard.value = data.leaderboard // Find current user's rank const userRank = leaderboard.value.find( (entry) => entry.username === userInfo.value.username ) if (userRank) { userInfo.value.rank = userRank.rank userInfo.value.score = userRank.total_score userInfo.value.deathsCount = userRank.deaths_count } } catch (err) { error.value = 'Failed to fetch leaderboard' console.error('Error fetching leaderboard:', err) } finally { isLoadingLeaderboard.value = false } } const loadUserData = async () => { try { const response = await fetch('/api/user') if (response.ok) { const user = await response.json() if (user.is_authenticated) { userInfo.value.username = user.username userInfo.value.isStaff = user.is_staff || false } } } catch (err) { console.error('Error fetching user info:', err) } await Promise.all([fetchUserResults(), fetchLeaderboard()]) } const submitRun = async (files: File[]) => { if (files.length === 0) return isUploading.value = true try { for (const file of files) { const formData = new FormData() formData.append('file', file) const response = await fetch('/api/noita/submit', { method: 'POST', body: formData, }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.detail || 'Unknown error') } const result = await response.json() console.log('Submission successful:', result) } // Refresh objectives, score, and rank after successful submission await Promise.all([fetchUserResults(), fetchLeaderboard()]) } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Unknown error' error.value = `Error submitting run: ${errorMessage}` throw err } finally { isUploading.value = false } } const clearCache = async () => { try { const response = await fetch('/api/cache/clear', { method: 'POST', }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.detail || 'Unknown error') } await Promise.all([fetchUserResults(), fetchLeaderboard()]) } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Unknown error' error.value = `Error clearing cache: ${errorMessage}` throw err } } const refreshData = async () => { await Promise.all([fetchUserResults(), fetchLeaderboard()]) } return { // State userInfo, objectives, leaderboard, isLoadingLeaderboard, isUploading, error, // Actions fetchUserResults, fetchLeaderboard, loadUserData, submitRun, clearCache, refreshData, } })