@devrongx/games 0.4.16 → 0.4.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrongx/games",
3
- "version": "0.4.16",
3
+ "version": "0.4.18",
4
4
  "description": "Game UI components for sports prediction markets",
5
5
  "license": "MIT",
6
6
  "main": "./src/index.ts",
@@ -132,7 +132,7 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
132
132
  const mIdx = config.markets.findIndex((m) => m.backendChallengeId === bet.challenge_id);
133
133
  if (mIdx < 0) continue;
134
134
  const oIdx = config.markets[mIdx].options.findIndex(
135
- (o) => o.label.toLowerCase().replace(/\s+/g, "_") === bet.selected_option,
135
+ (o) => (o.key ?? o.label.toLowerCase().replace(/\s+/g, "_")) === bet.selected_option,
136
136
  );
137
137
  if (oIdx < 0) continue;
138
138
  loaded[mIdx] = { optionIdx: oIdx, amount: bet.coin_amount, parlaySlot: null };
@@ -158,7 +158,7 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
158
158
  const mIdx = config.markets.findIndex((m) => m.backendChallengeId === d.challenge_id);
159
159
  if (mIdx < 0) continue;
160
160
  const optionIdx = config.markets[mIdx].options.findIndex(
161
- (o) => o.label.toLowerCase().replace(/\s+/g, "_") === d.selected_option,
161
+ (o) => (o.key ?? o.label.toLowerCase().replace(/\s+/g, "_")) === d.selected_option,
162
162
  );
163
163
  if (optionIdx < 0) continue;
164
164
  restored[mIdx] = { optionIdx, amount: d.coin_amount, parlaySlot: null };
@@ -194,7 +194,7 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
194
194
  if (!option) return null;
195
195
  return {
196
196
  challenge_id: m.backendChallengeId,
197
- selected_option: option.label.toLowerCase().replace(/\s+/g, "_"),
197
+ selected_option: option.key ?? option.label.toLowerCase().replace(/\s+/g, "_"),
198
198
  coin_amount: b.amount,
199
199
  };
200
200
  })
@@ -272,7 +272,7 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
272
272
  const market = config.markets[Number(mIdxStr)];
273
273
  return {
274
274
  challenge_id: market.backendChallengeId!,
275
- selected_option: market.options[b.optionIdx].label.toLowerCase().replace(/\s+/g, "_"),
275
+ selected_option: market.options[b.optionIdx].key ?? market.options[b.optionIdx].label.toLowerCase().replace(/\s+/g, "_"),
276
276
  coin_amount: b.amount,
277
277
  };
278
278
  })
@@ -8,6 +8,7 @@ import seedrandom from "seedrandom";
8
8
  // ────── Types ──────
9
9
 
