@agg-build/ui 1.2.12 → 1.3.0

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 (61) hide show
  1. package/README.md +34 -1
  2. package/dist/{chunk-YSW4ULL5.mjs → chunk-55ODXLOS.mjs} +1 -1
  3. package/dist/{chunk-4WBQTUPW.mjs → chunk-5ALBEKAT.mjs} +603 -317
  4. package/dist/{chunk-J6WELNCX.mjs → chunk-6PQ6O6M5.mjs} +583 -186
  5. package/dist/{chunk-U55T5BPE.mjs → chunk-ONVP7YWS.mjs} +44 -13
  6. package/dist/{chunk-X3KCFWXN.mjs → chunk-QUZWA34R.mjs} +975 -849
  7. package/dist/{chunk-IBOE7DRY.mjs → chunk-UFC7L74C.mjs} +26 -27
  8. package/dist/{chunk-3JXBOU24.mjs → chunk-YWJIYEJV.mjs} +146 -81
  9. package/dist/events.js +1833 -1435
  10. package/dist/events.mjs +5 -3
  11. package/dist/index.js +4100 -3213
  12. package/dist/index.mjs +13 -9
  13. package/dist/modals.js +964 -899
  14. package/dist/modals.mjs +3 -3
  15. package/dist/pages.js +3593 -2724
  16. package/dist/pages.mjs +6 -6
  17. package/dist/primitives.js +995 -902
  18. package/dist/primitives.mjs +3 -1
  19. package/dist/styles.css +1 -1
  20. package/dist/tailwind.css +1 -1
  21. package/dist/trading.js +828 -688
  22. package/dist/trading.mjs +4 -4
  23. package/dist/types/events/item/event-list-item-v2.utils.d.mts +28 -0
  24. package/dist/types/events/item/event-list-item-v2.utils.d.ts +28 -0
  25. package/dist/types/events/item/event-list-item.constants.d.mts +1 -1
  26. package/dist/types/events/item/event-list-item.constants.d.ts +1 -1
  27. package/dist/types/events/item/index.d.mts +4 -0
  28. package/dist/types/events/item/index.d.ts +4 -0
  29. package/dist/types/events/list/event-list.types.d.mts +2 -0
  30. package/dist/types/events/list/event-list.types.d.ts +2 -0
  31. package/dist/types/events/list/event-list.utils.d.mts +19 -0
  32. package/dist/types/events/list/event-list.utils.d.ts +19 -0
  33. package/dist/types/events/list/index.d.mts +1 -1
  34. package/dist/types/events/list/index.d.ts +1 -1
  35. package/dist/types/pages/home/home.types.d.mts +1 -0
  36. package/dist/types/pages/home/home.types.d.ts +1 -0
  37. package/dist/types/pages/user-profile/user-profile.types.d.mts +30 -4
  38. package/dist/types/pages/user-profile/user-profile.types.d.ts +30 -4
  39. package/dist/types/primitives/icon/index.d.mts +2 -1
  40. package/dist/types/primitives/icon/index.d.ts +2 -1
  41. package/dist/types/primitives/icon/registry.d.mts +4 -0
  42. package/dist/types/primitives/icon/registry.d.ts +4 -0
  43. package/dist/types/primitives/icon/svg/gift-bonus.d.mts +5 -0
  44. package/dist/types/primitives/icon/svg/gift-bonus.d.ts +5 -0
  45. package/dist/types/primitives/search/search.types.d.mts +2 -1
  46. package/dist/types/primitives/search/search.types.d.ts +2 -1
  47. package/dist/types/primitives/skeleton/index.d.mts +1 -1
  48. package/dist/types/primitives/skeleton/index.d.ts +1 -1
  49. package/dist/types/primitives/skeleton/skeleton.types.d.mts +4 -0
  50. package/dist/types/primitives/skeleton/skeleton.types.d.ts +4 -0
  51. package/dist/types/primitives/skeleton/views/event-list-skeleton-view.d.mts +1 -1
  52. package/dist/types/primitives/skeleton/views/event-list-skeleton-view.d.ts +1 -1
  53. package/dist/types/profile/tabs/accounts-wallets-tab.d.mts +1 -1
  54. package/dist/types/profile/tabs/accounts-wallets-tab.d.ts +1 -1
  55. package/dist/types/trading/place-order/index.d.mts +1 -1
  56. package/dist/types/trading/place-order/index.d.ts +1 -1
  57. package/dist/types/trading/place-order/index.place-order.types.d.mts +4 -1
  58. package/dist/types/trading/place-order/index.place-order.types.d.ts +4 -1
  59. package/dist/types/trading/place-order/index.place-order.utils.d.mts +2 -0
  60. package/dist/types/trading/place-order/index.place-order.utils.d.ts +2 -0
  61. package/package.json +3 -3
@@ -10,13 +10,13 @@ import {
10
10
  isErrorWithStatus,
11
11
  useEventListTabs,
12
12
  useEventListTabsHeaderOverflow
13
- } from "./chunk-4WBQTUPW.mjs";
13
+ } from "./chunk-5ALBEKAT.mjs";
14
14
  import {
15
15
  DEPOSIT_MODAL_OPEN_EVENT,
16
16
  PlaceOrder,
17
17
  SettlementDetails,
18
18
  WITHDRAW_MODAL_OPEN_EVENT
19
- } from "./chunk-3JXBOU24.mjs";
19
+ } from "./chunk-YWJIYEJV.mjs";
20
20
  import {
21
21
  AggErrorBoundary,
22
22
  Button,
@@ -44,11 +44,15 @@ import {
44
44
  cn,
45
45
  filterOpenEvents,
46
46
  resolveTabVenus,
47
- shortenAddress
48
- } from "./chunk-X3KCFWXN.mjs";
47
+ shortenAddress,
48
+ sortCategoriesForNavigation,
49
+ sortMarketsByVolumeDesc,
50
+ useOptionalToast
51
+ } from "./chunk-QUZWA34R.mjs";
49
52
 
50
53
  // src/pages/home/index.tsx
51
54
  import {
55
+ getVisibleVenueIdsByConfig,
52
56
  useAppConfig,
53
57
  useCategories,
54
58
  useEventListState,
@@ -57,7 +61,7 @@ import {
57
61
  useSearch
58
62
  } from "@agg-build/hooks";
59
63
  import { VENUES } from "@agg-build/sdk";
60
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef as useRef3, useState as useState4 } from "react";
64
+ import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
61
65
 
62
66
  // src/pages/event-market/index.tsx
