Fortune-PlayLogic/lib/store/betting-store.ts
2026-03-02 19:09:22 +03:00

109 lines
2.9 KiB
TypeScript

"use client"
import { create } from "zustand"
import type { AppEvent, QuickFilterKey } from "./betting-types"
import {
fetchEvents,
fetchOddsForEvent,
apiEventToAppEvent,
getListMarketsFromOddsResponse,
getTimeRangeForQuickFilter,
type EventsParams,
} from "./betting-api"
const PAGE_SIZE = 12
type BettingState = {
events: AppEvent[]
page: number
total: number | null
loading: boolean
error: string | null
hasMore: boolean
sportId: number | null
leagueId: string | null
quickFilter: QuickFilterKey
setFilters: (sportId: number | null, leagueId: string | null) => void
setQuickFilter: (key: QuickFilterKey) => void
loadPage: (pageNum: number, append: boolean) => Promise<void>
loadMore: () => void
reset: () => void
}
const initialState = {
events: [],
page: 1,
total: null,
loading: true,
error: null as string | null,
hasMore: true,
sportId: null as number | null,
leagueId: null as string | null,
quickFilter: "all" as QuickFilterKey,
}
export const useBettingStore = create<BettingState>((set, get) => ({
...initialState,
setFilters: (sportId, leagueId) => {
const prev = get()
if (prev.sportId === sportId && prev.leagueId === leagueId) return
set({ sportId, leagueId, page: 1 })
get().loadPage(1, false)
},
setQuickFilter: (quickFilter) => {
set({ quickFilter, page: 1 })
get().loadPage(1, false)
},
loadPage: async (pageNum: number, append: boolean) => {
const { sportId, leagueId, quickFilter } = get()
const timeRange = getTimeRangeForQuickFilter(quickFilter)
set({ loading: true, error: null })
try {
const params: EventsParams = {
page: pageNum,
page_size: PAGE_SIZE,
sport_id: sportId ?? undefined,
league_id: leagueId ? Number(leagueId) : undefined,
...timeRange,
}
const res = await fetchEvents(params)
const apiEvents = res.data ?? []
const oddsResponses = await Promise.all(
apiEvents.map((e) => fetchOddsForEvent(e.id).catch(() => ({ data: [] as typeof res.data })))
)
const newEvents: AppEvent[] = apiEvents.map((e, i) => {
const oddsList = oddsResponses[i]?.data ?? []
const listMarkets = getListMarketsFromOddsResponse(oddsList)
const appEvent = apiEventToAppEvent(e, listMarkets) as AppEvent
appEvent.rawOdds = oddsList
return appEvent
})
set((s) => ({
events: append ? [...s.events, ...newEvents] : newEvents,
loading: false,
total: res.total ?? s.total,
hasMore: newEvents.length === PAGE_SIZE,
page: pageNum,
}))
} catch (err) {
set({
loading: false,
error: err instanceof Error ? err.message : "Failed to load events",
events: append ? get().events : [],
})
}
},
loadMore: () => {
const { page, loadPage } = get()
const next = page + 1
set({ page: next })
loadPage(next, true)
},
reset: () => set(initialState),
}))