10
10
  export interface IChallengeOption {
11
+ key?: string; // Backend option key (authoritative for API calls) — absent on hardcoded demo data
11
12
  label: string;
12
13
  odds: number; // Decimal odds (e.g., 1.40 = 40% profit, 3.2 = 220% profit)
13
14
  entry: number; // Points to bet on this option
@@ -113,7 +113,7 @@ const GAME_TYPE_STYLE: Record<number, { icon: typeof Target; color: string; bg:
113
113
  };
114
114
 
115
115
  function PoolPill({ pool, onPress }: { pool: ITDPool; onPress: (pool: ITDPool) => void }) {
116
- const style = GAME_TYPE_STYLE[pool.game_type] ?? { icon: Target, color: "#22E3E8", bg: "rgba(34,227,232,0.06)" };
116
+ const style = GAME_TYPE_STYLE[pool.game_type] ?? { icon: Target, color: "#22E3E8", bg: "rgba(34,227,232,0.06)", label: "Play" };
117
117
  const isClosed = pool.status === TDPoolStatus.CLOSED || pool.status === TDPoolStatus.RESOLVING || pool.status === TDPoolStatus.COMPLETE;
118
118
  const isOpen = pool.status === TDPoolStatus.OPEN;
119
119
 
@@ -131,20 +131,20 @@ function PoolPill({ pool, onPress }: { pool: ITDPool; onPress: (pool: ITDPool) =
131
131
  boxShadow: isOpen ? `0 0 8px ${style.color}18` : undefined,
132
132
  }}
133
133
  >
134
- <span className="text-[10px] font-bold" style={{ ...OUTFIT, color: "#fff" }}>
135
- {pool.display_price}
136
- </span>
137
- {pool.entry_count > 0 && (
138
- <span className="text-[8px] font-medium" style={{ ...OUTFIT, color: "rgba(255,255,255,0.65)" }}>
139
- {pool.entry_count > 999 ? `${(pool.entry_count / 1000).toFixed(1)}k` : pool.entry_count}
140
- </span>
141
- )}
142
134
  {isOpen && (
143
135
  <span className="relative flex h-1.5 w-1.5 shrink-0">
144
136
  <span className="animate-ping absolute inline-flex h-full w-full rounded-full opacity-60" style={{ backgroundColor: style.color }} />
145
137
  <span className="relative inline-flex rounded-full h-1.5 w-1.5" style={{ backgroundColor: style.color }} />
146
138
  </span>
147
139
  )}
140
+ <span className="text-[10px] font-bold tracking-wide" style={{ ...OUTFIT, color: "#fff" }}>
141
+ PLAY
142
+ </span>
143
+ {pool.entry_count > 0 && (
144
+ <span className="text-[8px] font-medium" style={{ ...OUTFIT, color: `${style.color}99` }}>
145
+ {pool.entry_count > 999 ? `${(pool.entry_count / 1000).toFixed(1)}k` : pool.entry_count} in
146
+ </span>
147
+ )}
148
148
  </motion.button>
149
149
  );
150
150
  }
@@ -430,17 +430,6 @@ export function MatchCalendar({ tournamentId, onPoolPress, partnerSource }: Matc
430
430
  }
431
431
  }, [scrollTargetIndex, days]);
432
432
 
433
- // Stage groups
434
- const stageGroups = useMemo(() => {
435
- const stages = new Map<number, { name: string; orderNo: number }>();
436
- for (const m of matches) {
437
- if (m.stage && !stages.has(m.stage.id)) {
438
- stages.set(m.stage.id, { name: m.stage.name, orderNo: m.stage.order_no });
439
- }
440
- }
441
- return Array.from(stages.values()).sort((a, b) => a.orderNo - b.orderNo);
442
- }, [matches]);
443
-
444
433
  const tournament = matches[0]?.tournament;
445
434
 
446
435
  if (isLoading) {
@@ -471,20 +460,8 @@ export function MatchCalendar({ tournamentId, onPoolPress, partnerSource }: Matc
471
460
  </span>
472
461
  )}
473
462
  <span className="text-[11px] text-white" style={OUTFIT}>
474
- {matches.length} matches
463
+ {matches.length} matches announced
475
464
  </span>
476
- {stageGroups.length > 0 && (
477
- <span
478
- className="text-[9px] barlowcondensedBold tracking-widest px-2 py-0.5 rounded-full"
479
- style={{
480
- color: "#22E3E8",
481
- background: "rgba(34,227,232,0.08)",
482
- border: "1px solid rgba(34,227,232,0.15)",
483
- }}
484
- >
485
- {stageGroups[0].name.toUpperCase()}
486
- </span>
487
- )}
488
465
  </div>
489
466
  </div>
490
467
  )}
@@ -33,6 +33,7 @@ export function buildPMBConfig(pool: ITDPoolDetail, match: ITDMatch): IChallenge
33
33
  category: c.category,
34
34
  backendChallengeId: c.id,
35
35
  options: c.options.map((o) => ({
36
+ key: o.key,
36
37
  label: o.label,
37
38
  odds: o.odds,
38
39
  entry: o.entry,