63
67
  import {
@@ -69,7 +73,7 @@ import {
69
73
  useMidpoints
70
74
  } from "@agg-build/hooks";
71
75
  import * as Dialog from "@radix-ui/react-dialog";
72
- import { useEffect, useRef, useState } from "react";
76
+ import { useEffect, useMemo, useRef, useState } from "react";
73
77
 
74
78
  // src/pages/event-market/event-market.utils.ts
75
79
  var EVENT_MARKET_PAGE_STICKY_HEADER_OFFSET_PX = 48;
@@ -167,7 +171,7 @@ var resolveMobileTradePlaceOrderClassNames = (classNames) => {
167
171
  root: "rounded-t-agg-2xl rounded-b-none md:rounded-agg-2xl md:rounded-b-agg-2xl",
168
172
  body: cn("flex h-full min-h-0 flex-col", classNames == null ? void 0 : classNames.tradeBody, classNames == null ? void 0 : classNames.mobileTradeBody),
169
173
  content: cn(
170
- "min-h-0 flex-1 overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
174
+ "min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
171
175
  classNames == null ? void 0 : classNames.tradeContent,
172
176
  classNames == null ? void 0 : classNames.mobileTradeContent
173
177
  ),
@@ -353,14 +357,19 @@ var EventMarketPageContent = ({
353
357
  stickyOrderPanel,
354
358
  resolvedClaim
355
359
  }) => {
356
- const eventTradingState = resolveEventTradingState(event);
360
+ const sortedEvent = useMemo(() => {
361
+ return __spreadProps(__spreadValues({}, event), {
362
+ venueMarkets: sortMarketsByVolumeDesc(event.venueMarkets)
363
+ });
364
+ }, [event]);
365
+ const eventTradingState = useMemo(() => resolveEventTradingState(sortedEvent), [sortedEvent]);
357
366
  const stickyOrderPanelState = resolveEventMarketPageStickyState({
358
367
  stickyOrderPanel
359
368
  });
360
369
  const [isMobileTradeOpen, setIsMobileTradeOpen] = useState(false);
361
370
  const isMobileViewport = useIsMobileEventMarketViewport();
362
371
  const tradingContext = useEventTradingContext();
363
- const midpointsResult = useMidpoints(event.venueMarkets);
372
+ const midpointsResult = useMidpoints(sortedEvent.venueMarkets);
364
373
  const setTradeSideRef = useRef(tradingContext == null ? void 0 : tradingContext.setTradeSide);
365
374
  setTradeSideRef.current = tradingContext == null ? void 0 : tradingContext.setTradeSide;
366
375
  useEffect(() => {
@@ -369,7 +378,7 @@ var EventMarketPageContent = ({
369
378
  (_a = setTradeSideRef.current) == null ? void 0 : _a.call(setTradeSideRef, TradeSide.Buy);
370
379
  };
371
380
  }, []);
372
- if (!event || !event.venueMarkets.length) {
381
+ if (!sortedEvent.venueMarkets.length) {
373
382
  return /* @__PURE__ */ jsx(EventMarketPageUnavailableState, { ariaLabel });
374
383
  }
375
384
  return /* @__PURE__ */ jsxs(
@@ -380,7 +389,7 @@ var EventMarketPageContent = ({
380
389
  "w-full mx-auto max-w-[1360px] px-6 lg:px-10 pb-10",
381
390
  classNames == null ? void 0 : classNames.root
382
391
  ),
383
- "aria-label": ariaLabel != null ? ariaLabel : event.title,
392
+ "aria-label": ariaLabel != null ? ariaLabel : sortedEvent.title,
384
393
  children: [
385
394
  /* @__PURE__ */ jsxs(
386
395
  "div",
@@ -405,7 +414,7 @@ var EventMarketPageContent = ({
405
414
  /* @__PURE__ */ jsx(
406
415
  EventListItemDetails,
407
416
  {
408
- event,
417
+ event: sortedEvent,
409
418
  defaultMarketId,
410
419
  defaultOutcomeId,
411
420
  eventTradingState,
@@ -418,7 +427,7 @@ var EventMarketPageContent = ({
418
427
  /* @__PURE__ */ jsx(
419
428
  MarketDetailsList,
420
429
  {
421
- eventId: event.id,
430
+ eventId: sortedEvent.id,
422
431
  markets: eventTradingState.displayMarkets,
423
432
  eventTradingState,
424
433
  live: true,
@@ -446,7 +455,7 @@ var EventMarketPageContent = ({
446
455
  classNames: resolveMobileTradePlaceOrderClassNames(classNames)
447
456
  }
448
457
  ) }) : null,
449
- /* @__PURE__ */ jsx(SettlementDetails, { eventId: event.id, className: classNames == null ? void 0 : classNames.settlement })
458
+ /* @__PURE__ */ jsx(SettlementDetails, { eventId: sortedEvent.id, className: classNames == null ? void 0 : classNames.settlement })
450
459
  ]
451
460
  }
452
461
  ),
@@ -549,6 +558,7 @@ var getDefaultEventSectionItems = (labels) => {
549
558
 
550
559
  // src/pages/home/home.utils.ts
551
560
  var resolveCategoryTabs = (categories, allCategoryTabLabel) => {
561
+ var _a;
552
562
  const seenCategoryIds = /* @__PURE__ */ new Set();
553
563
  const tabs = [
554
564
  {
@@ -557,22 +567,31 @@ var resolveCategoryTabs = (categories, allCategoryTabLabel) => {
557
567
  iconName: "arrow-trend-up"
558
568
  }
559
569
  ];
570
+ const otherTabValues = /* @__PURE__ */ new Set();
560
571
  const categoryTabs = [];
561
572
  for (const category of categories) {
562
573
  if (seenCategoryIds.has(category.id)) continue;
563
574
  seenCategoryIds.add(category.id);
575
+ const label = (_a = category.displayName) != null ? _a : category.name.trim();
576
+ if (category.name.trim().toLowerCase() === "other") {
577
+ otherTabValues.add(category.id);
578
+ }
564
579
  categoryTabs.push({
565
580
  value: category.id,
566
- label: category.name.trim().toLowerCase(),
581
+ label,
567
582
  categoryIds: [category.id]
568
583
  });
569
584
  }
570
- categoryTabs.sort((a, b) => {
571
- const aIsOther = a.label === "other" ? 1 : 0;
572
- const bIsOther = b.label === "other" ? 1 : 0;
573
- return aIsOther - bIsOther;
574
- });
575
- return [...tabs, ...categoryTabs];
585
+ const sortedCategoryTabs = sortCategoriesForNavigation(
586
+ categoryTabs.map((tab) => __spreadProps(__spreadValues({}, tab), {
587
+ id: tab.value,
588
+ name: otherTabValues.has(tab.value) ? "other" : tab.label
589
+ }))
590
+ );
591
+ return [...tabs, ...sortedCategoryTabs.map((_b) => {
592
+ var _c = _b, { id: _id, name: _name } = _c, tab = __objRest(_c, ["id", "name"]);
593
+ return tab;
594
+ })];
576
595
  };
577
596
  var resolveInitialTabValue = (tabs, defaultActiveTab) => {
578
597
  var _a, _b;
@@ -656,16 +675,14 @@ var HomeSearchResults = ({
656
675
  const [activeVenueTabValue, setActiveVenueTabValue] = useState4("matched");
657
676
  const eventListTabs = useEventListTabs();
658
677
  const { headerRef, titleRef, shouldUseSelectOverflow } = useEventListTabsHeaderOverflow(eventListTabs);
659
- const visibleVenues = useMemo(
660
- () => disabledVenues.length === 0 ? void 0 : VENUES.filter(
661
- (v) => !disabledVenues.includes(v)
662
- ),
678
+ const visibleVenues = useMemo2(
679
+ () => disabledVenues.length === 0 ? void 0 : getVisibleVenueIdsByConfig(VENUES, disabledVenues),
663
680
  [disabledVenues]
664
681
  );
665
- const activeVenueTab = useMemo(() => {
682
+ const activeVenueTab = useMemo2(() => {
666
683
  return eventListTabs.find((tab) => tab.value === activeVenueTabValue);
667
684
  }, [activeVenueTabValue, eventListTabs]);
668
- const activeCategoryTab = useMemo(() => {
685
+ const activeCategoryTab = useMemo2(() => {
669
686
  return resolvedTabs.find((tab) => tab.value === activeTabValue);
670
687
  }, [activeTabValue, resolvedTabs]);
671
688
  const activeVenues = resolveTabVenus(activeVenueTab, visibleVenues);
@@ -689,7 +706,7 @@ var HomeSearchResults = ({
689
706
  // so debounced keystrokes don't pay reranker latency.
690
707
  deep: true
691
708
  });
692
- const openEvents = useMemo(() => {
709
+ const openEvents = useMemo2(() => {
693
710
  let filtered = filterOpenEvents(searchResults);
694
711
  if (activeVenues == null ? void 0 : activeVenues.length) {
695
712
  filtered = filtered.filter((e) => activeVenues.includes(e.venue));
@@ -775,7 +792,9 @@ var HomeSearchResults = ({
775
792
  "div",
776
793
  {
777
794
  className: cn(
778
- "agg-event-list-grid grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] md:grid-cols-[repeat(auto-fill,minmax(360px,1fr))] gap-4 transition-opacity duration-200",
795
+ "agg-event-list-grid",
796
+ "grid grid-cols-[repeat(auto-fill,minmax(240px,1fr))] md:grid-cols-[repeat(auto-fill,minmax(360px,1fr))] gap-4",
797
+ "transition-opacity duration-200",
779
798
  "empty:hidden",
780
799
  isPlaceholderData && "opacity-60"
781
800
  ),
@@ -785,7 +804,7 @@ var HomeSearchResults = ({
785
804
  {
786
805
  event,
787
806
  classNames: {
788
- root: "agg-event-list-item w-full min-w-0 max-w-none"
807
+ root: "agg-event-list-item w-full min-w-0! max-w-none justify-between!"
789
808
  },
790
809
  href: getEventHref == null ? void 0 : getEventHref(event),
791
810
  onEventClick: (selectedEvent) => {
@@ -921,10 +940,10 @@ var HomePage = ({
921
940
  limit: categoriesLimit,
922
941
  enabled: !hasCustomTabs
923
942
  });
924
- const categoryTabs = useMemo(() => {
943
+ const categoryTabs = useMemo2(() => {
925
944
  return resolveCategoryTabs(categories, resolvedAllCategoryTabLabel);
926
945
  }, [categories, resolvedAllCategoryTabLabel]);
927
- const resolvedTabs = useMemo(() => {
946
+ const resolvedTabs = useMemo2(() => {
928
947
  if (hasCustomTabs && tabs) return tabs;
929
948
  return categoryTabs;
930
949
  }, [categoryTabs, hasCustomTabs, tabs]);
@@ -944,7 +963,7 @@ var HomePage = ({
944
963
  return resolveInitialTabValue(resolvedTabs, defaultActiveTab);
945
964
  });
946
965
  }, [defaultActiveTab, resolvedTabs]);
947
- const tabsItems = useMemo(() => {
966
+ const tabsItems = useMemo2(() => {
948
967
  return resolvedTabs.map((tab) => {
949
968
  const isActive = tab.value === activeTabValue;
950
969
  return {
@@ -964,10 +983,10 @@ var HomePage = ({
964
983
  };
965
984
  });
966
985
  }, [activeTabValue, resolvedTabs]);
967
- const activeTab = useMemo(() => {
986
+ const activeTab = useMemo2(() => {
968
987
  return resolvedTabs.find((tab) => tab.value === activeTabValue);
969
988
  }, [activeTabValue, resolvedTabs]);
970
- const resolvedSectionItems = useMemo(() => {
989
+ const resolvedSectionItems = useMemo2(() => {
971
990
  var _a2, _b2, _c2;
972
991
  if (activeTabValue === ALL_CATEGORIES_TAB_VALUE) {
973
992
  return resolvedEventSectionItems;
@@ -987,9 +1006,24 @@ var HomePage = ({
987
1006
  setActiveTabValue(value);
988
1007
  _onTabChange == null ? void 0 : _onTabChange(value);
989
1008
  };
1009
+ const handleCategoryRootChange = (categoryId) => {
1010
+ const nextTab = categoryId ? resolvedTabs.find(
1011
+ (tab) => {
1012
+ var _a2;
1013
+ return tab.value === categoryId || ((_a2 = tab.categoryIds) == null ? void 0 : _a2.includes(categoryId));
1014
+ }
1015
+ ) : resolvedTabs.find((tab) => tab.value === ALL_CATEGORIES_TAB_VALUE);
1016
+ if (!nextTab) return;
1017
+ if (nextTab.value === activeTabValue) return;
1018
+ handleTabChange(nextTab.value);
1019
+ };
990
1020
  const handleLogoClick = () => {
991
1021
  onSearchChange == null ? void 0 : onSearchChange("");
992
1022
  };
1023
+ const handleMobileSearchSelect = (_eventId, event) => {
1024
+ if (!event) return;
1025
+ handleSelectEvent(event);
1026
+ };
993
1027
  const shouldRenderMobileSearch = isMobileSearchViewport && !resolvedSelectedEvent;
994
1028
  const isScrollRestorationReady = !!snapshot && !isShowingAllResults && !resolvedSelectedEvent && ((_b = (_a = eventListStateRef.current) == null ? void 0 : _a.loadedPageCount) != null ? _b : 0) >= ((_c = snapshot.loadedPageCount) != null ? _c : 1);
995
1029
  useScrollRestoration({
@@ -1012,7 +1046,7 @@ var HomePage = ({
1012
1046
  {
1013
1047
  className: cn(
1014
1048
  "agg-page-header",
1015
- "w-full bg-agg-secondary border-b border-agg-separator h-[60px]",
1049
+ "w-full bg-agg-secondary border-b border-agg-separator h-14! md:h-15!",
1016
1050
  classNames == null ? void 0 : classNames.header
1017
1051
  ),
1018
1052
  children: /* @__PURE__ */ jsx2("div", { className: "mx-auto h-full w-full max-w-[1360px] px-6 lg:px-10", children: /* @__PURE__ */ jsx2(
@@ -1021,7 +1055,7 @@ var HomePage = ({
1021
1055
  ariaLabel: labels.home.categoryTabsAria,
1022
1056
  variant: "underline",
1023
1057
  className: cn("w-full", classNames == null ? void 0 : classNames.tabs),
1024
- classNames: { tabList: "!h-[60px]" },
1058
+ classNames: { tabList: "h-14! md:h-15!" },
1025
1059
  items: tabsItems,
1026
1060
  value: activeTabValue,
1027
1061
  onChange: handleTabChange
@@ -1037,7 +1071,13 @@ var HomePage = ({
1037
1071
  "pt-4 sm:pt-6 md:pt-8 pb-10"
1038
1072
  ),
1039
1073
  children: [
1040
- shouldRenderMobileSearch ? /* @__PURE__ */ jsx2("div", { className: "agg-page-mobile-search w-full py-4 md:hidden ", children: /* @__PURE__ */ jsx2(Search, { onSeeAllEvents: onSeeAllEventsProp }) }) : null,
1074
+ shouldRenderMobileSearch ? /* @__PURE__ */ jsx2("div", { className: "agg-page-mobile-search w-full pb-5 md:hidden", children: /* @__PURE__ */ jsx2(
1075
+ Search,
1076
+ {
1077
+ onSelectEvent: handleMobileSearchSelect,
1078
+ onSeeAllEvents: onSeeAllEventsProp
1079
+ }
1080
+ ) }) : null,
1041
1081
  /* @__PURE__ */ jsx2(
1042
1082
  "main",
1043
1083
  {
@@ -1071,6 +1111,7 @@ var HomePage = ({
1071
1111
  maxVisibleItems: eventSectionItem.maxVisibleItems,
1072
1112
  search: (_b2 = eventSectionItem.search) != null ? _b2 : activeTab == null ? void 0 : activeTab.search,
1073
1113
  categoryIds: (_c2 = eventSectionItem.categoryIds) != null ? _c2 : activeTab == null ? void 0 : activeTab.categoryIds,
1114
+ onCategoryRootChange: handleCategoryRootChange,
1074
1115
  getEventHref,
1075
1116
  getMarketHref,
1076
1117
  onEventClick: (event) => {
@@ -1102,6 +1143,9 @@ import {
1102
1143
  computeClosedPositionTotals,
1103
1144
  executionKeys,
1104
1145
  getWalletAddressFromUserProfile,
1146
+ invalidateBalanceQueries,
1147
+ invalidatePositionQueries,
1148
+ invalidateUserActivityQueries,
1105
1149
  useAggAuthState,
1106
1150
  useAggBalance,
1107
1151
  useAggClient,
@@ -1116,7 +1160,7 @@ import {
1116
1160
  useUserActivity
1117
1161
  } from "@agg-build/hooks";
1118
1162
  import { Venue } from "@agg-build/sdk";
1119
- import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef5, useState as useState6 } from "react";
1163
+ import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef5, useState as useState6 } from "react";
1120
1164
 
1121
1165
  // src/pages/user-profile/chain-display.ts
1122
1166
  var CHAIN_ID_TO_LABEL = {
@@ -1317,7 +1361,7 @@ AvailableBalanceCard.displayName = "AvailableBalanceCard";
1317
1361
 
1318
1362
  // src/pages/user-profile/components/positions-activity.tsx
1319
1363
  import { optimizedImageUrl as optimizedImageUrl2, useLabels as useLabels4 } from "@agg-build/hooks";
1320
- import { Fragment as Fragment4, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState5 } from "react";
1364
+ import { Fragment as Fragment4, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef4, useState as useState5 } from "react";
1321
1365
 
1322
1366
  // src/pages/user-profile/user-profile.constants.ts
1323
1367
  var USER_PROFILE_TAB_POSITIONS = "positions";
@@ -1506,7 +1550,10 @@ var toPositionRowViewModel = (position, labels = defaultLabels) => {
1506
1550
  percentLabel: formatSignedPercent(payoutPercent),
1507
1551
  tone: getPositionTone(payoutPnl)
1508
1552
  },
1509
- canClaim: positionStatus === "won_unclaimed" && position.closedClaimStatus !== "pending"
1553
+ // "ineligible" winners (auto-settled venues like Hyperliquid, dust below
1554
+ // the redeem threshold) have no redeem path — a Claim button would only
1555
+ // error on click. Undefined closedClaimStatus keeps the legacy behavior.
1556
+ canClaim: positionStatus === "won_unclaimed" && position.closedClaimStatus !== "pending" && position.closedClaimStatus !== "ineligible"
1510
1557
  };
1511
1558
  };
1512
1559
 
@@ -1545,7 +1592,8 @@ var TRANSFER_ICON = {
1545
1592
  withdrawal: "upload",
1546
1593
  deposit: "download",
1547
1594
  bridge: "arrows-to-dot",
1548
- user_op: "wallet"
1595
+ user_op: "wallet",
1596
+ unknown: "info"
1549
1597
  };
1550
1598
  var TRANSFER_STATUS_VISUAL = {
1551
1599
  completed: { icon: "badge-check-thin", iconClassName: "text-agg-muted-foreground" },
@@ -1558,6 +1606,9 @@ var resolveActivityStatus = (activity) => {
1558
1606
  if (activity.status) return activity.status;
1559
1607
  return "completed";
1560
1608
  };
1609
+ var getStatusVisual = (activity) => {
1610
+ return TRANSFER_STATUS_VISUAL[resolveActivityStatus(activity)];
1611
+ };
1561
1612
  var resolveToneClasses = (_activity) => {
1562
1613
  return {
1563
1614
  primary: "text-agg-foreground",
@@ -1647,20 +1698,54 @@ var TransferTypeCell = ({
1647
1698
  }
1648
1699
  )
1649
1700
  ] });
1650
- var TradeOutcomeShares = ({
1701
+ var RedeemTypeCell = ({
1651
1702
  activity,
1652
1703
  tone
1653
- }) => /* @__PURE__ */ jsxs4(Fragment2, { children: [
1654
- /* @__PURE__ */ jsx4("span", { className: "agg-activity-outcome inline-flex items-center justify-center gap-1.5 rounded-full bg-agg-secondary-hover px-4 py-[6px]", children: /* @__PURE__ */ jsx4(
1704
+ }) => /* @__PURE__ */ jsxs4("div", { className: "hidden w-[108px] shrink-0 items-center gap-3 sm:flex", children: [
1705
+ /* @__PURE__ */ jsx4(
1706
+ Icon,
1707
+ {
1708
+ name: "gift-bonus",
1709
+ size: "small",
1710
+ className: cn(
1711
+ "shrink-0 text-agg-foreground",
1712
+ activity.hasError || activity.errorMessage ? "text-agg-error!" : ""
1713
+ )
1714
+ }
1715
+ ),
1716
+ /* @__PURE__ */ jsx4(
1717
+ "p",
1718
+ {
1719
+ className: cn(
1720
+ "agg-activity-type w-20 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal",
1721
+ tone.primary,
1722
+ activity.hasError || activity.errorMessage ? "text-agg-error!" : ""
1723
+ ),
1724
+ children: activity.type
1725
+ }
1726
+ )
1727
+ ] });
1728
+ var OutcomeBadge = ({
1729
+ label,
1730
+ tone
1731
+ }) => {
1732
+ if (!label) return null;
1733
+ return /* @__PURE__ */ jsx4("span", { className: "agg-activity-outcome inline-flex items-center justify-center gap-1.5 rounded-full bg-agg-secondary-hover px-4 py-[6px]", children: /* @__PURE__ */ jsx4(
1655
1734
  "span",
1656
1735
  {
1657
1736
  className: cn(
1658
1737
  "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal whitespace-nowrap",
1659
1738
  tone.primary
1660
1739
  ),
1661
- children: activity.outcomeLabel
1740
+ children: label
1662
1741
  }
1663
- ) }),
1742
+ ) });
1743
+ };
1744
+ var TradeOutcomeShares = ({
1745
+ activity,
1746
+ tone
1747
+ }) => /* @__PURE__ */ jsxs4(Fragment2, { children: [
1748
+ /* @__PURE__ */ jsx4(OutcomeBadge, { label: activity.outcomeLabel, tone }),
1664
1749
  /* @__PURE__ */ jsx4(
1665
1750
  "span",
1666
1751
  {
@@ -1672,6 +1757,145 @@ var TradeOutcomeShares = ({
1672
1757
  }
1673
1758
  )
1674
1759
  ] });
1760
+ var RedeemRow = ({
1761
+ activity,
1762
+ className,
1763
+ onClick
1764
+ }) => {
1765
+ const tone = resolveToneClasses(activity);
1766
+ const statusVisual = getStatusVisual(activity);
1767
+ const activityStatus = resolveActivityStatus(activity);
1768
+ const shouldShowInlineStatus = activityStatus !== "completed";
1769
+ return /* @__PURE__ */ jsx4("button", { type: "button", className, onClick, children: /* @__PURE__ */ jsx4(
1770
+ ConditionalWrapper,
1771
+ {
1772
+ condition: !!activity.errorMessage,
1773
+ wrapper: (children) => /* @__PURE__ */ jsx4(
1774
+ Tooltip,
1775
+ {
1776
+ size: "medium",
1777
+ content: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-4", children: [
1778
+ /* @__PURE__ */ jsx4(Icon, { name: "info", size: "small", className: "shrink-0 text-agg-error" }),
1779
+ /* @__PURE__ */ jsx4("p", { className: "font-agg-sans text-agg-sm font-agg-normal text-left", children: activity.errorMessage })
1780
+ ] }),
1781
+ sideOffset: 4,
1782
+ children
1783
+ }
1784
+ ),
1785
+ children: /* @__PURE__ */ jsxs4(
1786
+ "div",
1787
+ {
1788
+ className: cn(
1789
+ "flex w-full flex-col gap-3 text-left transition-colors sm:min-h-16 sm:flex-row sm:items-center",
1790
+ "relative z-10"
1791
+ ),
1792
+ "data-status": activityStatus,
1793
+ children: [
1794
+ /* @__PURE__ */ jsx4(RedeemTypeCell, { activity, tone }),
1795
+ /* @__PURE__ */ jsxs4("div", { className: "flex w-full items-center justify-between sm:hidden", children: [
1796
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1797
+ /* @__PURE__ */ jsx4(
1798
+ Icon,
1799
+ {
1800
+ name: "gift-bonus",
1801
+ size: "small",
1802
+ className: cn(
1803
+ "shrink-0 text-agg-foreground",
1804
+ activity.hasError || activity.errorMessage ? "text-agg-error!" : ""
1805
+ )
1806
+ }
1807
+ ),
1808
+ /* @__PURE__ */ jsx4(
1809
+ "p",
1810
+ {
1811
+ className: cn(
1812
+ "agg-activity-type font-agg-sans text-agg-sm leading-agg-5 font-agg-normal",
1813
+ tone.primary,
1814
+ activity.hasError || activity.errorMessage ? "text-agg-error!" : ""
1815
+ ),
1816
+ children: activity.type
1817
+ }
1818
+ )
1819
+ ] }),
1820
+ /* @__PURE__ */ jsx4(OutcomeBadge, { label: activity.outcomeLabel, tone })
1821
+ ] }),
1822
+ /* @__PURE__ */ jsxs4("div", { className: "flex w-full items-center justify-between sm:contents", children: [
1823
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-1 items-center gap-3 sm:gap-4", children: [
1824
+ /* @__PURE__ */ jsx4("div", { className: "agg-activity-image flex h-10 w-10 shrink-0 items-center justify-center sm:h-15 sm:w-15", children: /* @__PURE__ */ jsx4(
1825
+ RemoteImage,
1826
+ {
1827
+ src: activity.thumbnailSrc,
1828
+ alt: "",
1829
+ className: "h-full w-full rounded-agg-sm object-cover sm:rounded-agg-lg",
1830
+ classNames: { placeholder: "rounded-agg-sm sm:rounded-agg-lg" }
1831
+ }
1832
+ ) }),
1833
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-1 sm:gap-2", children: [
1834
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 items-center gap-2", children: [
1835
+ /* @__PURE__ */ jsx4(
1836
+ "p",
1837
+ {
1838
+ className: cn(
1839
+ "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap font-agg-sans text-agg-sm leading-agg-5 font-agg-bold sm:text-agg-base sm:leading-agg-6",
1840
+ tone.primary
1841
+ ),
1842
+ children: activity.title
1843
+ }
1844
+ ),
1845
+ shouldShowInlineStatus ? statusVisual.spin ? /* @__PURE__ */ jsx4(
1846
+ LoadingIcon,
1847
+ {
1848
+ size: "small",
1849
+ className: cn("shrink-0", statusVisual.iconClassName)
1850
+ }
1851
+ ) : /* @__PURE__ */ jsx4(
1852
+ Icon,
1853
+ {
1854
+ name: statusVisual.icon,
1855
+ size: "small",
1856
+ className: cn("shrink-0", statusVisual.iconClassName)
1857
+ }
1858
+ ) : null
1859
+ ] }),
1860
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 items-center gap-2 sm:gap-3", children: [
1861
+ /* @__PURE__ */ jsx4("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx4(OutcomeBadge, { label: activity.outcomeLabel, tone }) }),
1862
+ /* @__PURE__ */ jsx4(
1863
+ "p",
1864
+ {
1865
+ className: cn(
1866
+ "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap font-agg-sans text-agg-sm leading-agg-5 font-agg-normal",
1867
+ tone.meta
1868
+ ),
1869
+ children: activity.marketTitle
1870
+ }
1871
+ )
1872
+ ] })
1873
+ ] })
1874
+ ] }),
1875
+ /* @__PURE__ */ jsx4(
1876
+ AmountTimeStack,
1877
+ {
1878
+ amountLabel: activity.amountLabel,
1879
+ timeLabel: activity.timeLabel,
1880
+ tone,
1881
+ mobile: true
1882
+ }
1883
+ )
1884
+ ] }),
1885
+ /* @__PURE__ */ jsx4(
1886
+ AmountTimeStack,
1887
+ {
1888
+ amountLabel: activity.amountLabel,
1889
+ timeLabel: activity.timeLabel,
1890
+ tone
1891
+ }
1892
+ )
1893
+ ]
1894
+ }
1895
+ )
1896
+ }
1897
+ ) });
1898
+ };
1675
1899
  var TradeRow = ({
1676
1900
  activity,
1677
1901
  className,
@@ -1776,9 +2000,9 @@ var TransferRow = ({
1776
2000
  onClick
1777
2001
  }) => {
1778
2002
  const tone = resolveToneClasses(activity);
1779
- const transferIconName = TRANSFER_ICON[activity.kind];
1780
2003
  const transferStatus = resolveActivityStatus(activity);
1781
- const statusVisual = TRANSFER_STATUS_VISUAL[transferStatus];
2004
+ const transferIconName = TRANSFER_ICON[activity.kind];
2005
+ const statusVisual = getStatusVisual(activity);
1782
2006
  return /* @__PURE__ */ jsx4("button", { type: "button", className, onClick, children: /* @__PURE__ */ jsx4(
1783
2007
  ConditionalWrapper,
1784
2008
  {
@@ -1906,6 +2130,9 @@ var ActivityRow = ({ activity, href, onClick }) => {
1906
2130
  if (activity.kind === "trade") {
1907
2131
  return /* @__PURE__ */ jsx4(TradeRow, { activity, className: sharedClassName, href, onClick: handleClick });
1908
2132
  }
2133
+ if (activity.kind === "redeem") {
2134
+ return /* @__PURE__ */ jsx4(RedeemRow, { activity, className: sharedClassName, onClick: handleClick });
2135
+ }
1909
2136
  return /* @__PURE__ */ jsx4(TransferRow, { activity, className: sharedClassName, onClick: handleClick });
1910
2137
  };
1911
2138
  ActivityRow.displayName = "ActivityRow";
@@ -2305,7 +2532,7 @@ var PositionsActivity = ({
2305
2532
  const isPositionsTab = activeTab === USER_PROFILE_TAB_POSITIONS;
2306
2533
  const isActivityTab = activeTab === USER_PROFILE_TAB_ACTIVITY;
2307
2534
  const isClosedPositionsFilter = isPositionsTab && positionFilter === "closed";
2308
- const positionsForCurrentFilter = useMemo2(() => {
2535
+ const positionsForCurrentFilter = useMemo3(() => {
2309
2536
  if (positionFilter === "active") {
2310
2537
  return activePositions.filter((position) => !locallyClaimedPositionIds.has(position.id));
2311
2538
  }
@@ -2322,13 +2549,17 @@ var PositionsActivity = ({
2322
2549
  }
2323
2550
  return Array.from(byId.values());
2324
2551
  }, [activePositions, closedPositions, locallyClaimedPositionIds, positionFilter]);
2325
- const filteredPositions = useMemo2(() => {
2552
+ const filteredPositions = useMemo3(() => {
2326
2553
  if (!searchValue.trim()) return positionsForCurrentFilter;
2327
2554
  const q = searchValue.toLowerCase();
2328
2555
  return positionsForCurrentFilter.filter((p) => p.title.toLowerCase().includes(q));
2329
2556
  }, [positionsForCurrentFilter, searchValue]);
2330
2557
  const handleClaimPosition = (position) => __async(null, null, function* () {
2331
- yield onClaim == null ? void 0 : onClaim(position);
2558
+ try {
2559
+ yield onClaim == null ? void 0 : onClaim(position);
2560
+ } catch (e) {
2561
+ return;
2562
+ }
2332
2563
  setLocallyClaimedPositionIds((prev) => {
2333
2564
  const next = new Set(prev);
2334
2565
  next.add(position.id);
@@ -2343,7 +2574,7 @@ var PositionsActivity = ({
2343
2574
  const isLoadingMorePositions = positionFilter === "active" ? isLoadingMoreActivePositions : isLoadingMoreClosedPositions;
2344
2575
  const loadMorePositions = positionFilter === "active" ? onLoadMoreActivePositions : onLoadMoreClosedPositions;
2345
2576
  const filteredActivities = activities;
2346
- const searchResults = useMemo2(() => {
2577
+ const searchResults = useMemo3(() => {
2347
2578
  if (!isPositionsTab || !searchValue.trim()) return [];
2348
2579
  return filteredPositions.slice(0, 5).map((position) => ({
2349
2580
  id: position.id,
@@ -3140,13 +3371,19 @@ var OPEN_ORDER_STATUSES = /* @__PURE__ */ new Set([
3140
3371
  var SHOW_SOLD_POSITIONS = false;
3141
3372
  var SOLD_POSITION_SHARES_THRESHOLD = 0.1;
3142
3373
  var isOpenOrderStatus = (status) => OPEN_ORDER_STATUSES.has(status.toLowerCase());
3374
+ var shouldIncludeByShares = (position) => {
3375
+ if (SHOW_SOLD_POSITIONS) return true;
3376
+ if (typeof position.totalShares !== "number") return true;
3377
+ return position.totalShares >= SOLD_POSITION_SHARES_THRESHOLD;
3378
+ };
3143
3379
  var getActivityErrorMessage = (item) => {
3144
3380
  if (!("errorMessage" in item)) return null;
3145
3381
  return typeof item.errorMessage === "string" ? item.errorMessage : null;
3146
3382
  };
3147
3383
  var hasActivityError = (item) => {
3384
+ var _a;
3148
3385
  const errorMessage = getActivityErrorMessage(item);
3149
- return item.status.toLowerCase() === "failed" || !!(errorMessage == null ? void 0 : errorMessage.trim());
3386
+ return ((_a = item.status) == null ? void 0 : _a.toLowerCase()) === "failed" || !!(errorMessage == null ? void 0 : errorMessage.trim());
3150
3387
  };
3151
3388
  var normalizeTradeStatus = (status) => {
3152
3389
  const normalized = status.toLowerCase();
@@ -3182,17 +3419,52 @@ var normalizeDepositStatus = (status) => {
3182
3419
  if (TRANSFER_CANCELED_STATUSES.has(normalized)) return "canceled";
3183
3420
  return "completed";
3184
3421
  };
3422
+ var normalizeRedeemStatus = (status) => {
3423
+ const normalized = status.toLowerCase();
3424
+ if (normalized === "pending" || normalized === "submitted") return "pending";
3425
+ if (normalized === "confirmed" || normalized === "completed") return "completed";
3426
+ if (TRANSFER_FAILED_STATUSES.has(normalized)) return "failed";
3427
+ if (TRANSFER_CANCELED_STATUSES.has(normalized)) return "canceled";
3428
+ return "completed";
3429
+ };
3430
+ var getDerivedRedeemStatus = (item) => {
3431
+ const legs = Array.isArray(item.legs) ? item.legs : [];
3432
+ const legStatuses = legs.map((leg) => leg.status.toLowerCase());
3433
+ if (legStatuses.length > 0 && legStatuses.every((status) => status === "confirmed")) {
3434
+ return "completed";
3435
+ }
3436
+ if (legStatuses.some((status) => TRANSFER_FAILED_STATUSES.has(status))) return "failed";
3437
+ if (legStatuses.some((status) => TRANSFER_CANCELED_STATUSES.has(status))) return "canceled";
3438
+ return normalizeRedeemStatus(item.status);
3439
+ };
3185
3440
  var ZERO_AMOUNT_LABEL = "$0";
3186
3441
  var isVisibleActivityItem = (item) => {
3187
3442
  var _a;
3188
3443
  if (item.type === "user_op" || item.type === "bridge") return false;
3189
3444
  if (item.type === "trade") {
3190
- if (isOpenOrderStatus(item.status)) return false;
3191
- if (item.status.toLowerCase() === "failed" && ((_a = parseRawMicroValue(item.filledAmountRaw)) != null ? _a : 0) <= 0)
3445
+ const tradeItem = item;
3446
+ if (isOpenOrderStatus(tradeItem.status)) return false;
3447
+ if (tradeItem.status.toLowerCase() === "failed" && ((_a = parseRawMicroValue(tradeItem.filledAmountRaw)) != null ? _a : 0) <= 0)
3192
3448
  return false;
3193
3449
  }
3194
3450
  return true;
3195
3451
  };
3452
+ var getRuntimeActivityId = (item, index) => {
3453
+ return typeof item.id === "string" && item.id.trim() ? item.id : `unknown-activity-${index}`;
3454
+ };
3455
+ var getRuntimeActivityType = (item) => {
3456
+ return typeof item.type === "string" && item.type.trim() ? item.type : "unknown";
3457
+ };
3458
+ var getRuntimeActivityCreatedAt = (item) => {
3459
+ return item.createdAt instanceof Date || typeof item.createdAt === "string" ? item.createdAt : /* @__PURE__ */ new Date();
3460
+ };
3461
+ var logUnknownActivityType = (item) => {
3462
+ if (process.env.NODE_ENV !== "development") return;
3463
+ console.warn("[UserProfilePage] Unsupported activity type", {
3464
+ type: getRuntimeActivityType(item),
3465
+ id: typeof item.id === "string" ? item.id : void 0
3466
+ });
3467
+ };
3196
3468
  var isVisibleUserProfileActivity = (activity) => activity.kind !== "bridge";
3197
3469
  var shouldFetchFullUserProfile = (userProfile) => {
3198
3470
  var _a, _b, _c, _d;
@@ -3252,6 +3524,21 @@ var toTokenAmountLabel = ({
3252
3524
  const prefix = sign != null ? sign : "";
3253
3525
  return `${prefix}${formatTokenAmountTwoDecimals(amountRaw, tokenSymbol, chainId)} ${tokenSymbol}`;
3254
3526
  };
3527
+ var toRedeemPayoutAmountLabel = (item) => {
3528
+ var _a, _b;
3529
+ const legs = Array.isArray(item.legs) ? item.legs : [];
3530
+ const firstLeg = legs[0];
3531
+ const tokenSymbol = (_a = firstLeg == null ? void 0 : firstLeg.payoutTokenSymbol) != null ? _a : "USDC";
3532
+ if (item.totalPayoutRaw != null) {
3533
+ return `+${formatScaledNumberTwoDecimals(item.totalPayoutRaw)} ${tokenSymbol}`;
3534
+ }
3535
+ return toTokenAmountLabel({
3536
+ amountRaw: (_b = firstLeg == null ? void 0 : firstLeg.payoutAmountRaw) != null ? _b : "0",
3537
+ tokenSymbol,
3538
+ chainId: firstLeg == null ? void 0 : firstLeg.chainId,
3539
+ sign: "+"
3540
+ });
3541
+ };
3255
3542
  var POSITION_ROW_VENUE_ORDER = [
3256
3543
  Venue.polymarket,
3257
3544
  Venue.kalshi,
@@ -3278,6 +3565,10 @@ function buildVenueShareBreakdown(outcome) {
3278
3565
  sharesLabel: `${twoDecimalNumberFormatter.format(row.size)} shares`
3279
3566
  }));
3280
3567
  }
3568
+ var toClaimError = (err) => {
3569
+ if (err instanceof Error) return err;
3570
+ return new Error(String(err));
3571
+ };
3281
3572
  var UserProfilePage = ({
3282
3573
  user,
3283
3574
  balanceChainsOverride,
@@ -3335,17 +3626,22 @@ var UserProfilePage = ({
3335
3626
  const balanceState = useAggBalance();
3336
3627
  const client = useAggClient();
3337
3628
  const labels = useLabels6();
3629
+ const claimNotificationLabels = labels.notifications.claim;
3630
+ const toastCtx = useOptionalToast();
3338
3631
  const queryClient = useQueryClient();
3339
3632
  const redeemMutation = useRedeem();
3340
3633
  const [internalCancellingIds, setInternalCancellingIds] = useState6({});
3341
3634
  const [activeRedeems, setActiveRedeems] = useState6({});
3635
+ const activeClaimKeysRef = useRef5(/* @__PURE__ */ new Set());
3636
+ const pendingClaimToastIdsRef = useRef5({});
3637
+ const submittedClaimToastKeysRef = useRef5(/* @__PURE__ */ new Set());
3342
3638
  const [submittingClaimKeys, setSubmittingClaimKeys] = useState6({});
3343
- const lifecycleInputs = useMemo3(
3639
+ const lifecycleInputs = useMemo4(
3344
3640
  () => Object.values(activeRedeems),
3345
3641
  [activeRedeems]
3346
3642
  );
3347
3643
  const lifecycleStates = useRedeemLifecycles(lifecycleInputs);
3348
- const internalClaimingIds = useMemo3(() => {
3644
+ const internalClaimingIds = useMemo4(() => {
3349
3645
  const out = __spreadValues({}, submittingClaimKeys);
3350
3646
  for (const [claimKey, active] of Object.entries(activeRedeems)) {
3351
3647
  const state = lifecycleStates[active.redeemId];
@@ -3355,7 +3651,7 @@ var UserProfilePage = ({
3355
3651
  }, [activeRedeems, lifecycleStates, submittingClaimKeys]);
3356
3652
  const [profileUser, setProfileUser] = useState6(void 0);
3357
3653
  const shouldUseHookData = !user;
3358
- const connectedVenues = useMemo3(() => {
3654
+ const connectedVenues = useMemo4(() => {
3359
3655
  var _a;
3360
3656
  if (!shouldUseHookData) return [];
3361
3657
  const fromBalance = (_a = balanceState.connectedVenues) != null ? _a : [];
@@ -3414,17 +3710,83 @@ var UserProfilePage = ({
3414
3710
  }),
3415
3711
  [client, onCancelOrder, queryClient]
3416
3712
  );
3713
+ const invalidateClaimUiState = useCallback3(() => {
3714
+ invalidateBalanceQueries(queryClient);
3715
+ invalidatePositionQueries(queryClient);
3716
+ queryClient.invalidateQueries({
3717
+ queryKey: executionKeys.claimablePositionsCount(),
3718
+ refetchType: "active"
3719
+ });
3720
+ invalidateUserActivityQueries(queryClient);
3721
+ }, [queryClient]);
3417
3722
  const handleClaimPosition = useCallback3(
3418
3723
  (position) => __async(null, null, function* () {
3419
3724
  var _a, _b;
3420
- if (onClaim) {
3421
- yield onClaim(position);
3725
+ const claimKey = (_a = position.marketId) != null ? _a : position.id;
3726
+ if (activeClaimKeysRef.current.has(claimKey) || (claimingPositionKeys == null ? void 0 : claimingPositionKeys[claimKey]) || internalClaimingIds[claimKey]) {
3422
3727
  return;
3423
3728
  }
3424
- const venueMarketOutcomeIds = (_a = position.winningOutcomeIds) != null ? _a : [];
3425
- if (venueMarketOutcomeIds.length === 0) return;
3426
- const claimKey = (_b = position.marketId) != null ? _b : position.id;
3729
+ activeClaimKeysRef.current.add(claimKey);
3427
3730
  setSubmittingClaimKeys((prev) => __spreadProps(__spreadValues({}, prev), { [claimKey]: true }));
3731
+ const pendingToastId = toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.pendingMessage, {
3732
+ title: claimNotificationLabels.pendingTitle,
3733
+ tone: "info"
3734
+ });
3735
+ if (pendingToastId != null) {
3736
+ pendingClaimToastIdsRef.current[claimKey] = pendingToastId;
3737
+ }
3738
+ if (onClaim) {
3739
+ try {
3740
+ yield onClaim(position);
3741
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
3742
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
3743
+ delete pendingClaimToastIdsRef.current[claimKey];
3744
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.successMessage, {
3745
+ title: claimNotificationLabels.successTitle,
3746
+ tone: "success"
3747
+ });
3748
+ } catch (err) {
3749
+ const error = toClaimError(err);
3750
+ console.error("[UserProfilePage] redeem failed", error);
3751
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
3752
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
3753
+ delete pendingClaimToastIdsRef.current[claimKey];
3754
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
3755
+ title: claimNotificationLabels.failedTitle,
3756
+ tone: "error"
3757
+ });
3758
+ onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
3759
+ throw error;
3760
+ } finally {
3761
+ invalidateClaimUiState();
3762
+ activeClaimKeysRef.current.delete(claimKey);
3763
+ setSubmittingClaimKeys((prev) => {
3764
+ const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
3765
+ return rest;
3766
+ });
3767
+ }
3768
+ return;
3769
+ }
3770
+ const venueMarketOutcomeIds = (_b = position.winningOutcomeIds) != null ? _b : [];
3771
+ if (venueMarketOutcomeIds.length === 0) {
3772
+ const error = new Error(claimNotificationLabels.missingOutcomeMessage);
3773
+ console.error("[UserProfilePage] redeem failed", error);
3774
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
3775
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
3776
+ delete pendingClaimToastIdsRef.current[claimKey];
3777
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
3778
+ title: claimNotificationLabels.failedTitle,
3779
+ tone: "error"
3780
+ });
3781
+ onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
3782
+ invalidateClaimUiState();
3783
+ activeClaimKeysRef.current.delete(claimKey);
3784
+ setSubmittingClaimKeys((prev) => {
3785
+ const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
3786
+ return rest;
3787
+ });
3788
+ throw error;
3789
+ }
3428
3790
  try {
3429
3791
  const response = yield redeemMutation.mutateAsync({ venueMarketOutcomeIds });
3430
3792
  const expectedOutcomeIds = [];
@@ -3443,6 +3805,16 @@ var UserProfilePage = ({
3443
3805
  preFailedReasons[result.venueMarketOutcomeId] = result.reason;
3444
3806
  }
3445
3807
  }
3808
+ if (expectedOutcomeIds.length > 0) {
3809
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
3810
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
3811
+ delete pendingClaimToastIdsRef.current[claimKey];
3812
+ submittedClaimToastKeysRef.current.add(claimKey);
3813
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.submittedMessage, {
3814
+ title: claimNotificationLabels.submittedTitle,
3815
+ tone: "success"
3816
+ });
3817
+ }
3446
3818
  setActiveRedeems((prev) => __spreadProps(__spreadValues({}, prev), {
3447
3819
  [claimKey]: {
3448
3820
  redeemId: response.redeemId,
@@ -3455,19 +3827,40 @@ var UserProfilePage = ({
3455
3827
  }));
3456
3828
  yield queryClient.invalidateQueries({ queryKey: ["current-user"] });
3457
3829
  } catch (err) {
3458
- console.error("[UserProfilePage] redeem failed", err);
3459
- onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, err instanceof Error ? err : new Error(String(err)));
3830
+ const error = toClaimError(err);
3831
+ console.error("[UserProfilePage] redeem failed", error);
3832
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
3833
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
3834
+ delete pendingClaimToastIdsRef.current[claimKey];
3835
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage(error.message), {
3836
+ title: claimNotificationLabels.failedTitle,
3837
+ tone: "error"
3838
+ });
3839
+ onClaimSubmitError == null ? void 0 : onClaimSubmitError(claimKey, error);
3840
+ throw error;
3460
3841
  } finally {
3842
+ activeClaimKeysRef.current.delete(claimKey);
3461
3843
  setSubmittingClaimKeys((prev) => {
3462
3844
  const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
3463
3845
  return rest;
3464
3846
  });
3465
3847
  }
3466
3848
  }),
3467
- [onClaim, onClaimSubmitError, queryClient, redeemMutation]
3849
+ [
3850
+ claimingPositionKeys,
3851
+ claimNotificationLabels,
3852
+ invalidateClaimUiState,
3853
+ internalClaimingIds,
3854
+ onClaim,
3855
+ onClaimSubmitError,
3856
+ queryClient,
3857
+ redeemMutation,
3858
+ toastCtx
3859
+ ]
3468
3860
  );
3469
3861
  const firedTerminalRef = useRef5({});
3470
3862
  useEffect5(() => {
3863
+ var _a, _b;
3471
3864
  for (const [claimKey, active] of Object.entries(activeRedeems)) {
3472
3865
  const state = lifecycleStates[active.redeemId];
3473
3866
  if (!state || !state.terminal) continue;
@@ -3478,17 +3871,46 @@ var UserProfilePage = ({
3478
3871
  anyFailed: state.anyFailed,
3479
3872
  errorMessage: state.errorMessage
3480
3873
  });
3481
- void queryClient.invalidateQueries({ queryKey: executionKeys.positionsPrefix() });
3482
- void queryClient.invalidateQueries({
3483
- queryKey: executionKeys.claimableClosedPositionsCount()
3484
- });
3874
+ const pendingId = pendingClaimToastIdsRef.current[claimKey];
3875
+ if (pendingId != null) toastCtx == null ? void 0 : toastCtx.dismiss(pendingId);
3876
+ delete pendingClaimToastIdsRef.current[claimKey];
3877
+ if (state.allConfirmed) {
3878
+ if (!submittedClaimToastKeysRef.current.has(claimKey)) {
3879
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.successMessage, {
3880
+ title: claimNotificationLabels.successTitle,
3881
+ tone: "success"
3882
+ });
3883
+ }
3884
+ } else if (state.anyFailed) {
3885
+ const hasConfirmedLeg = Object.values(state.legs).some((leg) => leg.status === "confirmed");
3886
+ if (hasConfirmedLeg) {
3887
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.partialMessage((_a = state.errorMessage) != null ? _a : void 0), {
3888
+ title: claimNotificationLabels.partialTitle,
3889
+ tone: "warning"
3890
+ });
3891
+ } else {
3892
+ toastCtx == null ? void 0 : toastCtx.toast(claimNotificationLabels.failedMessage((_b = state.errorMessage) != null ? _b : void 0), {
3893
+ title: claimNotificationLabels.failedTitle,
3894
+ tone: "error"
3895
+ });
3896
+ }
3897
+ }
3898
+ submittedClaimToastKeysRef.current.delete(claimKey);
3899
+ invalidateClaimUiState();
3485
3900
  delete firedTerminalRef.current[active.redeemId];
3486
3901
  setActiveRedeems((prev) => {
3487
- const _a = prev, { [claimKey]: _removed } = _a, rest = __objRest(_a, [__restKey(claimKey)]);
3902
+ const _a2 = prev, { [claimKey]: _removed } = _a2, rest = __objRest(_a2, [__restKey(claimKey)]);
3488
3903
  return rest;
3489
3904
  });
3490
3905
  }
3491
- }, [activeRedeems, lifecycleStates, onClaimResult, queryClient]);
3906
+ }, [
3907
+ activeRedeems,
3908
+ claimNotificationLabels,
3909
+ invalidateClaimUiState,
3910
+ lifecycleStates,
3911
+ onClaimResult,
3912
+ toastCtx
3913
+ ]);
3492
3914
  useEffect5(() => {
3493
3915
  if (!shouldUseHookData || !isAuthenticated) {
3494
3916
  setProfileUser(void 0);
@@ -3508,7 +3930,7 @@ var UserProfilePage = ({
3508
3930
  isActive = false;
3509
3931
  };
3510
3932
  }, [client, currentUser, isAuthenticated, shouldUseHookData]);
3511
- const resolvedUser = useMemo3(() => {
3933
+ const resolvedUser = useMemo4(() => {
3512
3934
  var _a, _b, _c, _d, _e, _f;
3513
3935
  if (user) return user;
3514
3936
  const fullUser = profileUser != null ? profileUser : currentUser;
@@ -3542,7 +3964,7 @@ var UserProfilePage = ({
3542
3964
  socialHandle: normalizedTwitterHandle != null ? normalizedTwitterHandle : void 0
3543
3965
  };
3544
3966
  }, [connectedVenues, currentUser, profileUser, user]);
3545
- const _resolvedVenueBalances = useMemo3(() => {
3967
+ const _resolvedVenueBalances = useMemo4(() => {
3546
3968
  if (_venueBalances) return _venueBalances;
3547
3969
  return balanceState.balanceBreakdown.map((item) => ({
3548
3970
  chain: item.label,
@@ -3550,7 +3972,7 @@ var UserProfilePage = ({
3550
3972
  balanceLabel: formatUsd(item.balance)
3551
3973
  }));
3552
3974
  }, [_venueBalances, balanceState.balanceBreakdown]);
3553
- const positionsValueLabel = useMemo3(() => {
3975
+ const positionsValueLabel = useMemo4(() => {
3554
3976
  var _a;
3555
3977
  if (balance == null ? void 0 : balance.totalLabel) return balance.totalLabel;
3556
3978
  const managed = balanceState.managedBalances;
@@ -3558,95 +3980,97 @@ var UserProfilePage = ({
3558
3980
  const positionsValueTotal = positions.reduce((sum, p) => sum + (Number(p.balance) || 0), 0);
3559
3981
  return formatUsd(positionsValueTotal);
3560
3982
  }, [balance, balanceState]);
3561
- const availableBalanceLabel = useMemo3(() => {
3983
+ const availableBalanceLabel = useMemo4(() => {
3562
3984
  var _a;
3563
3985
  return formatUsd((_a = balanceState.totalBalance) != null ? _a : 0);
3564
3986
  }, [balanceState.totalBalance]);
3565
3987
  const isPositionsValueLoading = !(balance == null ? void 0 : balance.totalLabel) && balanceState.isLoading;
3566
3988
  const isAvailableBalanceLoading = balanceState.isLoading;
3567
- const resolvedActivities = useMemo3(() => {
3989
+ const resolvedActivities = useMemo4(() => {
3568
3990
  if (activities) return activities.filter(isVisibleUserProfileActivity);
3569
3991
  const formatTime = isHydrated ? toRelativeTimeLabel : toAbsoluteTimeLabel;
3570
3992
  const fullUser = profileUser != null ? profileUser : currentUser;
3571
3993
  const connectedWalletAddresses = getConnectedWalletAccountAddresses(fullUser);
3572
- return activityQuery.activities.filter(isVisibleActivityItem).map((item) => {
3573
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
3574
- const timeLabel = formatTime(item.createdAt);
3994
+ return activityQuery.activities.filter(isVisibleActivityItem).map((item, index) => {
3995
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
3996
+ const timeLabel = formatTime(getRuntimeActivityCreatedAt(item));
3575
3997
  if (item.type === "trade") {
3576
3998
  const tradeItem = item;
3577
- const sideLower = item.side.toLowerCase();
3999
+ const sideLower = tradeItem.side.toLowerCase();
3578
4000
  const type = sideLower === "sell" ? "Sell" : "Buy";
3579
- const status = normalizeTradeStatus(item.status);
3580
- const isFailed = item.status.toLowerCase() === "failed";
3581
- const hasError = hasActivityError(item);
4001
+ const status = normalizeTradeStatus(tradeItem.status);
4002
+ const isFailed = tradeItem.status.toLowerCase() === "failed";
4003
+ const hasError = hasActivityError(tradeItem);
3582
4004
  const eventId = (_b = (_a = tradeItem.venueMarket) == null ? void 0 : _a.venueEventId) != null ? _b : void 0;
3583
4005
  const marketId = (_d = (_c = tradeItem.venueMarket) == null ? void 0 : _c.id) != null ? _d : void 0;
3584
4006
  const marketQuestion = (_g = (_f = (_e = tradeItem.venueMarket) == null ? void 0 : _e.question) != null ? _f : tradeItem.marketQuestion) != null ? _g : "Market";
3585
4007
  const outcomeLabel = (_l = (_k = (_j = (_h = tradeItem.venueMarketOutcome) == null ? void 0 : _h.title) != null ? _j : (_i = tradeItem.venueMarketOutcome) == null ? void 0 : _i.label) != null ? _k : tradeItem.outcomeLabel) != null ? _l : "";
3586
4008
  return {
3587
4009
  kind: "trade",
3588
- id: item.id,
4010
+ id: tradeItem.id,
3589
4011
  eventId,
3590
4012
  marketId,
3591
4013
  isFailed,
3592
4014
  hasError,
3593
- errorMessage: (_m = item.errorMessage) != null ? _m : void 0,
4015
+ errorMessage: (_m = tradeItem.errorMessage) != null ? _m : void 0,
3594
4016
  status,
3595
4017
  type,
3596
4018
  thumbnailSrc: toTradeThumbnailSrc(tradeItem, ordersQuery.orders),
3597
4019
  title: marketQuestion,
3598
- venue: item.venue,
4020
+ venue: tradeItem.venue,
3599
4021
  outcomeLabel,
3600
- sharesLabel: isFailed ? "-" : `${formatTradeQuantityTwoDecimals(item.executionPrice, item.filledAmountRaw)} shares`,
4022
+ sharesLabel: isFailed ? "-" : `${formatTradeQuantityTwoDecimals(tradeItem.executionPrice, tradeItem.filledAmountRaw)} shares`,
3601
4023
  amountLabel: isFailed ? "-" : toSignedAmountLabel(
3602
4024
  sideLower === "sell" ? "+" : "-",
3603
- item.executionPrice,
3604
- item.filledAmountRaw
4025
+ tradeItem.executionPrice,
4026
+ tradeItem.filledAmountRaw
3605
4027
  ),
3606
4028
  timeLabel
3607
4029
  };
3608
4030
  }
3609
4031
  if (item.type === "withdrawal") {
3610
- const normalizedStatus = normalizeWithdrawalStatus(item.status);
3611
- const timedOut = normalizedStatus === "pending" && isPendingTransferTimedOut(item.createdAt);
4032
+ const withdrawalItem = item;
4033
+ const normalizedStatus = normalizeWithdrawalStatus(withdrawalItem.status);
4034
+ const timedOut = normalizedStatus === "pending" && isPendingTransferTimedOut(withdrawalItem.createdAt);
3612
4035
  const status = timedOut ? "failed" : normalizedStatus;
3613
- const errorMessage = timedOut ? PENDING_TRANSFER_TIMEOUT_ERROR_MESSAGE : (_n = item.errorMessage) != null ? _n : void 0;
4036
+ const errorMessage = timedOut ? PENDING_TRANSFER_TIMEOUT_ERROR_MESSAGE : (_n = withdrawalItem.errorMessage) != null ? _n : void 0;
3614
4037
  const isFailed = status === "failed";
3615
- const hasError = timedOut || hasActivityError(item);
4038
+ const hasError = timedOut || hasActivityError(withdrawalItem);
3616
4039
  const titleByStatus = labels.userProfile.activity.withdrawalStatusTitles;
3617
- const settledWithdrawalAmountRaw = status === "completed" ? (_o = item.completedAmountRaw) != null ? _o : item.amountRaw : item.amountRaw;
4040
+ const settledWithdrawalAmountRaw = status === "completed" ? (_o = withdrawalItem.completedAmountRaw) != null ? _o : withdrawalItem.amountRaw : withdrawalItem.amountRaw;
3618
4041
  const amountLabel = status === "failed" || status === "canceled" ? ZERO_AMOUNT_LABEL : toTokenAmountLabel({
3619
4042
  amountRaw: settledWithdrawalAmountRaw,
3620
- chainId: item.destinationChainId,
3621
- tokenSymbol: item.tokenSymbol,
4043
+ chainId: withdrawalItem.destinationChainId,
4044
+ tokenSymbol: withdrawalItem.tokenSymbol,
3622
4045
  sign: "-"
3623
4046
  });
3624
4047
  return {
3625
4048
  kind: "withdrawal",
3626
- id: item.id,
4049
+ id: withdrawalItem.id,
3627
4050
  isFailed,
3628
4051
  hasError,
3629
4052
  errorMessage,
3630
4053
  status,
3631
4054
  type: labels.userProfile.activity.withdrawalType,
3632
4055
  title: titleByStatus[status],
3633
- subtitleLabel: `to ${(_p = shortenAddress(item.destinationAddress)) != null ? _p : item.destinationAddress} \xB7 ${formatChainIdLabel(item.destinationChainId)}`,
4056
+ subtitleLabel: `to ${(_p = shortenAddress(withdrawalItem.destinationAddress)) != null ? _p : withdrawalItem.destinationAddress} \xB7 ${formatChainIdLabel(withdrawalItem.destinationChainId)}`,
3634
4057
  amountLabel,
3635
4058
  timeLabel
3636
4059
  };
3637
4060
  }
3638
4061
  if (item.type === "deposit") {
3639
- const normalizedStatus = normalizeDepositStatus(item.status);
3640
- const timedOut = normalizedStatus === "pending" && isPendingTransferTimedOut(item.createdAt);
4062
+ const depositItem = item;
4063
+ const normalizedStatus = normalizeDepositStatus(depositItem.status);
4064
+ const timedOut = normalizedStatus === "pending" && isPendingTransferTimedOut(depositItem.createdAt);
3641
4065
  const status = timedOut ? "failed" : normalizedStatus;
3642
- const errorMessage = timedOut ? PENDING_TRANSFER_TIMEOUT_ERROR_MESSAGE : (_q = getActivityErrorMessage(item)) != null ? _q : void 0;
4066
+ const errorMessage = timedOut ? PENDING_TRANSFER_TIMEOUT_ERROR_MESSAGE : (_q = getActivityErrorMessage(depositItem)) != null ? _q : void 0;
3643
4067
  const isFailed = status === "failed";
3644
- const hasError = timedOut || hasActivityError(item);
4068
+ const hasError = timedOut || hasActivityError(depositItem);
3645
4069
  const depositSource = resolveDepositActivitySource({
3646
- fromAddress: item.fromAddress,
3647
- chainId: item.chainId,
4070
+ fromAddress: depositItem.fromAddress,
4071
+ chainId: depositItem.chainId,
3648
4072
  connectedWalletAddresses,
3649
- depositAddress: depositAddressesQuery.getAddress(toNumericChainId(item.chainId))
4073
+ depositAddress: depositAddressesQuery.getAddress(toNumericChainId(depositItem.chainId))
3650
4074
  });
3651
4075
  const depositTitlesBySource = {
3652
4076
  wallet: labels.userProfile.activity.depositStatusTitles.connectedWallet,
@@ -3654,29 +4078,64 @@ var UserProfilePage = ({
3654
4078
  card: labels.userProfile.activity.depositStatusTitles.card
3655
4079
  };
3656
4080
  const amountLabel = status === "failed" || status === "canceled" ? ZERO_AMOUNT_LABEL : toTokenAmountLabel({
3657
- amountRaw: item.amountRaw,
3658
- chainId: item.chainId,
3659
- tokenSymbol: item.tokenSymbol,
4081
+ amountRaw: depositItem.amountRaw,
4082
+ chainId: depositItem.chainId,
4083
+ tokenSymbol: depositItem.tokenSymbol,
3660
4084
  sign: "+"
3661
4085
  });
3662
4086
  return {
3663
4087
  kind: "deposit",
3664
- id: item.id,
4088
+ id: depositItem.id,
3665
4089
  isFailed,
3666
4090
  hasError,
3667
4091
  errorMessage,
3668
4092
  status,
3669
4093
  type: labels.userProfile.activity.depositType,
3670
4094
  title: depositTitlesBySource[depositSource][status],
3671
- subtitleLabel: `from ${(_r = shortenAddress(item.fromAddress)) != null ? _r : item.fromAddress} \xB7 ${formatChainIdLabel(item.chainId)}`,
4095
+ subtitleLabel: `from ${(_r = shortenAddress(depositItem.fromAddress)) != null ? _r : depositItem.fromAddress} \xB7 ${formatChainIdLabel(depositItem.chainId)}`,
3672
4096
  amountLabel,
3673
4097
  timeLabel,
3674
4098
  depositSource,
3675
- chainId: item.chainId
4099
+ chainId: depositItem.chainId
3676
4100
  };
3677
4101
  }
3678
- const _exhaustive = item;
3679
- return _exhaustive;
4102
+ if (item.type === "redeem") {
4103
+ const redeemItem = item;
4104
+ const redeemLegs = Array.isArray(redeemItem.legs) ? redeemItem.legs : [];
4105
+ const firstLeg = redeemLegs[0];
4106
+ const status = getDerivedRedeemStatus(redeemItem);
4107
+ const firstLegErrorMessage = (_t = (_s = redeemLegs.find((leg) => typeof leg.errorMessage === "string" && leg.errorMessage)) == null ? void 0 : _s.errorMessage) != null ? _t : void 0;
4108
+ const errorMessage = (_u = getActivityErrorMessage(redeemItem)) != null ? _u : firstLegErrorMessage;
4109
+ const isFailed = status === "failed";
4110
+ const hasError = isFailed || !!(errorMessage == null ? void 0 : errorMessage.trim());
4111
+ const titleByStatus = labels.userProfile.activity.redeemStatusTitles;
4112
+ return {
4113
+ kind: "redeem",
4114
+ id: redeemItem.id,
4115
+ isFailed,
4116
+ hasError,
4117
+ errorMessage: errorMessage != null ? errorMessage : void 0,
4118
+ status,
4119
+ type: labels.userProfile.activity.redeemType,
4120
+ title: titleByStatus[status],
4121
+ thumbnailSrc: (_w = (_v = firstLeg == null ? void 0 : firstLeg.venueMarket) == null ? void 0 : _v.image) != null ? _w : fallbackThumbnailSrc,
4122
+ marketTitle: (_y = (_x = firstLeg == null ? void 0 : firstLeg.venueMarket) == null ? void 0 : _x.question) != null ? _y : "Market",
4123
+ outcomeLabel: (_C = (_B = (_z = firstLeg == null ? void 0 : firstLeg.venueMarketOutcome) == null ? void 0 : _z.title) != null ? _B : (_A = firstLeg == null ? void 0 : firstLeg.venueMarketOutcome) == null ? void 0 : _A.label) != null ? _C : "",
4124
+ amountLabel: status === "failed" || status === "canceled" ? ZERO_AMOUNT_LABEL : toRedeemPayoutAmountLabel(redeemItem),
4125
+ timeLabel
4126
+ };
4127
+ }
4128
+ logUnknownActivityType(item);
4129
+ return {
4130
+ kind: "unknown",
4131
+ id: getRuntimeActivityId(item, index),
4132
+ status: "completed",
4133
+ type: "Activity",
4134
+ title: "Unsupported activity",
4135
+ subtitleLabel: getRuntimeActivityType(item),
4136
+ amountLabel: ZERO_AMOUNT_LABEL,
4137
+ timeLabel
4138
+ };
3680
4139
  });
3681
4140
  }, [
3682
4141
  activities,
@@ -3688,7 +4147,7 @@ var UserProfilePage = ({
3688
4147
  ordersQuery.orders,
3689
4148
  profileUser
3690
4149
  ]);
3691
- const resolvedOpenOrders = useMemo3(() => {
4150
+ const resolvedOpenOrders = useMemo4(() => {
3692
4151
  if (openOrders) return openOrders;
3693
4152
  return ordersQuery.orders.filter((order) => isOpenOrderStatus(order.status)).map((order) => {
3694
4153
  var _a, _b, _c, _d, _e, _f, _g;
@@ -3775,76 +4234,14 @@ var UserProfilePage = ({
3775
4234
  },
3776
4235
  []
3777
4236
  );
3778
- const resolvedActivePositions = useMemo3(() => {
3779
- const shouldIncludeByShares = (position) => {
3780
- if (SHOW_SOLD_POSITIONS) return true;
3781
- if (typeof position.totalShares !== "number") return true;
3782
- return position.totalShares >= SOLD_POSITION_SHARES_THRESHOLD;
3783
- };
3784
- const classifyPosition = (position) => {
3785
- if (position.marketStatus === "open") return "active";
3786
- if (position.winner === true) {
3787
- return position.closedClaimStatus === "redeemed" ? "closed" : "active";
3788
- }
3789
- if (position.winner === false) return "closed";
3790
- if (position.marketStatus === "closed" || position.marketStatus === "resolved") {
3791
- return "closed";
3792
- }
3793
- return "active";
3794
- };
3795
- const sourcePositions = activePositions || closedPositions ? [...activePositions != null ? activePositions : [], ...closedPositions != null ? closedPositions : []] : [
3796
- ...adaptPositionGroups(activePositionsQuery.positions),
3797
- ...adaptPositionGroups(closedPositionsQuery.positions)
3798
- ];
3799
- const deduped = /* @__PURE__ */ new Map();
3800
- for (const position of sourcePositions) {
3801
- deduped.set(position.id, position);
3802
- }
3803
- return Array.from(deduped.values()).filter(
3804
- (position) => shouldIncludeByShares(position) && classifyPosition(position) === "active"
3805
- );
3806
- }, [
3807
- activePositions,
3808
- activePositionsQuery.positions,
3809
- adaptPositionGroups,
3810
- closedPositions,
3811
- closedPositionsQuery.positions
3812
- ]);
3813
- const resolvedClosedPositions = useMemo3(() => {
3814
- const shouldIncludeByShares = (position) => {
3815
- if (SHOW_SOLD_POSITIONS) return true;
3816
- if (typeof position.totalShares !== "number") return true;
3817
- return position.totalShares >= SOLD_POSITION_SHARES_THRESHOLD;
3818
- };
3819
- const classifyPosition = (position) => {
3820
- if (position.marketStatus === "open") return "active";
3821
- if (position.winner === true) {
3822
- return position.closedClaimStatus === "redeemed" ? "closed" : "active";
3823
- }
3824
- if (position.winner === false) return "closed";
3825
- if (position.marketStatus === "closed" || position.marketStatus === "resolved") {
3826
- return "closed";
3827
- }
3828
- return "active";
3829
- };
3830
- const sourcePositions = activePositions || closedPositions ? [...activePositions != null ? activePositions : [], ...closedPositions != null ? closedPositions : []] : [
3831
- ...adaptPositionGroups(activePositionsQuery.positions),
3832
- ...adaptPositionGroups(closedPositionsQuery.positions)
3833
- ];
3834
- const deduped = /* @__PURE__ */ new Map();
3835
- for (const position of sourcePositions) {
3836
- deduped.set(position.id, position);
3837
- }
3838
- return Array.from(deduped.values()).filter(
3839
- (position) => shouldIncludeByShares(position) && classifyPosition(position) === "closed"
3840
- );
3841
- }, [
3842
- activePositions,
3843
- activePositionsQuery.positions,
3844
- adaptPositionGroups,
3845
- closedPositions,
3846
- closedPositionsQuery.positions
3847
- ]);
4237
+ const resolvedActivePositions = useMemo4(() => {
4238
+ const source = activePositions != null ? activePositions : adaptPositionGroups(activePositionsQuery.positions);
4239
+ return source.filter(shouldIncludeByShares);
4240
+ }, [activePositions, activePositionsQuery.positions, adaptPositionGroups]);
4241
+ const resolvedClosedPositions = useMemo4(() => {
4242
+ const source = closedPositions != null ? closedPositions : adaptPositionGroups(closedPositionsQuery.positions);
4243
+ return source.filter(shouldIncludeByShares);
4244
+ }, [closedPositions, closedPositionsQuery.positions, adaptPositionGroups]);
3848
4245
  return /* @__PURE__ */ jsx11(AggErrorBoundary, { onError, children: /* @__PURE__ */ jsx11(
3849
4246
  "section",
3850
4247
  {