@agg-market/ui 11.0.0 → 12.0.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 (65) hide show
  1. package/README.md +1 -0
  2. package/dist/{chunk-HMUMJUIL.mjs → chunk-AKR2ZSBQ.mjs} +613 -312
  3. package/dist/{chunk-5FSWOXEG.mjs → chunk-TA74OXPL.mjs} +206 -118
  4. package/dist/{chunk-UONHGMFI.mjs → chunk-VMJGQKKU.mjs} +23 -45
  5. package/dist/{chunk-2KGE5AJQ.mjs → chunk-VOYSFL6U.mjs} +66 -131
  6. package/dist/{chunk-IUJXJEDQ.mjs → chunk-XUML4ZJQ.mjs} +836 -645
  7. package/dist/events.js +983 -924
  8. package/dist/events.mjs +2 -2
  9. package/dist/index.js +2879 -2397
  10. package/dist/index.mjs +12 -7
  11. package/dist/modals.js +1020 -864
  12. package/dist/modals.mjs +2 -2
  13. package/dist/pages.js +2162 -1763
  14. package/dist/pages.mjs +4 -4
  15. package/dist/primitives.js +832 -632
  16. package/dist/primitives.mjs +7 -1
  17. package/dist/styles.css +2 -2
  18. package/dist/tailwind.css +2 -2
  19. package/dist/trading.js +793 -673
  20. package/dist/trading.mjs +2 -2
  21. package/dist/types/pages/home/index.d.mts +1 -1
  22. package/dist/types/pages/home/index.d.ts +1 -1
  23. package/dist/types/pages/user-profile/components/available-balance-card.d.mts +17 -0
  24. package/dist/types/pages/user-profile/components/available-balance-card.d.ts +17 -0
  25. package/dist/types/pages/user-profile/components/balance-display.d.mts +3 -5
  26. package/dist/types/pages/user-profile/components/balance-display.d.ts +3 -5
  27. package/dist/types/pages/user-profile/components/positions-activity.d.mts +11 -1
  28. package/dist/types/pages/user-profile/components/positions-activity.d.ts +11 -1
  29. package/dist/types/pages/user-profile/components/positions-value-card.d.mts +10 -0
  30. package/dist/types/pages/user-profile/components/positions-value-card.d.ts +10 -0
  31. package/dist/types/pages/user-profile/components/user-info-card.d.mts +3 -1
  32. package/dist/types/pages/user-profile/components/user-info-card.d.ts +3 -1
  33. package/dist/types/pages/user-profile/index.d.mts +2 -2
  34. package/dist/types/pages/user-profile/index.d.ts +2 -2
  35. package/dist/types/pages/user-profile/user-profile.constants.d.mts +1 -2
  36. package/dist/types/pages/user-profile/user-profile.constants.d.ts +1 -2
  37. package/dist/types/pages/user-profile/user-profile.types.d.mts +29 -16
  38. package/dist/types/pages/user-profile/user-profile.types.d.ts +29 -16
  39. package/dist/types/primitives/icon/index.d.mts +3 -1
  40. package/dist/types/primitives/icon/index.d.ts +3 -1
  41. package/dist/types/primitives/icon/registry.d.mts +8 -0
  42. package/dist/types/primitives/icon/registry.d.ts +8 -0
  43. package/dist/types/primitives/icon/svg/bnb.d.mts +5 -0
  44. package/dist/types/primitives/icon/svg/bnb.d.ts +5 -0
  45. package/dist/types/primitives/icon/svg/polygon.d.mts +5 -0
  46. package/dist/types/primitives/icon/svg/polygon.d.ts +5 -0
  47. package/dist/types/primitives/index.d.mts +1 -0
  48. package/dist/types/primitives/index.d.ts +1 -0
  49. package/dist/types/primitives/skeleton/skeleton.types.d.mts +2 -0
  50. package/dist/types/primitives/skeleton/skeleton.types.d.ts +2 -0
  51. package/dist/types/primitives/skeleton/views/user-profile-overview-skeleton-view.d.mts +5 -0
  52. package/dist/types/primitives/skeleton/views/user-profile-overview-skeleton-view.d.ts +5 -0
  53. package/dist/types/primitives/skeleton/views/user-profile-positions-activity-skeleton-view.d.mts +5 -0
  54. package/dist/types/primitives/skeleton/views/user-profile-positions-activity-skeleton-view.d.ts +5 -0
  55. package/dist/types/primitives/tooltip/index.d.mts +6 -0
  56. package/dist/types/primitives/tooltip/index.d.ts +6 -0
  57. package/dist/types/primitives/tooltip/tooltip.constants.d.mts +2 -0
  58. package/dist/types/primitives/tooltip/tooltip.constants.d.ts +2 -0
  59. package/dist/types/primitives/tooltip/tooltip.types.d.mts +27 -0
  60. package/dist/types/primitives/tooltip/tooltip.types.d.ts +27 -0
  61. package/dist/types/profile/tabs/about-tab.d.mts +1 -1
  62. package/dist/types/profile/tabs/about-tab.d.ts +1 -1
  63. package/dist/types/profile/tabs/accounts-wallets-tab.d.mts +1 -1
  64. package/dist/types/profile/tabs/accounts-wallets-tab.d.ts +1 -1
  65. package/package.json +2 -1
@@ -7,11 +7,11 @@ import {
7
7
  getDefaultEventListTabs,
8
8
  isErrorWithStatus,
9
9
  resolveTabVenus
10
- } from "./chunk-2KGE5AJQ.mjs";
10
+ } from "./chunk-VOYSFL6U.mjs";
11
11
  import {
12
12
  PlaceOrder,
13
13
  Settlement
14
- } from "./chunk-UONHGMFI.mjs";
14
+ } from "./chunk-VMJGQKKU.mjs";
15
15
  import {
16
16
  Button,
17
17
  Card,
@@ -19,15 +19,20 @@ import {
19
19
  Icon,
20
20
  Modal,
21
21
  RemoteImage,
22
+ SearchEmptyIcon,
22
23
  Skeleton,
23
24
  StateMessage,
24
25
  Tabs,
26
+ Tooltip,
25
27
  Typography,
26
28
  VenueLogo,
27
29
  __spreadProps,
28
30
  __spreadValues,
29
- cn
30
- } from "./chunk-IUJXJEDQ.mjs";
31
+ cn,
32
+ skeletonViews,
33
+ venueLogoLabels,
34
+ venueLogoUrlRegistry
35
+ } from "./chunk-XUML4ZJQ.mjs";
31
36
 
32
37
  // src/pages/home/index.tsx
