@agg-build/ui 2.1.1 → 2.1.2

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.
Files changed (40) hide show
  1. package/dist/{chunk-TERG43WW.mjs → chunk-5RBHMMY3.mjs} +1 -1
  2. package/dist/{chunk-RPXRTXCY.mjs → chunk-75AMJAWR.mjs} +1 -1
  3. package/dist/{chunk-IQT4I5B4.mjs → chunk-7ZR5JYB3.mjs} +39 -241
  4. package/dist/{chunk-NK57KMYN.mjs → chunk-JJDYOBVG.mjs} +117 -48
  5. package/dist/{chunk-WU2C3C6K.mjs → chunk-NRNBJPYK.mjs} +1 -1
  6. package/dist/{chunk-YJO6LMRT.mjs → chunk-TBD3N4T4.mjs} +69 -7
  7. package/dist/{chunk-XHDGSRG7.mjs → chunk-ZOECARZW.mjs} +359 -14
  8. package/dist/events.js +175 -59
  9. package/dist/events.mjs +3 -3
  10. package/dist/index.js +1080 -820
  11. package/dist/index.mjs +12 -8
  12. package/dist/modals.js +1 -1
  13. package/dist/modals.mjs +3 -3
  14. package/dist/pages.js +845 -589
  15. package/dist/pages.mjs +6 -6
  16. package/dist/primitives.js +68 -7
  17. package/dist/primitives.mjs +1 -1
  18. package/dist/styles.css +1 -1
  19. package/dist/tailwind.css +1 -1
  20. package/dist/trading.js +679 -339
  21. package/dist/trading.mjs +10 -6
  22. package/dist/types/events/shared/format-event-title.d.mts +25 -0
  23. package/dist/types/events/shared/format-event-title.d.ts +25 -0
  24. package/dist/types/events/shared/select-best-outcome.d.mts +88 -0
  25. package/dist/types/events/shared/select-best-outcome.d.ts +88 -0
  26. package/dist/types/pages/event-market/event-market.types.d.mts +7 -0
  27. package/dist/types/pages/event-market/event-market.types.d.ts +7 -0
  28. package/dist/types/primitives/search/search.utils.d.mts +3 -1
  29. package/dist/types/primitives/search/search.utils.d.ts +3 -1
  30. package/dist/types/trading/index.d.mts +2 -0
  31. package/dist/types/trading/index.d.ts +2 -0
  32. package/dist/types/trading/place-order/index.d.mts +1 -1
  33. package/dist/types/trading/place-order/index.d.ts +1 -1
  34. package/dist/types/trading/place-order/index.place-order.types.d.mts +23 -1
  35. package/dist/types/trading/place-order/index.place-order.types.d.ts +23 -1
  36. package/dist/types/trading/use-claim-winnings.d.mts +84 -0
  37. package/dist/types/trading/use-claim-winnings.d.ts +84 -0
  38. package/dist/types/trading/use-resolved-market-claim.d.mts +26 -0
  39. package/dist/types/trading/use-resolved-market-claim.d.ts +26 -0
  40. package/package.json +3 -3
