@devrongx/games 0.4.26 → 0.4.27

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.26",
3
+ "version": "0.4.27",
4
4
  "description": "Game UI components for sports prediction markets",
5
5
  "license": "MIT",
6
6
  "main": "./src/index.ts",
@@ -462,6 +462,7 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
462
462
  editSubmitting={editSubmitting}
463
463
  savedBetSummary={savedBetSummary}
464
464
  hasUnsavedEdits={hasUnsavedEdits}
465
+ onGoToIntro={() => setUserFlowState("intro")}
465
466
  />
466
467
  )}
467
468
 
@@ -56,6 +56,7 @@ interface PreMatchGameProps {
56
56
  editSubmitting?: number | null;
57
57
  savedBetSummary?: IBetSummary | null;
58
58
  hasUnsavedEdits?: boolean;
59
+ onGoToIntro?: () => void;
59
60
  }
60
61
 
61
62
  // ─── Component ───────────────────────────────────────────────────────────────
@@ -66,7 +67,7 @@ export const PreMatchGame = ({
66
67
  parlayEnabled = false, submitting = false,
67
68
  ignoredMarkets: _ignoredMarkets, onToggleIgnore, editingMarkets: _editingMarkets,
68
69
  dirtyMarkets: _dirtyMarkets, onEditMarket, onConfirmMarketEdit, onCancelMarketEdit,
69
- editSubmitting, savedBetSummary, hasUnsavedEdits = false,
70
+ editSubmitting, savedBetSummary, hasUnsavedEdits = false, onGoToIntro,
70
71
  }: PreMatchGameProps) => {
71
72
  const ignoredMarkets = _ignoredMarkets ?? EMPTY_SET;
72
73
  const editingMarkets = _editingMarkets ?? EMPTY_SET;
@@ -77,11 +78,6 @@ export const PreMatchGame = ({
77
78
  // Whether bets have been submitted to the server at least once
78
79
  const hasSubmitted = !!submittedBets && Object.keys(submittedBets).length > 0;
79
80
 
80
- // Button state for initial submit flow (fresh = never submitted)
81
- const buttonState = useMemo<"fresh" | "submitted">(() => {
82
- return hasSubmitted ? "submitted" : "fresh";
83
- }, [hasSubmitted]);
84
-
85
81
  const goTo = useGamePopupStore(s => s.goTo);
86
82
 
87
83
  // ── Onboarding — visible whenever no points have been bet yet ─────────────
@@ -144,11 +140,6 @@ export const PreMatchGame = ({
144
140
  });
145
141
  }, []);
146
142
 
147
- const handleExpandAll = useCallback(() => setCollapsedMarkets(new Set()), []);
148
- const handleCollapseAll = useCallback(() => {
149
- setCollapsedMarkets(new Set(config.markets.map((_, i) => i)));
150
- }, [config.markets]);
151
-
152
143
  // ── Computed: filtered/sorted market indices ─────────────────────────────
153
144
  const sortActive = activeFilters.has("bets_first") || activeFilters.has("unanswered_first");
154
145
 
@@ -165,14 +156,30 @@ export const PreMatchGame = ({
165
156
  });
166
157
  } else if (activeFilters.has("unanswered_first")) {
167
158
  indices.sort((a, b) => {
168
- const aAns = bets[a] !== undefined ? 1 : 0;
169
- const bAns = bets[b] !== undefined ? 1 : 0;
170
- return aAns - bAns || a - b;
159
+ const aHasAmount = (bets[a]?.amount ?? 0) > 0 ? 1 : 0;
160
+ const bHasAmount = (bets[b]?.amount ?? 0) > 0 ? 1 : 0;
161
+ return aHasAmount - bHasAmount || a - b;
171
162
  });
172
163
  }
173
164
  return indices;
174
165
  }, [config.markets, activeFilters, ignoredMarkets, bets]);
175
166
 
167
+ const handleExpandAll = useCallback(() => {
168
+ setCollapsedMarkets(prev => {
169
+ const next = new Set(prev);
170
+ for (const i of visibleMarketIndices) next.delete(i);
171
+ return next;
172
+ });
173
+ }, [visibleMarketIndices]);
174
+
175
+ const handleCollapseAll = useCallback(() => {
176
+ setCollapsedMarkets(prev => {
177
+ const next = new Set(prev);
178
+ for (const i of visibleMarketIndices) next.add(i);
179
+ return next;
180
+ });
181
+ }, [visibleMarketIndices]);
182
+
176
183
  // Category headers — only shown when no sort is active
177
184
  const categoryForIndex = useMemo(() => {
178
185
  const map = new Map<number, string>();
@@ -245,7 +252,7 @@ export const PreMatchGame = ({
245
252
  {/* How to Play + Filter pills */}
246
253
  <div className="pt-2 flex items-center gap-2 overflow-x-auto scrollbar-hide">
247
254
  <button
248
- onClick={() => goTo("intro")}
255
+ onClick={() => { onGoToIntro ? onGoToIntro() : goTo("intro"); }}
249
256
  className="flex-shrink-0 flex items-center gap-1.5 px-3 py-1.5 rounded-full border border-[#22E3E8]/20 bg-[#22E3E8]/[0.06]"
250
257
  >
251
258
  <Play size={10} fill="#22E3E8" strokeWidth={0} className="text-[#22E3E8]" />
@@ -631,9 +638,9 @@ export const PreMatchGame = ({
631
638
  </AnimatePresence>
632
639
  </div>
633
640
 
634
- {/* Right — action button */}
641
+ {/* Right — play button (fresh only) */}
635
642
  <AnimatePresence>
636
- {buttonState === "fresh" && totalEntry > 0 && (
643
+ {!hasSubmitted && totalEntry > 0 && (
637
644
  <motion.button
638
645
  onClick={onSubmit ? onSubmit : undefined}
639
646
  disabled={submitting}
@@ -652,16 +659,6 @@ export const PreMatchGame = ({
652
659
  : <Play size={26} fill="white" strokeWidth={0} className="relative z-10" />}
653
660
  </motion.button>
654
661
  )}
655
- {buttonState === "submitted" && (
656
- <motion.div
657
- className="w-[54px] min-h-[54px] rounded-xl flex-shrink-0 flex items-center justify-center"
658
- style={{ background: "rgba(74,222,128,0.10)" }}
659
- initial={{ opacity: 0, scale: 0.8 }}
660
- animate={{ opacity: 1, scale: 1 }}
661
- transition={{ type: "spring", stiffness: 300, damping: 20 }}>
662
- <Check size={22} strokeWidth={2.5} className="text-white" />
663
- </motion.div>
664
- )}
665
662
  </AnimatePresence>
666
663
  </div>
667
664