33
38
  import { useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
@@ -40,23 +45,19 @@ import dayjs from "dayjs";
40
45
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
41
46
  var resolveHeroMarketId = (event, heroMarketId) => {
42
47
  var _a, _b;
43
- if (!((_a = event == null ? void 0 : event.venueMarkets) == null ? void 0 : _a.length))
44
- return void 0;
48
+ if (!((_a = event == null ? void 0 : event.venueMarkets) == null ? void 0 : _a.length)) return void 0;
45
49
  if (heroMarketId) {
46
50
  const matchingHeroMarket = event.venueMarkets.find(
47
51
  (market) => market.id === heroMarketId
48
52
  );
49
- if (matchingHeroMarket)
50
- return matchingHeroMarket.id;
53
+ if (matchingHeroMarket) return matchingHeroMarket.id;
51
54
  }
52
55
  return (_b = event.venueMarkets[0]) == null ? void 0 : _b.id;
53
56
  };
54
57
  var buildHeroEvent = (event, heroMarketId) => {
55
- if (!heroMarketId)
56
- return void 0;
58
+ if (!heroMarketId) return void 0;
57
59
  const heroMarket = event.venueMarkets.find((market) => market.id === heroMarketId);
58
- if (!heroMarket)
59
- return void 0;
60
+ if (!heroMarket) return void 0;
60
61
  return __spreadProps(__spreadValues({}, event), {
61
62
  venueMarkets: [heroMarket]
62
63
  });
@@ -363,8 +364,7 @@ var resolveCategoryTabs = (categories, allCategoryTabLabel) => {
363
364
  }
364
365
  ];
365
366
  for (const category of categories) {
366
- if (seenCategoryIds.has(category.id))
367
- continue;
367
+ if (seenCategoryIds.has(category.id)) continue;
368
368
  seenCategoryIds.add(category.id);
369
369
  tabs.push({
370
370
  value: category.id,
@@ -378,8 +378,7 @@ var resolveInitialTabValue = (tabs, defaultActiveTab) => {
378
378
  var _a, _b;
379
379
  if (defaultActiveTab) {
380
380
  const hasDefaultTab = tabs.some((tab) => tab.value === defaultActiveTab);
381
- if (hasDefaultTab)
382
- return defaultActiveTab;
381
+ if (hasDefaultTab) return defaultActiveTab;
383
382
  }
384
383
  return (_b = (_a = tabs[0]) == null ? void 0 : _a.value) != null ? _b : ALL_CATEGORIES_TAB_VALUE;
385
384
  };
@@ -391,9 +390,7 @@ var SEARCH_DEBOUNCE_MS = 300;
391
390
  var SEARCH_RESULTS_LIMIT = 9;
392
391
  var HomeSearchResults = ({
393
392
  activeTabValue,
394
- onTabChange,
395
393
  query,
396
- tabs,
397
394
  resolvedTabs,
398
395
  className
399
396
  }) => {
@@ -418,18 +415,14 @@ var HomeSearchResults = ({
418
415
  });
419
416
  const loadMoreRef = useRef(null);
420
417
  useEffect2(() => {
421
- if (!hasNextPage)
422
- return;
418
+ if (!hasNextPage) return;
423
419
  const target = loadMoreRef.current;
424
- if (!target)
425
- return;
420
+ if (!target) return;
426
421
  const observer = new IntersectionObserver(
427
422
  (entries) => {
428
423
  const entry = entries[0];
429
- if (!(entry == null ? void 0 : entry.isIntersecting))
430
- return;
431
- if (isLoading || isFetchingNextPage || !hasNextPage)
432
- return;
424
+ if (!(entry == null ? void 0 : entry.isIntersecting)) return;
425
+ if (isLoading || isFetchingNextPage || !hasNextPage) return;
433
426
  void fetchNextPage();
434
427
  },
435
428
  {
@@ -496,8 +489,7 @@ var HomeSearchResults = ({
496
489
  root: "w-full min-w-0 max-w-none"
497
490
  },
498
491
  onClick: (selectedEvent) => {
499
- if (!selectedEvent)
500
- return;
492
+ if (!selectedEvent) return;
501
493
  searchConfig.onSelect(selectedEvent);
502
494
  }
503
495
  },
@@ -536,7 +528,7 @@ var HomeSearchResults = ({
536
528
  var HomePage = ({
537
529
  tabs,
538
530
  defaultActiveTab,
539
- onTabChange,
531
+ onTabChange: _onTabChange,
540
532
  eventSectionItems,
541
533
  classNames,
542
534
  categoriesLimit = DEFAULT_CATEGORIES_LIMIT,
@@ -569,7 +561,7 @@ var HomePage = ({
569
561
  };
570
562
  }, [normalizedSearchValue]);
571
563
  const resolvedAllCategoryTabLabel = allCategoryTabLabel === DEFAULT_ALL_CATEGORY_TAB_LABEL ? labels.home.trending : allCategoryTabLabel;
572
- const { categories, isLoading: isCategoriesLoading } = useCategories({
564
+ const { categories } = useCategories({
573
565
  limit: categoriesLimit,
574
566
  enabled: !hasCustomTabs
575
567
  });
@@ -577,8 +569,7 @@ var HomePage = ({
577
569
  return resolveCategoryTabs(categories, resolvedAllCategoryTabLabel);
578
570
  }, [categories, resolvedAllCategoryTabLabel]);
579
571
  const resolvedTabs = useMemo2(() => {
580
- if (hasCustomTabs && tabs)
581
- return tabs;
572
+ if (hasCustomTabs && tabs) return tabs;
582
573
  return categoryTabs;
583
574
  }, [categoryTabs, hasCustomTabs, tabs]);
584
575
  const resolvedEventSectionItems = eventSectionItems && eventSectionItems.length > 0 ? eventSectionItems : getDefaultEventSectionItems(labels);
@@ -588,8 +579,7 @@ var HomePage = ({
588
579
  useEffect2(() => {
589
580
  setActiveTabValue((currentValue) => {
590
581
  const hasCurrentValue = resolvedTabs.some((tab) => tab.value === currentValue);
591
- if (hasCurrentValue)
592
- return currentValue;
582
+ if (hasCurrentValue) return currentValue;
593
583
  return resolveInitialTabValue(resolvedTabs, defaultActiveTab);
594
584
  });
595
585
  }, [defaultActiveTab, resolvedTabs]);
@@ -636,7 +626,7 @@ var HomePage = ({
636
626
  }, [activeTab, activeTabValue, resolvedEventSectionItems]);
637
627
  const handleTabChange = (value) => {
638
628
  setActiveTabValue(value);
639
- onTabChange == null ? void 0 : onTabChange(value);
629
+ _onTabChange == null ? void 0 : _onTabChange(value);
640
630
  };
641
631
  return /* @__PURE__ */ jsxs2("section", { className: cn("flex w-full flex-col", classNames == null ? void 0 : classNames.root), children: [
642
632
  /* @__PURE__ */ jsx2(Header, { searchProps: {} }),
@@ -671,9 +661,7 @@ var HomePage = ({
671
661
  HomeSearchResults,
672
662
  {
673
663
  activeTabValue,
674
- onTabChange: handleTabChange,
675
664
  query: debouncedSearchValue,
676
- tabs: tabsItems,
677
665
  resolvedTabs
678
666
  }
679
667
  ) : resolvedSectionItems.map((eventSectionItem) => {
@@ -688,8 +676,7 @@ var HomePage = ({
688
676
  search: debouncedSearchValue || eventSectionItem.search || (activeTab == null ? void 0 : activeTab.search),
689
677
  categoryIds: (_b = eventSectionItem.categoryIds) != null ? _b : activeTab == null ? void 0 : activeTab.categoryIds,
690
678
  onClick: (event) => {
691
- if (!event)
692
- return;
679
+ if (!event) return;
693
680
  onSelectEvent(event);
694
681
  }
695
682
  },
@@ -702,134 +689,194 @@ var HomePage = ({
702
689
  };
703
690
  HomePage.displayName = "HomePage";
704
691
 
705
- // src/pages/user-profile/components/balance-display.tsx
706
- import { useState as useState3 } from "react";
707
-
708
- // src/pages/user-profile/user-profile.constants.ts
709
- var USER_PROFILE_TAB_POSITIONS = "positions";
710
- var USER_PROFILE_TAB_ACTIVITY = "activity";
711
- var USER_PROFILE_TIME_RANGES = ["1D", "1W", "1M", "All"];
712
- var USER_PROFILE_POSITION_FILTERS = [
713
- { value: "active", label: "Active" },
714
- { value: "closed", label: "Closed" }
715
- ];
692
+ // src/pages/user-profile/index.tsx
693
+ import { useMemo as useMemo4 } from "react";
694
+ import {
695
+ getWalletAddressFromUserProfile,
696
+ useAggBalance,
697
+ useAggAuthState,
698
+ useExecutionOrders,
699
+ useExecutionPositions
700
+ } from "@agg-market/hooks";
716
701
 
717
- // src/pages/user-profile/components/balance-display.tsx
702
+ // src/pages/user-profile/components/positions-value-card.tsx
718
703
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
719
- var BalanceDisplay = ({
720
- balance,
721
- defaultTimeRange = "All",
722
- onTimeRangeChange,
704
+ var PositionsValueCard = ({
705
+ label = "Positions Value",
706
+ valueLabel,
723
707
  className
724
708
  }) => {
725
- var _a, _b;
726
- const [activeRange, setActiveRange] = useState3(defaultTimeRange);
727
- const currentBalance = balance == null ? void 0 : balance[activeRange];
728
- const handleRangeChange = (range) => {
729
- setActiveRange(range);
730
- onTimeRangeChange == null ? void 0 : onTimeRangeChange(range);
731
- };
732
709
  return /* @__PURE__ */ jsxs3(
733
710
  "div",
734
711
  {
735
712
  className: cn(
736
- "flex items-end justify-between overflow-clip rounded-agg-md border border-agg-separator bg-agg-secondary p-5",
713
+ "flex h-full flex-col gap-3 rounded-agg-md border border-agg-separator bg-agg-secondary p-5",
737
714
  className
738
715
  ),
739
716
  children: [
740
- /* @__PURE__ */ jsxs3("div", { className: "flex items-end gap-3", children: [
741
- /* @__PURE__ */ jsx3("span", { className: "agg-type-display text-agg-foreground", children: (_a = currentBalance == null ? void 0 : currentBalance.totalLabel) != null ? _a : "$0.00" }),
742
- /* @__PURE__ */ jsx3("span", { className: "font-agg-sans text-agg-base leading-6 font-agg-normal text-agg-muted-foreground", children: "Profit/Loss" }),
743
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
744
- /* @__PURE__ */ jsx3(
745
- "span",
746
- {
747
- className: cn(
748
- "font-agg-sans text-agg-base leading-6 font-agg-bold",
749
- (currentBalance == null ? void 0 : currentBalance.isPositive) ? "text-agg-success" : "text-agg-error"
750
- ),
751
- children: (_b = currentBalance == null ? void 0 : currentBalance.changePercentLabel) != null ? _b : "0%"
752
- }
753
- ),
754
- /* @__PURE__ */ jsx3(
755
- Icon,
756
- {
757
- name: "triangle-up-filled",
758
- size: "small",
759
- className: cn(
760
- (currentBalance == null ? void 0 : currentBalance.isPositive) ? "text-agg-success" : "rotate-180 text-agg-error"
761
- )
762
- }
763
- )
764
- ] })
765
- ] }),
766
- /* @__PURE__ */ jsx3("div", { className: "flex w-[100px] items-center justify-between", children: USER_PROFILE_TIME_RANGES.map((range) => {
767
- const isActive = range === activeRange;
768
- return /* @__PURE__ */ jsx3(
769
- "button",
717
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
718
+ /* @__PURE__ */ jsx3(
719
+ "svg",
770
720
  {
771
- type: "button",
772
- onClick: () => handleRangeChange(range),
773
- className: cn(
774
- "cursor-pointer bg-transparent font-agg-sans text-agg-sm leading-agg-5",
775
- isActive ? "font-agg-bold text-agg-foreground" : "font-agg-normal text-agg-muted-foreground hover:text-agg-foreground"
776
- ),
777
- children: range
778
- },
779
- range
780
- );
781
- }) })
721
+ xmlns: "http://www.w3.org/2000/svg",
722
+ width: "16",
723
+ height: "16",
724
+ viewBox: "0 0 16 16",
725
+ fill: "none",
726
+ children: /* @__PURE__ */ jsx3(
727
+ "path",
728
+ {
729
+ d: "M16 7.99957C16 8.36757 15.702 8.66623 15.3333 8.66623H13.6893C13.388 8.66623 13.1233 8.86957 13.0453 9.15957L11.9273 13.3209C11.8 13.7376 11.444 13.9996 11.0333 13.9996H11.022C10.6067 13.9949 10.252 13.7229 10.1393 13.3236L7.95667 4.50623L5.838 11.9989C5.71067 12.3969 5.378 12.6496 4.98467 12.6649C4.57667 12.6869 4.23867 12.4549 4.088 12.0902L3.02133 9.10757C2.926 8.84357 2.674 8.66557 2.39333 8.66557H0.666667C0.298 8.66557 0 8.3669 0 7.9989C0 7.6309 0.298 7.33223 0.666667 7.33223H2.394C3.23667 7.33223 3.99267 7.8649 4.27733 8.65823L4.90267 10.4089L7.092 2.66557C7.226 2.2489 7.57667 1.9809 7.99933 1.9989C8.41133 2.00623 8.76333 2.27757 8.876 2.67357L11.0487 11.4509L11.7567 8.81357C11.9907 7.94157 12.7847 7.33223 13.688 7.33223H15.332C15.7007 7.33223 15.9987 7.6309 15.9987 7.9989L16 7.99957Z",
730
+ fill: "#9D9FAF"
731
+ }
732
+ )
733
+ }
734
+ ),
735
+ /* @__PURE__ */ jsx3("span", { className: "font-agg-sans text-agg-base leading-6 font-agg-normal text-agg-muted-foreground", children: label })
736
+ ] }),
737
+ /* @__PURE__ */ jsx3("div", { className: "font-agg-sans text-agg-2xl leading-8 font-agg-bold text-agg-foreground", children: valueLabel }),
738
+ /* @__PURE__ */ jsx3("div", { className: "flex-1" })
782
739
  ]
783
740
  }
784
741
  );
785
742
  };
786
- BalanceDisplay.displayName = "BalanceDisplay";
743
+ PositionsValueCard.displayName = "PositionsValueCard";
787
744
 
788
- // src/pages/user-profile/components/balances-card.tsx
745
+ // src/pages/user-profile/components/available-balance-card.tsx
789
746
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
790
- var BalancesCard = ({
791
- venueBalances = [],
792
- onDeposit,
793
- onWithdraw,
747
+ var chainIconName = (label) => {
748
+ const key = label.trim().toLowerCase();
749
+ if (key.includes("polygon")) return "polygon";
750
+ if (key.includes("solana")) return "solana";
751
+ if (key.includes("bnb")) return "bnb";
752
+ if (key.includes("base")) return "bnb";
753
+ if (key.includes("arbitrum")) return "bnb";
754
+ if (key.includes("ethereum") || key.includes("eth")) return "ethereum";
755
+ return void 0;
756
+ };
757
+ var AvailableBalanceCard = ({
758
+ label = "Available Balance",
759
+ valueLabel,
760
+ chains,
794
761
  className
795
762
  }) => {
796
763
  return /* @__PURE__ */ jsxs4(
797
764
  "div",
798
765
  {
799
766
  className: cn(
800
- "flex flex-col gap-4 rounded-agg-md border border-agg-separator bg-agg-secondary p-5",
767
+ "flex h-full flex-col gap-3 rounded-agg-md border border-agg-separator bg-agg-secondary p-5",
801
768
  className
802
769
  ),
803
770
  children: [
804
- /* @__PURE__ */ jsx4("h3", { className: "agg-type-body-large-strong text-agg-foreground", children: "Balances" }),
805
- /* @__PURE__ */ jsxs4("div", { className: "relative min-h-0 flex-1 overflow-clip", children: [
806
- /* @__PURE__ */ jsx4("div", { className: "flex max-h-full flex-col gap-3 overflow-y-auto pr-1", children: venueBalances.map((balance, idx) => /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between", children: [
807
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5", children: [
808
- /* @__PURE__ */ jsx4(VenueLogo, { venue: balance.venue, size: "small" }),
809
- /* @__PURE__ */ jsx4("span", { className: "font-agg-sans text-agg-base leading-6 font-agg-normal text-agg-foreground capitalize", children: balance.venue })
810
- ] }),
811
- /* @__PURE__ */ jsx4("span", { className: "font-agg-sans text-agg-base leading-6 font-agg-bold text-agg-foreground", children: balance.balanceLabel })
812
- ] }, `${balance.venue}-${idx}`)) }),
771
+ /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
813
772
  /* @__PURE__ */ jsx4(
814
- "div",
773
+ "svg",
815
774
  {
816
- "aria-hidden": true,
817
- className: "pointer-events-none absolute bottom-0 left-0 h-10 w-full bg-gradient-to-b from-transparent to-white"
775
+ xmlns: "http://www.w3.org/2000/svg",
776
+ width: "16",
777
+ height: "16",
778
+ viewBox: "0 0 16 16",
779
+ fill: "none",
780
+ "aria-hidden": "true",
781
+ focusable: "false",
782
+ children: /* @__PURE__ */ jsx4(
783
+ "path",
784
+ {
785
+ d: "M14 4.00065H3.33333C2.76067 4.00065 2.21867 3.75265 1.84333 3.33465C2.21 2.92532 2.74267 2.66732 3.33333 2.66732H15.3333C15.702 2.66732 16 2.36865 16 2.00065C16 1.63265 15.702 1.33398 15.3333 1.33398H3.33333C1.49267 1.33398 0 2.82665 0 4.66732V11.334C0 13.1747 1.49267 14.6673 3.33333 14.6673H14C15.1047 14.6673 16 13.772 16 12.6673V6.00065C16 4.89598 15.1047 4.00065 14 4.00065ZM14.6667 12.6673C14.6667 13.0347 14.368 13.334 14 13.334H3.33333C2.23067 13.334 1.33333 12.4367 1.33333 11.334V4.66598C1.90267 5.09198 2.60267 5.33398 3.33333 5.33398H14C14.368 5.33398 14.6667 5.63332 14.6667 6.00065V12.6673ZM13.3333 9.33399C13.3333 9.70199 13.0347 10.0007 12.6667 10.0007C12.2987 10.0007 12 9.70199 12 9.33399C12 8.96599 12.2987 8.66732 12.6667 8.66732C13.0347 8.66732 13.3333 8.96599 13.3333 9.33399Z",
786
+ fill: "#9D9FAF"
787
+ }
788
+ )
789
+ }
790
+ ),
791
+ /* @__PURE__ */ jsx4("span", { className: "font-agg-sans text-agg-base leading-6 font-agg-normal text-agg-muted-foreground", children: label })
792
+ ] }) }),
793
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3", children: [
794
+ /* @__PURE__ */ jsx4("div", { className: "font-agg-sans text-agg-2xl leading-8 font-agg-bold text-agg-foreground", children: valueLabel }),
795
+ /* @__PURE__ */ jsx4(
796
+ Tooltip,
797
+ {
798
+ "aria-label": "Balances by chain",
799
+ size: "small",
800
+ side: "top",
801
+ classNames: { content: "border-0" },
802
+ content: /* @__PURE__ */ jsxs4("div", { className: "flex min-w-[280px] max-w-[360px] flex-col gap-2 p-3 sm:p-4", children: [
803
+ /* @__PURE__ */ jsx4("div", { className: "font-agg-sans text-agg-sm leading-5 font-agg-bold text-agg-foreground", children: "Balance by network" }),
804
+ /* @__PURE__ */ jsx4("div", { role: "list", className: "divide-y divide-agg-separator/60", children: chains.map((row) => {
805
+ const icon = chainIconName(row.label);
806
+ return /* @__PURE__ */ jsxs4(
807
+ "div",
808
+ {
809
+ role: "listitem",
810
+ className: "grid grid-cols-[1fr_auto] items-center gap-x-4 py-2 first:pt-0 last:pb-0",
811
+ children: [
812
+ /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 items-center gap-2", children: [
813
+ icon ? /* @__PURE__ */ jsx4(Icon, { name: icon, size: "small", className: "text-agg-foreground" }) : /* @__PURE__ */ jsx4("span", { className: "flex h-5 w-5 items-center justify-center rounded-agg-sm border border-agg-separator text-agg-xs text-agg-muted-foreground", children: row.label.slice(0, 2).toUpperCase() }),
814
+ /* @__PURE__ */ jsx4("span", { className: "truncate font-agg-sans text-agg-sm leading-5 font-agg-normal text-agg-foreground", children: row.label })
815
+ ] }),
816
+ /* @__PURE__ */ jsx4("span", { className: "shrink-0 whitespace-nowrap tabular-nums font-agg-sans text-agg-sm leading-5 font-agg-bold text-agg-foreground", children: row.balance.toLocaleString("en-US", {
817
+ style: "currency",
818
+ currency: "USD",
819
+ minimumFractionDigits: 2,
820
+ maximumFractionDigits: 2
821
+ }) })
822
+ ]
823
+ },
824
+ row.key
825
+ );
826
+ }) }),
827
+ /* @__PURE__ */ jsx4("div", { className: "mt-1 rounded-agg-md bg-agg-secondary-hover p-3 font-agg-sans text-agg-sm leading-5 font-agg-normal text-agg-foreground", children: "Funds are stored across networks. We handle routing automatically, but keeping funds on the right network enables faster trades and lower fees. When depositing, you can choose your preferred network." })
828
+ ] }),
829
+ children: /* @__PURE__ */ jsxs4(
830
+ "div",
831
+ {
832
+ "data-testid": "balances-by-network-trigger",
833
+ className: "flex min-h-[20px] min-w-[20px] items-center gap-1 rounded-[6px] bg-agg-secondary-hover p-1.5",
834
+ children: [
835
+ (chains.slice(0, 4).length > 0 ? chains.slice(0, 4) : [{ key: "placeholder", label: "", balance: 0, accountCount: 0 }]).map((row) => {
836
+ const icon = chainIconName(row.label);
837
+ return icon ? /* @__PURE__ */ jsx4(
838
+ "span",
839
+ {
840
+ className: "relative z-0 flex h-4 w-4 items-center justify-center rounded-[4px] bg-agg-secondary",
841
+ children: /* @__PURE__ */ jsx4(Icon, { name: icon, size: "small", className: "text-agg-foreground" })
842
+ },
843
+ `icon-${row.key}`
844
+ ) : /* @__PURE__ */ jsx4(
845
+ "span",
846
+ {
847
+ className: "relative z-0 flex h-4 w-4 items-center justify-center rounded-[4px] bg-agg-secondary text-[10px] leading-3 text-agg-muted-foreground",
848
+ children: row.label ? row.label.slice(0, 2).toUpperCase() : ""
849
+ },
850
+ `icon-${row.key}`
851
+ );
852
+ }),
853
+ chains.length > 4 ? /* @__PURE__ */ jsxs4("span", { className: "relative z-0 flex h-4 w-4 items-center justify-center rounded-[4px] bg-agg-secondary font-agg-sans text-[10px] leading-3 text-agg-muted-foreground", children: [
854
+ "+",
855
+ chains.length - 4
856
+ ] }) : null
857
+ ]
858
+ }
859
+ )
818
860
  }
819
861
  )
820
862
  ] }),
821
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-3", children: [
822
- onDeposit ? /* @__PURE__ */ jsx4(Button, { variant: "primary", size: "small", onClick: onDeposit, className: "flex-1", children: "Deposit" }) : null,
823
- onWithdraw ? /* @__PURE__ */ jsx4(Button, { variant: "secondary", size: "small", onClick: onWithdraw, className: "flex-1", children: "Withdraw" }) : null
824
- ] })
863
+ /* @__PURE__ */ jsx4("div", { className: "flex-1" })
825
864
  ]
826
865
  }
827
866
  );
828
867
  };
829
- BalancesCard.displayName = "BalancesCard";
868
+ AvailableBalanceCard.displayName = "AvailableBalanceCard";
830
869
 
831
870
  // src/pages/user-profile/components/positions-activity.tsx
832
- import { useMemo as useMemo3, useState as useState4 } from "react";
871
+ import { useMemo as useMemo3, useState as useState3 } from "react";
872
+
873
+ // src/pages/user-profile/user-profile.constants.ts
874
+ var USER_PROFILE_TAB_POSITIONS = "positions";
875
+ var USER_PROFILE_TAB_ACTIVITY = "activity";
876
+ var USER_PROFILE_POSITION_FILTERS = [
877
+ { value: "active", label: "Active" },
878
+ { value: "closed", label: "Closed" }
879
+ ];
833
880
 
834
881
  // src/pages/user-profile/components/activity-row.tsx
835
882
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
@@ -842,34 +889,34 @@ var ActivityRow = ({ activity, onClick }) => {
842
889
  {
843
890
  type: "button",
844
891
  className: cn(
845
- "flex w-full items-center gap-6 rounded-agg-sm p-0 text-left",
892
+ "flex w-full flex-col gap-3 rounded-agg-sm p-0 text-left sm:flex-row sm:items-center sm:gap-6",
846
893
  "hover:bg-agg-secondary-hover focus-visible:outline-none focus-visible:bg-agg-secondary-hover",
847
894
  "cursor-pointer"
848
895
  ),
849
896
  onClick: handleClick,
850
897
  children: [
851
- /* @__PURE__ */ jsx5("p", { className: "w-[60px] shrink-0 font-agg-sans text-agg-base leading-agg-6 font-agg-normal text-agg-foreground", children: activity.type }),
852
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 flex-1 items-center gap-4", children: [
898
+ /* @__PURE__ */ jsx5("p", { className: "hidden w-[60px] shrink-0 font-agg-sans text-agg-base leading-agg-6 font-agg-normal text-agg-foreground sm:block", children: activity.type }),
899
+ /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 w-full flex-1 items-center gap-3 sm:gap-4", children: [
853
900
  /* @__PURE__ */ jsx5(VenueLogo, { venue: activity.venue, size: "small", className: "shrink-0" }),
854
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 flex-1 items-center gap-4", children: [
901
+ /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 flex-1 items-center gap-3 sm:gap-4", children: [
855
902
  /* @__PURE__ */ jsx5(
856
903
  RemoteImage,
857
904
  {
858
905
  src: activity.thumbnailSrc,
859
906
  alt: "",
860
- className: "h-[60px] w-[60px] shrink-0 rounded-agg-sm object-cover"
907
+ className: "h-[52px] w-[52px] shrink-0 rounded-agg-sm object-cover sm:h-[60px] sm:w-[60px]"
861
908
  }
862
909
  ),
863
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 flex-1 flex-col gap-2 justify-center", children: [
910
+ /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-2", children: [
864
911
  /* @__PURE__ */ jsx5("p", { className: "min-w-full overflow-hidden text-ellipsis whitespace-nowrap font-agg-sans text-agg-base leading-agg-6 font-agg-bold text-agg-foreground", children: activity.title }),
865
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
866
- /* @__PURE__ */ jsx5("span", { className: "inline-flex items-center justify-center gap-1.5 rounded-full bg-agg-secondary-hover px-4 py-1.5", children: /* @__PURE__ */ jsx5("span", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-foreground whitespace-nowrap", children: activity.outcomeLabel }) }),
912
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3", children: [
913
+ /* @__PURE__ */ jsx5("span", { className: "inline-flex items-center justify-center gap-1.5 rounded-full bg-agg-secondary-hover px-3 py-1.5 sm:px-4", children: /* @__PURE__ */ jsx5("span", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-foreground whitespace-nowrap", children: activity.outcomeLabel }) }),
867
914
  /* @__PURE__ */ jsx5("span", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-black whitespace-nowrap", children: activity.sharesLabel })
868
915
  ] })
869
916
  ] })
870
917
  ] })
871
918
  ] }),
872
- /* @__PURE__ */ jsxs5("div", { className: "flex w-[120px] shrink-0 flex-col items-end justify-center gap-1 text-agg-base leading-agg-6 whitespace-nowrap", children: [
919
+ /* @__PURE__ */ jsxs5("div", { className: "flex w-full flex-row items-center justify-between gap-1 text-agg-base leading-agg-6 whitespace-nowrap sm:w-[120px] sm:shrink-0 sm:flex-col sm:items-end sm:justify-center", children: [
873
920
  /* @__PURE__ */ jsx5("p", { className: "font-agg-sans font-agg-bold text-black", children: activity.amountLabel }),
874
921
  /* @__PURE__ */ jsx5("p", { className: "font-agg-sans font-agg-normal text-agg-muted-foreground", children: activity.timeLabel })
875
922
  ] })
@@ -881,50 +928,6 @@ ActivityRow.displayName = "ActivityRow";
881
928
 
882
929
  // src/pages/user-profile/components/empty-state.tsx
883
930
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
884
- var EmptyIcon = () => /* @__PURE__ */ jsxs6(
885
- "svg",
886
- {
887
- width: "40",
888
- height: "40",
889
- viewBox: "0 0 40 40",
890
- fill: "none",
891
- xmlns: "http://www.w3.org/2000/svg",
892
- className: "text-agg-muted-foreground",
893
- "aria-hidden": true,
894
- children: [
895
- /* @__PURE__ */ jsx6(
896
- "path",
897
- {
898
- d: "M33.3333 5H6.66667C5.74619 5 5 5.74619 5 6.66667V33.3333C5 34.2538 5.74619 35 6.66667 35H33.3333C34.2538 35 35 34.2538 35 33.3333V6.66667C35 5.74619 34.2538 5 33.3333 5Z",
899
- stroke: "currentColor",
900
- strokeWidth: "1.5",
901
- strokeLinecap: "round",
902
- strokeLinejoin: "round"
903
- }
904
- ),
905
- /* @__PURE__ */ jsx6(
906
- "path",
907
- {
908
- d: "M14.1667 16.6667C15.5474 16.6667 16.6667 15.5474 16.6667 14.1667C16.6667 12.786 15.5474 11.6667 14.1667 11.6667C12.786 11.6667 11.6667 12.786 11.6667 14.1667C11.6667 15.5474 12.786 16.6667 14.1667 16.6667Z",
909
- stroke: "currentColor",
910
- strokeWidth: "1.5",
911
- strokeLinecap: "round",
912
- strokeLinejoin: "round"
913
- }
914
- ),
915
- /* @__PURE__ */ jsx6(
916
- "path",
917
- {
918
- d: "M35 25L26.6667 16.6667L6.66667 36.6667",
919
- stroke: "currentColor",
920
- strokeWidth: "1.5",
921
- strokeLinecap: "round",
922
- strokeLinejoin: "round"
923
- }
924
- )
925
- ]
926
- }
927
- );
928
931
  var EmptyState = ({ title, description, className }) => {
929
932
  return /* @__PURE__ */ jsx6(
930
933
  "div",
@@ -933,7 +936,7 @@ var EmptyState = ({ title, description, className }) => {
933
936
  role: "status",
934
937
  "aria-live": "polite",
935
938
  children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-5", children: [
936
- /* @__PURE__ */ jsx6(EmptyIcon, {}),
939
+ /* @__PURE__ */ jsx6(SearchEmptyIcon, { className: "h-10 w-10 text-agg-muted-foreground", "aria-hidden": true }),
937
940
  /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-1 text-center text-agg-foreground", children: [
938
941
  /* @__PURE__ */ jsx6("p", { className: "font-agg-sans text-agg-base leading-agg-6 font-agg-bold", children: title }),
939
942
  description ? /* @__PURE__ */ jsx6("p", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal", children: description }) : null
@@ -955,43 +958,43 @@ var PositionRow = ({ position, onClick }) => {
955
958
  {
956
959
  type: "button",
957
960
  className: cn(
958
- "flex w-full items-center gap-6 rounded-agg-sm p-0 text-left",
961
+ "flex w-full flex-col gap-3 rounded-agg-sm p-0 text-left sm:flex-row sm:items-center sm:gap-6",
959
962
  "hover:bg-agg-secondary-hover focus-visible:outline-none focus-visible:bg-agg-secondary-hover",
960
963
  "cursor-pointer"
961
964
  ),
962
965
  onClick: handleClick,
963
966
  children: [
964
- /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-4", children: [
967
+ /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 w-full flex-1 items-center gap-3 sm:gap-4", children: [
965
968
  /* @__PURE__ */ jsx7(VenueLogo, { venue: position.venue, size: "small", className: "shrink-0" }),
966
- /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-4", children: [
969
+ /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-3 sm:gap-4", children: [
967
970
  /* @__PURE__ */ jsx7(
968
971
  RemoteImage,
969
972
  {
970
973
  src: position.thumbnailSrc,
971
974
  alt: "",
972
- className: "h-[60px] w-[60px] shrink-0 rounded-agg-sm object-cover"
975
+ className: "h-[52px] w-[52px] shrink-0 rounded-agg-sm object-cover sm:h-[60px] sm:w-[60px]"
973
976
  }
974
977
  ),
975
- /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 flex-col gap-2 justify-center", children: [
978
+ /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 flex-col justify-center gap-2", children: [
976
979
  /* @__PURE__ */ jsx7("p", { className: "min-w-full overflow-hidden text-ellipsis whitespace-nowrap font-agg-sans text-agg-base leading-agg-6 font-agg-bold text-agg-foreground", children: position.title }),
977
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
978
- /* @__PURE__ */ jsx7("span", { className: "inline-flex items-center justify-center gap-1.5 rounded-full bg-agg-secondary-hover px-4 py-1.5", children: /* @__PURE__ */ jsx7("span", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-foreground whitespace-nowrap", children: position.outcomeLabel }) }),
980
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3", children: [
981
+ /* @__PURE__ */ jsx7("span", { className: "inline-flex items-center justify-center gap-1.5 rounded-full bg-agg-secondary-hover px-3 py-1.5 sm:px-4", children: /* @__PURE__ */ jsx7("span", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-foreground whitespace-nowrap", children: position.outcomeLabel }) }),
979
982
  /* @__PURE__ */ jsx7("span", { className: "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-black whitespace-nowrap", children: position.sharesLabel })
980
983
  ] })
981
984
  ] })
982
985
  ] })
983
986
  ] }),
984
- /* @__PURE__ */ jsx7("p", { className: "w-[120px] shrink-0 agg-type-title text-agg-foreground", children: position.averageLabel }),
985
- /* @__PURE__ */ jsx7("p", { className: "w-[120px] shrink-0 agg-type-title text-agg-foreground", children: position.currentLabel }),
986
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-6 shrink-0", children: [
987
- /* @__PURE__ */ jsxs7("div", { className: "flex w-[140px] flex-col items-end justify-center gap-1 text-agg-base leading-agg-6 whitespace-nowrap", children: [
987
+ /* @__PURE__ */ jsx7("p", { className: "hidden w-[120px] shrink-0 agg-type-title text-agg-foreground sm:block", children: position.averageLabel }),
988
+ /* @__PURE__ */ jsx7("p", { className: "hidden w-[120px] shrink-0 agg-type-title text-agg-foreground sm:block", children: position.currentLabel }),
989
+ /* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center justify-between gap-3 sm:w-auto sm:justify-start sm:gap-6 sm:shrink-0", children: [
990
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col justify-center gap-1 text-agg-base leading-agg-6 whitespace-nowrap sm:w-[140px] sm:items-end", children: [
988
991
  /* @__PURE__ */ jsx7("p", { className: "font-agg-sans font-agg-bold text-black", children: position.valueLabel }),
989
992
  /* @__PURE__ */ jsx7(
990
993
  "p",
991
994
  {
992
995
  className: cn(
993
996
  "font-agg-sans font-agg-normal",
994
- position.isPnlPositive ? "text-[#00c853]" : "text-[#e5455f]"
997
+ position.isPnlPositive ? "text-agg-success" : "text-agg-error"
995
998
  ),
996
999
  children: position.pnlLabel
997
1000
  }
@@ -1017,22 +1020,30 @@ var PositionsActivity = ({
1017
1020
  activities = [],
1018
1021
  onPositionClick,
1019
1022
  onActivityClick,
1023
+ isLoadingPositions = false,
1024
+ isLoadingActivities = false,
1025
+ positionsError = false,
1026
+ activitiesError = false,
1027
+ hasMorePositions = false,
1028
+ isLoadingMorePositions = false,
1029
+ onLoadMorePositions,
1030
+ hasMoreActivities = false,
1031
+ isLoadingMoreActivities = false,
1032
+ onLoadMoreActivities,
1020
1033
  className
1021
1034
  }) => {
1022
- const [activeTab, setActiveTab] = useState4(USER_PROFILE_TAB_POSITIONS);
1023
- const [positionFilter, setPositionFilter] = useState4("active");
1024
- const [searchValue, setSearchValue] = useState4("");
1035
+ const [activeTab, setActiveTab] = useState3(USER_PROFILE_TAB_POSITIONS);
1036
+ const [positionFilter, setPositionFilter] = useState3("active");
1037
+ const [searchValue, setSearchValue] = useState3("");
1025
1038
  const isPositionsTab = activeTab === USER_PROFILE_TAB_POSITIONS;
1026
1039
  const filteredPositions = useMemo3(() => {
1027
1040
  const positions = positionFilter === "active" ? activePositions : closedPositions;
1028
- if (!searchValue.trim())
1029
- return positions;
1041
+ if (!searchValue.trim()) return positions;
1030
1042
  const query = searchValue.toLowerCase();
1031
1043
  return positions.filter((p) => p.title.toLowerCase().includes(query));
1032
1044
  }, [activePositions, closedPositions, positionFilter, searchValue]);
1033
1045
  const filteredActivities = useMemo3(() => {
1034
- if (!searchValue.trim())
1035
- return activities;
1046
+ if (!searchValue.trim()) return activities;
1036
1047
  const query = searchValue.toLowerCase();
1037
1048
  return activities.filter((a) => a.title.toLowerCase().includes(query));
1038
1049
  }, [activities, searchValue]);
@@ -1054,12 +1065,15 @@ var PositionsActivity = ({
1054
1065
  value: activeTab,
1055
1066
  onChange: setActiveTab,
1056
1067
  variant: "underline",
1057
- className: "w-full [&>div]:w-full"
1068
+ className: "w-full [&>div]:w-full",
1069
+ classNames: {
1070
+ tabList: "h-11 sm:h-12"
1071
+ }
1058
1072
  }
1059
1073
  ),
1060
- /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-6 p-6", children: [
1061
- /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-5", children: [
1062
- isPositionsTab ? /* @__PURE__ */ jsx8("div", { className: "flex h-10 w-[270px] shrink-0 items-stretch overflow-clip rounded-agg-sm border border-agg-separator", children: USER_PROFILE_POSITION_FILTERS.map((filter, idx) => {
1074
+ /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-4 p-4 sm:gap-6 sm:p-6", children: [
1075
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-start gap-3 sm:flex-row sm:gap-5", children: [
1076
+ isPositionsTab ? /* @__PURE__ */ jsx8("div", { className: "flex h-11 w-full shrink-0 items-stretch overflow-clip rounded-agg-sm border border-agg-separator sm:h-10 sm:w-[270px]", children: USER_PROFILE_POSITION_FILTERS.map((filter, idx) => {
1063
1077
  const isActive = filter.value === positionFilter;
1064
1078
  return /* @__PURE__ */ jsxs8("div", { className: "flex flex-1 items-stretch", children: [
1065
1079
  idx > 0 ? /* @__PURE__ */ jsx8("div", { className: "w-px bg-agg-separator", "aria-hidden": true }) : null,
@@ -1069,7 +1083,7 @@ var PositionsActivity = ({
1069
1083
  type: "button",
1070
1084
  onClick: () => setPositionFilter(filter.value),
1071
1085
  className: cn(
1072
- "flex flex-1 items-center justify-center px-4 py-3 font-agg-sans text-agg-base leading-agg-6 cursor-pointer",
1086
+ "flex flex-1 cursor-pointer items-center justify-center px-3 py-3 font-agg-sans text-agg-sm leading-agg-5 sm:px-4 sm:text-agg-base sm:leading-agg-6",
1073
1087
  isActive ? "bg-agg-secondary-hover font-agg-bold text-agg-primary" : "bg-agg-secondary font-agg-normal text-agg-foreground hover:bg-agg-secondary-hover"
1074
1088
  ),
1075
1089
  children: filter.label
@@ -1077,7 +1091,7 @@ var PositionsActivity = ({
1077
1091
  )
1078
1092
  ] }, filter.value);
1079
1093
  }) }) : null,
1080
- /* @__PURE__ */ jsx8("label", { className: "flex min-w-0 flex-1", children: /* @__PURE__ */ jsxs8("div", { className: "flex h-10 w-full items-center gap-3 rounded-agg-sm border border-agg-separator bg-agg-secondary px-3 py-2.5 focus-within:border-2 focus-within:border-agg-primary", children: [
1094
+ /* @__PURE__ */ jsx8("label", { className: "flex w-full min-w-0 flex-1", children: /* @__PURE__ */ jsxs8("div", { className: "flex h-11 w-full items-center gap-3 rounded-agg-sm border border-agg-separator bg-agg-secondary px-3 py-2.5 focus-within:border-2 focus-within:border-agg-primary sm:h-10", children: [
1081
1095
  /* @__PURE__ */ jsx8(Icon, { name: "search", size: "small", className: "shrink-0 text-agg-muted-foreground" }),
1082
1096
  /* @__PURE__ */ jsx8(
1083
1097
  "input",
@@ -1095,30 +1109,67 @@ var PositionsActivity = ({
1095
1109
  )
1096
1110
  ] }) })
1097
1111
  ] }),
1098
- isPositionsTab && filteredPositions.length > 0 ? /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-6 px-0", children: [
1112
+ isPositionsTab && filteredPositions.length > 0 ? /* @__PURE__ */ jsxs8("div", { className: "hidden items-center gap-6 px-0 sm:flex", children: [
1099
1113
  /* @__PURE__ */ jsx8("p", { className: "min-w-0 flex-1 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground", children: "Market" }),
1100
1114
  /* @__PURE__ */ jsx8("p", { className: "w-[120px] shrink-0 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground", children: "Average" }),
1101
1115
  /* @__PURE__ */ jsx8("p", { className: "w-[120px] shrink-0 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground", children: "Current" }),
1102
1116
  /* @__PURE__ */ jsx8("p", { className: "w-[184px] shrink-0 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground text-right", children: "Value" })
1103
1117
  ] }) : null,
1104
- !isPositionsTab && filteredActivities.length > 0 ? /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-6 px-0", children: [
1118
+ !isPositionsTab && filteredActivities.length > 0 ? /* @__PURE__ */ jsxs8("div", { className: "hidden items-center gap-6 px-0 sm:flex", children: [
1105
1119
  /* @__PURE__ */ jsx8("p", { className: "w-[60px] shrink-0 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground", children: "Type" }),
1106
1120
  /* @__PURE__ */ jsx8("p", { className: "min-w-0 flex-1 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground", children: "Market" }),
1107
1121
  /* @__PURE__ */ jsx8("p", { className: "w-[120px] shrink-0 font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-muted-foreground text-right", children: "Amount" })
1108
1122
  ] }) : null,
1109
- isPositionsTab ? filteredPositions.length > 0 ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-4", children: filteredPositions.map((position) => /* @__PURE__ */ jsx8(PositionRow, { position, onClick: onPositionClick }, position.id)) }) : /* @__PURE__ */ jsx8(
1123
+ isPositionsTab ? isLoadingPositions && filteredPositions.length === 0 ? /* @__PURE__ */ jsx8(
1124
+ Skeleton,
1125
+ {
1126
+ view: skeletonViews.userProfilePositionsActivity,
1127
+ ariaLabel: "Loading positions"
1128
+ }
1129
+ ) : positionsError && filteredPositions.length === 0 ? /* @__PURE__ */ jsx8(
1130
+ EmptyState,
1131
+ {
1132
+ title: "Unable to load positions",
1133
+ description: "Please try again in a moment."
1134
+ }
1135
+ ) : filteredPositions.length > 0 ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-3 sm:gap-4", children: filteredPositions.map((position) => /* @__PURE__ */ jsx8(PositionRow, { position, onClick: onPositionClick }, position.id)) }) : /* @__PURE__ */ jsx8(
1110
1136
  EmptyState,
1111
1137
  {
1112
1138
  title: "No positions yet",
1113
1139
  description: "Your open trades will appear here once you place an order."
1114
1140
  }
1115
- ) : filteredActivities.length > 0 ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-4", children: filteredActivities.map((activity) => /* @__PURE__ */ jsx8(ActivityRow, { activity, onClick: onActivityClick }, activity.id)) }) : /* @__PURE__ */ jsx8(
1141
+ ) : isLoadingActivities && filteredActivities.length === 0 ? /* @__PURE__ */ jsx8(
1142
+ Skeleton,
1143
+ {
1144
+ view: skeletonViews.userProfilePositionsActivity,
1145
+ ariaLabel: "Loading activity"
1146
+ }
1147
+ ) : activitiesError && filteredActivities.length === 0 ? /* @__PURE__ */ jsx8(EmptyState, { title: "Unable to load activity", description: "Please try again in a moment." }) : filteredActivities.length > 0 ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-3 sm:gap-4", children: filteredActivities.map((activity) => /* @__PURE__ */ jsx8(ActivityRow, { activity, onClick: onActivityClick }, activity.id)) }) : /* @__PURE__ */ jsx8(
1116
1148
  EmptyState,
1117
1149
  {
1118
1150
  title: "No activity yet",
1119
1151
  description: "Your trading activity will appear here."
1120
1152
  }
1121
- )
1153
+ ),
1154
+ isPositionsTab ? hasMorePositions ? /* @__PURE__ */ jsx8("div", { className: "flex w-full justify-center pt-1", children: /* @__PURE__ */ jsx8(
1155
+ Button,
1156
+ {
1157
+ variant: "secondary",
1158
+ size: "medium",
1159
+ isLoading: isLoadingMorePositions,
1160
+ onClick: onLoadMorePositions,
1161
+ children: "Load more"
1162
+ }
1163
+ ) }) : null : hasMoreActivities ? /* @__PURE__ */ jsx8("div", { className: "flex w-full justify-center pt-1", children: /* @__PURE__ */ jsx8(
1164
+ Button,
1165
+ {
1166
+ variant: "secondary",
1167
+ size: "medium",
1168
+ isLoading: isLoadingMoreActivities,
1169
+ onClick: onLoadMoreActivities,
1170
+ children: "Load more"
1171
+ }
1172
+ ) }) : null
1122
1173
  ] })
1123
1174
  ]
1124
1175
  }
@@ -1177,88 +1228,147 @@ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1177
1228
  var UserInfoCard = ({
1178
1229
  user,
1179
1230
  onEditProfile,
1231
+ onDeposit,
1232
+ onWithdraw,
1180
1233
  className
1181
1234
  }) => {
1182
1235
  var _a, _b, _c;
1183
1236
  const evmExchanges = ((_a = user.connectedExchanges) != null ? _a : []).filter((ex) => ex.venue !== "kalshi");
1184
1237
  const totalExchangeCount = (_c = (_b = user.connectedExchanges) == null ? void 0 : _b.length) != null ? _c : 0;
1185
1238
  const hasEvmExchanges = evmExchanges.length > 0;
1186
- return /* @__PURE__ */ jsx10(
1239
+ return /* @__PURE__ */ jsxs10(
1187
1240
  "div",
1188
1241
  {
1189
1242
  className: cn(
1190
- "flex flex-col items-start rounded-agg-md border border-agg-separator bg-agg-secondary p-5",
1243
+ "flex h-full flex-col items-start gap-4 sm:gap-6 rounded-agg-md border border-agg-separator bg-agg-secondary p-5",
1191
1244
  className
1192
1245
  ),
1193
- children: /* @__PURE__ */ jsxs10("div", { className: "flex w-full items-start gap-5", children: [
1194
- /* @__PURE__ */ jsx10("div", { className: "shrink-0", children: user.avatarUrl ? /* @__PURE__ */ jsx10(
1195
- RemoteImage,
1196
- {
1197
- src: user.avatarUrl,
1198
- alt: user.username,
1199
- className: "h-[120px] w-[120px] rounded-full object-cover"
1200
- }
1201
- ) : /* @__PURE__ */ jsx10(DefaultAvatar, { className: "h-[120px] w-[120px]" }) }),
1202
- /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: [
1203
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-4", children: [
1204
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
1205
- /* @__PURE__ */ jsx10("h2", { className: "agg-type-heading text-agg-foreground", children: user.username }),
1206
- user.socialLinks && user.socialLinks.length > 0 ? /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-2", children: user.socialLinks.map((social) => {
1207
- const iconName = social.platform === "twitter" ? "twitter" : social.platform === "discord" ? "discord" : "telegram";
1208
- return /* @__PURE__ */ jsx10(
1209
- "span",
1246
+ children: [
1247
+ /* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col items-start gap-4 sm:flex-row sm:gap-5", children: [
1248
+ /* @__PURE__ */ jsx10("div", { className: "shrink-0", children: user.avatarUrl ? /* @__PURE__ */ jsx10(
1249
+ RemoteImage,
1250
+ {
1251
+ src: user.avatarUrl,
1252
+ alt: user.username,
1253
+ className: "h-20 w-20 rounded-full object-cover sm:h-[120px] sm:w-[120px]"
1254
+ }
1255
+ ) : /* @__PURE__ */ jsx10(DefaultAvatar, { className: "h-20 w-20 sm:h-[120px] sm:w-[120px]" }) }),
1256
+ /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 w-full flex-1 flex-col gap-3 sm:gap-4", children: [
1257
+ /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center justify-between gap-3 sm:gap-4", children: [
1258
+ /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-center gap-2", children: [
1259
+ /* @__PURE__ */ jsx10("h2", { className: "truncate text-[22px] leading-7 font-agg-bold text-agg-foreground sm:agg-type-heading", children: user.username }),
1260
+ user.socialLinks && user.socialLinks.length > 0 ? /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-2", children: user.socialLinks.map((social) => {
1261
+ const iconName = social.platform === "twitter" ? "twitter" : social.platform === "discord" ? "discord" : "telegram";
1262
+ const iconNode = /* @__PURE__ */ jsx10("span", { className: "flex size-7 shrink-0 items-center justify-center rounded-full border border-agg-separator bg-agg-secondary sm:size-8", children: /* @__PURE__ */ jsx10(Icon, { name: iconName, size: "small", className: "text-agg-foreground" }) });
1263
+ if (!social.handle) {
1264
+ return /* @__PURE__ */ jsx10("span", { children: iconNode }, `${social.platform}-icon`);
1265
+ }
1266
+ return /* @__PURE__ */ jsx10(
1267
+ "a",
1268
+ {
1269
+ href: social.handle,
1270
+ target: "_blank",
1271
+ rel: "noreferrer noopener",
1272
+ "aria-label": `${social.platform} profile`,
1273
+ children: iconNode
1274
+ },
1275
+ `${social.platform}-${social.handle}`
1276
+ );
1277
+ }) }) : null
1278
+ ] }),
1279
+ onEditProfile ? /* @__PURE__ */ jsxs10(
1280
+ "button",
1281
+ {
1282
+ type: "button",
1283
+ onClick: onEditProfile,
1284
+ className: "hidden shrink-0 cursor-pointer items-center gap-2 bg-transparent text-agg-primary hover:opacity-80 sm:flex",
1285
+ children: [
1286
+ /* @__PURE__ */ jsx10(Icon, { name: "pencil", size: "small", className: "text-agg-primary" }),
1287
+ /* @__PURE__ */ jsx10("span", { className: "text-agg-base font-agg-bold leading-6", children: "Edit" })
1288
+ ]
1289
+ }
1290
+ ) : null
1291
+ ] }),
1292
+ totalExchangeCount > 0 || user.socialHandle ? /* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-2.5 sm:gap-3", children: [
1293
+ hasEvmExchanges ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-2 sm:gap-3", children: [
1294
+ /* @__PURE__ */ jsx10("div", { className: "flex items-center", children: evmExchanges.map((exchange, idx) => /* @__PURE__ */ jsx10(
1295
+ "div",
1210
1296
  {
1211
- className: "flex size-8 shrink-0 items-center justify-center rounded-full border border-agg-separator bg-agg-secondary",
1212
- children: /* @__PURE__ */ jsx10(Icon, { name: iconName, size: "small", className: "text-agg-foreground" })
1297
+ className: cn(
1298
+ "relative flex h-5 w-5 shrink-0 items-center justify-center overflow-hidden rounded-[4px]",
1299
+ idx > 0 && "-ml-2"
1300
+ ),
1301
+ style: { zIndex: evmExchanges.length - idx },
1302
+ children: /* @__PURE__ */ jsx10(
1303
+ RemoteImage,
1304
+ {
1305
+ src: venueLogoUrlRegistry[exchange.venue],
1306
+ alt: venueLogoLabels[exchange.venue],
1307
+ className: "h-5 w-5"
1308
+ }
1309
+ )
1213
1310
  },
1214
- social.platform
1215
- );
1216
- }) }) : null
1217
- ] }),
1218
- onEditProfile ? /* @__PURE__ */ jsxs10(
1311
+ `${exchange.venue}-${idx}`
1312
+ )) }),
1313
+ user.displayAddress ? /* @__PURE__ */ jsx10("span", { className: "text-agg-sm font-agg-normal leading-5 text-agg-foreground sm:text-agg-base sm:leading-6", children: user.displayAddress }) : null,
1314
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
1315
+ /* @__PURE__ */ jsxs10("span", { className: "text-agg-sm font-agg-normal leading-5 text-agg-muted-foreground", children: [
1316
+ totalExchangeCount,
1317
+ " exchange",
1318
+ totalExchangeCount !== 1 ? "s" : ""
1319
+ ] }),
1320
+ /* @__PURE__ */ jsx10(Icon, { name: "info", size: "small", className: "text-agg-muted-foreground" })
1321
+ ] })
1322
+ ] }) : null,
1323
+ user.socialHandle ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 sm:gap-3", children: [
1324
+ user.socialHandleVenue ? /* @__PURE__ */ jsx10("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center overflow-hidden rounded-[4px]", children: /* @__PURE__ */ jsx10(
1325
+ RemoteImage,
1326
+ {
1327
+ src: venueLogoUrlRegistry[user.socialHandleVenue],
1328
+ alt: venueLogoLabels[user.socialHandleVenue],
1329
+ className: "h-5 w-5"
1330
+ }
1331
+ ) }) : null,
1332
+ /* @__PURE__ */ jsx10("span", { className: "text-agg-sm font-agg-normal leading-5 text-agg-foreground sm:text-agg-base sm:leading-6", children: user.socialHandle })
1333
+ ] }) : null
1334
+ ] }) : null
1335
+ ] })
1336
+ ] }),
1337
+ (onDeposit || onWithdraw) && /* @__PURE__ */ jsxs10("div", { className: "flex w-full items-center gap-5", children: [
1338
+ /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
1339
+ onDeposit ? /* @__PURE__ */ jsx10(
1340
+ "button",
1341
+ {
1342
+ type: "button",
1343
+ onClick: onDeposit,
1344
+ className: "inline-flex h-9 min-w-0 flex-1 items-center justify-center rounded-agg-full bg-agg-primary px-4 font-agg-sans text-agg-base font-agg-bold text-white hover:opacity-90 sm:h-10 sm:px-6",
1345
+ children: "Deposit"
1346
+ }
1347
+ ) : null,
1348
+ onWithdraw ? /* @__PURE__ */ jsx10(
1219
1349
  "button",
1220
1350
  {
1221
1351
  type: "button",
1222
- onClick: onEditProfile,
1223
- className: "flex shrink-0 cursor-pointer items-center gap-1.5 bg-transparent text-agg-primary hover:opacity-80",
1224
- children: [
1225
- /* @__PURE__ */ jsx10(Icon, { name: "pencil", size: "small", className: "text-agg-primary" }),
1226
- /* @__PURE__ */ jsx10("span", { className: "text-agg-base font-agg-bold leading-6", children: "Edit" })
1227
- ]
1352
+ onClick: onWithdraw,
1353
+ className: "inline-flex h-9 min-w-0 flex-1 items-center justify-center rounded-agg-full border border-agg-separator bg-transparent px-4 font-agg-sans text-agg-base font-agg-bold text-agg-foreground hover:bg-agg-secondary-hover sm:h-10 sm:px-6",
1354
+ children: "Withdraw"
1228
1355
  }
1229
1356
  ) : null
1230
1357
  ] }),
