) : activeCategory === "all" ? (
// Show all categories
{groupedGames.map((category, index) => (
-
))}
@@ -180,16 +202,16 @@ export default function VirtualPage() {
- {activeCategoryData?.provider_name || 'Games'}
+ {activeCategoryData?.provider_name || "Games"}
-
-
+
{displayedGames.map((game, idx) => (
@@ -200,5 +222,5 @@ export default function VirtualPage() {
- )
+ );
}
diff --git a/lib/store/betting-types.ts b/lib/store/betting-types.ts
new file mode 100644
index 0000000..2a63172
--- /dev/null
+++ b/lib/store/betting-types.ts
@@ -0,0 +1,191 @@
+/**
+ * Betting API and app types. Used by betting-store and betting-api.
+ */
+
+/** Sport IDs for API (sport_id). Use for live and prematch. */
+export const SportEnum = {
+ SOCCER: 1,
+ BASKETBALL: 18,
+ TENNIS: 13,
+ VOLLEYBALL: 91,
+ HANDBALL: 78,
+ BASEBALL: 16,
+ HORSE_RACING: 2,
+ GREYHOUNDS: 4,
+ ICE_HOCKEY: 17,
+ SNOOKER: 14,
+ AMERICAN_FOOTBALL: 12,
+ CRICKET: 3,
+ FUTSAL: 83,
+ DARTS: 15,
+ TABLE_TENNIS: 92,
+ BADMINTON: 94,
+ RUGBY_UNION: 8,
+ RUGBY_LEAGUE: 19,
+ AUSTRALIAN_RULES: 36,
+ BOWLS: 66,
+ BOXING: 9,
+ GAELIC_SPORTS: 75,
+ FLOORBALL: 90,
+ BEACH_VOLLEYBALL: 95,
+ WATER_POLO: 110,
+ SQUASH: 107,
+ E_SPORTS: 151,
+ MMA: 162,
+ SURFING: 148,
+} as const
+
+export type SportId = (typeof SportEnum)[keyof typeof SportEnum]
+
+export type ApiEvent = {
+ id: number
+ source_event_id: string
+ sport_id: number
+ match_name: string
+ home_team: string
+ away_team: string
+ home_team_id: number
+ away_team_id: number
+ home_team_image: string
+ away_team_image: string
+ league_id: number
+ league_name: string
+ league_cc: string
+ start_time: string
+ source: string
+ status: string
+ is_live: boolean
+ is_featured?: boolean
+ is_active?: boolean
+ total_odd_outcomes?: number
+ number_of_bets?: number
+ total_amount?: number
+ average_bet_amount?: number
+ total_potential_winnings?: number
+ score?: string
+ match_minute?: number
+ timer_status?: string
+ added_time?: number
+ match_period?: number
+ fetched_at?: string
+ updated_at?: string
+}
+
+export type ApiLeague = {
+ id: number
+ name: string
+ cc: string
+ bet365_id?: number
+ sport_id: number
+ default_is_active: boolean
+ default_is_featured: boolean
+}
+
+export type ApiOddsOutcome = {
+ id: string
+ name?: string
+ odds: string
+ header?: string
+ handicap?: string
+}
+
+export type ApiOdds = {
+ id: number
+ event_id: number
+ market_type: string
+ market_name: string
+ market_category: string
+ market_id: number
+ number_of_outcomes: number
+ raw_odds: ApiOddsOutcome[]
+ fetched_at: string
+ expires_at: string
+ is_active: boolean
+}
+
+export type ApiTopLeaguesResponse = {
+ leagues: Array<{
+ league_id: number
+ league_name: string
+ league_cc: string
+ league_sport_id: number
+ events: ApiEvent[]
+ }>
+}
+
+export type EventsParams = {
+ page?: number
+ page_size?: number
+ sport_id?: number
+ league_id?: number
+ /** RFC3339 datetime; filter events with start_time >= this */
+ first_start_time?: string
+ /** RFC3339 datetime; filter events with start_time <= this (e.g. for 3h/6h/12h windows) */
+ last_start_time?: string
+ /** When true, return only in-play/live events */
+ is_live?: boolean
+}
+
+/** Quick filter key for time-based event filtering */
+export type QuickFilterKey = "all" | "today" | "3h" | "6h" | "9h" | "12h"
+
+export type EventsResponse = {
+ data: ApiEvent[]
+ total?: number
+ page?: number
+ total_pages?: number
+ message?: string
+ status?: string
+}
+
+export type LeaguesResponse = {
+ data: ApiLeague[]
+ message?: string
+ status?: string
+}
+
+export type OddsResponse = {
+ data: ApiOdds[]
+ message?: string
+ status?: string
+}
+
+export type DetailMarketSectionFromApi = {
+ id: string
+ title: string
+ outcomes: { label: string; odds: number }[]
+}
+
+export type MarketTabKey =
+ | "main"
+ | "goals"
+ | "handicap"
+ | "half_time"
+ | "correct_score"
+ | "1st_half"
+ | "2nd_half"
+ | "combo"
+ | "chance_mix"
+ | "home"
+
+export type TabColumnCell = { id: string; label: string; odds: number }
+
+export type AppEvent = {
+ id: string
+ sport: string
+ sportIcon: string
+ league: string
+ country: string
+ homeTeam: string
+ awayTeam: string
+ time: string
+ date: string
+ isLive: boolean
+ markets: { id: string; label: string; odds: number }[]
+ totalMarkets: number
+ rawOdds?: ApiOdds[]
+ /** Live: e.g. "2 - 1" */
+ score?: string
+ /** Live: match minute */
+ matchMinute?: number
+}