package/dist/pages.js CHANGED
@@ -98,9 +98,9 @@ __export(pages_exports, {
98
98
  module.exports = __toCommonJS(pages_exports);
99
99
 
100
100
  // src/pages/home/index.tsx
101
- var import_hooks54 = require("@agg-build/hooks");
101
+ var import_hooks56 = require("@agg-build/hooks");
102
102
  var import_sdk18 = require("@agg-build/sdk");
103
- var import_react34 = require("react");
103
+ var import_react36 = require("react");
104
104
 
105
105
  // src/events/item/index.tsx
106
106
  var import_hooks35 = require("@agg-build/hooks");
@@ -6039,7 +6039,57 @@ var SEARCH_DEBOUNCE_MS = 300;
6039
6039
 
6040
6040
  // src/primitives/search/search.utils.ts
6041
6041
  var import_sdk11 = require("@agg-build/sdk");
6042
+ var import_dayjs3 = __toESM(require("dayjs"));
6043
+
6044
+ // src/events/shared/format-event-title.ts
6042
6045
  var import_dayjs2 = __toESM(require("dayjs"));
6046
+ var SPORT_CATEGORY_TOKENS = /* @__PURE__ */ new Set(["sport", "sports"]);
6047
+ var normalizeCategoryToken = (value) => {
6048
+ if (typeof value !== "string") return null;
6049
+ const normalizedValue = value.trim().toLowerCase();
6050
+ if (!normalizedValue) return null;
6051
+ return normalizedValue;
6052
+ };
6053
+ var isSportCategoryToken = (value) => {
6054
+ const normalizedValue = normalizeCategoryToken(value);
6055
+ if (!normalizedValue) return false;
6056
+ return SPORT_CATEGORY_TOKENS.has(normalizedValue);
6057
+ };
6058
+ var isSportEvent = (categories, structureType) => {
6059
+ var _a;
6060
+ if (isSportCategoryToken(structureType)) return true;
6061
+ return (_a = categories == null ? void 0 : categories.some((categoryEntry) => {
6062
+ var _a2, _b, _c, _d;
6063
+ return isSportCategoryToken(categoryEntry.id) || isSportCategoryToken((_a2 = categoryEntry.category) == null ? void 0 : _a2.id) || isSportCategoryToken((_b = categoryEntry.category) == null ? void 0 : _b.name) || isSportCategoryToken((_c = categoryEntry.category) == null ? void 0 : _c.displayName) || isSportCategoryToken((_d = categoryEntry.category) == null ? void 0 : _d.parentId);
6064
+ })) != null ? _a : false;
6065
+ };
6066
+ var formatEventDateSuffix = (value, locale) => {
6067
+ if (!(0, import_dayjs2.default)(value).isValid()) return null;
6068
+ return new Intl.DateTimeFormat(locale, {
6069
+ month: "long",
6070
+ day: "numeric",
6071
+ timeZone: "UTC"
6072
+ }).format(new Date(value));
6073
+ };
6074
+ var formatEventTitleWithDateSuffix = ({
6075
+ title: title2,
6076
+ categories,
6077
+ structureType,
6078
+ gameStartTime,
6079
+ endDate,
6080
+ locale = "en-US"
6081
+ }) => {
6082
+ const resolvedTitle = title2.trim();
6083
+ if (!resolvedTitle) return resolvedTitle;
6084
+ if (!isSportEvent(categories, structureType)) return resolvedTitle;
6085
+ const dateSource = gameStartTime != null ? gameStartTime : endDate;
6086
+ if (!dateSource) return resolvedTitle;
6087
+ const formattedDate = formatEventDateSuffix(dateSource, locale);
6088
+ if (!formattedDate) return resolvedTitle;
6089
+ const suffix = ` - ${formattedDate}`;
6090
+ if (resolvedTitle.endsWith(suffix)) return resolvedTitle;
6091
+ return `${resolvedTitle}${suffix}`;
6092
+ };
6043
6093
 
6044
6094
  // src/events/item/event-list-item.utils.ts
6045
6095
  var import_hooks26 = require("@agg-build/hooks");
@@ -6352,8 +6402,8 @@ var resolveDisplayVolume = (eventVolume, venueMarkets) => {
6352
6402
 
6353
6403
  // src/primitives/search/search.utils.ts
6354
6404
  var formatSearchContextLabel = (value) => {
6355
- if (!(0, import_dayjs2.default)(value).isValid()) return value;
6356
- return (0, import_dayjs2.default)(value).format("MMMM D, YYYY");
6405
+ if (!(0, import_dayjs3.default)(value).isValid()) return value;
6406
+ return (0, import_dayjs3.default)(value).format("MMMM D, YYYY");
6357
6407
  };
6358
6408
  var venueLogoNameSet = new Set(import_sdk11.VENUES);
6359
6409
  var toVenueLogoName = (value) => {
@@ -6361,7 +6411,7 @@ var toVenueLogoName = (value) => {
6361
6411
  if (!venueLogoNameSet.has(value)) return null;
6362
6412
  return value;
6363
6413
  };
6364
- var mapVenueEventToSearchResult = (event, labels, formatPercent, formatCompactCurrency) => {
6414
+ var mapVenueEventToSearchResult = (event, labels, formatPercent, formatCompactCurrency, options) => {
6365
6415
  var _a, _b;
6366
6416
  const primaryVenueMarket = selectPrimaryVenueMarket(event.venueMarkets);
6367
6417
  if (!primaryVenueMarket) return null;
@@ -6371,7 +6421,14 @@ var mapVenueEventToSearchResult = (event, labels, formatPercent, formatCompactCu
6371
6421
  if (!visibleOutcome) return null;
6372
6422
  const probability = normalizeProbability(visibleOutcome.outcome.price);
6373
6423
  if (probability == null) return null;
6374
- const resolvedTitle = (_a = event == null ? void 0 : event.title) == null ? void 0 : _a.trim();
6424
+ const resolvedTitle = formatEventTitleWithDateSuffix({
6425
+ title: (_a = event == null ? void 0 : event.title) != null ? _a : "",
6426
+ categories: event.categories,
6427
+ structureType: event.structureType,
6428
+ gameStartTime: event.gameStartTime,
6429
+ endDate: event.endDate,
6430
+ locale: options == null ? void 0 : options.locale
6431
+ });
6375
6432
  if (!resolvedTitle) return null;
6376
6433
  const { marketCount, venueCount } = getVenueSummary(event.venueMarkets);
6377
6434
  const marketSummaryLabel = [
@@ -6584,6 +6641,7 @@ var Search = ({
6584
6641
  const {
6585
6642
  search: searchConfig,
6586
6643
  features: { enableAnimations },
6644
+ general: { locale },
6587
6645
  formatting: { formatCompactCurrency, formatPercent }
6588
6646
  } = (0, import_hooks27.useSdkUiConfig)();
6589
6647
  const resolvedValue = searchConfig.value;
@@ -6624,7 +6682,10 @@ var Search = ({
6624
6682
  event,
6625
6683
  labels,
6626
6684
  formatPercent,
6627
- formatCompactCurrency
6685
+ formatCompactCurrency,
6686
+ {
6687
+ locale
6688
+ }
6628
6689
  );
6629
6690
  if (!item) return null;
6630
6691
  nextEventsByResultId.set(item.id, event);
@@ -6634,7 +6695,7 @@ var Search = ({
6634
6695
  validatedResults: nextResults,
6635
6696
  eventsByResultId: nextEventsByResultId
6636
6697
  };
6637
- }, [openEvents, formatCompactCurrency, formatPercent, labels]);
6698
+ }, [formatCompactCurrency, formatPercent, labels, locale, openEvents]);
6638
6699
  const hasSearchValue = trimmedValue.length > 0;
6639
6700
  const shouldRenderDropdown = isFocused && shouldSearchValue && !searchConfig.result && !searchConfig.isShowingAllResults;
6640
6701
  const resolvedIsActive = isFocused;
@@ -7689,7 +7750,7 @@ var Select = ({
7689
7750
  disabled: item.disabled,
7690
7751
  className: cn(
7691
7752
  "agg-select-item",
7692
- "relative flex w-full items-center gap-3 rounded-[6px] px-5 py-3 text-left text-agg-sm leading-agg-5 outline-none",
7753
+ "relative flex w-full items-center gap-3 rounded-[6px] pl-3 pr-5 py-3 text-left text-agg-sm leading-agg-5 outline-none",
7693
7754
  "hover:bg-agg-secondary-hover focus-visible:bg-agg-secondary-hover",
7694
7755
  isSelected ? "bg-agg-primary/10 font-agg-normal text-agg-primary" : "font-agg-normal text-agg-foreground",
7695
7756
  item.disabled && "cursor-not-allowed opacity-60",
@@ -8922,7 +8983,14 @@ var EventListItemContent = ({
8922
8983
  const config = (0, import_hooks35.useSdkUiConfig)();
8923
8984
  const labels = (0, import_hooks35.useLabels)();
8924
8985
  const allVenueMarkets = (0, import_react14.useMemo)(() => event.venueMarkets, [event.venueMarkets]);
8925
- const resolvedTitle = event.title;
8986
+ const resolvedTitle = formatEventTitleWithDateSuffix({
8987
+ title: event.title,
8988
+ categories: event.categories,
8989
+ structureType: event.structureType,
8990
+ gameStartTime: event.gameStartTime,
8991
+ endDate: event.endDate,
8992
+ locale: config.general.locale
8993
+ });
8926
8994
  const resolvedImage = event.image;
8927
8995
  const visibleVenueLogos = (0, import_react14.useMemo)(() => {
8928
8996
  var _a2;
@@ -10252,9 +10320,9 @@ var EventList = ({
10252
10320
  EventList.displayName = "EventList";
10253
10321
 
10254
10322
  // src/pages/event-market/index.tsx
10255
- var import_hooks53 = require("@agg-build/hooks");
10323
+ var import_hooks55 = require("@agg-build/hooks");
10256
10324
  var Dialog4 = __toESM(require("@radix-ui/react-dialog"));
10257
- var import_react31 = require("react");
10325
+ var import_react33 = require("react");
10258
10326
 
10259
10327
  // src/events/item-details/index.tsx
10260
10328
  var import_hooks46 = require("@agg-build/hooks");
@@ -10373,10 +10441,10 @@ var import_hooks39 = require("@agg-build/hooks");
10373
10441
 
10374
10442
  // src/events/market-details/market-details.utils.ts
10375
10443
  var import_sdk15 = require("@agg-build/sdk");
10376
- var import_dayjs4 = __toESM(require("dayjs"));
10444
+ var import_dayjs5 = __toESM(require("dayjs"));
10377
10445
 
10378
10446
  // src/events/item-details/event-list-item-details.utils.ts
10379
- var import_dayjs3 = __toESM(require("dayjs"));
10447
+ var import_dayjs4 = __toESM(require("dayjs"));
10380
10448
  var compareOutcomeSelectorLabels = (leftLabel, rightLabel) => {
10381
10449
  const leftSemanticLabel = toSemanticLabel(leftLabel);
10382
10450
  const rightSemanticLabel = toSemanticLabel(rightLabel);
@@ -10389,8 +10457,8 @@ var compareOutcomeSelectorLabels = (leftLabel, rightLabel) => {
10389
10457
  if (leftBinaryOrder != null && rightBinaryOrder != null) {
10390
10458
  return leftBinaryOrder - rightBinaryOrder;
10391
10459
  }
10392
- const leftDate = isDateLikeLabel(leftLabel) ? (0, import_dayjs3.default)(leftLabel).valueOf() : null;
10393
- const rightDate = isDateLikeLabel(rightLabel) ? (0, import_dayjs3.default)(rightLabel).valueOf() : null;
10460
+ const leftDate = isDateLikeLabel(leftLabel) ? (0, import_dayjs4.default)(leftLabel).valueOf() : null;
10461
+ const rightDate = isDateLikeLabel(rightLabel) ? (0, import_dayjs4.default)(rightLabel).valueOf() : null;
10394
10462
  if (leftDate != null && rightDate != null && leftDate !== rightDate) {
10395
10463
  return leftDate - rightDate;
10396
10464
  }
@@ -10431,7 +10499,7 @@ var toSemanticLabel = (value) => {
10431
10499
  };
10432
10500
  var isDateLikeLabel = (value) => {
10433
10501
  if (!value.trim()) return false;
10434
- return (0, import_dayjs3.default)(value).isValid();
10502
+ return (0, import_dayjs4.default)(value).isValid();
10435
10503
  };
10436
10504
  var matchOutcomeByLabel = (outcome, selectedOutcomeLabel) => {
10437
10505
  const normalizedSelectedLabel = normalizeLabel(selectedOutcomeLabel);
@@ -10896,19 +10964,19 @@ var resolveOtherTabRows = (market, labels) => {
10896
10964
  if (market.creationDate) {
10897
10965
  rows.push({
10898
10966
  label: labels.marketDetails.meta.created,
10899
- value: (0, import_dayjs4.default)(market.creationDate).format("MMM D, YYYY")
10967
+ value: (0, import_dayjs5.default)(market.creationDate).format("MMM D, YYYY")
10900
10968
  });
10901
10969
  }
10902
10970
  if (market.startDate) {
10903
10971
  rows.push({
10904
10972
  label: labels.marketDetails.meta.opens,
10905
- value: (0, import_dayjs4.default)(market.startDate).format("MMM D, YYYY")
10973
+ value: (0, import_dayjs5.default)(market.startDate).format("MMM D, YYYY")
10906
10974
  });
10907
10975
  }
10908
10976
  if (market.endDate) {
10909
10977
  rows.push({
10910
10978
  label: labels.marketDetails.meta.closes,
10911
- value: (0, import_dayjs4.default)(market.endDate).format("MMM D, YYYY")
10979
+ value: (0, import_dayjs5.default)(market.endDate).format("MMM D, YYYY")
10912
10980
  });
10913
10981
  }
10914
10982
  if (rows.length === 1) {
@@ -11982,12 +12050,12 @@ var import_react21 = require("react");
11982
12050
 
11983
12051
  // src/trading/utils.ts
11984
12052
  var import_hooks43 = require("@agg-build/hooks");
11985
- var import_dayjs5 = __toESM(require("dayjs"));
12053
+ var import_dayjs6 = __toESM(require("dayjs"));
11986
12054
  var defaultLabels = (0, import_hooks43.resolveAggUiLabels)("en-US");
11987
12055
  var defaultSettlementSectionLabel = defaultLabels.trading.settlementSection;
11988
12056
  var defaultTradingDisclaimer = defaultLabels.trading.disclaimer;
11989
12057
  var getTradingDateLabel = (value) => {
11990
- const parsedValue = (0, import_dayjs5.default)(value);
12058
+ const parsedValue = (0, import_dayjs6.default)(value);
11991
12059
  if (!parsedValue.isValid()) {
11992
12060
  return typeof value === "string" ? value : "";
11993
12061
  }
@@ -12861,11 +12929,28 @@ var EventListItemDetailsContent = ({
12861
12929
  if (typeof resolvedVolume !== "number") return "";
12862
12930
  return `${config.formatting.formatCompactCurrency(resolvedVolume)} ${labels.eventItemDetails.volumeSuffix}`;
12863
12931
  }, [config, event.volume, labels.eventItemDetails.volumeSuffix, venueMarkets]);
12932
+ const resolvedTitle = (0, import_react23.useMemo)(() => {
12933
+ return formatEventTitleWithDateSuffix({
12934
+ title: event.title,
12935
+ categories: event.categories,
12936
+ structureType: event.structureType,
12937
+ gameStartTime: event.gameStartTime,
12938
+ endDate: event.endDate,
12939
+ locale: config.general.locale
12940
+ });
12941
+ }, [
12942
+ config.general.locale,
12943
+ event.categories,
12944
+ event.gameStartTime,
12945
+ event.endDate,
12946
+ event.structureType,
12947
+ event.title
12948
+ ]);
12864
12949
  return /* @__PURE__ */ (0, import_jsx_runtime136.jsxs)(
12865
12950
  Card,
12866
12951
  {
12867
12952
  className: cn("group/agg-event-details", detailsBaseCardClassName, classNames == null ? void 0 : classNames.root),
12868
- "aria-label": ariaLabel != null ? ariaLabel : event.title,
12953
+ "aria-label": ariaLabel != null ? ariaLabel : resolvedTitle,
12869
12954
  onClick: () => {
12870
12955
  onClick == null ? void 0 : onClick(event);
12871
12956
  },
@@ -12900,7 +12985,7 @@ var EventListItemDetailsContent = ({
12900
12985
  "truncate text-wrap wrap-break-word line-clamp-2",
12901
12986
  classNames == null ? void 0 : classNames.title
12902
12987
  ),
12903
- children: event.title
12988
+ children: resolvedTitle
12904
12989
  }
12905
12990
  ),
12906
12991
  venueMarkets.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(
@@ -13598,37 +13683,71 @@ var Orderbook = ({
13598
13683
  };
13599
13684
  Orderbook.displayName = "Orderbook";
13600
13685
 
13601
- // src/events/shared/display-outcome-venue.ts
13686
+ // src/events/shared/select-best-outcome.ts
13602
13687
  var normalizeOutcomeLabel3 = (label2) => {
13603
13688
  return typeof label2 === "string" ? label2.trim().toLowerCase() : "";
13604
13689
  };
13605
- var getDisplayOutcomeVenue = ({
13606
- outcomeId,
13607
- outcomeLabel,
13608
- selection,
13609
- bestMidpointVenue,
13610
- bestVenueByOutcomeId,
13611
- bestPriceVenuesByOutcomeId,
13612
- fallbackVenue
13613
- }) => {
13614
- var _a;
13615
- if (selection && outcomeId) {
13616
- const sideVenues = bestPriceVenuesByOutcomeId == null ? void 0 : bestPriceVenuesByOutcomeId.get(outcomeId);
13617
- if (selection === "buy" && (sideVenues == null ? void 0 : sideVenues.bestAskVenue)) return sideVenues.bestAskVenue;
13618
- if (selection === "sell" && (sideVenues == null ? void 0 : sideVenues.bestBidVenue)) return sideVenues.bestBidVenue;
13690
+ var selectBestOutcomeCandidate = (args) => {
13691
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
13692
+ const { outcomeId, selection } = args;
13693
+ if (!outcomeId) return void 0;
13694
+ const resolveVenueMarketId = (venue) => {
13695
+ var _a2, _b2;
13696
+ return venue ? (_b2 = (_a2 = args.venueMarketIdByVenue) == null ? void 0 : _a2.get(venue)) != null ? _b2 : void 0 : void 0;
13697
+ };
13698
+ const make = (price, venue, source, updatedAt) => ({
13699
+ price,
13700
+ venue: venue != null ? venue : void 0,
13701
+ venueMarketId: resolveVenueMarketId(venue != null ? venue : void 0),
13702
+ outcomeId,
13703
+ source,
13704
+ updatedAt: updatedAt != null ? updatedAt : void 0
13705
+ });
13706
+ if (selection === "buy" || selection === "sell") {
13707
+ const wsSidePrice = selection === "buy" ? (_a = args.live) == null ? void 0 : _a.bestAsk : (_b = args.live) == null ? void 0 : _b.bestBid;
13708
+ const wsSideVenue = selection === "buy" ? (_c = args.live) == null ? void 0 : _c.bestAskVenue : (_d = args.live) == null ? void 0 : _d.bestBidVenue;
13709
+ if (wsSidePrice != null) {
13710
+ return make(wsSidePrice, wsSideVenue, "ws", (_e = args.live) == null ? void 0 : _e.updatedAt);
13711
+ }
13712
+ const restSidePrice = selection === "buy" ? (_f = args.restBest) == null ? void 0 : _f.bestAsk : (_g = args.restBest) == null ? void 0 : _g.bestBid;
13713
+ const restSideVenue = selection === "buy" ? (_h = args.restBestVenues) == null ? void 0 : _h.bestAskVenue : (_i = args.restBestVenues) == null ? void 0 : _i.bestBidVenue;
13714
+ if (restSidePrice != null) {
13715
+ return make(restSidePrice, restSideVenue, "rest-best", void 0);
13716
+ }
13619
13717
  }
13620
- if (normalizeOutcomeLabel3(outcomeLabel) === "yes" && bestMidpointVenue) {
13621
- return bestMidpointVenue;
13718
+ if (((_j = args.live) == null ? void 0 : _j.midpoint) != null) {
13719
+ return make(args.live.midpoint, args.live.midpointVenue, "ws", args.live.updatedAt);
13622
13720
  }
13623
- const bestVenue = outcomeId ? bestVenueByOutcomeId == null ? void 0 : bestVenueByOutcomeId.get(outcomeId) : void 0;
13624
- return (_a = bestVenue != null ? bestVenue : fallbackVenue) != null ? _a : void 0;
13721
+ if (normalizeOutcomeLabel3(args.outcomeLabel) === "yes" && args.bestMidpoint != null && args.bestMidpointVenue) {
13722
+ return make(args.bestMidpoint, args.bestMidpointVenue, "rest-midpoint", void 0);
13723
+ }
13724
+ if (args.restMidpoint != null) {
13725
+ return make(args.restMidpoint, args.restMidpointVenue, "rest-midpoint", void 0);
13726
+ }
13727
+ if (args.staticPrice != null) {
13728
+ return make(args.staticPrice, args.staticVenue, "static", void 0);
13729
+ }
13730
+ return void 0;
13731
+ };
13732
+ var buildVenueMarketIdByVenue = (venueMarkets) => {
13733
+ var _a;
13734
+ const map = /* @__PURE__ */ new Map();
13735
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return map;
13736
+ const visit = (vm) => {
13737
+ if (vm.venue && vm.id && !map.has(vm.venue)) map.set(vm.venue, vm.id);
13738
+ };
13739
+ for (const vm of venueMarkets) {
13740
+ visit(vm);
13741
+ for (const sibling of (_a = vm.matchedVenueMarkets) != null ? _a : []) visit(sibling);
13742
+ }
13743
+ return map;
13625
13744
  };
13626
13745
 
13627
13746
  // src/events/shared/event-trading-state.utils.ts
13628
- var import_dayjs6 = __toESM(require("dayjs"));
13747
+ var import_dayjs7 = __toESM(require("dayjs"));
13629
13748
  var formatTradingStateDate = (value) => {
13630
- if (!(0, import_dayjs6.default)(value).isValid()) return value;
13631
- return (0, import_dayjs6.default)(value).format("MMM D, YYYY");
13749
+ if (!(0, import_dayjs7.default)(value).isValid()) return value;
13750
+ return (0, import_dayjs7.default)(value).format("MMM D, YYYY");
13632
13751
  };
13633
13752
  var resolveTradingStateTimestampLabel = (labels, state) => {
13634
13753
  if (state.kind === "resolved" && state.resolvesAt) {
@@ -13883,7 +14002,7 @@ var MarketDetailsContent = ({
13883
14002
  suppressOutcomeFallbackSelection,
13884
14003
  midpointsResult
13885
14004
  }) => {
13886
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
14005
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
13887
14006
  const config = (0, import_hooks48.useSdkUiConfig)();
13888
14007
  const {
13889
14008
  features: { enableAnimations },
@@ -13897,6 +14016,7 @@ var MarketDetailsContent = ({
13897
14016
  const tradeSide = (_a = tradingContext == null ? void 0 : tradingContext.tradeSide) != null ? _a : "buy";
13898
14017
  const wsLivePrices = (0, import_hooks48.useLiveOutcomePrices)(venueMarkets);
13899
14018
  const wsBestPrices = (0, import_hooks48.useLiveBestPrices)(venueMarkets);
14019
+ const wsBestCandidates = (0, import_hooks48.useLiveBestPriceCandidates)(venueMarkets);
13900
14020
  const resolvedMarket = (0, import_react26.useMemo)(() => {
13901
14021
  return resolveMarketFromVenueMarkets(venueMarkets, marketId);
13902
14022
  }, [venueMarkets, marketId]);
@@ -13906,6 +14026,10 @@ var MarketDetailsContent = ({
13906
14026
  return (_b2 = (_a2 = resolvedMarket.venueMarkets.find((venueMarket) => venueMarket.id === resolvedMarket.id)) != null ? _a2 : resolvedMarket.venueMarkets[0]) != null ? _b2 : null;
13907
14027
  }, [resolvedMarket]);
13908
14028
  const isResolvedMarket = (0, import_hooks48.resolveMarketTradingState)(scopedResolvedMarket).kind === "resolved";
14029
+ (0, import_hooks48.useEventOrderbookData)(
14030
+ isResolvedMarket ? [] : resolvedMarket == null ? void 0 : resolvedMarket.venueMarkets,
14031
+ (_b = scopedResolvedMarket == null ? void 0 : scopedResolvedMarket.id) != null ? _b : null
14032
+ );
13909
14033
  const clusterMidpointResult = midpointsResult != null ? midpointsResult : {
13910
14034
  prices: /* @__PURE__ */ new Map(),
13911
14035
  bestMidpointsByOutcomeId: /* @__PURE__ */ new Map(),
@@ -13916,7 +14040,7 @@ var MarketDetailsContent = ({
13916
14040
  bestMidpoint: void 0,
13917
14041
  bestMidpointVenue: void 0
13918
14042
  };
13919
- const clusterMidpoints = (_b = clusterMidpointResult.bestMidpointsByOutcomeId) != null ? _b : clusterMidpointResult.prices;
14043
+ const clusterMidpoints = (_c = clusterMidpointResult.bestMidpointsByOutcomeId) != null ? _c : clusterMidpointResult.prices;
13920
14044
  const clusterBestMidpointsByOutcomeId = clusterMidpoints;
13921
14045
  const clusterVenueByOutcomeId = clusterMidpointResult.venueByOutcomeId;
13922
14046
  const clusterBestMidpoint = clusterMidpointResult.bestMidpoint;
@@ -14031,7 +14155,7 @@ var MarketDetailsContent = ({
14031
14155
  tradingContext == null ? void 0 : tradingContext.selectedOutcomeId
14032
14156
  ]);
14033
14157
  const selectedOutcomeId = scopedSelectedOutcomeState.outcomeId;
14034
- const selectedOutcomeLabel = (_c = scopedSelectedOutcomeState.outcomeLabel) != null ? _c : null;
14158
+ const selectedOutcomeLabel = (_d = scopedSelectedOutcomeState.outcomeLabel) != null ? _d : null;
14035
14159
  const selectOutcome = tradingContext == null ? void 0 : tradingContext.selectOutcome;
14036
14160
  const [selectedGraphVenue, setSelectedGraphVenue] = (0, import_react26.useState)(null);
14037
14161
  const [chartOutcomeLabel, setChartOutcomeLabel] = (0, import_react26.useState)(selectedOutcomeLabel);
@@ -14065,31 +14189,33 @@ var MarketDetailsContent = ({
14065
14189
  tradingContext == null ? void 0 : tradingContext.selectedMarketId,
14066
14190
  selectOutcome
14067
14191
  ]);
14192
+ const venueMarketIdByVenue = (0, import_react26.useMemo)(
14193
+ () => buildVenueMarketIdByVenue(model == null ? void 0 : model.market.venueMarkets),
14194
+ [model]
14195
+ );
14068
14196
  const headerOutcomeItems = (0, import_react26.useMemo)(() => {
14069
14197
  if (!model) return [];
14070
14198
  const items = resolveHeaderOutcomeItems(model.market.venueMarkets, scopedMarketForCard);
14071
14199
  return items.map((item) => {
14072
14200
  var _a2;
14073
14201
  const fallbackPrice = midpointsFallback == null ? void 0 : midpointsFallback.get(item.id);
14074
- const bestVenue = getDisplayOutcomeVenue({
14075
- outcomeId: item.id,
14076
- outcomeLabel: item.label,
14077
- selection: tradeSide,
14078
- bestMidpointVenue: clusterBestMidpointVenue,
14079
- bestVenueByOutcomeId: clusterVenueByOutcomeId,
14080
- bestPriceVenuesByOutcomeId: clusterBestPriceVenuesByOutcomeId,
14081
- fallbackVenue: midpointsFallbackVenues == null ? void 0 : midpointsFallbackVenues.get(item.id)
14082
- });
14083
- const outcomeBestPrice = getDisplayOutcomePrice({
14202
+ const candidate = selectBestOutcomeCandidate({
14084
14203
  outcomeId: item.id,
14085
14204
  outcomeLabel: item.label,
14086
14205
  selection: tradeSide,
14087
- bestPrices: clusterBestPrices,
14206
+ live: wsBestCandidates.get(item.id),
14207
+ restBest: clusterBestPricesRest.get(item.id),
14208
+ restBestVenues: clusterBestPriceVenuesByOutcomeId.get(item.id),
14209
+ restMidpoint: clusterBestMidpointsByOutcomeId.get(item.id),
14210
+ restMidpointVenue: clusterVenueByOutcomeId.get(item.id),
14088
14211
  bestMidpoint: clusterBestMidpoint,
14089
- bestMidpointsByOutcomeId: clusterBestMidpointsByOutcomeId,
14090
- livePrices: wsLivePrices,
14091
- fallbackPrice
14212
+ bestMidpointVenue: clusterBestMidpointVenue,
14213
+ staticPrice: fallbackPrice,
14214
+ staticVenue: midpointsFallbackVenues == null ? void 0 : midpointsFallbackVenues.get(item.id),
14215
+ venueMarketIdByVenue
14092
14216
  });
14217
+ const bestVenue = candidate == null ? void 0 : candidate.venue;
14218
+ const outcomeBestPrice = candidate == null ? void 0 : candidate.price;
14093
14219
  if (isResolvedMarket) {
14094
14220
  const isWinningOutcome = item.id === ((_a2 = marketTradingState.winningOutcome) == null ? void 0 : _a2.id);
14095
14221
  return __spreadValues(__spreadProps(__spreadValues({}, item), {
@@ -14107,17 +14233,18 @@ var MarketDetailsContent = ({
14107
14233
  clusterBestMidpoint,
14108
14234
  clusterBestMidpointVenue,
14109
14235
  clusterBestMidpointsByOutcomeId,
14110
- clusterBestPrices,
14236
+ clusterBestPricesRest,
14111
14237
  clusterBestPriceVenuesByOutcomeId,
14112
14238
  model,
14113
14239
  scopedMarketForCard,
14114
14240
  clusterVenueByOutcomeId,
14115
14241
  isResolvedMarket,
14116
- (_d = marketTradingState.winningOutcome) == null ? void 0 : _d.id,
14242
+ (_e = marketTradingState.winningOutcome) == null ? void 0 : _e.id,
14117
14243
  midpointsFallback,
14118
14244
  midpointsFallbackVenues,
14119
14245
  tradeSide,
14120
- wsLivePrices
14246
+ venueMarketIdByVenue,
14247
+ wsBestCandidates
14121
14248
  ]);
14122
14249
  const headlineProbability = (0, import_react26.useMemo)(() => {
14123
14250
  var _a2, _b2, _c2, _d2;
@@ -14183,9 +14310,9 @@ var MarketDetailsContent = ({
14183
14310
  const chartEnabled = isOpened && effectiveSelectedTab === "graph";
14184
14311
  const orderBookEnabled = isOpened && effectiveSelectedTab === "order-book" && !marketTradingState.isTradingDisabled;
14185
14312
  const rollingWindow = (0, import_hooks48.useRollingChartWindow)({ range: effectiveChartTimeRange });
14186
- const primaryVenueMarketId = (_f = (_e = selectedOutcomesByVenue[0]) == null ? void 0 : _e.market.id) != null ? _f : null;
14187
- const primaryOutcomeId = (_h = (_g = selectedOutcomesByVenue[0]) == null ? void 0 : _g.outcome.id) != null ? _h : null;
14188
- const chartPrimaryOutcomeId = (_j = (_i = chartOutcomesByVenue[0]) == null ? void 0 : _i.outcome.id) != null ? _j : null;
14313
+ const primaryVenueMarketId = (_g = (_f = selectedOutcomesByVenue[0]) == null ? void 0 : _f.market.id) != null ? _g : null;
14314
+ const primaryOutcomeId = (_i = (_h = selectedOutcomesByVenue[0]) == null ? void 0 : _h.outcome.id) != null ? _i : null;
14315
+ const chartPrimaryOutcomeId = (_k = (_j = chartOutcomesByVenue[0]) == null ? void 0 : _j.outcome.id) != null ? _k : null;
14189
14316
  const chartVenueOutcomeIds = (0, import_react26.useMemo)(() => {
14190
14317
  return chartOutcomesByVenue.map((item) => item.outcome.id);
14191
14318
  }, [chartOutcomesByVenue]);
@@ -14688,7 +14815,7 @@ var MarketDetailsContent = ({
14688
14815
  height: 260,
14689
14816
  isLoading: isMarketChartLoading,
14690
14817
  chartType: selectedChartType,
14691
- liveCandle: selectedChartType === "candlestick" ? (_k = graphLiveState.liveCandle) != null ? _k : void 0 : void 0,
14818
+ liveCandle: selectedChartType === "candlestick" ? (_l = graphLiveState.liveCandle) != null ? _l : void 0 : void 0,
14692
14819
  lineValue: graphLiveState.lineValue,
14693
14820
  classNames: { root: "agg-chart-region w-full" },
14694
14821
  showSeriesControls: chartAvailableOutcomesByVenue.length > 0 || headerOutcomeItems.length > 0,
@@ -17504,10 +17631,8 @@ var PlaceOrderResolvedView = ({
17504
17631
  resolvedClaim,
17505
17632
  className
17506
17633
  }) => {
17507
- var _a, _b, _c, _d, _e;
17508
17634
  const labels = (0, import_hooks52.useLabels)();
17509
17635
  const tradingLabels = labels.trading;
17510
- const extendedTradingLabels = tradingLabels;
17511
17636
  return /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
17512
17637
  Card,
17513
17638
  {
@@ -17546,18 +17671,18 @@ var PlaceOrderResolvedView = ({
17546
17671
  resolvedClaim ? /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(import_jsx_runtime145.Fragment, { children: [
17547
17672
  /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("div", { className: "h-px w-full bg-agg-separator" }),
17548
17673
  /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { className: "flex w-full flex-col gap-5 p-6", children: [
17549
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Typography, { variant: "body-strong", className: "text-center", children: (_a = extendedTradingLabels.resolvedEarningsTitle) != null ? _a : "Your Earnings" }),
17674
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Typography, { variant: "body-strong", className: "text-center", children: tradingLabels.resolvedEarningsTitle }),
17550
17675
  /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { className: "flex flex-col gap-3 text-agg-sm leading-agg-5 text-agg-foreground", children: [
17551
17676
  resolvedClaim.resolutionDateLabel ? /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
17552
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { children: (_b = extendedTradingLabels.resolvedResolutionDateLabel) != null ? _b : "Resolution date" }),
17677
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { children: tradingLabels.resolvedResolutionDateLabel }),
17553
17678
  /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { className: "font-agg-bold", children: resolvedClaim.resolutionDateLabel })
17554
17679
  ] }) : null,
17555
17680
  /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
17556
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { children: (_c = extendedTradingLabels.resolvedSharesLabel) != null ? _c : "Shares" }),
17681
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { children: tradingLabels.resolvedSharesLabel }),
17557
17682
  /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { className: "font-agg-bold", children: resolvedClaim.sharesLabel })
17558
17683
  ] }),
17559
17684
  /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
17560
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { children: (_d = extendedTradingLabels.resolvedTotalPayoutLabel) != null ? _d : "Total payout" }),
17685
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { children: tradingLabels.resolvedTotalPayoutLabel }),
17561
17686
  /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("span", { className: "font-agg-bold", children: resolvedClaim.totalPayoutLabel })
17562
17687
  ] })
17563
17688
  ] }),
@@ -17569,7 +17694,7 @@ var PlaceOrderResolvedView = ({
17569
17694
  onClick: resolvedClaim.onClaim,
17570
17695
  isLoading: resolvedClaim.isClaiming,
17571
17696
  disabled: resolvedClaim.isClaiming,
17572
- children: (_e = extendedTradingLabels.claimWinnings) != null ? _e : "Claim Winnings"
17697
+ children: tradingLabels.claimWinnings
17573
17698
  }
17574
17699
  ) : null
17575
17700
  ] })
@@ -17905,6 +18030,7 @@ var PlaceOrder = ({
17905
18030
  onClose,
17906
18031
  onOutcomeChange,
17907
18032
  onPrimaryAction,
18033
+ onBeforePrimaryAction,
17908
18034
  onTabChange,
17909
18035
  onSuccess,
17910
18036
  onError,
@@ -18043,6 +18169,7 @@ var PlaceOrder = ({
18043
18169
  const [isSplitDetailOpen, setIsSplitDetailOpen] = (0, import_react30.useState)(false);
18044
18170
  const [submissionFeedback, setSubmissionFeedback] = (0, import_react30.useState)(null);
18045
18171
  const [submissionProgressState, setSubmissionProgressState] = (0, import_react30.useState)(null);
18172
+ const [isBeforeActionPending, setIsBeforeActionPending] = (0, import_react30.useState)(false);
18046
18173
  const executionDebugStoreRef = (0, import_react30.useRef)(null);
18047
18174
  const executionDebugAttemptIdRef = (0, import_react30.useRef)(null);
18048
18175
  const submittedSelectionRef = (0, import_react30.useRef)(null);
@@ -18628,7 +18755,7 @@ var PlaceOrder = ({
18628
18755
  }
18629
18756
  ];
18630
18757
  }, [activeFeeBreakdown, tradingLabels]);
18631
- const isActionLoading = isPrimaryActionLoading || executeManaged.isPending;
18758
+ const isActionLoading = isPrimaryActionLoading || executeManaged.isPending || isBeforeActionPending;
18632
18759
  const selectedRouteGeoBlocked = (_D = selectedRouteCard == null ? void 0 : selectedRouteCard.isUnavailable) != null ? _D : false;
18633
18760
  const geoBlockedVenuesFromWarnings = (0, import_react30.useMemo)(
18634
18761
  () => {
@@ -18994,7 +19121,7 @@ var PlaceOrder = ({
18994
19121
  });
18995
19122
  };
18996
19123
  const handlePrimaryAction = () => __async(null, null, function* () {
18997
- var _a2;
19124
+ var _a2, _b2, _c2;
18998
19125
  if (!orderEligibility.canPlaceOrder) {
18999
19126
  setSubmissionFeedback({
19000
19127
  message: (_a2 = resolveOrderEligibilityMessage(labels, orderEligibility.reason)) != null ? _a2 : tradingLabels.orderFailed,
@@ -19004,6 +19131,26 @@ var PlaceOrder = ({
19004
19131
  }
19005
19132
  if (!selectedRouteCard) return;
19006
19133
  setSubmissionFeedback(null);
19134
+ if (onBeforePrimaryAction) {
19135
+ const beforeContext = isPaperMode ? { quoteId: (_b2 = selectedRouteCard.quoteData) == null ? void 0 : _b2.quoteId, mode: "paper" } : { quoteId: (_c2 = selectedRouteCard.quoteData) == null ? void 0 : _c2.quoteId };
19136
+ setIsBeforeActionPending(true);
19137
+ try {
19138
+ const proceed = yield onBeforePrimaryAction(beforeContext);
19139
+ if (proceed === false) return;
19140
+ } catch (error) {
19141
+ setSubmissionFeedback({
19142
+ message: normalizePlaceOrderErrorMessage({
19143
+ errorMessage: error instanceof Error ? error.message : String(error),
19144
+ fallbackMessage: tradingLabels.orderFailed,
19145
+ labels: tradingLabels
19146
+ }),
19147
+ tone: "error"
19148
+ });
19149
+ return;
19150
+ } finally {
19151
+ setIsBeforeActionPending(false);
19152
+ }
19153
+ }
19007
19154
  if (scopedSelectedMarket && scopedSelectedOutcomeId) {
19008
19155
  submittedSelectionRef.current = {
19009
19156
  marketId: scopedSelectedMarket.id,
@@ -19474,177 +19621,485 @@ var PlaceOrder = ({
19474
19621
  };
19475
19622
  PlaceOrder.displayName = "PlaceOrder";
19476
19623
 
19477
- // src/pages/event-market/event-market.utils.ts
19478
- var EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX = 48;
19479
- var EVENT_MARKET_PAGE_STICKY_SPACING_PX = 32;
19480
- var EVENT_MARKET_PAGE_STICKY_TOP_PX = EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX + EVENT_MARKET_PAGE_STICKY_SPACING_PX;
19481
- var EVENT_MARKET_PAGE_STICKY_TOP_CSS_VAR = "--agg-event-market-sidebar-top";
19482
- var EVENT_MARKET_PAGE_STICKY_SPACING_CSS_VAR = "--agg-event-market-sidebar-spacing";
19483
- var toCssLength = (value, fallback) => {
19484
- if (typeof value === "number") {
19485
- return `${value}px`;
19486
- }
19487
- return value != null ? value : `${fallback}px`;
19488
- };
19489
- var deriveSpacingFromTop = (top) => {
19490
- if (typeof top !== "number") {
19491
- return void 0;
19492
- }
19493
- return Math.max(top - EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX, 0);
19494
- };
19495
- var resolveEventMarketPageStickyState = ({
19496
- stickyOrderPanel
19497
- }) => {
19498
- var _a, _b;
19499
- const isEnabled = (_a = stickyOrderPanel == null ? void 0 : stickyOrderPanel.enabled) != null ? _a : Boolean(stickyOrderPanel);
19500
- if (!isEnabled) {
19501
- return {
19502
- contentClassName: cn(),
19503
- sidebarClassName: cn("pt-4 sm:pt-6 md:pt-8 pb-10"),
19504
- placeOrder: cn("mb-10"),
19505
- mainClassName: cn("pt-4 sm:pt-6 md:pt-8"),
19506
- style: {}
19507
- };
19508
- }
19509
- return {
19510
- contentClassName: cn("lg:items-stretch!"),
19511
- sidebarClassName: cn(
19512
- "pt-4 sm:pt-6 md:pt-8 pb-10",
19513
- "lg:self-start lg:sticky lg:top-[var(--agg-event-market-sidebar-top)] lg:max-h-[calc(100vh-var(--agg-event-market-sidebar-top))] lg:overflow-y-auto lg:overscroll-contain",
19514
- stickyOrderPanel == null ? void 0 : stickyOrderPanel.className
19515
- ),
19516
- placeOrder: cn("mb-10"),
19517
- mainClassName: cn("pt-4 sm:pt-6 md:pt-8"),
19518
- style: {
19519
- [EVENT_MARKET_PAGE_STICKY_TOP_CSS_VAR]: toCssLength(
19520
- stickyOrderPanel == null ? void 0 : stickyOrderPanel.top,
19521
- EVENT_MARKET_PAGE_STICKY_TOP_PX
19522
- ),
19523
- [EVENT_MARKET_PAGE_STICKY_SPACING_CSS_VAR]: toCssLength(
19524
- (_b = stickyOrderPanel == null ? void 0 : stickyOrderPanel.spacing) != null ? _b : deriveSpacingFromTop(stickyOrderPanel == null ? void 0 : stickyOrderPanel.top),
19525
- EVENT_MARKET_PAGE_STICKY_SPACING_PX
19526
- )
19527
- }
19528
- };
19529
- };
19530
-
19531
- // src/pages/event-market/index.tsx
19532
- var import_jsx_runtime146 = require("react/jsx-runtime");
19533
- var MOBILE_EVENT_MARKET_MEDIA_QUERY = "(max-width: 1023px)";
19534
- var getIsMobileEventMarketViewport = () => {
19535
- if (typeof window === "undefined") return false;
19536
- if (typeof window.matchMedia !== "function") return false;
19537
- return window.matchMedia(MOBILE_EVENT_MARKET_MEDIA_QUERY).matches;
19538
- };
19539
- var useIsMobileEventMarketViewport = () => {
19540
- const [isMobileViewport, setIsMobileViewport] = (0, import_react31.useState)(getIsMobileEventMarketViewport);
19541
- (0, import_react31.useEffect)(() => {
19542
- if (typeof window === "undefined") return;
19543
- if (typeof window.matchMedia !== "function") return;
19544
- const mediaQueryList = window.matchMedia(MOBILE_EVENT_MARKET_MEDIA_QUERY);
19545
- const handleChange = () => {
19546
- setIsMobileViewport(mediaQueryList.matches);
19547
- };
19548
- handleChange();
19549
- mediaQueryList.addEventListener("change", handleChange);
19550
- return () => {
19551
- mediaQueryList.removeEventListener("change", handleChange);
19552
- };
19553
- }, []);
19554
- return isMobileViewport;
19555
- };
19556
- var resolveDesktopTradePlaceOrderClassNames = (classNames) => {
19557
- const resolvedClassNames = {
19558
- body: classNames == null ? void 0 : classNames.tradeBody,
19559
- content: classNames == null ? void 0 : classNames.tradeContent,
19560
- footer: classNames == null ? void 0 : classNames.tradeFooter,
19561
- header: classNames == null ? void 0 : classNames.tradeHeader
19562
- };
19563
- if (!Object.values(resolvedClassNames).some(Boolean)) {
19564
- return void 0;
19565
- }
19566
- return resolvedClassNames;
19567
- };
19568
- var resolveMobileTradePlaceOrderClassNames = (classNames) => {
19569
- return {
19570
- root: "rounded-t-agg-2xl rounded-b-none md:rounded-agg-2xl md:rounded-b-agg-2xl",
19571
- body: cn("flex h-full min-h-0 flex-col", classNames == null ? void 0 : classNames.tradeBody, classNames == null ? void 0 : classNames.mobileTradeBody),
19572
- content: cn(
19573
- "min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
19574
- classNames == null ? void 0 : classNames.tradeContent,
19575
- classNames == null ? void 0 : classNames.mobileTradeContent
19576
- ),
19577
- footer: cn(classNames == null ? void 0 : classNames.tradeFooter, classNames == null ? void 0 : classNames.mobileTradeFooter),
19578
- header: cn(
19579
- "sticky top-0 z-10 bg-agg-secondary",
19580
- classNames == null ? void 0 : classNames.tradeHeader,
19581
- classNames == null ? void 0 : classNames.mobileTradeHeader
19582
- )
19583
- };
19624
+ // src/trading/use-claim-winnings.ts
19625
+ var import_hooks53 = require("@agg-build/hooks");
19626
+ var import_react31 = require("react");
19627
+ var toClaimError = (err) => {
19628
+ if (err instanceof Error) return err;
19629
+ return new Error(String(err));
19584
19630
  };
19585
- var EventMarketPageMobileTrade = ({
19586
- classNames,
19587
- eventTradingState,
19588
- executionMode,
19589
- showPlaceOrder = true,
19590
- isOpen,
19591
- onOpenChange,
19592
- midpointsResult
19593
- }) => {
19631
+ function useClaimWinnings(options = {}) {
19632
+ const { onClaim, onClaimResult, onClaimSubmitError, externalClaimingKeys } = options;
19594
19633
  const labels = (0, import_hooks53.useLabels)();
19595
- if (!showPlaceOrder) return null;
19596
- const handleOpenChange = (nextOpen) => {
19597
- onOpenChange(nextOpen);
19598
- };
19599
- const handleClose = () => {
19600
- onOpenChange(false);
19601
- };
19602
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(import_jsx_runtime146.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Modal, { open: isOpen, onOpenChange: handleOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(
19603
- Modal.Container,
19604
- {
19605
- classNames: {
19606
- content: "items-end p-0 sm:items-center sm:p-4",
19607
- container: cn(
19608
- "agg-mobile-trade-modal",
19609
- "w-full border-0 bg-transparent shadow-none",
19610
- classNames == null ? void 0 : classNames.mobileTradeModal
19611
- )
19612
- },
19613
- children: [
19614
- /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Dialog4.Title, { className: "sr-only", children: labels.trading.confirmOrder }),
19615
- /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Dialog4.Description, { className: "sr-only", children: labels.trading.disclaimer }),
19616
- /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { className: "agg-mobile-trade-handle relative flex w-full flex-col items-center sm:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
19617
- "button",
19618
- {
19619
- type: "button",
19620
- className: "absolute right-3 top-4 z-100 flex cursor-pointer items-center justify-center rounded-full p-1 text-agg-muted-foreground hover:text-agg-foreground",
19621
- "aria-label": labels.common.close,
19622
- onClick: handleClose,
19623
- children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(CloseIcon, { className: "h-5 w-5" })
19624
- }
19625
- ) }),
19626
- /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
19627
- PlaceOrder,
19628
- {
19629
- eventTradingState,
19630
- executionMode,
19631
- midpointsResult,
19632
- className: cn(
19633
- "agg-mobile-trade-panel w-full overflow-hidden rounded-t-agg-2xl sm:rounded-agg-xl",
19634
- classNames == null ? void 0 : classNames.mobileTrade
19635
- ),
19636
- classNames: resolveMobileTradePlaceOrderClassNames(classNames),
19637
- onClose: handleClose
19638
- }
19639
- )
19640
- ]
19634
+ const claimNotificationLabels = labels.notifications.claim;
19635
+ const toastCtx = useOptionalToast();
19636
+ const queryClient = (0, import_hooks53.useQueryClient)();
19637
+ const redeemMutation = (0, import_hooks53.useRedeem)();
19638
+ const [activeRedeems, setActiveRedeems] = (0, import_react31.useState)({});
19639
+ const activeClaimKeysRef = (0, import_react31.useRef)(/* @__PURE__ */ new Set());
19640
+ const pendingClaimToastIdsRef = (0, import_react31.useRef)({});
19641
+ const submittedClaimToastKeysRef = (0, import_react31.useRef)(/* @__PURE__ */ new Set());
19642
+ const [submittingClaimKeys, setSubmittingClaimKeys] = (0, import_react31.useState)({});
19643
+ const lifecycleInputs = (0, import_react31.useMemo)(
19644
+ () => Object.values(activeRedeems),
19645
+ [activeRedeems]
19646
+ );
19647
+ const lifecycleStates = (0, import_hooks53.useRedeemLifecycles)(lifecycleInputs);
19648
+ const internalClaimingIds = (0, import_react31.useMemo)(() => {
19649
+ const out = __spreadValues({}, submittingClaimKeys);
19650
+ for (const [claimKey, active] of Object.entries(activeRedeems)) {
19651
+ const state = lifecycleStates[active.redeemId];
19652
+ if (!state || !state.terminal) out[claimKey] = true;
19641
19653
  }
19642
- ) }) });
19654
+ return out;
19655
+ }, [activeRedeems, lifecycleStates, submittingClaimKeys]);
19656
+ const claimingKeys = externalClaimingKeys != null ? externalClaimingKeys : internalClaimingIds;
19657
+ const isClaiming = (0, import_react31.useCallback)(
19658
+ (claimKey) => Boolean(externalClaimingKeys == null ? void 0 : externalClaimingKeys[claimKey]) || Boolean(internalClaimingIds[claimKey]),
19659
+ [externalClaimingKeys, internalClaimingIds]
19660
+ );
19661
+ const invalidateClaimUiState = (0, import_react31.useCallback)(() => {
19662
+ (0, import_hooks53.invalidateBalanceQueries)(queryClient);
19663
+ (0, import_hooks53.invalidatePositionQueries)(queryClient);
19664
+ queryClient.invalidateQueries({
19665
+ queryKey: import_hooks53.executionKeys.claimablePositionsCount(),
19666
+ refetchType: "active"
19667
+ });
19668
+ (0, import_hooks53.invalidateUserActivityQueries)(queryClient);
19669
+ }, [queryClient]);
19670
+ const claim = (0, import_react31.useCallback)(
19671
+ (_0) => __async(null, [_0], function* ({ claimKey, winningOutcomeIds, payload }) {
19672
+ if (activeClaimKeysRef.current.has(claimKey) || Boolean(externalClaimingKeys == null ? void 0 : externalClaimingKeys[claimKey]) || internalClaimingIds[claimKey]) {
19673
+ return;
19674
+ }
19675
+ activeClaimKeysRef.current.add(claimKey);
19676
+ setSubmittingClaimKeys((prev) => __spreadProps(__spreadValues({}, prev), { [claimKey]: true }));
19677
+ const pendingToastId = toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.pendingMessage, {
19678
+ title: claimNotificationLabels.pendingTitle,
19679
+ tone: "info"
19680
+ });
19681
+ if (pendingToastId != null) {
19682
+ pendingClaimToastIdsRef.current[claimKey] = pendingToastId;
19683
+ }
19684
+ if (onClaim) {
19685
+ try {
19686
+ yield onClaim(payload);
19687
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
19688
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
19689
+ delete pendingClaimToastIdsRef.current[claimKey];
19690
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.successMessage, {
19691
+ title: claimNotificationLabels.successTitle,
19692
+ tone: "success"
19693
+ });
19694
+ } catch (err) {
19695
+ const error = toClaimError(err);
19696
+ console.error("[useClaimWinnings] redeem failed", error);
19697
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
19698
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
19699
+ delete pendingClaimToastIdsRef.current[claimKey];
19700
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
19701
+ title: claimNotificationLabels.failedTitle,
19702
+ tone: "error"
19703
+ });
19704
+ onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
19705
+ throw error;
19706
+ } finally {
19707
+ invalidateClaimUiState();
19708
+ activeClaimKeysRef.current.delete(claimKey);
19709
+ setSubmittingClaimKeys((prev) => {
19710
+ const _a = prev, { [claimKey]: _removed } = _a, rest = __objRest(_a, [__restKey(claimKey)]);
19711
+ return rest;
19712
+ });
19713
+ }
19714
+ return;
19715
+ }
19716
+ if (winningOutcomeIds.length === 0) {
19717
+ const error = new Error(claimNotificationLabels.missingOutcomeMessage);
19718
+ console.error("[useClaimWinnings] redeem failed", error);
19719
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
19720
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
19721
+ delete pendingClaimToastIdsRef.current[claimKey];
19722
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
19723
+ title: claimNotificationLabels.failedTitle,
19724
+ tone: "error"
19725
+ });
19726
+ onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
19727
+ invalidateClaimUiState();
19728
+ activeClaimKeysRef.current.delete(claimKey);
19729
+ setSubmittingClaimKeys((prev) => {
19730
+ const _a = prev, { [claimKey]: _removed } = _a, rest = __objRest(_a, [__restKey(claimKey)]);
19731
+ return rest;
19732
+ });
19733
+ throw error;
19734
+ }
19735
+ try {
19736
+ const response = yield redeemMutation.mutateAsync({
19737
+ venueMarketOutcomeIds: winningOutcomeIds
19738
+ });
19739
+ const expectedOutcomeIds = [];
19740
+ const preFailedOutcomeIds = [];
19741
+ const preFailedReasons = {};
19742
+ const preConfirmedOutcomeIds = [];
19743
+ const preConfirmedTxHashes = {};
19744
+ for (const result of response.results) {
19745
+ if (result.status === "submitted") {
19746
+ expectedOutcomeIds.push(result.venueMarketOutcomeId);
19747
+ } else if (result.status === "confirmed") {
19748
+ preConfirmedOutcomeIds.push(result.venueMarketOutcomeId);
19749
+ preConfirmedTxHashes[result.venueMarketOutcomeId] = result.txHash;
19750
+ } else if (result.status === "ineligible" || result.status === "rejected") {
19751
+ preFailedOutcomeIds.push(result.venueMarketOutcomeId);
19752
+ preFailedReasons[result.venueMarketOutcomeId] = result.reason;
19753
+ }
19754
+ }
19755
+ if (expectedOutcomeIds.length > 0) {
19756
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
19757
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
19758
+ delete pendingClaimToastIdsRef.current[claimKey];
19759
+ submittedClaimToastKeysRef.current.add(claimKey);
19760
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.submittedMessage, {
19761
+ title: claimNotificationLabels.submittedTitle,
19762
+ tone: "success"
19763
+ });
19764
+ }
19765
+ setActiveRedeems((prev) => __spreadProps(__spreadValues({}, prev), {
19766
+ [claimKey]: {
19767
+ redeemId: response.redeemId,
19768
+ expectedOutcomeIds,
19769
+ preFailedOutcomeIds,
19770
+ preFailedReasons,
19771
+ preConfirmedOutcomeIds,
19772
+ preConfirmedTxHashes
19773
+ }
19774
+ }));
19775
+ yield queryClient.invalidateQueries({ queryKey: ["current-user"] });
19776
+ } catch (err) {
19777
+ const error = toClaimError(err);
19778
+ console.error("[useClaimWinnings] redeem failed", error);
19779
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
19780
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
19781
+ delete pendingClaimToastIdsRef.current[claimKey];
19782
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
19783
+ title: claimNotificationLabels.failedTitle,
19784
+ tone: "error"
19785
+ });
19786
+ onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
19787
+ throw error;
19788
+ } finally {
19789
+ activeClaimKeysRef.current.delete(claimKey);
19790
+ setSubmittingClaimKeys((prev) => {
19791
+ const _a = prev, { [claimKey]: _removed } = _a, rest = __objRest(_a, [__restKey(claimKey)]);
19792
+ return rest;
19793
+ });
19794
+ }
19795
+ }),
19796
+ [
19797
+ claimNotificationLabels,
19798
+ externalClaimingKeys,
19799
+ internalClaimingIds,
19800
+ invalidateClaimUiState,
19801
+ onClaim,
19802
+ onClaimSubmitError,
19803
+ queryClient,
19804
+ redeemMutation,
19805
+ toastCtx
19806
+ ]
19807
+ );
19808
+ const firedTerminalRef = (0, import_react31.useRef)({});
19809
+ (0, import_react31.useEffect)(() => {
19810
+ var _a, _b;
19811
+ for (const [claimKey, active] of Object.entries(activeRedeems)) {
19812
+ const state = lifecycleStates[active.redeemId];
19813
+ if (!state || !state.terminal) continue;
19814
+ if (firedTerminalRef.current[active.redeemId]) continue;
19815
+ firedTerminalRef.current[active.redeemId] = true;
19816
+ onClaimResult == null ? void 0 : onClaimResult(claimKey, {
19817
+ allConfirmed: state.allConfirmed,
19818
+ anyFailed: state.anyFailed,
19819
+ errorMessage: state.errorMessage
19820
+ });
19821
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
19822
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
19823
+ delete pendingClaimToastIdsRef.current[claimKey];
19824
+ if (state.allConfirmed) {
19825
+ if (!submittedClaimToastKeysRef.current.has(claimKey)) {
19826
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.successMessage, {
19827
+ title: claimNotificationLabels.successTitle,
19828
+ tone: "success"
19829
+ });
19830
+ }
19831
+ } else if (state.anyFailed) {
19832
+ const hasConfirmedLeg = Object.values(state.legs).some((leg) => leg.status === "confirmed");
19833
+ if (hasConfirmedLeg) {
19834
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.partialMessage((_a = state.errorMessage) != null ? _a : void 0), {
19835
+ title: claimNotificationLabels.partialTitle,
19836
+ tone: "warning"
19837
+ });
19838
+ } else {
19839
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage((_b = state.errorMessage) != null ? _b : void 0), {
19840
+ title: claimNotificationLabels.failedTitle,
19841
+ tone: "error"
19842
+ });
19843
+ }
19844
+ }
19845
+ submittedClaimToastKeysRef.current.delete(claimKey);
19846
+ invalidateClaimUiState();
19847
+ delete firedTerminalRef.current[active.redeemId];
19848
+ setActiveRedeems((prev) => {
19849
+ const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
19850
+ return rest;
19851
+ });
19852
+ }
19853
+ }, [
19854
+ activeRedeems,
19855
+ claimNotificationLabels,
19856
+ invalidateClaimUiState,
19857
+ lifecycleStates,
19858
+ onClaimResult,
19859
+ toastCtx
19860
+ ]);
19861
+ return { claim, claimingKeys, isClaiming };
19862
+ }
19863
+
19864
+ // src/trading/use-resolved-market-claim.ts
19865
+ var import_hooks54 = require("@agg-build/hooks");
19866
+ var import_react32 = require("react");
19867
+ var sharesFormatter = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 });
19868
+ var dateFormatter = new Intl.DateTimeFormat("en-US", {
19869
+ month: "short",
19870
+ day: "numeric",
19871
+ year: "numeric"
19872
+ });
19873
+ var formatResolutionDate = (value) => {
19874
+ if (!value) return "";
19875
+ const date = new Date(value);
19876
+ if (Number.isNaN(date.getTime())) return "";
19877
+ return dateFormatter.format(date);
19878
+ };
19879
+ function useResolvedMarketClaim(options = {}) {
19880
+ var _a;
19881
+ const { market, enabled = true, executionMode } = options;
19882
+ const { isAuthenticated } = (0, import_hooks54.useAggAuthState)();
19883
+ const tradingState = (0, import_react32.useMemo)(() => (0, import_hooks54.resolveMarketTradingState)(market), [market]);
19884
+ const isResolved = tradingState.kind === "resolved";
19885
+ const marketId = (_a = market == null ? void 0 : market.id) != null ? _a : null;
19886
+ const shouldFetch = Boolean(enabled && isAuthenticated && isResolved && marketId);
19887
+ const { positions } = (0, import_hooks54.useExecutionPositions)(__spreadValues({
19888
+ enabled: shouldFetch,
19889
+ status: "active",
19890
+ limit: 50
19891
+ }, executionMode === "paper" ? { mode: "paper" } : {}));
19892
+ const claimWinnings = useClaimWinnings();
19893
+ return (0, import_react32.useMemo)(() => {
19894
+ var _a2, _b, _c;
19895
+ if (!shouldFetch || !marketId) return void 0;
19896
+ const group = positions.find(
19897
+ (candidate) => candidate.targetMarketId === marketId
19898
+ );
19899
+ if (!group || group.venueMarket.status !== "resolved") return void 0;
19900
+ const winningOutcomes = group.venueMarket.venueMarketOutcomes.filter(
19901
+ (outcome) => outcome.winner === true && outcome.totalSize > 0
19902
+ );
19903
+ if (winningOutcomes.length === 0) return void 0;
19904
+ const totals = (0, import_hooks54.computeClosedPositionTotals)(group);
19905
+ const winningShares = winningOutcomes.reduce((sum, outcome) => sum + outcome.totalSize, 0);
19906
+ const winningOutcomeLabel = ((_b = (_a2 = winningOutcomes[0]) == null ? void 0 : _a2.title) == null ? void 0 : _b.trim()) || ((_c = winningOutcomes[0]) == null ? void 0 : _c.label) || "";
19907
+ const claimKey = group.targetMarketId;
19908
+ const canClaim = group.redeemStatus === "eligible" && totals.winningOutcomeIds.length > 0;
19909
+ return {
19910
+ resolutionDateLabel: formatResolutionDate(group.resolutionDate),
19911
+ winningOutcomeLabel,
19912
+ sharesLabel: `${sharesFormatter.format(winningShares)} ${winningOutcomeLabel}`.trim(),
19913
+ // Payout is always shown with 2 decimals (e.g. "$8.50"), matching the
19914
+ // resolved-earnings design and the profile positions list.
19915
+ totalPayoutLabel: formatUsd(totals.amountWon, {
19916
+ minimumFractionDigits: 2,
19917
+ maximumFractionDigits: 2
19918
+ }),
19919
+ isClaiming: claimWinnings.isClaiming(claimKey),
19920
+ onClaim: canClaim ? () => {
19921
+ void claimWinnings.claim({
19922
+ claimKey,
19923
+ winningOutcomeIds: totals.winningOutcomeIds
19924
+ });
19925
+ } : void 0
19926
+ };
19927
+ }, [claimWinnings, marketId, positions, shouldFetch]);
19928
+ }
19929
+
19930
+ // src/pages/event-market/event-market.utils.ts
19931
+ var EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX = 48;
19932
+ var EVENT_MARKET_PAGE_STICKY_SPACING_PX = 32;
19933
+ var EVENT_MARKET_PAGE_STICKY_TOP_PX = EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX + EVENT_MARKET_PAGE_STICKY_SPACING_PX;
19934
+ var EVENT_MARKET_PAGE_STICKY_TOP_CSS_VAR = "--agg-event-market-sidebar-top";
19935
+ var EVENT_MARKET_PAGE_STICKY_SPACING_CSS_VAR = "--agg-event-market-sidebar-spacing";
19936
+ var toCssLength = (value, fallback) => {
19937
+ if (typeof value === "number") {
19938
+ return `${value}px`;
19939
+ }
19940
+ return value != null ? value : `${fallback}px`;
19941
+ };
19942
+ var deriveSpacingFromTop = (top) => {
19943
+ if (typeof top !== "number") {
19944
+ return void 0;
19945
+ }
19946
+ return Math.max(top - EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX, 0);
19947
+ };
19948
+ var resolveEventMarketPageStickyState = ({
19949
+ stickyOrderPanel
19950
+ }) => {
19951
+ var _a, _b;
19952
+ const isEnabled = (_a = stickyOrderPanel == null ? void 0 : stickyOrderPanel.enabled) != null ? _a : Boolean(stickyOrderPanel);
19953
+ if (!isEnabled) {
19954
+ return {
19955
+ contentClassName: cn(),
19956
+ sidebarClassName: cn("pt-4 sm:pt-6 md:pt-8 pb-10"),
19957
+ placeOrder: cn("mb-10"),
19958
+ mainClassName: cn("pt-4 sm:pt-6 md:pt-8"),
19959
+ style: {}
19960
+ };
19961
+ }
19962
+ return {
19963
+ contentClassName: cn("lg:items-stretch!"),
19964
+ sidebarClassName: cn(
19965
+ "pt-4 sm:pt-6 md:pt-8 pb-10",
19966
+ "lg:self-start lg:sticky lg:top-[var(--agg-event-market-sidebar-top)] lg:max-h-[calc(100vh-var(--agg-event-market-sidebar-top))] lg:overflow-y-auto lg:overscroll-contain",
19967
+ stickyOrderPanel == null ? void 0 : stickyOrderPanel.className
19968
+ ),
19969
+ placeOrder: cn("mb-10"),
19970
+ mainClassName: cn("pt-4 sm:pt-6 md:pt-8"),
19971
+ style: {
19972
+ [EVENT_MARKET_PAGE_STICKY_TOP_CSS_VAR]: toCssLength(
19973
+ stickyOrderPanel == null ? void 0 : stickyOrderPanel.top,
19974
+ EVENT_MARKET_PAGE_STICKY_TOP_PX
19975
+ ),
19976
+ [EVENT_MARKET_PAGE_STICKY_SPACING_CSS_VAR]: toCssLength(
19977
+ (_b = stickyOrderPanel == null ? void 0 : stickyOrderPanel.spacing) != null ? _b : deriveSpacingFromTop(stickyOrderPanel == null ? void 0 : stickyOrderPanel.top),
19978
+ EVENT_MARKET_PAGE_STICKY_SPACING_PX
19979
+ )
19980
+ }
19981
+ };
19982
+ };
19983
+
19984
+ // src/pages/event-market/index.tsx
19985
+ var import_jsx_runtime146 = require("react/jsx-runtime");
19986
+ var MOBILE_EVENT_MARKET_MEDIA_QUERY = "(max-width: 1023px)";
19987
+ var getIsMobileEventMarketViewport = () => {
19988
+ if (typeof window === "undefined") return false;
19989
+ if (typeof window.matchMedia !== "function") return false;
19990
+ return window.matchMedia(MOBILE_EVENT_MARKET_MEDIA_QUERY).matches;
19991
+ };
19992
+ var useIsMobileEventMarketViewport = () => {
19993
+ const [isMobileViewport, setIsMobileViewport] = (0, import_react33.useState)(getIsMobileEventMarketViewport);
19994
+ (0, import_react33.useEffect)(() => {
19995
+ if (typeof window === "undefined") return;
19996
+ if (typeof window.matchMedia !== "function") return;
19997
+ const mediaQueryList = window.matchMedia(MOBILE_EVENT_MARKET_MEDIA_QUERY);
19998
+ const handleChange = () => {
19999
+ setIsMobileViewport(mediaQueryList.matches);
20000
+ };
20001
+ handleChange();
20002
+ mediaQueryList.addEventListener("change", handleChange);
20003
+ return () => {
20004
+ mediaQueryList.removeEventListener("change", handleChange);
20005
+ };
20006
+ }, []);
20007
+ return isMobileViewport;
20008
+ };
20009
+ var resolveDesktopTradePlaceOrderClassNames = (classNames) => {
20010
+ const resolvedClassNames = {
20011
+ body: classNames == null ? void 0 : classNames.tradeBody,
20012
+ content: classNames == null ? void 0 : classNames.tradeContent,
20013
+ footer: classNames == null ? void 0 : classNames.tradeFooter,
20014
+ header: classNames == null ? void 0 : classNames.tradeHeader
20015
+ };
20016
+ if (!Object.values(resolvedClassNames).some(Boolean)) {
20017
+ return void 0;
20018
+ }
20019
+ return resolvedClassNames;
20020
+ };
20021
+ var resolveMobileTradePlaceOrderClassNames = (classNames) => {
20022
+ return {
20023
+ root: "rounded-t-agg-2xl rounded-b-none md:rounded-agg-2xl md:rounded-b-agg-2xl",
20024
+ body: cn("flex h-full min-h-0 flex-col", classNames == null ? void 0 : classNames.tradeBody, classNames == null ? void 0 : classNames.mobileTradeBody),
20025
+ content: cn(
20026
+ "min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
20027
+ classNames == null ? void 0 : classNames.tradeContent,
20028
+ classNames == null ? void 0 : classNames.mobileTradeContent
20029
+ ),
20030
+ footer: cn(classNames == null ? void 0 : classNames.tradeFooter, classNames == null ? void 0 : classNames.mobileTradeFooter),
20031
+ header: cn(
20032
+ "sticky top-0 z-10 bg-agg-secondary",
20033
+ classNames == null ? void 0 : classNames.tradeHeader,
20034
+ classNames == null ? void 0 : classNames.mobileTradeHeader
20035
+ )
20036
+ };
20037
+ };
20038
+ var EventMarketPageMobileTrade = ({
20039
+ classNames,
20040
+ eventTradingState,
20041
+ executionMode,
20042
+ showPlaceOrder = true,
20043
+ isOpen,
20044
+ onOpenChange,
20045
+ midpointsResult,
20046
+ onBeforePrimaryAction
20047
+ }) => {
20048
+ const labels = (0, import_hooks55.useLabels)();
20049
+ if (!showPlaceOrder) return null;
20050
+ const handleOpenChange = (nextOpen) => {
20051
+ onOpenChange(nextOpen);
20052
+ };
20053
+ const handleClose = () => {
20054
+ onOpenChange(false);
20055
+ };
20056
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(import_jsx_runtime146.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Modal, { open: isOpen, onOpenChange: handleOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(
20057
+ Modal.Container,
20058
+ {
20059
+ classNames: {
20060
+ content: "items-end p-0 sm:items-center sm:p-4",
20061
+ container: cn(
20062
+ "agg-mobile-trade-modal",
20063
+ "w-full border-0 bg-transparent shadow-none",
20064
+ classNames == null ? void 0 : classNames.mobileTradeModal
20065
+ )
20066
+ },
20067
+ children: [
20068
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Dialog4.Title, { className: "sr-only", children: labels.trading.confirmOrder }),
20069
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Dialog4.Description, { className: "sr-only", children: labels.trading.disclaimer }),
20070
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { className: "agg-mobile-trade-handle relative flex w-full flex-col items-center sm:hidden", children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
20071
+ "button",
20072
+ {
20073
+ type: "button",
20074
+ className: "absolute right-3 top-4 z-100 flex cursor-pointer items-center justify-center rounded-full p-1 text-agg-muted-foreground hover:text-agg-foreground",
20075
+ "aria-label": labels.common.close,
20076
+ onClick: handleClose,
20077
+ children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(CloseIcon, { className: "h-5 w-5" })
20078
+ }
20079
+ ) }),
20080
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
20081
+ PlaceOrder,
20082
+ {
20083
+ eventTradingState,
20084
+ executionMode,
20085
+ midpointsResult,
20086
+ onBeforePrimaryAction,
20087
+ className: cn(
20088
+ "agg-mobile-trade-panel w-full overflow-hidden rounded-t-agg-2xl sm:rounded-agg-xl",
20089
+ classNames == null ? void 0 : classNames.mobileTrade
20090
+ ),
20091
+ classNames: resolveMobileTradePlaceOrderClassNames(classNames),
20092
+ onClose: handleClose
20093
+ }
20094
+ )
20095
+ ]
20096
+ }
20097
+ ) }) });
19643
20098
  };
19644
20099
  var EventMarketPageUnavailableState = ({
19645
20100
  ariaLabel: _ariaLabel
19646
20101
  }) => {
19647
- const labels = (0, import_hooks53.useLabels)();
20102
+ const labels = (0, import_hooks55.useLabels)();
19648
20103
  return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
19649
20104
  StateMessage,
19650
20105
  {
@@ -19660,7 +20115,7 @@ var EventMarketPageUnavailableState = ({
19660
20115
  var EventMarketPageNotFoundState = ({
19661
20116
  ariaLabel: _ariaLabel
19662
20117
  }) => {
19663
- const labels = (0, import_hooks53.useLabels)();
20118
+ const labels = (0, import_hooks55.useLabels)();
19664
20119
  return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
19665
20120
  StateMessage,
19666
20121
  {
@@ -19757,26 +20212,33 @@ var EventMarketPageContent = ({
19757
20212
  showPlaceOrder,
19758
20213
  executionMode,
19759
20214
  stickyOrderPanel,
19760
- resolvedClaim
20215
+ resolvedClaim,
20216
+ onBeforePrimaryAction
19761
20217
  }) => {
19762
- const eventTradingState = (0, import_react31.useMemo)(() => (0, import_hooks53.resolveEventTradingState)(event), [event]);
20218
+ const eventTradingState = (0, import_react33.useMemo)(() => (0, import_hooks55.resolveEventTradingState)(event), [event]);
19763
20219
  const stickyOrderPanelState = resolveEventMarketPageStickyState({
19764
20220
  stickyOrderPanel
19765
20221
  });
19766
20222
  const {
19767
20223
  trading: { executionMode: configuredExecutionMode }
19768
- } = (0, import_hooks53.useSdkUiConfig)();
20224
+ } = (0, import_hooks55.useSdkUiConfig)();
19769
20225
  const resolvedExecutionMode = executionMode != null ? executionMode : configuredExecutionMode;
19770
- const [isMobileTradeOpen, setIsMobileTradeOpen] = (0, import_react31.useState)(false);
20226
+ const [isMobileTradeOpen, setIsMobileTradeOpen] = (0, import_react33.useState)(false);
19771
20227
  const isMobileViewport = useIsMobileEventMarketViewport();
19772
- const tradingContext = (0, import_hooks53.useEventTradingContext)();
19773
- const midpointsResult = (0, import_hooks53.useMidpoints)(event.venueMarkets);
19774
- const setTradeSideRef = (0, import_react31.useRef)(tradingContext == null ? void 0 : tradingContext.setTradeSide);
20228
+ const tradingContext = (0, import_hooks55.useEventTradingContext)();
20229
+ const midpointsResult = (0, import_hooks55.useMidpoints)(event.venueMarkets);
20230
+ const internalResolvedClaim = useResolvedMarketClaim({
20231
+ market: eventTradingState.primaryMarket,
20232
+ enabled: eventTradingState.kind === "resolved",
20233
+ executionMode: resolvedExecutionMode
20234
+ });
20235
+ const effectiveResolvedClaim = resolvedClaim != null ? resolvedClaim : internalResolvedClaim;
20236
+ const setTradeSideRef = (0, import_react33.useRef)(tradingContext == null ? void 0 : tradingContext.setTradeSide);
19775
20237
  setTradeSideRef.current = tradingContext == null ? void 0 : tradingContext.setTradeSide;
19776
- (0, import_react31.useEffect)(() => {
20238
+ (0, import_react33.useEffect)(() => {
19777
20239
  return () => {
19778
20240
  var _a;
19779
- (_a = setTradeSideRef.current) == null ? void 0 : _a.call(setTradeSideRef, import_hooks53.TradeSide.Buy);
20241
+ (_a = setTradeSideRef.current) == null ? void 0 : _a.call(setTradeSideRef, import_hooks55.TradeSide.Buy);
19780
20242
  };
19781
20243
  }, []);
19782
20244
  if (!event.venueMarkets.length) {
@@ -19848,8 +20310,9 @@ var EventMarketPageContent = ({
19848
20310
  {
19849
20311
  eventTradingState,
19850
20312
  executionMode: resolvedExecutionMode,
19851
- resolvedClaim,
20313
+ resolvedClaim: effectiveResolvedClaim,
19852
20314
  midpointsResult,
20315
+ onBeforePrimaryAction,
19853
20316
  className: cn(
19854
20317
  "agg-mobile-trade-panel w-full overflow-hidden",
19855
20318
  classNames == null ? void 0 : classNames.mobileTrade
@@ -19874,8 +20337,9 @@ var EventMarketPageContent = ({
19874
20337
  {
19875
20338
  eventTradingState,
19876
20339
  executionMode: resolvedExecutionMode,
19877
- resolvedClaim,
20340
+ resolvedClaim: effectiveResolvedClaim,
19878
20341
  midpointsResult,
20342
+ onBeforePrimaryAction,
19879
20343
  className: cn(stickyOrderPanelState == null ? void 0 : stickyOrderPanelState.placeOrder, classNames == null ? void 0 : classNames.trade),
19880
20344
  classNames: resolveDesktopTradePlaceOrderClassNames(classNames)
19881
20345
  }
@@ -19894,7 +20358,8 @@ var EventMarketPageContent = ({
19894
20358
  showPlaceOrder,
19895
20359
  isOpen: isMobileTradeOpen,
19896
20360
  onOpenChange: setIsMobileTradeOpen,
19897
- midpointsResult
20361
+ midpointsResult,
20362
+ onBeforePrimaryAction
19898
20363
  }
19899
20364
  ) : null
19900
20365
  ]
@@ -19908,7 +20373,7 @@ var EventMarketPage = (props) => {
19908
20373
  event: fetchedEvent,
19909
20374
  error: eventError,
19910
20375
  isLoading: isFetchingEvent
19911
- } = (0, import_hooks53.useEnrichedVenueEvent)({
20376
+ } = (0, import_hooks55.useEnrichedVenueEvent)({
19912
20377
  eventId: hasEventProp ? "" : (_a = props.eventId) != null ? _a : "",
19913
20378
  enabled: !props.isLoading && !hasEventProp && !!props.eventId
19914
20379
  });
@@ -20007,15 +20472,15 @@ var resolveInitialTabValue = (tabs, defaultActiveTab) => {
20007
20472
  };
20008
20473
 
20009
20474
  // src/pages/home/use-scroll-restoration.ts
20010
- var import_react32 = require("react");
20475
+ var import_react34 = require("react");
20011
20476
  function useScrollRestoration({
20012
20477
  enabled,
20013
20478
  scrollY,
20014
20479
  isReady
20015
20480
  }) {
20016
- const restoredRef = (0, import_react32.useRef)(false);
20017
- const [isRestoring, setIsRestoring] = (0, import_react32.useState)(enabled && scrollY > 0);
20018
- (0, import_react32.useLayoutEffect)(() => {
20481
+ const restoredRef = (0, import_react34.useRef)(false);
20482
+ const [isRestoring, setIsRestoring] = (0, import_react34.useState)(enabled && scrollY > 0);
20483
+ (0, import_react34.useLayoutEffect)(() => {
20019
20484
  if (!enabled || restoredRef.current) return;
20020
20485
  if (!isReady) return;
20021
20486
  restoredRef.current = true;
@@ -20028,15 +20493,15 @@ function useScrollRestoration({
20028
20493
  }
20029
20494
 
20030
20495
  // src/pages/home/use-home-page-modals.ts
20031
- var import_react33 = require("react");
20496
+ var import_react35 = require("react");
20032
20497
  var useHomePageModals = () => {
20033
- const [profileOpen, setProfileOpen] = (0, import_react33.useState)(false);
20034
- const [depositOpen, setDepositOpen] = (0, import_react33.useState)(false);
20035
- const [withdrawOpen, setWithdrawOpen] = (0, import_react33.useState)(false);
20036
- const onProfileClick = (0, import_react33.useCallback)(() => setProfileOpen(true), []);
20037
- const onDepositClick = (0, import_react33.useCallback)(() => setDepositOpen(true), []);
20038
- const onWithdrawClick = (0, import_react33.useCallback)(() => setWithdrawOpen(true), []);
20039
- (0, import_react33.useEffect)(() => {
20498
+ const [profileOpen, setProfileOpen] = (0, import_react35.useState)(false);
20499
+ const [depositOpen, setDepositOpen] = (0, import_react35.useState)(false);
20500
+ const [withdrawOpen, setWithdrawOpen] = (0, import_react35.useState)(false);
20501
+ const onProfileClick = (0, import_react35.useCallback)(() => setProfileOpen(true), []);
20502
+ const onDepositClick = (0, import_react35.useCallback)(() => setDepositOpen(true), []);
20503
+ const onWithdrawClick = (0, import_react35.useCallback)(() => setWithdrawOpen(true), []);
20504
+ (0, import_react35.useEffect)(() => {
20040
20505
  if (typeof window === "undefined") return;
20041
20506
  window.addEventListener(DEPOSIT_MODAL_OPEN_EVENT, onDepositClick);
20042
20507
  window.addEventListener(WITHDRAW_MODAL_OPEN_EVENT, onWithdrawClick);
@@ -20073,20 +20538,20 @@ var HomeSearchResults = ({
20073
20538
  onEventClick,
20074
20539
  onMarketClick
20075
20540
  }) => {
20076
- const labels = (0, import_hooks54.useLabels)();
20077
- const { search: searchConfig } = (0, import_hooks54.useSdkUiConfig)();
20078
- const { disabledVenues } = (0, import_hooks54.useAppConfig)();
20079
- const [activeVenueTabValue, setActiveVenueTabValue] = (0, import_react34.useState)("matched");
20541
+ const labels = (0, import_hooks56.useLabels)();
20542
+ const { search: searchConfig } = (0, import_hooks56.useSdkUiConfig)();
20543
+ const { disabledVenues } = (0, import_hooks56.useAppConfig)();
20544
+ const [activeVenueTabValue, setActiveVenueTabValue] = (0, import_react36.useState)("matched");
20080
20545
  const eventListTabs = useEventListTabs();
20081
20546
  const { headerRef, titleRef, shouldUseSelectOverflow } = useEventListTabsHeaderOverflow(eventListTabs);
20082
- const visibleVenues = (0, import_react34.useMemo)(
20083
- () => disabledVenues.length === 0 ? void 0 : (0, import_hooks54.getVisibleVenueIdsByConfig)(import_sdk18.VENUES, disabledVenues),
20547
+ const visibleVenues = (0, import_react36.useMemo)(
20548
+ () => disabledVenues.length === 0 ? void 0 : (0, import_hooks56.getVisibleVenueIdsByConfig)(import_sdk18.VENUES, disabledVenues),
20084
20549
  [disabledVenues]
20085
20550
  );
20086
- const activeVenueTab = (0, import_react34.useMemo)(() => {
20551
+ const activeVenueTab = (0, import_react36.useMemo)(() => {
20087
20552
  return eventListTabs.find((tab) => tab.value === activeVenueTabValue);
20088
20553
  }, [activeVenueTabValue, eventListTabs]);
20089
- const activeCategoryTab = (0, import_react34.useMemo)(() => {
20554
+ const activeCategoryTab = (0, import_react36.useMemo)(() => {
20090
20555
  return resolvedTabs.find((tab) => tab.value === activeTabValue);
20091
20556
  }, [activeTabValue, resolvedTabs]);
20092
20557
  const activeVenues = resolveTabVenus(activeVenueTab, visibleVenues);
@@ -20098,7 +20563,7 @@ var HomeSearchResults = ({
20098
20563
  hasNextPage,
20099
20564
  isFetchingNextPage,
20100
20565
  isPlaceholderData
20101
- } = (0, import_hooks54.useSearch)({
20566
+ } = (0, import_hooks56.useSearch)({
20102
20567
  q: query,
20103
20568
  type: "events",
20104
20569
  categoryIds: activeTabValue === ALL_CATEGORIES_TAB_VALUE ? void 0 : activeCategoryTab == null ? void 0 : activeCategoryTab.categoryIds,
@@ -20110,15 +20575,15 @@ var HomeSearchResults = ({
20110
20575
  // so debounced keystrokes don't pay reranker latency.
20111
20576
  deep: true
20112
20577
  });
20113
- const openEvents = (0, import_react34.useMemo)(() => {
20578
+ const openEvents = (0, import_react36.useMemo)(() => {
20114
20579
  let filtered = filterOpenEvents(searchResults);
20115
20580
  if (activeVenues == null ? void 0 : activeVenues.length) {
20116
20581
  filtered = filtered.filter((e) => activeVenues.includes(e.venue));
20117
20582
  }
20118
20583
  return filtered;
20119
20584
  }, [searchResults, activeVenues]);
20120
- const loadMoreRef = (0, import_react34.useRef)(null);
20121
- (0, import_react34.useEffect)(() => {
20585
+ const loadMoreRef = (0, import_react36.useRef)(null);
20586
+ (0, import_react36.useEffect)(() => {
20122
20587
  if (!hasNextPage) return;
20123
20588
  const target = loadMoreRef.current;
20124
20589
  if (!target) return;
@@ -20260,7 +20725,7 @@ var HomePage = ({
20260
20725
  stickyOrderPanel
20261
20726
  }) => {
20262
20727
  var _a, _b, _c, _d;
20263
- const labels = (0, import_hooks54.useLabels)();
20728
+ const labels = (0, import_hooks56.useLabels)();
20264
20729
  const {
20265
20730
  search: {
20266
20731
  value: searchValue,
@@ -20270,11 +20735,11 @@ var HomePage = ({
20270
20735
  onSelect: onSelectEventInternal
20271
20736
  },
20272
20737
  trading: { executionMode }
20273
- } = (0, import_hooks54.useSdkUiConfig)();
20274
- const { capture, consume } = (0, import_hooks54.useEventListState)();
20275
- const [snapshot] = (0, import_react34.useState)(() => consume());
20276
- const eventListStateRef = (0, import_react34.useRef)(null);
20277
- const handleSelectEvent = (0, import_react34.useCallback)(
20738
+ } = (0, import_hooks56.useSdkUiConfig)();
20739
+ const { capture, consume } = (0, import_hooks56.useEventListState)();
20740
+ const [snapshot] = (0, import_react36.useState)(() => consume());
20741
+ const eventListStateRef = (0, import_react36.useRef)(null);
20742
+ const handleSelectEvent = (0, import_react36.useCallback)(
20278
20743
  (event) => {
20279
20744
  var _a2, _b2, _c2, _d2;
20280
20745
  capture({
@@ -20293,14 +20758,14 @@ var HomePage = ({
20293
20758
  );
20294
20759
  const hasCustomTabs = !!tabs && tabs.length > 0;
20295
20760
  const normalizedSearchValue = searchValue.trim();
20296
- const [stickySelectedEvent, setStickySelectedEvent] = (0, import_react34.useState)(
20761
+ const [stickySelectedEvent, setStickySelectedEvent] = (0, import_react36.useState)(
20297
20762
  selectedEvent
20298
20763
  );
20299
- const [debouncedSearchValue, setDebouncedSearchValue] = (0, import_react34.useState)(() => {
20764
+ const [debouncedSearchValue, setDebouncedSearchValue] = (0, import_react36.useState)(() => {
20300
20765
  return normalizedSearchValue.length >= MIN_SEARCH_LENGTH2 ? normalizedSearchValue : "";
20301
20766
  });
20302
- const [isMobileSearchViewport, setIsMobileSearchViewport] = (0, import_react34.useState)(false);
20303
- (0, import_react34.useEffect)(() => {
20767
+ const [isMobileSearchViewport, setIsMobileSearchViewport] = (0, import_react36.useState)(false);
20768
+ (0, import_react36.useEffect)(() => {
20304
20769
  if (typeof window === "undefined") return;
20305
20770
  const mediaQueryList = window.matchMedia(MOBILE_HOME_SEARCH_MEDIA_QUERY);
20306
20771
  const handleMediaQueryChange = (event) => {
@@ -20318,7 +20783,7 @@ var HomePage = ({
20318
20783
  mediaQueryList.removeListener(handleMediaQueryChange);
20319
20784
  };
20320
20785
  }, []);
20321
- (0, import_react34.useEffect)(() => {
20786
+ (0, import_react36.useEffect)(() => {
20322
20787
  if (normalizedSearchValue.length < MIN_SEARCH_LENGTH2) {
20323
20788
  setDebouncedSearchValue("");
20324
20789
  return;
@@ -20330,7 +20795,7 @@ var HomePage = ({
20330
20795
  window.clearTimeout(timeoutId);
20331
20796
  };
20332
20797
  }, [normalizedSearchValue]);
20333
- (0, import_react34.useEffect)(() => {
20798
+ (0, import_react36.useEffect)(() => {
20334
20799
  if (selectedEvent) {
20335
20800
  setStickySelectedEvent(selectedEvent);
20336
20801
  return;
@@ -20341,34 +20806,34 @@ var HomePage = ({
20341
20806
  }, [isShowingAllResults, normalizedSearchValue, selectedEvent]);
20342
20807
  const resolvedSelectedEvent = selectedEvent != null ? selectedEvent : stickySelectedEvent;
20343
20808
  const resolvedAllCategoryTabLabel = allCategoryTabLabel === DEFAULT_ALL_CATEGORY_TAB_LABEL ? labels.home.trending : allCategoryTabLabel;
20344
- const { categories } = (0, import_hooks54.useCategories)({
20809
+ const { categories } = (0, import_hooks56.useCategories)({
20345
20810
  limit: categoriesLimit,
20346
20811
  enabled: !hasCustomTabs
20347
20812
  });
20348
- const categoryTabs = (0, import_react34.useMemo)(() => {
20813
+ const categoryTabs = (0, import_react36.useMemo)(() => {
20349
20814
  return resolveCategoryTabs(categories, resolvedAllCategoryTabLabel);
20350
20815
  }, [categories, resolvedAllCategoryTabLabel]);
20351
- const resolvedTabs = (0, import_react34.useMemo)(() => {
20816
+ const resolvedTabs = (0, import_react36.useMemo)(() => {
20352
20817
  if (hasCustomTabs && tabs) return tabs;
20353
20818
  return categoryTabs;
20354
20819
  }, [categoryTabs, hasCustomTabs, tabs]);
20355
20820
  const resolvedEventSectionItems = eventSectionItems && eventSectionItems.length > 0 ? eventSectionItems : getDefaultEventSectionItems(labels);
20356
- const [activeTabValue, setActiveTabValue] = (0, import_react34.useState)(() => {
20821
+ const [activeTabValue, setActiveTabValue] = (0, import_react36.useState)(() => {
20357
20822
  if (snapshot == null ? void 0 : snapshot.categoryTab) {
20358
20823
  return snapshot.categoryTab;
20359
20824
  }
20360
20825
  return resolveInitialTabValue(resolvedTabs, defaultActiveTab);
20361
20826
  });
20362
- const activeTabValueRef = (0, import_react34.useRef)(activeTabValue);
20827
+ const activeTabValueRef = (0, import_react36.useRef)(activeTabValue);
20363
20828
  activeTabValueRef.current = activeTabValue;
20364
- (0, import_react34.useEffect)(() => {
20829
+ (0, import_react36.useEffect)(() => {
20365
20830
  setActiveTabValue((currentValue) => {
20366
20831
  const hasCurrentValue = resolvedTabs.some((tab) => tab.value === currentValue);
20367
20832
  if (hasCurrentValue) return currentValue;
20368
20833
  return resolveInitialTabValue(resolvedTabs, defaultActiveTab);
20369
20834
  });
20370
20835
  }, [defaultActiveTab, resolvedTabs]);
20371
- const tabsItems = (0, import_react34.useMemo)(() => {
20836
+ const tabsItems = (0, import_react36.useMemo)(() => {
20372
20837
  return resolvedTabs.map((tab) => {
20373
20838
  const isActive = tab.value === activeTabValue;
20374
20839
  return {
@@ -20388,10 +20853,10 @@ var HomePage = ({
20388
20853
  };
20389
20854
  });
20390
20855
  }, [activeTabValue, resolvedTabs]);
20391
- const activeTab = (0, import_react34.useMemo)(() => {
20856
+ const activeTab = (0, import_react36.useMemo)(() => {
20392
20857
  return resolvedTabs.find((tab) => tab.value === activeTabValue);
20393
20858
  }, [activeTabValue, resolvedTabs]);
20394
- const resolvedSectionItems = (0, import_react34.useMemo)(() => {
20859
+ const resolvedSectionItems = (0, import_react36.useMemo)(() => {
20395
20860
  var _a2, _b2, _c2;
20396
20861
  if (activeTabValue === ALL_CATEGORIES_TAB_VALUE) {
20397
20862
  return resolvedEventSectionItems;
@@ -20551,9 +21016,9 @@ var HomePage = ({
20551
21016
  HomePage.displayName = "HomePage";
20552
21017
 
20553
21018
  // src/pages/user-profile/index.tsx
20554
- var import_hooks59 = require("@agg-build/hooks");
21019
+ var import_hooks61 = require("@agg-build/hooks");
20555
21020
  var import_sdk19 = require("@agg-build/sdk");
20556
- var import_react36 = require("react");
21021
+ var import_react38 = require("react");
20557
21022
 
20558
21023
  // src/pages/user-profile/chain-display.ts
20559
21024
  var CHAIN_ID_TO_LABEL = {
@@ -20576,7 +21041,7 @@ var formatChainIdLabel = (chainId) => {
20576
21041
  };
20577
21042
 
20578
21043
  // src/pages/user-profile/components/available-balance-card.tsx
20579
- var import_hooks55 = require("@agg-build/hooks");
21044
+ var import_hooks57 = require("@agg-build/hooks");
20580
21045
  var import_jsx_runtime148 = require("react/jsx-runtime");
20581
21046
  var BASE_URL = "https://assets.snagsolutions.io";
20582
21047
  var CHAIN_ID_TO_ICON_URL = {
@@ -20631,7 +21096,7 @@ var AvailableBalanceCard = ({
20631
21096
  isLoading = false,
20632
21097
  className
20633
21098
  }) => {
20634
- const labels = (0, import_hooks55.useLabels)();
21099
+ const labels = (0, import_hooks57.useLabels)();
20635
21100
  const balanceLabels = labels.userProfile.balance;
20636
21101
  const resolvedLabel = label2 != null ? label2 : balanceLabels.availableBalance;
20637
21102
  const hasPaperBalance = chains.some(isPaperChain);
@@ -20790,8 +21255,8 @@ var AvailableBalanceCard = ({
20790
21255
  AvailableBalanceCard.displayName = "AvailableBalanceCard";
20791
21256
 
20792
21257
  // src/pages/user-profile/components/positions-activity.tsx
20793
- var import_hooks57 = require("@agg-build/hooks");
20794
- var import_react35 = require("react");
21258
+ var import_hooks59 = require("@agg-build/hooks");
21259
+ var import_react37 = require("react");
20795
21260
 
20796
21261
  // src/pages/user-profile/user-profile.constants.ts
20797
21262
  var USER_PROFILE_TAB_POSITIONS = "positions";
@@ -21640,7 +22105,7 @@ var EmptyState = ({ title: title2, description, className }) => {
21640
22105
  EmptyState.displayName = "EmptyState";
21641
22106
 
21642
22107
  // src/pages/user-profile/components/position-row.tsx
21643
- var import_hooks56 = require("@agg-build/hooks");
22108
+ var import_hooks58 = require("@agg-build/hooks");
21644
22109
  var import_jsx_runtime151 = require("react/jsx-runtime");
21645
22110
  var shouldUseNativeLinkNavigation2 = (event) => {
21646
22111
  return event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button === 1;
@@ -21778,7 +22243,7 @@ var PositionRow = ({
21778
22243
  onClaim,
21779
22244
  isClaiming = false
21780
22245
  }) => {
21781
- const labels = (0, import_hooks56.useLabels)().userProfile.positions;
22246
+ const labels = (0, import_hooks58.useLabels)().userProfile.positions;
21782
22247
  const model = toPositionRowViewModel(position, {
21783
22248
  avgPrefix: labels.avgPrefix,
21784
22249
  nowPrefix: labels.nowPrefix,
@@ -21832,7 +22297,7 @@ var PositionRow = ({
21832
22297
  /* @__PURE__ */ (0, import_jsx_runtime151.jsx)("div", { className: "agg-position-image flex h-10 w-10 shrink-0 items-center justify-center md:h-15 md:w-15", children: /* @__PURE__ */ (0, import_jsx_runtime151.jsx)(
21833
22298
  RemoteImage,
21834
22299
  {
21835
- src: (0, import_hooks56.optimizedImageUrl)(model.thumbnailSrc, 60),
22300
+ src: (0, import_hooks58.optimizedImageUrl)(model.thumbnailSrc, 60),
21836
22301
  alt: "",
21837
22302
  className: "h-full w-full rounded-agg-sm object-cover"
21838
22303
  }
@@ -21958,7 +22423,7 @@ var tabItems = [
21958
22423
  // Restore by re-adding USER_PROFILE_TAB_OPEN_ORDERS here and the renderer below.
21959
22424
  { value: USER_PROFILE_TAB_ACTIVITY, label: "Activity" }
21960
22425
  ];
21961
- var TabRowsSkeleton = ({ ariaLabel }) => /* @__PURE__ */ (0, import_jsx_runtime152.jsx)("div", { role: "status", "aria-label": ariaLabel, className: "flex flex-col gap-3 sm:gap-4", children: Array.from({ length: 3 }).map((_, index, acc) => /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)(import_react35.Fragment, { children: [
22426
+ var TabRowsSkeleton = ({ ariaLabel }) => /* @__PURE__ */ (0, import_jsx_runtime152.jsx)("div", { role: "status", "aria-label": ariaLabel, className: "flex flex-col gap-3 sm:gap-4", children: Array.from({ length: 3 }).map((_, index, acc) => /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)(import_react37.Fragment, { children: [
21962
22427
  /* @__PURE__ */ (0, import_jsx_runtime152.jsx)("div", { className: "h-14 rounded-agg-sm bg-agg-secondary-hover/80 sm:h-16" }, index),
21963
22428
  index < acc.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime152.jsx)("div", { className: "agg-position-divider h-px w-full shrink-0 bg-agg-separator", "aria-hidden": true }) : null
21964
22429
  ] }, index)) });
@@ -21991,9 +22456,9 @@ var PositionsActivity = ({
21991
22456
  initialPositionFilter = "active",
21992
22457
  className
21993
22458
  }) => {
21994
- const positionsLabels = (0, import_hooks57.useLabels)().userProfile.positions;
22459
+ const positionsLabels = (0, import_hooks59.useLabels)().userProfile.positions;
21995
22460
  const isTabControlled = tab !== void 0;
21996
- const [internalActiveTab, setInternalActiveTab] = (0, import_react35.useState)(
22461
+ const [internalActiveTab, setInternalActiveTab] = (0, import_react37.useState)(
21997
22462
  tab != null ? tab : USER_PROFILE_TAB_POSITIONS
21998
22463
  );
21999
22464
  const activeTab = isTabControlled ? tab : internalActiveTab;
@@ -22001,19 +22466,19 @@ var PositionsActivity = ({
22001
22466
  if (!isTabControlled) setInternalActiveTab(next);
22002
22467
  onTabChange == null ? void 0 : onTabChange(next);
22003
22468
  };
22004
- const [positionFilter, setPositionFilter] = (0, import_react35.useState)(initialPositionFilter);
22005
- const [searchValue, setSearchValue] = (0, import_react35.useState)("");
22006
- const [isSearchFocused, setIsSearchFocused] = (0, import_react35.useState)(false);
22007
- const [locallyClaimedPositionIds, setLocallyClaimedPositionIds] = (0, import_react35.useState)(
22469
+ const [positionFilter, setPositionFilter] = (0, import_react37.useState)(initialPositionFilter);
22470
+ const [searchValue, setSearchValue] = (0, import_react37.useState)("");
22471
+ const [isSearchFocused, setIsSearchFocused] = (0, import_react37.useState)(false);
22472
+ const [locallyClaimedPositionIds, setLocallyClaimedPositionIds] = (0, import_react37.useState)(
22008
22473
  () => /* @__PURE__ */ new Set()
22009
22474
  );
22010
- const positionsLoadMoreRef = (0, import_react35.useRef)(null);
22011
- const activitiesLoadMoreRef = (0, import_react35.useRef)(null);
22012
- const rowsScrollRef = (0, import_react35.useRef)(null);
22475
+ const positionsLoadMoreRef = (0, import_react37.useRef)(null);
22476
+ const activitiesLoadMoreRef = (0, import_react37.useRef)(null);
22477
+ const rowsScrollRef = (0, import_react37.useRef)(null);
22013
22478
  const isPositionsTab = activeTab === USER_PROFILE_TAB_POSITIONS;
22014
22479
  const isActivityTab = activeTab === USER_PROFILE_TAB_ACTIVITY;
22015
22480
  const isClosedPositionsFilter = isPositionsTab && positionFilter === "closed";
22016
- const positionsForCurrentFilter = (0, import_react35.useMemo)(() => {
22481
+ const positionsForCurrentFilter = (0, import_react37.useMemo)(() => {
22017
22482
  if (positionFilter === "active") {
22018
22483
  return activePositions.filter((position) => !locallyClaimedPositionIds.has(position.id));
22019
22484
  }
@@ -22030,7 +22495,7 @@ var PositionsActivity = ({
22030
22495
  }
22031
22496
  return Array.from(byId.values());
22032
22497
  }, [activePositions, closedPositions, locallyClaimedPositionIds, positionFilter]);
22033
- const filteredPositions = (0, import_react35.useMemo)(() => {
22498
+ const filteredPositions = (0, import_react37.useMemo)(() => {
22034
22499
  if (!searchValue.trim()) return positionsForCurrentFilter;
22035
22500
  const q = searchValue.toLowerCase();
22036
22501
  return positionsForCurrentFilter.filter((p) => p.title.toLowerCase().includes(q));
@@ -22055,7 +22520,7 @@ var PositionsActivity = ({
22055
22520
  const isLoadingMorePositions = positionFilter === "active" ? isLoadingMoreActivePositions : isLoadingMoreClosedPositions;
22056
22521
  const loadMorePositions = positionFilter === "active" ? onLoadMoreActivePositions : onLoadMoreClosedPositions;
22057
22522
  const filteredActivities = activities;
22058
- const searchResults = (0, import_react35.useMemo)(() => {
22523
+ const searchResults = (0, import_react37.useMemo)(() => {
22059
22524
  if (!isPositionsTab || !searchValue.trim()) return [];
22060
22525
  return filteredPositions.slice(0, 5).map((position) => ({
22061
22526
  id: position.id,
@@ -22073,11 +22538,11 @@ var PositionsActivity = ({
22073
22538
  const handleSearchChange = (event) => {
22074
22539
  setSearchValue(event.target.value);
22075
22540
  };
22076
- (0, import_react35.useEffect)(() => {
22541
+ (0, import_react37.useEffect)(() => {
22077
22542
  if (isPositionsTab) return;
22078
22543
  setIsSearchFocused(false);
22079
22544
  }, [isPositionsTab]);
22080
- (0, import_react35.useEffect)(() => {
22545
+ (0, import_react37.useEffect)(() => {
22081
22546
  if (!isPositionsTab || !hasMorePositions) return;
22082
22547
  const target = positionsLoadMoreRef.current;
22083
22548
  if (!target || !loadMorePositions) return;
@@ -22099,7 +22564,7 @@ var PositionsActivity = ({
22099
22564
  isPositionsTab,
22100
22565
  loadMorePositions
22101
22566
  ]);
22102
- (0, import_react35.useEffect)(() => {
22567
+ (0, import_react37.useEffect)(() => {
22103
22568
  if (!isActivityTab || !hasMoreActivities) return;
22104
22569
  const target = activitiesLoadMoreRef.current;
22105
22570
  if (!target || !onLoadMoreActivities) return;
@@ -22218,7 +22683,7 @@ var PositionsActivity = ({
22218
22683
  /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(
22219
22684
  "img",
22220
22685
  {
22221
- src: (0, import_hooks57.optimizedImageUrl)(item.thumbnailSrc, 48),
22686
+ src: (0, import_hooks59.optimizedImageUrl)(item.thumbnailSrc, 48),
22222
22687
  alt: "",
22223
22688
  className: "size-12 shrink-0 rounded-agg-lg object-cover"
22224
22689
  }
@@ -22326,7 +22791,7 @@ var PositionsActivity = ({
22326
22791
  }
22327
22792
  ) : filteredPositions.length > 0 ? filteredPositions.map((position, index) => {
22328
22793
  var _a;
22329
- return /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)(import_react35.Fragment, { children: [
22794
+ return /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)(import_react37.Fragment, { children: [
22330
22795
  index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(
22331
22796
  "div",
22332
22797
  {
@@ -22371,7 +22836,7 @@ var PositionsActivity = ({
22371
22836
  title: "Unable to load activity",
22372
22837
  description: "Please try again in a moment."
22373
22838
  }
22374
- ) : filteredActivities.length > 0 ? filteredActivities.map((activity, index) => /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)(import_react35.Fragment, { children: [
22839
+ ) : filteredActivities.length > 0 ? filteredActivities.map((activity, index) => /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)(import_react37.Fragment, { children: [
22375
22840
  index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(
22376
22841
  "div",
22377
22842
  {
@@ -22461,7 +22926,7 @@ var PositionsValueCard = ({
22461
22926
  PositionsValueCard.displayName = "PositionsValueCard";
22462
22927
 
22463
22928
  // src/pages/user-profile/components/user-info-card.tsx
22464
- var import_hooks58 = require("@agg-build/hooks");
22929
+ var import_hooks60 = require("@agg-build/hooks");
22465
22930
 
22466
22931
  // src/pages/user-profile/components/default-avatar.tsx
22467
22932
  var import_jsx_runtime154 = require("react/jsx-runtime");
@@ -22520,7 +22985,7 @@ var UserInfoCard = ({
22520
22985
  className
22521
22986
  }) => {
22522
22987
  var _a;
22523
- const labels = (0, import_hooks58.useLabels)();
22988
+ const labels = (0, import_hooks60.useLabels)();
22524
22989
  const wallets = (_a = user.connectedWallets) != null ? _a : [];
22525
22990
  const hasWallets = wallets.length > 0;
22526
22991
  return /* @__PURE__ */ (0, import_jsx_runtime155.jsxs)(
@@ -22536,7 +23001,7 @@ var UserInfoCard = ({
22536
23001
  /* @__PURE__ */ (0, import_jsx_runtime155.jsx)("div", { className: "agg-profile-avatar shrink-0", children: user.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime155.jsx)(
22537
23002
  RemoteImage,
22538
23003
  {
22539
- src: (0, import_hooks58.optimizedImageUrl)(user.avatarUrl, 120),
23004
+ src: (0, import_hooks60.optimizedImageUrl)(user.avatarUrl, 120),
22540
23005
  alt: user.username,
22541
23006
  className: "h-20 w-20 rounded-full object-cover sm:h-[120px] sm:w-[120px]"
22542
23007
  }
@@ -23032,10 +23497,6 @@ function buildVenueShareBreakdown(outcome) {
23032
23497
  sharesLabel: `${twoDecimalNumberFormatter.format(row.size)} shares`
23033
23498
  }));
23034
23499
  }
23035
- var toClaimError = (err) => {
23036
- if (err instanceof Error) return err;
23037
- return new Error(String(err));
23038
- };
23039
23500
  var UserProfilePage = ({
23040
23501
  user,
23041
23502
  balanceChainsOverride,
@@ -23085,84 +23546,69 @@ var UserProfilePage = ({
23085
23546
  classNames,
23086
23547
  onError
23087
23548
  }) => {
23088
- const [isHydrated, setIsHydrated] = (0, import_react36.useState)(false);
23089
- (0, import_react36.useEffect)(() => {
23549
+ const [isHydrated, setIsHydrated] = (0, import_react38.useState)(false);
23550
+ (0, import_react38.useEffect)(() => {
23090
23551
  setIsHydrated(true);
23091
23552
  }, []);
23092
- const { user: currentUser, isAuthenticated } = (0, import_hooks59.useAggAuthState)();
23093
- const { isDepositBlocked } = (0, import_hooks59.useGeoBlock)();
23094
- const balanceState = (0, import_hooks59.useAggBalance)();
23095
- const client = (0, import_hooks59.useAggClient)();
23096
- const labels = (0, import_hooks59.useLabels)();
23553
+ const { user: currentUser, isAuthenticated } = (0, import_hooks61.useAggAuthState)();
23554
+ const { isDepositBlocked } = (0, import_hooks61.useGeoBlock)();
23555
+ const balanceState = (0, import_hooks61.useAggBalance)();
23556
+ const client = (0, import_hooks61.useAggClient)();
23557
+ const labels = (0, import_hooks61.useLabels)();
23097
23558
  const {
23098
23559
  trading: { executionMode: configuredExecutionMode }
23099
- } = (0, import_hooks59.useSdkUiConfig)();
23100
- const claimNotificationLabels = labels.notifications.claim;
23101
- const toastCtx = useOptionalToast();
23102
- const queryClient = (0, import_hooks59.useQueryClient)();
23103
- const redeemMutation = (0, import_hooks59.useRedeem)();
23104
- const [internalCancellingIds, setInternalCancellingIds] = (0, import_react36.useState)({});
23105
- const [activeRedeems, setActiveRedeems] = (0, import_react36.useState)({});
23106
- const activeClaimKeysRef = (0, import_react36.useRef)(/* @__PURE__ */ new Set());
23107
- const pendingClaimToastIdsRef = (0, import_react36.useRef)({});
23108
- const submittedClaimToastKeysRef = (0, import_react36.useRef)(/* @__PURE__ */ new Set());
23109
- const [submittingClaimKeys, setSubmittingClaimKeys] = (0, import_react36.useState)({});
23110
- const lifecycleInputs = (0, import_react36.useMemo)(
23111
- () => Object.values(activeRedeems),
23112
- [activeRedeems]
23113
- );
23114
- const lifecycleStates = (0, import_hooks59.useRedeemLifecycles)(lifecycleInputs);
23115
- const internalClaimingIds = (0, import_react36.useMemo)(() => {
23116
- const out = __spreadValues({}, submittingClaimKeys);
23117
- for (const [claimKey, active] of Object.entries(activeRedeems)) {
23118
- const state = lifecycleStates[active.redeemId];
23119
- if (!state || !state.terminal) out[claimKey] = true;
23120
- }
23121
- return out;
23122
- }, [activeRedeems, lifecycleStates, submittingClaimKeys]);
23123
- const [profileUser, setProfileUser] = (0, import_react36.useState)(void 0);
23560
+ } = (0, import_hooks61.useSdkUiConfig)();
23561
+ const queryClient = (0, import_hooks61.useQueryClient)();
23562
+ const [internalCancellingIds, setInternalCancellingIds] = (0, import_react38.useState)({});
23563
+ const { claim: startClaim, claimingKeys } = useClaimWinnings({
23564
+ onClaim,
23565
+ onClaimResult,
23566
+ onClaimSubmitError,
23567
+ externalClaimingKeys: claimingPositionKeys
23568
+ });
23569
+ const [profileUser, setProfileUser] = (0, import_react38.useState)(void 0);
23124
23570
  const shouldUseHookData = !user;
23125
- const connectedVenues = (0, import_react36.useMemo)(() => {
23571
+ const connectedVenues = (0, import_react38.useMemo)(() => {
23126
23572
  var _a;
23127
23573
  if (!shouldUseHookData) return [];
23128
23574
  const fromBalance = (_a = balanceState.connectedVenues) != null ? _a : [];
23129
23575
  return [...new Set(fromBalance)].sort((a, b) => a.localeCompare(b));
23130
23576
  }, [balanceState, shouldUseHookData]);
23131
- const [positionFilter, setPositionFilter] = (0, import_react36.useState)(initialPositionFilter);
23577
+ const [positionFilter, setPositionFilter] = (0, import_react38.useState)(initialPositionFilter);
23132
23578
  const resolvedExecutionMode = executionMode != null ? executionMode : configuredExecutionMode;
23133
23579
  const queryExecutionMode = resolvedExecutionMode === "paper" ? "paper" : void 0;
23134
- const activePositionsQuery = (0, import_hooks59.useExecutionPositions)({
23580
+ const activePositionsQuery = (0, import_hooks61.useExecutionPositions)({
23135
23581
  enabled: shouldUseHookData && isAuthenticated,
23136
23582
  status: "active",
23137
23583
  limit: 25,
23138
23584
  mode: queryExecutionMode
23139
23585
  });
23140
- const closedPositionsQuery = (0, import_hooks59.useExecutionPositions)({
23586
+ const closedPositionsQuery = (0, import_hooks61.useExecutionPositions)({
23141
23587
  enabled: shouldUseHookData && isAuthenticated,
23142
23588
  status: "closed",
23143
23589
  limit: 25,
23144
23590
  mode: queryExecutionMode
23145
23591
  });
23146
- const handlePositionFilterChange = (0, import_react36.useCallback)(
23592
+ const handlePositionFilterChange = (0, import_react38.useCallback)(
23147
23593
  (filter) => {
23148
23594
  setPositionFilter(filter);
23149
23595
  onPositionFilterChangeProp == null ? void 0 : onPositionFilterChangeProp(filter);
23150
23596
  },
23151
23597
  [onPositionFilterChangeProp]
23152
23598
  );
23153
- (0, import_react36.useEffect)(() => {
23599
+ (0, import_react38.useEffect)(() => {
23154
23600
  setPositionFilter(initialPositionFilter);
23155
23601
  }, [initialPositionFilter]);
23156
- const ordersQuery = (0, import_hooks59.useExecutionOrders)({
23602
+ const ordersQuery = (0, import_hooks61.useExecutionOrders)({
23157
23603
  enabled: shouldUseHookData && isAuthenticated,
23158
23604
  limit: 25,
23159
23605
  mode: queryExecutionMode
23160
23606
  });
23161
- const activityQuery = (0, import_hooks59.useUserActivity)({
23607
+ const activityQuery = (0, import_hooks61.useUserActivity)({
23162
23608
  enabled: shouldUseHookData && isAuthenticated,
23163
23609
  limit: 25
23164
23610
  });
23165
- const handleCancelOrder = (0, import_react36.useCallback)(
23611
+ const handleCancelOrder = (0, import_react38.useCallback)(
23166
23612
  (order) => __async(null, null, function* () {
23167
23613
  if (onCancelOrder) {
23168
23614
  onCancelOrder(order);
@@ -23182,208 +23628,18 @@ var UserProfilePage = ({
23182
23628
  }),
23183
23629
  [client, onCancelOrder, queryClient]
23184
23630
  );
23185
- const invalidateClaimUiState = (0, import_react36.useCallback)(() => {
23186
- (0, import_hooks59.invalidateBalanceQueries)(queryClient);
23187
- (0, import_hooks59.invalidatePositionQueries)(queryClient);
23188
- queryClient.invalidateQueries({
23189
- queryKey: import_hooks59.executionKeys.claimablePositionsCount(),
23190
- refetchType: "active"
23191
- });
23192
- (0, import_hooks59.invalidateUserActivityQueries)(queryClient);
23193
- }, [queryClient]);
23194
- const handleClaimPosition = (0, import_react36.useCallback)(
23195
- (position) => __async(null, null, function* () {
23631
+ const handleClaimPosition = (0, import_react38.useCallback)(
23632
+ (position) => {
23196
23633
  var _a, _b;
23197
- const claimKey = (_a = position.marketId) != null ? _a : position.id;
23198
- if (activeClaimKeysRef.current.has(claimKey) || (claimingPositionKeys == null ? void 0 : claimingPositionKeys[claimKey]) || internalClaimingIds[claimKey]) {
23199
- return;
23200
- }
23201
- activeClaimKeysRef.current.add(claimKey);
23202
- setSubmittingClaimKeys((prev) => __spreadProps(__spreadValues({}, prev), { [claimKey]: true }));
23203
- const pendingToastId = toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.pendingMessage, {
23204
- title: claimNotificationLabels.pendingTitle,
23205
- tone: "info"
23634
+ return startClaim({
23635
+ claimKey: (_a = position.marketId) != null ? _a : position.id,
23636
+ winningOutcomeIds: (_b = position.winningOutcomeIds) != null ? _b : [],
23637
+ payload: position
23206
23638
  });
23207
- if (pendingToastId != null) {
23208
- pendingClaimToastIdsRef.current[claimKey] = pendingToastId;
23209
- }
23210
- if (onClaim) {
23211
- try {
23212
- yield onClaim(position);
23213
- const pendingId = pendingClaimToastIdsRef.current[claimKey];
23214
- if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
23215
- delete pendingClaimToastIdsRef.current[claimKey];
23216
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.successMessage, {
23217
- title: claimNotificationLabels.successTitle,
23218
- tone: "success"
23219
- });
23220
- } catch (err) {
23221
- const error = toClaimError(err);
23222
- console.error("[UserProfilePage] redeem failed", error);
23223
- const pendingId = pendingClaimToastIdsRef.current[claimKey];
23224
- if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
23225
- delete pendingClaimToastIdsRef.current[claimKey];
23226
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
23227
- title: claimNotificationLabels.failedTitle,
23228
- tone: "error"
23229
- });
23230
- onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
23231
- throw error;
23232
- } finally {
23233
- invalidateClaimUiState();
23234
- activeClaimKeysRef.current.delete(claimKey);
23235
- setSubmittingClaimKeys((prev) => {
23236
- const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
23237
- return rest;
23238
- });
23239
- }
23240
- return;
23241
- }
23242
- const venueMarketOutcomeIds = (_b = position.winningOutcomeIds) != null ? _b : [];
23243
- if (venueMarketOutcomeIds.length === 0) {
23244
- const error = new Error(claimNotificationLabels.missingOutcomeMessage);
23245
- console.error("[UserProfilePage] redeem failed", error);
23246
- const pendingId = pendingClaimToastIdsRef.current[claimKey];
23247
- if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
23248
- delete pendingClaimToastIdsRef.current[claimKey];
23249
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
23250
- title: claimNotificationLabels.failedTitle,
23251
- tone: "error"
23252
- });
23253
- onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
23254
- invalidateClaimUiState();
23255
- activeClaimKeysRef.current.delete(claimKey);
23256
- setSubmittingClaimKeys((prev) => {
23257
- const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
23258
- return rest;
23259
- });
23260
- throw error;
23261
- }
23262
- try {
23263
- const response = yield redeemMutation.mutateAsync({ venueMarketOutcomeIds });
23264
- const expectedOutcomeIds = [];
23265
- const preFailedOutcomeIds = [];
23266
- const preFailedReasons = {};
23267
- const preConfirmedOutcomeIds = [];
23268
- const preConfirmedTxHashes = {};
23269
- for (const result of response.results) {
23270
- if (result.status === "submitted") {
23271
- expectedOutcomeIds.push(result.venueMarketOutcomeId);
23272
- } else if (result.status === "confirmed") {
23273
- preConfirmedOutcomeIds.push(result.venueMarketOutcomeId);
23274
- preConfirmedTxHashes[result.venueMarketOutcomeId] = result.txHash;
23275
- } else if (result.status === "ineligible" || result.status === "rejected") {
23276
- preFailedOutcomeIds.push(result.venueMarketOutcomeId);
23277
- preFailedReasons[result.venueMarketOutcomeId] = result.reason;
23278
- }
23279
- }
23280
- if (expectedOutcomeIds.length > 0) {
23281
- const pendingId = pendingClaimToastIdsRef.current[claimKey];
23282
- if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
23283
- delete pendingClaimToastIdsRef.current[claimKey];
23284
- submittedClaimToastKeysRef.current.add(claimKey);
23285
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.submittedMessage, {
23286
- title: claimNotificationLabels.submittedTitle,
23287
- tone: "success"
23288
- });
23289
- }
23290
- setActiveRedeems((prev) => __spreadProps(__spreadValues({}, prev), {
23291
- [claimKey]: {
23292
- redeemId: response.redeemId,
23293
- expectedOutcomeIds,
23294
- preFailedOutcomeIds,
23295
- preFailedReasons,
23296
- preConfirmedOutcomeIds,
23297
- preConfirmedTxHashes
23298
- }
23299
- }));
23300
- yield queryClient.invalidateQueries({ queryKey: ["current-user"] });
23301
- } catch (err) {
23302
- const error = toClaimError(err);
23303
- console.error("[UserProfilePage] redeem failed", error);
23304
- const pendingId = pendingClaimToastIdsRef.current[claimKey];
23305
- if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
23306
- delete pendingClaimToastIdsRef.current[claimKey];
23307
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
23308
- title: claimNotificationLabels.failedTitle,
23309
- tone: "error"
23310
- });
23311
- onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
23312
- throw error;
23313
- } finally {
23314
- activeClaimKeysRef.current.delete(claimKey);
23315
- setSubmittingClaimKeys((prev) => {
23316
- const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
23317
- return rest;
23318
- });
23319
- }
23320
- }),
23321
- [
23322
- claimingPositionKeys,
23323
- claimNotificationLabels,
23324
- invalidateClaimUiState,
23325
- internalClaimingIds,
23326
- onClaim,
23327
- onClaimSubmitError,
23328
- queryClient,
23329
- redeemMutation,
23330
- toastCtx
23331
- ]
23639
+ },
23640
+ [startClaim]
23332
23641
  );
23333
- const firedTerminalRef = (0, import_react36.useRef)({});
23334
- (0, import_react36.useEffect)(() => {
23335
- var _a, _b;
23336
- for (const [claimKey, active] of Object.entries(activeRedeems)) {
23337
- const state = lifecycleStates[active.redeemId];
23338
- if (!state || !state.terminal) continue;
23339
- if (firedTerminalRef.current[active.redeemId]) continue;
23340
- firedTerminalRef.current[active.redeemId] = true;
23341
- onClaimResult == null ? void 0 : onClaimResult(claimKey, {
23342
- allConfirmed: state.allConfirmed,
23343
- anyFailed: state.anyFailed,
23344
- errorMessage: state.errorMessage
23345
- });
23346
- const pendingId = pendingClaimToastIdsRef.current[claimKey];
23347
- if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
23348
- delete pendingClaimToastIdsRef.current[claimKey];
23349
- if (state.allConfirmed) {
23350
- if (!submittedClaimToastKeysRef.current.has(claimKey)) {
23351
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.successMessage, {
23352
- title: claimNotificationLabels.successTitle,
23353
- tone: "success"
23354
- });
23355
- }
23356
- } else if (state.anyFailed) {
23357
- const hasConfirmedLeg = Object.values(state.legs).some((leg) => leg.status === "confirmed");
23358
- if (hasConfirmedLeg) {
23359
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.partialMessage((_a = state.errorMessage) != null ? _a : void 0), {
23360
- title: claimNotificationLabels.partialTitle,
23361
- tone: "warning"
23362
- });
23363
- } else {
23364
- toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage((_b = state.errorMessage) != null ? _b : void 0), {
23365
- title: claimNotificationLabels.failedTitle,
23366
- tone: "error"
23367
- });
23368
- }
23369
- }
23370
- submittedClaimToastKeysRef.current.delete(claimKey);
23371
- invalidateClaimUiState();
23372
- delete firedTerminalRef.current[active.redeemId];
23373
- setActiveRedeems((prev) => {
23374
- const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
23375
- return rest;
23376
- });
23377
- }
23378
- }, [
23379
- activeRedeems,
23380
- claimNotificationLabels,
23381
- invalidateClaimUiState,
23382
- lifecycleStates,
23383
- onClaimResult,
23384
- toastCtx
23385
- ]);
23386
- (0, import_react36.useEffect)(() => {
23642
+ (0, import_react38.useEffect)(() => {
23387
23643
  if (!shouldUseHookData || !isAuthenticated) {
23388
23644
  setProfileUser(void 0);
23389
23645
  return;
@@ -23402,11 +23658,11 @@ var UserProfilePage = ({
23402
23658
  isActive = false;
23403
23659
  };
23404
23660
  }, [client, currentUser, isAuthenticated, shouldUseHookData]);
23405
- const resolvedUser = (0, import_react36.useMemo)(() => {
23661
+ const resolvedUser = (0, import_react38.useMemo)(() => {
23406
23662
  var _a, _b, _c, _d, _e, _f;
23407
23663
  if (user) return user;
23408
23664
  const fullUser = profileUser != null ? profileUser : currentUser;
23409
- const walletAddress = (0, import_hooks59.getWalletAddressFromUserProfile)(fullUser);
23665
+ const walletAddress = (0, import_hooks61.getWalletAddressFromUserProfile)(fullUser);
23410
23666
  const fallbackUsername = walletAddress && shortenAddress(walletAddress) || "username";
23411
23667
  const twitterAccount = (_a = fullUser == null ? void 0 : fullUser.accounts) == null ? void 0 : _a.find(
23412
23668
  (account) => String(account.provider).toLowerCase() === "twitter"
@@ -23436,7 +23692,7 @@ var UserProfilePage = ({
23436
23692
  socialHandle: normalizedTwitterHandle != null ? normalizedTwitterHandle : void 0
23437
23693
  };
23438
23694
  }, [connectedVenues, currentUser, profileUser, user]);
23439
- const _resolvedVenueBalances = (0, import_react36.useMemo)(() => {
23695
+ const _resolvedVenueBalances = (0, import_react38.useMemo)(() => {
23440
23696
  if (_venueBalances) return _venueBalances;
23441
23697
  return balanceState.balanceBreakdown.map((item) => ({
23442
23698
  chain: item.label,
@@ -23444,7 +23700,7 @@ var UserProfilePage = ({
23444
23700
  balanceLabel: formatUsd2(item.balance)
23445
23701
  }));
23446
23702
  }, [_venueBalances, balanceState.balanceBreakdown]);
23447
- const positionsValueLabel = (0, import_react36.useMemo)(() => {
23703
+ const positionsValueLabel = (0, import_react38.useMemo)(() => {
23448
23704
  var _a;
23449
23705
  if (balance == null ? void 0 : balance.totalLabel) return balance.totalLabel;
23450
23706
  const managed = balanceState.managedBalances;
@@ -23452,13 +23708,13 @@ var UserProfilePage = ({
23452
23708
  const positionsValueTotal = positions.reduce((sum, p) => sum + (Number(p.balance) || 0), 0);
23453
23709
  return formatUsd2(positionsValueTotal);
23454
23710
  }, [balance, balanceState]);
23455
- const availableBalanceLabel = (0, import_react36.useMemo)(() => {
23711
+ const availableBalanceLabel = (0, import_react38.useMemo)(() => {
23456
23712
  var _a;
23457
23713
  return formatUsd2((_a = balanceState.totalBalance) != null ? _a : 0);
23458
23714
  }, [balanceState.totalBalance]);
23459
23715
  const isPositionsValueLoading = !(balance == null ? void 0 : balance.totalLabel) && balanceState.isLoading;
23460
23716
  const isAvailableBalanceLoading = balanceState.isLoading;
23461
- const resolvedActivities = (0, import_react36.useMemo)(() => {
23717
+ const resolvedActivities = (0, import_react38.useMemo)(() => {
23462
23718
  if (activities) return activities.filter(isVisibleUserProfileActivity);
23463
23719
  const formatTime = isHydrated ? toRelativeTimeLabel : toAbsoluteTimeLabel;
23464
23720
  return activityQuery.activities.filter(isVisibleActivityItem).map((item, index) => {
@@ -23607,7 +23863,7 @@ var UserProfilePage = ({
23607
23863
  };
23608
23864
  });
23609
23865
  }, [activities, activityQuery.activities, isHydrated, labels, ordersQuery.orders]);
23610
- const resolvedOpenOrders = (0, import_react36.useMemo)(() => {
23866
+ const resolvedOpenOrders = (0, import_react38.useMemo)(() => {
23611
23867
  if (openOrders) return openOrders;
23612
23868
  return ordersQuery.orders.filter((order) => isOpenOrderStatus(order.status)).map((order) => {
23613
23869
  var _a, _b, _c, _d, _e, _f, _g;
@@ -23624,11 +23880,11 @@ var UserProfilePage = ({
23624
23880
  };
23625
23881
  });
23626
23882
  }, [openOrders, ordersQuery.orders]);
23627
- const adaptPositionGroups = (0, import_react36.useCallback)(
23883
+ const adaptPositionGroups = (0, import_react38.useCallback)(
23628
23884
  (groups) => {
23629
23885
  return groups.flatMap((group) => {
23630
23886
  var _a, _b, _c, _d;
23631
- const closedTotals = (0, import_hooks59.computeClosedPositionTotals)(group);
23887
+ const closedTotals = (0, import_hooks61.computeClosedPositionTotals)(group);
23632
23888
  const winningOutcome = group.venueMarket.venueMarketOutcomes.find(
23633
23889
  (outcome) => outcome.winner === true
23634
23890
  );
@@ -23694,11 +23950,11 @@ var UserProfilePage = ({
23694
23950
  },
23695
23951
  []
23696
23952
  );
23697
- const resolvedActivePositions = (0, import_react36.useMemo)(() => {
23953
+ const resolvedActivePositions = (0, import_react38.useMemo)(() => {
23698
23954
  const source = activePositions != null ? activePositions : adaptPositionGroups(activePositionsQuery.positions);
23699
23955
  return source.filter(shouldIncludeByShares);
23700
23956
  }, [activePositions, activePositionsQuery.positions, adaptPositionGroups]);
23701
- const resolvedClosedPositions = (0, import_react36.useMemo)(() => {
23957
+ const resolvedClosedPositions = (0, import_react38.useMemo)(() => {
23702
23958
  const source = closedPositions != null ? closedPositions : adaptPositionGroups(closedPositionsQuery.positions);
23703
23959
  return source.filter(shouldIncludeByShares);
23704
23960
  }, [closedPositions, closedPositionsQuery.positions, adaptPositionGroups]);
@@ -23787,7 +24043,7 @@ var UserProfilePage = ({
23787
24043
  onPositionClick,
23788
24044
  getPositionHref,
23789
24045
  onClaim: handleClaimPosition,
23790
- claimingPositionKeys: claimingPositionKeys != null ? claimingPositionKeys : internalClaimingIds,
24046
+ claimingPositionKeys: claimingKeys,
23791
24047
  onActivityClick,
23792
24048
  getActivityHref,
23793
24049
  onOpenOrderClick,