1231
- totalExchangeCount > 0 || user.socialHandle ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-3", children: [
1232
- hasEvmExchanges ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
1233
- /* @__PURE__ */ jsx10("div", { className: "flex items-center", children: evmExchanges.map((exchange, idx) => /* @__PURE__ */ jsx10(
1234
- "div",
1235
- {
1236
- className: cn(
1237
- "relative flex h-5 w-5 shrink-0 items-center justify-center overflow-hidden rounded-[4px]",
1238
- idx > 0 && "-ml-2"
1239
- ),
1240
- style: { zIndex: evmExchanges.length - idx },
1241
- children: /* @__PURE__ */ jsx10(VenueLogo, { venue: exchange.venue, size: "small", className: "h-5 w-5" })
1242
- },
1243
- `${exchange.venue}-${idx}`
1244
- )) }),
1245
- user.displayAddress ? /* @__PURE__ */ jsx10("span", { className: "text-agg-base font-agg-normal leading-6 text-agg-foreground", children: user.displayAddress }) : null,
1246
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
1247
- /* @__PURE__ */ jsxs10("span", { className: "text-agg-sm font-agg-normal leading-5 text-agg-muted-foreground", children: [
1248
- totalExchangeCount,
1249
- " exchange",
1250
- totalExchangeCount !== 1 ? "s" : ""
1251
- ] }),
1252
- /* @__PURE__ */ jsx10(Icon, { name: "info", size: "small", className: "text-agg-muted-foreground" })
1253
- ] })
1254
- ] }) : null,
1255
- user.socialHandle ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
1256
- user.socialHandleVenue ? /* @__PURE__ */ jsx10("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center overflow-hidden rounded-[4px]", children: /* @__PURE__ */ jsx10(VenueLogo, { venue: user.socialHandleVenue, size: "small", className: "h-5 w-5" }) }) : null,
1257
- /* @__PURE__ */ jsx10("span", { className: "text-agg-base font-agg-normal leading-6 text-agg-foreground", children: user.socialHandle })
1258
- ] }) : null
1259
- ] }) : null
1358
+ onEditProfile ? /* @__PURE__ */ jsxs10(
1359
+ "button",
1360
+ {
1361
+ type: "button",
1362
+ onClick: onEditProfile,
1363
+ className: "flex shrink-0 cursor-pointer items-center gap-1.5 bg-transparent text-agg-primary hover:opacity-80 sm:hidden",
1364
+ children: [
1365
+ /* @__PURE__ */ jsx10(Icon, { name: "pencil", size: "small", className: "h-3.5 w-3.5 text-agg-primary" }),
1366
+ /* @__PURE__ */ jsx10("span", { className: "text-agg-sm font-agg-bold leading-5", children: "Edit" })
1367
+ ]
1368
+ }
1369
+ ) : null
1260
1370
  ] })
1261
- ] })
1371
+ ]
1262
1372
  }
1263
1373
  );
1264
1374
  };
@@ -1266,12 +1376,56 @@ UserInfoCard.displayName = "UserInfoCard";
1266
1376
 
1267
1377
  // src/pages/user-profile/index.tsx
1268
1378
  import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1379
+ var currencyFormatter = new Intl.NumberFormat("en-US", {
1380
+ style: "currency",
1381
+ currency: "USD",
1382
+ minimumFractionDigits: 2,
1383
+ maximumFractionDigits: 2
1384
+ });
1385
+ var formatUsd = (value) => currencyFormatter.format(Number.isFinite(value) ? value : 0);
1386
+ var shortenAddress = (address) => {
1387
+ if (!address) return void 0;
1388
+ if (address.length <= 12) return address;
1389
+ return `${address.slice(0, 6)}...${address.slice(-5)}`;
1390
+ };
1391
+ var fallbackThumbnailSrc = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><rect width="100%" height="100%" fill="%23f4f4f7"/></svg>';
1392
+ var toRelativeTimeLabel = (value) => {
1393
+ const timestamp = value instanceof Date ? value.getTime() : Date.parse(value);
1394
+ if (Number.isNaN(timestamp)) return "";
1395
+ const diffMs = Date.now() - timestamp;
1396
+ const minute = 60 * 1e3;
1397
+ const hour = 60 * minute;
1398
+ const day = 24 * hour;
1399
+ const week = 7 * day;
1400
+ if (diffMs < hour) {
1401
+ const minutes = Math.max(1, Math.floor(diffMs / minute));
1402
+ return `${minutes}m ago`;
1403
+ }
1404
+ if (diffMs < day) {
1405
+ const hours = Math.max(1, Math.floor(diffMs / hour));
1406
+ return `${hours}h ago`;
1407
+ }
1408
+ if (diffMs < week) {
1409
+ const days = Math.max(1, Math.floor(diffMs / day));
1410
+ return `${days}d ago`;
1411
+ }
1412
+ const weeks = Math.max(1, Math.floor(diffMs / week));
1413
+ return `${weeks}w ago`;
1414
+ };
1415
+ var toAmountLabel = (amountRaw, executionPrice, filledAmountRaw) => {
1416
+ const parsedExecutionPrice = executionPrice ? Number(executionPrice) : Number.NaN;
1417
+ const parsedFilledAmount = filledAmountRaw ? Number(filledAmountRaw) : Number.NaN;
1418
+ if (Number.isFinite(parsedExecutionPrice) && Number.isFinite(parsedFilledAmount)) {
1419
+ return formatUsd(parsedExecutionPrice * parsedFilledAmount);
1420
+ }
1421
+ const parsedAmount = Number(amountRaw);
1422
+ if (Number.isFinite(parsedAmount)) return formatUsd(parsedAmount);
1423
+ return "$0.00";
1424
+ };
1269
1425
  var UserProfilePage = ({
1270
1426
  user,
1271
- venueBalances,
1427
+ venueBalances: _venueBalances,
1272
1428
  balance,
1273
- defaultTimeRange,
1274
- onTimeRangeChange,
1275
1429
  activePositions,
1276
1430
  closedPositions,
1277
1431
  activities,
@@ -1280,54 +1434,201 @@ var UserProfilePage = ({
1280
1434
  onWithdraw,
1281
1435
  onPositionClick,
1282
1436
  onActivityClick,
1437
+ isLoadingPositions,
1438
+ isLoadingActivities,
1439
+ positionsError,
1440
+ activitiesError,
1441
+ hasMorePositions,
1442
+ isLoadingMorePositions,
1443
+ onLoadMorePositions,
1444
+ hasMoreActivities,
1445
+ isLoadingMoreActivities,
1446
+ onLoadMoreActivities,
1283
1447
  classNames
1284
1448
  }) => {
1285
- return /* @__PURE__ */ jsx11("div", { className: "box-border w-full overflow-x-hidden p-10", children: /* @__PURE__ */ jsxs11(
1449
+ const { user: currentUser, isAuthenticated } = useAggAuthState();
1450
+ const balanceState = useAggBalance();
1451
+ const shouldUseHookData = !user;
1452
+ const connectedVenuesFromBalance = useMemo4(
1453
+ () => {
1454
+ var _a;
1455
+ return (_a = balanceState.connectedVenues) != null ? _a : [];
1456
+ },
1457
+ [balanceState]
1458
+ );
1459
+ const connectedVenues = useMemo4(() => {
1460
+ if (!shouldUseHookData) return [];
1461
+ return [...new Set(connectedVenuesFromBalance)].sort((a, b) => a.localeCompare(b));
1462
+ }, [connectedVenuesFromBalance, shouldUseHookData]);
1463
+ const positionsQuery = useExecutionPositions({
1464
+ enabled: shouldUseHookData && isAuthenticated,
1465
+ limit: 25
1466
+ });
1467
+ const ordersQuery = useExecutionOrders({
1468
+ enabled: shouldUseHookData && isAuthenticated,
1469
+ limit: 25
1470
+ });
1471
+ const resolvedUser = useMemo4(() => {
1472
+ var _a, _b, _c, _d;
1473
+ if (user) return user;
1474
+ const fallbackUsername = (currentUser == null ? void 0 : currentUser.id) ? `user_${currentUser.id.slice(0, 6)}` : "User";
1475
+ const twitterAccount = (_a = currentUser == null ? void 0 : currentUser.accounts) == null ? void 0 : _a.find(
1476
+ (account) => String(account.provider).toLowerCase() === "twitter"
1477
+ );
1478
+ const normalizedTwitterHandle = (_b = twitterAccount == null ? void 0 : twitterAccount.providerAccountId) == null ? void 0 : _b.replace(/^@/, "");
1479
+ return {
1480
+ username: (_c = currentUser == null ? void 0 : currentUser.username) != null ? _c : fallbackUsername,
1481
+ avatarUrl: (_d = currentUser == null ? void 0 : currentUser.avatarUrl) != null ? _d : null,
1482
+ socialLinks: normalizedTwitterHandle ? [
1483
+ {
1484
+ platform: "twitter",
1485
+ handle: `https://x.com/${normalizedTwitterHandle}`
1486
+ }
1487
+ ] : [],
1488
+ connectedExchanges: connectedVenues.map((venue) => ({ venue })),
1489
+ displayAddress: shortenAddress(getWalletAddressFromUserProfile(currentUser)),
1490
+ socialHandle: normalizedTwitterHandle != null ? normalizedTwitterHandle : void 0
1491
+ };
1492
+ }, [connectedVenues, currentUser, user]);
1493
+ const positionsValueLabel = useMemo4(() => {
1494
+ var _a;
1495
+ if (balance == null ? void 0 : balance.totalLabel) return balance.totalLabel;
1496
+ const managed = balanceState.managedBalances;
1497
+ const positions = (_a = managed == null ? void 0 : managed.positions) != null ? _a : [];
1498
+ const positionsValueTotal = positions.reduce((sum, p) => sum + (Number(p.balance) || 0), 0);
1499
+ return formatUsd(positionsValueTotal);
1500
+ }, [balance, balanceState]);
1501
+ const availableBalanceLabel = useMemo4(() => {
1502
+ var _a;
1503
+ return formatUsd((_a = balanceState.totalBalance) != null ? _a : 0);
1504
+ }, [balanceState.totalBalance]);
1505
+ const resolvedActivities = useMemo4(() => {
1506
+ if (activities) return activities;
1507
+ return ordersQuery.orders.map((order) => {
1508
+ var _a, _b, _c, _d, _e, _f;
1509
+ const parsedSide = order.side.toLowerCase() === "buy" || order.side.toLowerCase() === "sell" ? order.side.toLowerCase() : "buy";
1510
+ const type = parsedSide === "buy" ? "Buy" : "Sell";
1511
+ const venue = connectedVenues.includes(order.venue) ? order.venue : "polymarket";
1512
+ return {
1513
+ id: order.id,
1514
+ type,
1515
+ thumbnailSrc: (_b = (_a = order.venueMarket) == null ? void 0 : _a.image) != null ? _b : fallbackThumbnailSrc,
1516
+ title: ((_c = order.venueMarket) == null ? void 0 : _c.question) || "Market",
1517
+ venue,
1518
+ outcomeLabel: ((_d = order.venueMarketOutcome) == null ? void 0 : _d.title) || ((_e = order.venueMarketOutcome) == null ? void 0 : _e.label) || "Outcome",
1519
+ sharesLabel: `${(_f = order.filledAmountRaw) != null ? _f : order.amountRaw} shares`,
1520
+ amountLabel: toAmountLabel(order.amountRaw, order.executionPrice, order.filledAmountRaw),
1521
+ timeLabel: toRelativeTimeLabel(order.createdAt)
1522
+ };
1523
+ });
1524
+ }, [activities, connectedVenues, ordersQuery.orders]);
1525
+ const resolvedActivePositions = useMemo4(() => {
1526
+ if (activePositions) return activePositions;
1527
+ return positionsQuery.positions.flatMap(
1528
+ (group) => group.venueMarket.venueMarketOutcomes.map((outcome) => {
1529
+ var _a, _b, _c;
1530
+ const outcomeVenue = (_a = outcome.venueBreakdown[0]) == null ? void 0 : _a.venue;
1531
+ const venue = connectedVenues.includes(outcomeVenue != null ? outcomeVenue : "polymarket") ? outcomeVenue != null ? outcomeVenue : "polymarket" : "polymarket";
1532
+ const currentPriceCents = Math.round(outcome.currentPrice * 100);
1533
+ const averagePriceCents = Math.round(outcome.avgEntryPrice * 100);
1534
+ const pnlPrefix = outcome.unrealizedPnl >= 0 ? "+" : "";
1535
+ const pnlPercent = (outcome.unrealizedPnlPercent * 100).toFixed(2);
1536
+ return {
1537
+ id: `${group.targetMarketId}-${outcome.label}-${(_b = outcome.title) != null ? _b : ""}`,
1538
+ thumbnailSrc: (_c = group.venueMarket.image) != null ? _c : fallbackThumbnailSrc,
1539
+ title: group.venueMarket.question,
1540
+ venue,
1541
+ outcomeLabel: `${outcome.label} ${currentPriceCents}\xA2`,
1542
+ sharesLabel: `${outcome.totalSize.toFixed(2)} shares`,
1543
+ averageLabel: `${averagePriceCents}\xA2`,
1544
+ currentLabel: `${currentPriceCents}\xA2`,
1545
+ valueLabel: formatUsd(outcome.totalValue),
1546
+ pnlLabel: `${pnlPrefix}${formatUsd(outcome.unrealizedPnl)} (${pnlPrefix}${pnlPercent}%)`,
1547
+ isPnlPositive: outcome.unrealizedPnl >= 0
1548
+ };
1549
+ })
1550
+ );
1551
+ }, [activePositions, connectedVenues, positionsQuery.positions]);
1552
+ const resolvedClosedPositions = useMemo4(() => {
1553
+ return closedPositions != null ? closedPositions : [];
1554
+ }, [closedPositions]);
1555
+ return /* @__PURE__ */ jsx11("div", { className: "box-border w-full overflow-x-hidden p-5 sm:p-10", children: /* @__PURE__ */ jsxs11(
1286
1556
  "section",
1287
1557
  {
1288
1558
  className: cn(
1289
- "flex w-full flex-col gap-10 rounded-agg-xl border border-agg-separator bg-agg-secondary p-10 overflow-clip",
1559
+ // Outer container spacing per updated Figma
1560
+ "flex w-full flex-col gap-6 sm:gap-8 overflow-clip rounded-agg-xl border border-agg-separator bg-agg-secondary p-5 sm:p-8",
1290
1561
  classNames == null ? void 0 : classNames.root
1291
1562
  ),
1292
1563
  children: [
1293
- /* @__PURE__ */ jsxs11("div", { className: cn("flex items-stretch gap-6", classNames == null ? void 0 : classNames.topRow), children: [
1294
- /* @__PURE__ */ jsxs11("div", { className: cn("flex min-w-0 flex-1 flex-col gap-6", classNames == null ? void 0 : classNames.leftColumn), children: [
1295
- /* @__PURE__ */ jsx11(
1296
- UserInfoCard,
1297
- {
1298
- user,
1299
- onEditProfile,
1300
- className: classNames == null ? void 0 : classNames.userInfoCard
1301
- }
1564
+ /* @__PURE__ */ jsxs11(
1565
+ "div",
1566
+ {
1567
+ className: cn(
1568
+ "grid grid-cols-1 gap-6 sm:grid-cols-[1fr_minmax(300px,420px)] sm:items-stretch sm:gap-8",
1569
+ classNames == null ? void 0 : classNames.topRow
1302
1570
  ),
1303
- /* @__PURE__ */ jsx11(
1304
- BalanceDisplay,
1305
- {
1306
- balance,
1307
- defaultTimeRange,
1308
- onTimeRangeChange,
1309
- className: classNames == null ? void 0 : classNames.balanceDisplay
1310
- }
1311
- )
1312
- ] }),
1313
- /* @__PURE__ */ jsx11("div", { className: "relative w-[465px] shrink-0", children: /* @__PURE__ */ jsx11(
1314
- BalancesCard,
1315
- {
1316
- venueBalances,
1317
- onDeposit,
1318
- onWithdraw,
1319
- className: cn("absolute inset-0", classNames == null ? void 0 : classNames.balancesCard)
1320
- }
1321
- ) })
1322
- ] }),
1571
+ children: [
1572
+ /* @__PURE__ */ jsx11(
1573
+ "div",
1574
+ {
1575
+ className: cn(
1576
+ "flex min-w-0 flex-1 flex-col gap-4 sm:gap-6 h-full",
1577
+ classNames == null ? void 0 : classNames.leftColumn
1578
+ ),
1579
+ children: /* @__PURE__ */ jsx11(
1580
+ UserInfoCard,
1581
+ {
1582
+ user: resolvedUser,
1583
+ onEditProfile,
1584
+ onDeposit,
1585
+ onWithdraw,
1586
+ className: cn("h-full", classNames == null ? void 0 : classNames.userInfoCard)
1587
+ }
1588
+ )
1589
+ }
1590
+ ),
1591
+ /* @__PURE__ */ jsxs11("div", { className: cn("grid grid-cols-1 grid-rows-2 gap-4 h-full", classNames == null ? void 0 : classNames.rightColumn), children: [
1592
+ /* @__PURE__ */ jsx11(PositionsValueCard, { valueLabel: positionsValueLabel, className: "h-full" }),
1593
+ /* @__PURE__ */ jsx11(
1594
+ AvailableBalanceCard,
1595
+ {
1596
+ valueLabel: availableBalanceLabel,
1597
+ chains: balanceState.balanceBreakdown.map((b) => ({
1598
+ key: b.key,
1599
+ label: b.label,
1600
+ balance: b.balance,
1601
+ accountCount: b.accountCount
1602
+ })),
1603
+ className: "h-full"
1604
+ }
1605
+ )
1606
+ ] })
1607
+ ]
1608
+ }
1609
+ ),
1323
1610
  /* @__PURE__ */ jsx11(
1324
1611
  PositionsActivity,
1325
1612
  {
1326
- activePositions,
1327
- closedPositions,
1328
- activities,
1613
+ activePositions: resolvedActivePositions,
1614
+ closedPositions: resolvedClosedPositions,
1615
+ activities: resolvedActivities,
1329
1616
  onPositionClick,
1330
1617
  onActivityClick,
1618
+ isLoadingPositions: isLoadingPositions != null ? isLoadingPositions : !!shouldUseHookData && positionsQuery.isLoading,
1619
+ isLoadingActivities: isLoadingActivities != null ? isLoadingActivities : !!shouldUseHookData && ordersQuery.isLoading,
1620
+ positionsError: positionsError != null ? positionsError : !!shouldUseHookData && !!positionsQuery.error,
1621
+ activitiesError: activitiesError != null ? activitiesError : !!shouldUseHookData && !!ordersQuery.error,
1622
+ hasMorePositions: hasMorePositions != null ? hasMorePositions : !!shouldUseHookData && !!positionsQuery.hasNextPage,
1623
+ isLoadingMorePositions: isLoadingMorePositions != null ? isLoadingMorePositions : !!shouldUseHookData && !!positionsQuery.isFetchingNextPage,
1624
+ onLoadMorePositions: onLoadMorePositions != null ? onLoadMorePositions : shouldUseHookData && positionsQuery.hasNextPage ? () => {
1625
+ void positionsQuery.fetchNextPage();
1626
+ } : void 0,
1627
+ hasMoreActivities: hasMoreActivities != null ? hasMoreActivities : !!shouldUseHookData && !!ordersQuery.hasNextPage,
1628
+ isLoadingMoreActivities: isLoadingMoreActivities != null ? isLoadingMoreActivities : !!shouldUseHookData && !!ordersQuery.isFetchingNextPage,
1629
+ onLoadMoreActivities: onLoadMoreActivities != null ? onLoadMoreActivities : shouldUseHookData && ordersQuery.hasNextPage ? () => {
1630
+ void ordersQuery.fetchNextPage();
1631
+ } : void 0,
1331
1632
  className: classNames == null ? void 0 : classNames.positionsActivity
1332
1633
  }
1333
1634
  )