@agg-build/ui 4.18.1 → 4.19.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 (52) hide show
  1. package/README.md +1 -0
  2. package/dist/{chunk-ZNOAKSPT.mjs → chunk-47CCGQH6.mjs} +2 -2
  3. package/dist/{chunk-2OBJ7DYT.mjs → chunk-5YHKIJ23.mjs} +21 -10
  4. package/dist/{chunk-2UPO6G3S.mjs → chunk-DWPBGMVJ.mjs} +50 -6
  5. package/dist/{chunk-VUZ72Q7H.mjs → chunk-DXASFSVL.mjs} +3 -2
  6. package/dist/{chunk-YXMDEUHP.mjs → chunk-GT3DCFIT.mjs} +494 -41
  7. package/dist/{chunk-HFL3CEWG.mjs → chunk-NSQQ62QK.mjs} +4 -4
  8. package/dist/{chunk-NRPS2D3Q.mjs → chunk-ROA5K67W.mjs} +1 -1
  9. package/dist/{chunk-JJ3VVCEP.mjs → chunk-WOCZ4TVT.mjs} +12 -8
  10. package/dist/{chunk-WIGSRHUG.mjs → chunk-XZVGHKMW.mjs} +3 -2
  11. package/dist/{event-market-GX24AP2H.mjs → event-market-2BAMDM5I.mjs} +6 -6
  12. package/dist/events.js +60 -11
  13. package/dist/events.mjs +4 -4
  14. package/dist/index.js +1148 -621
  15. package/dist/index.mjs +17 -9
  16. package/dist/modals.js +3 -2
  17. package/dist/modals.mjs +3 -3
  18. package/dist/pages.js +580 -53
  19. package/dist/pages.mjs +16 -8
  20. package/dist/primitives.js +3 -2
  21. package/dist/primitives.mjs +1 -1
  22. package/dist/styles.css +1 -1
  23. package/dist/tailwind.css +1 -1
  24. package/dist/trading.js +21 -9
  25. package/dist/trading.mjs +4 -4
  26. package/dist/types/pages/index.d.mts +1 -0
  27. package/dist/types/pages/index.d.ts +1 -0
  28. package/dist/types/pages/leaderboard/components/leaderboard-header-row.d.mts +7 -0
  29. package/dist/types/pages/leaderboard/components/leaderboard-header-row.d.ts +7 -0
  30. package/dist/types/pages/leaderboard/components/leaderboard-row.d.mts +7 -0
  31. package/dist/types/pages/leaderboard/components/leaderboard-row.d.ts +7 -0
  32. package/dist/types/pages/leaderboard/components/leaderboard-skeleton.d.mts +3 -0
  33. package/dist/types/pages/leaderboard/components/leaderboard-skeleton.d.ts +3 -0
  34. package/dist/types/pages/leaderboard/components/segmented-control.d.mts +18 -0
  35. package/dist/types/pages/leaderboard/components/segmented-control.d.ts +18 -0
  36. package/dist/types/pages/leaderboard/index.d.mts +28 -0
  37. package/dist/types/pages/leaderboard/index.d.ts +28 -0
  38. package/dist/types/pages/leaderboard/leaderboard.constants.d.mts +8 -0
  39. package/dist/types/pages/leaderboard/leaderboard.constants.d.ts +8 -0
  40. package/dist/types/pages/leaderboard/leaderboard.types.d.mts +11 -0
  41. package/dist/types/pages/leaderboard/leaderboard.types.d.ts +11 -0
  42. package/dist/types/pages/user-profile/position-view-model.d.mts +2 -4
  43. package/dist/types/pages/user-profile/position-view-model.d.ts +2 -4
  44. package/dist/types/primitives/remote-image/index.d.mts +1 -1
  45. package/dist/types/primitives/remote-image/index.d.ts +1 -1
  46. package/dist/types/primitives/remote-image/remote-image.types.d.mts +6 -0
  47. package/dist/types/primitives/remote-image/remote-image.types.d.ts +6 -0
  48. package/dist/types/shared/pnl-format.d.mts +20 -0
  49. package/dist/types/shared/pnl-format.d.ts +20 -0
  50. package/package.json +3 -3
  51. /package/dist/types/{pages/user-profile/components → shared}/default-avatar.d.mts +0 -0
  52. /package/dist/types/{pages/user-profile/components → shared}/default-avatar.d.ts +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  EventListTabs,
9
9
  useEventListTabs,
10
10
  useEventListTabsHeaderOverflow
11
- } from "./chunk-VUZ72Q7H.mjs";
11
+ } from "./chunk-DXASFSVL.mjs";
12
12
  import {
13
13
  OPEN_ORDER_FALLBACK_THUMBNAIL_SRC,
14
14
  OPEN_ORDER_QUERY_STATUSES,
@@ -21,14 +21,14 @@ import {
21
21
  parseRawMicroValue,
22
22
  selectOpenLimitOrders,
23
23
  useOpenOrderCancellation
24
- } from "./chunk-HFL3CEWG.mjs";
24
+ } from "./chunk-NSQQ62QK.mjs";
25
25
  import {
26
26
  BetdexAccountCard,
27
27
  DEPOSIT_MODAL_OPEN_EVENT,
28
28
  WITHDRAW_MODAL_OPEN_EVENT,
29
29
  formatChainIdLabel,
30
30
  useClaimWinnings
31
- } from "./chunk-2OBJ7DYT.mjs";
31
+ } from "./chunk-5YHKIJ23.mjs";
32
32
  import {
33
33
  AggErrorBoundary,
34
34
  Button,
@@ -59,7 +59,7 @@ import {
59
59
  skeletonViews,
60
60
  sortCategoriesForNavigation,
61
61
  useOptionalToast
62
- } from "./chunk-WIGSRHUG.mjs";
62
+ } from "./chunk-XZVGHKMW.mjs";
63
63
 
64
64
  // src/pages/home/index.tsx
65
65
  import {
@@ -267,7 +267,7 @@ var useHomePageModals = () => {
267
267
  // src/pages/home/index.tsx
268
268
  import { jsx, jsxs } from "react/jsx-runtime";
269
269
  var DeferredEventMarketPage = lazy(
270
- () => import("./event-market-GX24AP2H.mjs").then((module) => ({ default: module.EventMarketPage }))
270
+ () => import("./event-market-2BAMDM5I.mjs").then((module) => ({ default: module.EventMarketPage }))
271
271
  );
272
272
  var MIN_SEARCH_LENGTH = 3;
273
273
  var SEARCH_DEBOUNCE_MS = 300;
@@ -2101,24 +2101,58 @@ var USER_PROFILE_POSITION_FILTERS = [
2101
2101
  { value: "closed", label: "Closed" }
2102
2102
  ];
2103
2103
 
2104
- // src/pages/user-profile/position-view-model.ts
2105
- var defaultLabels = {
2106
- avgPrefix: "avg",
2107
- nowPrefix: "now",
2108
- finalPrefix: "final"
2109
- };
2110
- var missingLabel = "\u2014";
2104
+ // src/shared/pnl-format.ts
2105
+ var MISSING_VALUE_LABEL = "\u2014";
2111
2106
  var usdFormatter = new Intl.NumberFormat("en-US", {
2112
2107
  style: "currency",
2113
2108
  currency: "USD",
2114
2109
  minimumFractionDigits: 2,
2115
2110
  maximumFractionDigits: 2
2116
2111
  });
2112
+ var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
2113
+ var formatCurrency = (value, formatCurrencyOverride) => {
2114
+ if (!isFiniteNumber(value)) return MISSING_VALUE_LABEL;
2115
+ if (formatCurrencyOverride) return formatCurrencyOverride(value);
2116
+ return usdFormatter.format(value);
2117
+ };
2118
+ var NEGLIGIBLE_CURRENCY_THRESHOLD = 5e-3;
2119
+ var formatSignedCurrency = (value, formatCurrencyOverride, options = {}) => {
2120
+ if (!isFiniteNumber(value)) return MISSING_VALUE_LABEL;
2121
+ if (value === 0) return formatCurrency(0, formatCurrencyOverride);
2122
+ const sign = value > 0 ? "+" : "-";
2123
+ const magnitude = Math.abs(value);
2124
+ if (options.markNegligible && magnitude < NEGLIGIBLE_CURRENCY_THRESHOLD) {
2125
+ return `${sign}<${formatCurrency(0.01, formatCurrencyOverride)}`;
2126
+ }
2127
+ return `${sign}${formatCurrency(magnitude, formatCurrencyOverride)}`;
2128
+ };
2129
+ var formatCurrencyMarkingNegligible = (value, formatCurrencyOverride) => {
2130
+ if (!isFiniteNumber(value)) return MISSING_VALUE_LABEL;
2131
+ if (value !== 0 && Math.abs(value) < NEGLIGIBLE_CURRENCY_THRESHOLD) {
2132
+ return `<${formatCurrency(0.01, formatCurrencyOverride)}`;
2133
+ }
2134
+ return formatCurrency(value, formatCurrencyOverride);
2135
+ };
2136
+ var getPositionTone = (value) => {
2137
+ if (!isFiniteNumber(value) || value === 0) return "neutral";
2138
+ return value > 0 ? "positive" : "negative";
2139
+ };
2140
+ var toneClassName = (tone) => {
2141
+ if (tone === "positive") return "text-agg-success";
2142
+ if (tone === "negative") return "text-agg-error";
2143
+ return "text-agg-muted-foreground";
2144
+ };
2145
+
2146
+ // src/pages/user-profile/position-view-model.ts
2147
+ var defaultLabels = {
2148
+ avgPrefix: "avg",
2149
+ nowPrefix: "now",
2150
+ finalPrefix: "final"
2151
+ };
2117
2152
  var percentFormatter = new Intl.NumberFormat("en-US", {
2118
2153
  minimumFractionDigits: 0,
2119
2154
  maximumFractionDigits: 1
2120
2155
  });
2121
- var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
2122
2156
  var parseCurrencyLabel = (label) => {
2123
2157
  if (!label) return null;
2124
2158
  const normalized = label.replace(/[$,\s]/g, "");
@@ -2139,23 +2173,13 @@ var parsePercentLabel = (label) => {
2139
2173
  const parsed = Number(match[1].replace(/,/g, ""));
2140
2174
  return Number.isFinite(parsed) ? parsed : null;
2141
2175
  };
2142
- var formatCurrency = (value, formatCurrencyOverride) => {
2143
- if (!isFiniteNumber(value)) return missingLabel;
2144
- if (formatCurrencyOverride) return formatCurrencyOverride(value);
2145
- return usdFormatter.format(value);
2146
- };
2147
- var formatSignedCurrency = (value, formatCurrencyOverride) => {
2148
- if (!isFiniteNumber(value)) return missingLabel;
2149
- if (value === 0) return formatCurrency(0, formatCurrencyOverride);
2150
- return `${value > 0 ? "+" : "-"}${formatCurrency(Math.abs(value), formatCurrencyOverride)}`;
2151
- };
2152
2176
  var formatPriceCents = (value, formatPrice) => {
2153
- if (!isFiniteNumber(value)) return missingLabel;
2177
+ if (!isFiniteNumber(value)) return MISSING_VALUE_LABEL;
2154
2178
  if (formatPrice) return formatPrice(value);
2155
2179
  return `${Math.round(value * 100)}\xA2`;
2156
2180
  };
2157
2181
  var formatSignedPercent = (value) => {
2158
- if (!isFiniteNumber(value)) return missingLabel;
2182
+ if (!isFiniteNumber(value)) return MISSING_VALUE_LABEL;
2159
2183
  if (value === 0) return "0%";
2160
2184
  return `${value > 0 ? "+" : "-"}${percentFormatter.format(Math.abs(value))}%`;
2161
2185
  };
@@ -2243,10 +2267,6 @@ var getFinalPnlPercent = (position, pnlValue) => {
2243
2267
  }
2244
2268
  return null;
2245
2269
  };
2246
- var getPositionTone = (value) => {
2247
- if (!isFiniteNumber(value) || value === 0) return "neutral";
2248
- return value > 0 ? "positive" : "negative";
2249
- };
2250
2270
  var toPositionRowViewModel = (position, labels = defaultLabels, formatters = {}) => {
2251
2271
  const { formatCurrency: currency, formatPrice: price } = formatters;
2252
2272
  const positionStatus = resolvePositionStatus(position);
@@ -2260,10 +2280,10 @@ var toPositionRowViewModel = (position, labels = defaultLabels, formatters = {})
2260
2280
  position,
2261
2281
  positionStatus,
2262
2282
  bucket: resolvePositionBucket(position),
2263
- title: position.title || missingLabel,
2283
+ title: position.title || MISSING_VALUE_LABEL,
2264
2284
  thumbnailSrc: position.thumbnailSrc,
2265
- selectedOutcomeLabel: position.outcomeLabel || missingLabel,
2266
- resolutionLabel: position.resolutionLabel || position.outcomeLabel || missingLabel,
2285
+ selectedOutcomeLabel: position.outcomeLabel || MISSING_VALUE_LABEL,
2286
+ resolutionLabel: position.resolutionLabel || position.outcomeLabel || MISSING_VALUE_LABEL,
2267
2287
  venueShareBreakdown: position.venueShareBreakdown,
2268
2288
  totalTraded: {
2269
2289
  primaryLabel: formatCurrency(getTotalTradedValue(position), currency),
@@ -2886,11 +2906,6 @@ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-run
2886
2906
  var shouldUseNativeLinkNavigation2 = (event) => {
2887
2907
  return event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button === 1;
2888
2908
  };
2889
- var toneTextClassName = (tone) => {
2890
- if (tone === "positive") return "text-agg-success";
2891
- if (tone === "negative") return "text-agg-error";
2892
- return "text-agg-muted-foreground";
2893
- };
2894
2909
  var OutcomePill = ({ label }) => /* @__PURE__ */ jsx7("span", { className: "agg-position-outcome max-w-[120px] inline-flex items-center justify-center rounded-full bg-agg-secondary-hover px-4 py-[6px]", children: /* @__PURE__ */ jsx7("span", { className: "whitespace-nowrap font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-foreground truncate", children: label }) });
2895
2910
  var ResolutionPill = ({ label }) => /* @__PURE__ */ jsx7("span", { className: "agg-position-resolution-pill inline-flex w-full items-center justify-center overflow-hidden rounded-full bg-agg-secondary-hover px-4 py-[6px] md:w-auto", children: /* @__PURE__ */ jsx7("span", { className: "truncate whitespace-nowrap font-agg-sans text-agg-sm leading-agg-5 font-agg-normal text-agg-foreground", children: label }) });
2896
2911
  var VenueShares = ({
@@ -2989,7 +3004,7 @@ var PositionValueCell = ({
2989
3004
  {
2990
3005
  className: cn(
2991
3006
  "font-agg-sans text-agg-sm leading-agg-5 font-agg-normal",
2992
- toneTextClassName(value.tone)
3007
+ toneClassName(value.tone)
2993
3008
  ),
2994
3009
  children: value.deltaLabel
2995
3010
  }
@@ -3002,7 +3017,7 @@ var PositionValueCell = ({
3002
3017
  {
3003
3018
  className: cn(
3004
3019
  "font-agg-sans text-agg-xs leading-agg-4 font-agg-normal",
3005
- toneTextClassName(value.tone)
3020
+ toneClassName(value.tone)
3006
3021
  ),
3007
3022
  children: value.percentLabel
3008
3023
  }
@@ -3918,7 +3933,7 @@ var ConditionalWrapper = ({
3918
3933
  }) => condition ? wrapper(children) : children;
3919
3934
  ConditionalWrapper.displayName = "ConditionalWrapper";
3920
3935
 
3921
- // src/pages/user-profile/components/default-avatar.tsx
3936
+ // src/shared/default-avatar.tsx
3922
3937
  import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
3923
3938
  var DefaultAvatar = ({ className }) => {
3924
3939
  return /* @__PURE__ */ jsxs10(
@@ -5316,6 +5331,440 @@ var UserProfilePage = ({
5316
5331
  };
5317
5332
  UserProfilePage.displayName = "UserProfilePage";
5318
5333
 
5334
+ // src/pages/leaderboard/index.tsx
5335
+ import { useAggAuthState as useAggAuthState2, useLabels as useLabels12, useLeaderboard, LEADERBOARD_PERIODS } from "@agg-build/hooks";
5336
+ import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useState as useState7 } from "react";
5337
+
5338
+ // src/pages/leaderboard/components/leaderboard-header-row.tsx
5339
+ import { useLabels as useLabels9 } from "@agg-build/hooks";
5340
+
5341
+ // src/pages/leaderboard/leaderboard.constants.ts
5342
+ var LEADERBOARD_DEFAULT_PERIOD = "30d";
5343
+ var LEADERBOARD_DEFAULT_METRIC = "realizedPnl";
5344
+ var LEADERBOARD_METRICS = ["realizedPnl", "volume"];
5345
+ var LEADERBOARD_TOP_RANKS = 3;
5346
+ var LEADERBOARD_GRID_CLASS = "grid grid-cols-[36px_minmax(0,1fr)] grid-rows-[auto_auto] gap-x-3 gap-y-2 sm:grid-cols-[48px_minmax(0,1fr)_88px_128px_128px] sm:grid-rows-1 sm:gap-x-3 sm:gap-y-0";
5347
+
5348
+ // src/pages/leaderboard/components/leaderboard-header-row.tsx
5349
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
5350
+ var SORT_CARET = /* @__PURE__ */ jsx13("svg", { viewBox: "0 0 10 10", className: "size-2.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx13("path", { d: "M5 8 1 3h8z", fill: "currentColor" }) });
5351
+ function LeaderboardHeaderRow({
5352
+ metric,
5353
+ onMetricChange
5354
+ }) {
5355
+ const labels = useLabels9().leaderboard;
5356
+ const sortable = (key, text) => {
5357
+ const active = metric === key;
5358
+ return /* @__PURE__ */ jsx13(
5359
+ "span",
5360
+ {
5361
+ role: "columnheader",
5362
+ "aria-sort": active ? "descending" : void 0,
5363
+ className: "text-right",
5364
+ children: /* @__PURE__ */ jsxs13(
5365
+ "button",
5366
+ {
5367
+ type: "button",
5368
+ onClick: () => onMetricChange(key),
5369
+ className: cn(
5370
+ "inline-flex cursor-pointer items-center justify-end gap-1 uppercase tracking-wide outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-agg-primary-hover",
5371
+ active ? "font-agg-bold text-agg-foreground" : "hover:text-agg-foreground"
5372
+ ),
5373
+ children: [
5374
+ text,
5375
+ active ? SORT_CARET : null
5376
+ ]
5377
+ }
5378
+ )
5379
+ }
5380
+ );
5381
+ };
5382
+ return /* @__PURE__ */ jsxs13(
5383
+ "div",
5384
+ {
5385
+ role: "row",
5386
+ className: cn(
5387
+ LEADERBOARD_GRID_CLASS,
5388
+ "agg-leaderboard-header hidden h-10 items-center border-b border-agg-separator bg-agg-secondary-hover px-5 text-agg-xs leading-agg-4 uppercase tracking-wide text-agg-muted-foreground sm:grid"
5389
+ ),
5390
+ children: [
5391
+ /* @__PURE__ */ jsx13("span", { role: "columnheader", children: labels.columns.rank }),
5392
+ /* @__PURE__ */ jsx13("span", { role: "columnheader", children: labels.columns.trader }),
5393
+ /* @__PURE__ */ jsx13("span", { role: "columnheader", className: "text-right", children: labels.columns.orders }),
5394
+ sortable("volume", labels.columns.volume),
5395
+ sortable("realizedPnl", labels.columns.realizedPnl)
5396
+ ]
5397
+ }
5398
+ );
5399
+ }
5400
+
5401
+ // src/pages/leaderboard/components/leaderboard-row.tsx
5402
+ import { optimizedImageUrl as optimizedImageUrl4, useAggUiConfig as useAggUiConfig3, useLabels as useLabels10 } from "@agg-build/hooks";
5403
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
5404
+ var integer = new Intl.NumberFormat("en-US");
5405
+ function LeaderboardRowView({
5406
+ row,
5407
+ isCurrentUser,
5408
+ className
5409
+ }) {
5410
+ var _a, _b, _c;
5411
+ const labels = useLabels10().leaderboard;
5412
+ const { formatCurrency: formatCurrency2 } = useAggUiConfig3().formatting;
5413
+ const tone = getPositionTone(row.realizedPnl);
5414
+ const shortWallet = shortenAddress(row.walletAddress);
5415
+ const identity = (_b = (_a = row.username) != null ? _a : shortWallet) != null ? _b : labels.anonymousTrader;
5416
+ const identityKind = row.username ? "username" : shortWallet ? "wallet" : "anonymous";
5417
+ const isTop = row.rank != null && row.rank <= LEADERBOARD_TOP_RANKS;
5418
+ const hasOrders = Number.isFinite(row.orders);
5419
+ const cell = (caption, value, extra) => /* @__PURE__ */ jsxs14("span", { role: "cell", className: "flex flex-col text-left tabular-nums sm:block sm:text-right", children: [
5420
+ /* @__PURE__ */ jsx14("span", { className: "agg-type-caption uppercase tracking-wide text-agg-muted-foreground sm:hidden", children: caption }),
5421
+ /* @__PURE__ */ jsx14("span", { className: cn("text-agg-sm leading-agg-5", extra), children: value })
5422
+ ] });
5423
+ return /* @__PURE__ */ jsxs14(
5424
+ "div",
5425
+ {
5426
+ role: "row",
5427
+ "aria-current": isCurrentUser ? "true" : void 0,
5428
+ className: cn(
5429
+ LEADERBOARD_GRID_CLASS,
5430
+ "agg-leaderboard-row items-center px-4 py-3 sm:min-h-16 sm:px-5",
5431
+ isCurrentUser ? "bg-agg-trade-highlight-surface shadow-[inset_3px_0_0_var(--agg-color-primary)]" : "hover:bg-agg-secondary-hover/60",
5432
+ className
5433
+ ),
5434
+ children: [
5435
+ /* @__PURE__ */ jsx14(
5436
+ "span",
5437
+ {
5438
+ role: "cell",
5439
+ "data-testid": "agg-leaderboard-rank",
5440
+ className: cn(
5441
+ "agg-leaderboard-rank row-span-2 inline-flex size-7 items-center justify-center rounded-agg-full text-agg-sm tabular-nums sm:row-span-1",
5442
+ // cn() is a plain join: colour classes must be mutually exclusive.
5443
+ row.rank === 1 ? "border border-agg-primary bg-agg-secondary-hover font-agg-bold text-agg-primary" : isTop ? "border border-agg-separator bg-agg-secondary-hover font-agg-bold text-agg-foreground" : "text-agg-muted-foreground"
5444
+ ),
5445
+ children: (_c = row.rank) != null ? _c : "\u2013"
5446
+ }
5447
+ ),
5448
+ /* @__PURE__ */ jsxs14("div", { role: "cell", className: "agg-leaderboard-identity flex min-w-0 items-center gap-3", children: [
5449
+ row.avatarUrl ? /* @__PURE__ */ jsx14(
5450
+ RemoteImage,
5451
+ {
5452
+ src: optimizedImageUrl4(row.avatarUrl, 80),
5453
+ alt: "",
5454
+ className: "size-10 shrink-0 rounded-agg-full object-cover"
5455
+ }
5456
+ ) : /* @__PURE__ */ jsx14(DefaultAvatar, { className: "size-10 rounded-agg-full" }),
5457
+ /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-col", children: [
5458
+ /* @__PURE__ */ jsxs14("span", { className: "flex items-center gap-2", children: [
5459
+ /* @__PURE__ */ jsx14(
5460
+ "span",
5461
+ {
5462
+ className: cn(
5463
+ "truncate text-agg-sm leading-agg-5",
5464
+ identityKind === "username" && "font-agg-bold text-agg-foreground",
5465
+ identityKind === "wallet" && "font-mono font-agg-medium text-agg-foreground",
5466
+ identityKind === "anonymous" && "font-agg-medium text-agg-muted-foreground"
5467
+ ),
5468
+ children: identity
5469
+ }
5470
+ ),
5471
+ isCurrentUser ? /* @__PURE__ */ jsx14("span", { className: "rounded-agg-full bg-agg-primary px-1.5 text-agg-2xs font-agg-bold uppercase leading-agg-4 tracking-wide text-agg-on-primary", children: labels.you }) : null
5472
+ ] }),
5473
+ /* @__PURE__ */ jsx14("span", { className: "text-agg-xs leading-agg-4 text-agg-muted-foreground", children: hasOrders ? labels.tradesCount(row.orders) : MISSING_VALUE_LABEL })
5474
+ ] })
5475
+ ] }),
5476
+ /* @__PURE__ */ jsxs14("div", { className: "col-start-2 grid grid-cols-3 gap-2 sm:contents", children: [
5477
+ cell(labels.columns.orders, hasOrders ? integer.format(row.orders) : MISSING_VALUE_LABEL),
5478
+ cell(labels.columns.volume, formatCurrencyMarkingNegligible(row.volume, formatCurrency2)),
5479
+ cell(
5480
+ labels.columns.realizedPnl,
5481
+ formatSignedCurrency(row.realizedPnl, formatCurrency2, { markNegligible: true }),
5482
+ cn("font-agg-bold", toneClassName(tone))
5483
+ )
5484
+ ] })
5485
+ ]
5486
+ }
5487
+ );
5488
+ }
5489
+
5490
+ // src/pages/leaderboard/components/leaderboard-skeleton.tsx
5491
+ import { useLabels as useLabels11 } from "@agg-build/hooks";
5492
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
5493
+ function LeaderboardSkeleton({ rows = 4 }) {
5494
+ const labels = useLabels11().leaderboard;
5495
+ return /* @__PURE__ */ jsx15("div", { role: "status", "aria-label": labels.loadingAria, className: "agg-leaderboard-skeleton", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs15(
5496
+ "div",
5497
+ {
5498
+ className: cn(
5499
+ LEADERBOARD_GRID_CLASS,
5500
+ "items-center border-b border-agg-separator px-4 py-3 last:border-b-0 sm:min-h-16 sm:px-5"
5501
+ ),
5502
+ children: [
5503
+ /* @__PURE__ */ jsx15("span", { className: "size-7 rounded-agg-full bg-agg-secondary-hover/80" }),
5504
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3", children: [
5505
+ /* @__PURE__ */ jsx15("span", { className: "size-10 rounded-agg-full bg-agg-secondary-hover/80" }),
5506
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-1 flex-col gap-2", children: [
5507
+ /* @__PURE__ */ jsx15("span", { className: "h-3 w-2/5 rounded-agg-sm bg-agg-secondary-hover/80" }),
5508
+ /* @__PURE__ */ jsx15("span", { className: "h-3 w-1/5 rounded-agg-sm bg-agg-secondary-hover/80" })
5509
+ ] })
5510
+ ] }),
5511
+ /* @__PURE__ */ jsx15("span", { className: "hidden h-3 w-10 justify-self-end rounded-agg-sm bg-agg-secondary-hover/80 sm:block" }),
5512
+ /* @__PURE__ */ jsx15("span", { className: "hidden h-3 w-16 justify-self-end rounded-agg-sm bg-agg-secondary-hover/80 sm:block" }),
5513
+ /* @__PURE__ */ jsx15("span", { className: "hidden h-3 w-14 justify-self-end rounded-agg-sm bg-agg-secondary-hover/80 sm:block" })
5514
+ ]
5515
+ },
5516
+ i
5517
+ )) });
5518
+ }
5519
+
5520
+ // src/pages/leaderboard/components/segmented-control.tsx
5521
+ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
5522
+ function SegmentedControl({
5523
+ label,
5524
+ value,
5525
+ onChange,
5526
+ items,
5527
+ className,
5528
+ itemClassName
5529
+ }) {
5530
+ return /* @__PURE__ */ jsx16(
5531
+ "div",
5532
+ {
5533
+ role: "group",
5534
+ "aria-label": label,
5535
+ className: cn(
5536
+ "agg-segmented flex h-10 w-full items-stretch overflow-clip rounded-agg-sm border border-agg-separator sm:w-auto",
5537
+ className
5538
+ ),
5539
+ children: items.map((item, idx) => {
5540
+ const isActive = item.value === value;
5541
+ return /* @__PURE__ */ jsxs16("div", { className: "flex flex-1 items-stretch sm:flex-none", children: [
5542
+ idx > 0 ? /* @__PURE__ */ jsx16("div", { className: "w-px bg-agg-separator", "aria-hidden": true }) : null,
5543
+ /* @__PURE__ */ jsx16(
5544
+ "button",
5545
+ {
5546
+ type: "button",
5547
+ "aria-pressed": isActive,
5548
+ onClick: () => onChange(item.value),
5549
+ className: cn(
5550
+ "agg-segmented-trigger flex flex-1 cursor-pointer items-center justify-center px-3 font-agg-sans text-agg-sm leading-agg-5 whitespace-nowrap outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-agg-primary-hover sm:px-4",
5551
+ isActive ? "bg-agg-secondary-hover font-agg-bold text-agg-foreground" : "bg-agg-secondary font-agg-normal text-agg-muted-foreground hover:bg-agg-secondary-hover hover:text-agg-foreground",
5552
+ itemClassName
5553
+ ),
5554
+ children: item.label
5555
+ }
5556
+ )
5557
+ ] }, item.value);
5558
+ })
5559
+ }
5560
+ );
5561
+ }
5562
+
5563
+ // src/pages/leaderboard/index.tsx
5564
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
5565
+ function LeaderboardPage(props) {
5566
+ return /* @__PURE__ */ jsx17(AggErrorBoundary, { onError: props.onError, children: /* @__PURE__ */ jsx17(LeaderboardPageInner, __spreadValues({}, props)) });
5567
+ }
5568
+ function LeaderboardPageInner({
5569
+ rows: rowsProp,
5570
+ isLoading: isLoadingProp,
5571
+ error: errorProp,
5572
+ hasNextPage: hasNextPageProp,
5573
+ isLoadingMore: isLoadingMoreProp,
5574
+ onLoadMore: onLoadMoreProp,
5575
+ period: periodProp,
5576
+ onPeriodChange,
5577
+ metric: metricProp,
5578
+ onMetricChange,
5579
+ currentUserId: currentUserIdProp,
5580
+ appName,
5581
+ className,
5582
+ classNames
5583
+ }) {
5584
+ const allLabels = useLabels12();
5585
+ const labels = allLabels.leaderboard;
5586
+ const { user } = useAggAuthState2();
5587
+ const [periodState, setPeriodState] = useState7(LEADERBOARD_DEFAULT_PERIOD);
5588
+ const [metricState, setMetricState] = useState7(LEADERBOARD_DEFAULT_METRIC);
5589
+ const period = periodProp != null ? periodProp : periodState;
5590
+ const metric = metricProp != null ? metricProp : metricState;
5591
+ const handlePeriodChange = useCallback5(
5592
+ (next) => {
5593
+ if (periodProp === void 0) setPeriodState(next);
5594
+ onPeriodChange == null ? void 0 : onPeriodChange(next);
5595
+ },
5596
+ [onPeriodChange, periodProp]
5597
+ );
5598
+ const handleMetricChange = useCallback5(
5599
+ (next) => {
5600
+ if (metricProp === void 0) setMetricState(next);
5601
+ onMetricChange == null ? void 0 : onMetricChange(next);
5602
+ },
5603
+ [metricProp, onMetricChange]
5604
+ );
5605
+ const shouldUseHookData = !rowsProp;
5606
+ const query = useLeaderboard({ period, metric, enabled: shouldUseHookData });
5607
+ const rows = rowsProp != null ? rowsProp : query.rows;
5608
+ const isLoading = isLoadingProp != null ? isLoadingProp : shouldUseHookData && query.isLoading;
5609
+ const error = errorProp != null ? errorProp : shouldUseHookData ? query.error : null;
5610
+ const hasNextPage = hasNextPageProp != null ? hasNextPageProp : shouldUseHookData && query.hasNextPage;
5611
+ const isLoadingMore = isLoadingMoreProp != null ? isLoadingMoreProp : shouldUseHookData && query.isFetchingNextPage;
5612
+ const fetchNextPage = query.fetchNextPage;
5613
+ const onLoadMore = useMemo5(
5614
+ () => onLoadMoreProp != null ? onLoadMoreProp : shouldUseHookData ? () => void fetchNextPage() : void 0,
5615
+ [onLoadMoreProp, shouldUseHookData, fetchNextPage]
5616
+ );
5617
+ const retry = shouldUseHookData ? () => void query.refetch() : void 0;
5618
+ const currentUserId = currentUserIdProp != null ? currentUserIdProp : user == null ? void 0 : user.id;
5619
+ const [sentinel, setSentinel] = useState7(null);
5620
+ useEffect6(() => {
5621
+ const target = sentinel;
5622
+ if (!target || !hasNextPage || !onLoadMore || typeof IntersectionObserver === "undefined")
5623
+ return;
5624
+ const observer = new IntersectionObserver(
5625
+ (entries) => {
5626
+ var _a;
5627
+ if (!((_a = entries[0]) == null ? void 0 : _a.isIntersecting) || isLoading || isLoadingMore) return;
5628
+ onLoadMore();
5629
+ },
5630
+ { rootMargin: "60px 0px" }
5631
+ );
5632
+ observer.observe(target);
5633
+ return () => observer.disconnect();
5634
+ }, [sentinel, hasNextPage, isLoading, isLoadingMore, onLoadMore]);
5635
+ const hasRows = rows.length > 0;
5636
+ const showInlineError = Boolean(error) && hasRows;
5637
+ const periodItems = LEADERBOARD_PERIODS.map((value) => ({ value, label: labels.periods[value] }));
5638
+ const metricItems = LEADERBOARD_METRICS.map((value) => ({ value, label: labels.metrics[value] }));
5639
+ return /* @__PURE__ */ jsxs17(
5640
+ "div",
5641
+ {
5642
+ className: cn(
5643
+ "agg-leaderboard mx-auto flex w-full max-w-[960px] flex-col px-4 py-6 sm:px-6 gap-5 font-agg-sans text-agg-foreground",
5644
+ className,
5645
+ classNames == null ? void 0 : classNames.root
5646
+ ),
5647
+ children: [
5648
+ /* @__PURE__ */ jsxs17("header", { className: cn("agg-leaderboard-title flex flex-col gap-1", classNames == null ? void 0 : classNames.header), children: [
5649
+ /* @__PURE__ */ jsx17("h1", { className: "agg-type-heading m-0", children: labels.title }),
5650
+ /* @__PURE__ */ jsx17("p", { className: "m-0 text-agg-sm leading-agg-5 text-agg-muted-foreground", children: labels.subtitle(appName, labels.periods[period]) })
5651
+ ] }),
5652
+ /* @__PURE__ */ jsxs17(
5653
+ "div",
5654
+ {
5655
+ className: cn(
5656
+ "agg-leaderboard-toolbar flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between",
5657
+ classNames == null ? void 0 : classNames.toolbar
5658
+ ),
5659
+ children: [
5660
+ /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3", children: [
5661
+ /* @__PURE__ */ jsx17("span", { className: "agg-type-caption uppercase tracking-wide text-agg-muted-foreground", children: labels.periodLabel }),
5662
+ /* @__PURE__ */ jsx17(
5663
+ SegmentedControl,
5664
+ {
5665
+ label: labels.periodLabel,
5666
+ value: period,
5667
+ onChange: handlePeriodChange,
5668
+ items: periodItems
5669
+ }
5670
+ )
5671
+ ] }),
5672
+ /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3", children: [
5673
+ /* @__PURE__ */ jsx17("span", { className: "agg-type-caption uppercase tracking-wide text-agg-muted-foreground", children: labels.rankByLabel }),
5674
+ /* @__PURE__ */ jsx17(
5675
+ SegmentedControl,
5676
+ {
5677
+ label: labels.rankByLabel,
5678
+ value: metric,
5679
+ onChange: handleMetricChange,
5680
+ items: metricItems
5681
+ }
5682
+ )
5683
+ ] })
5684
+ ]
5685
+ }
5686
+ ),
5687
+ /* @__PURE__ */ jsxs17(
5688
+ "section",
5689
+ {
5690
+ "aria-label": labels.title,
5691
+ className: cn(
5692
+ "agg-leaderboard-list overflow-clip rounded-agg-xl border border-agg-separator bg-agg-secondary shadow-agg-card",
5693
+ classNames == null ? void 0 : classNames.list
5694
+ ),
5695
+ children: [
5696
+ /* @__PURE__ */ jsxs17("div", { role: "table", "aria-label": labels.title, className: "agg-leaderboard-table", children: [
5697
+ /* @__PURE__ */ jsx17(LeaderboardHeaderRow, { metric, onMetricChange: handleMetricChange }),
5698
+ !isLoading && hasRows ? /* @__PURE__ */ jsx17("div", { className: "divide-y divide-agg-separator", children: rows.map((row) => /* @__PURE__ */ jsx17(
5699
+ LeaderboardRowView,
5700
+ {
5701
+ row,
5702
+ isCurrentUser: currentUserId !== void 0 && row.userId === currentUserId,
5703
+ className: classNames == null ? void 0 : classNames.row
5704
+ },
5705
+ row.userId
5706
+ )) }) : null
5707
+ ] }),
5708
+ isLoading ? /* @__PURE__ */ jsx17(LeaderboardSkeleton, {}) : error && !hasRows ? /* @__PURE__ */ jsx17("div", { className: "py-10", children: /* @__PURE__ */ jsx17(
5709
+ StateMessage,
5710
+ {
5711
+ title: labels.errorTitle,
5712
+ description: labels.errorDescription,
5713
+ icon: /* @__PURE__ */ jsx17(Icon, { name: "warning" }),
5714
+ onAction: retry
5715
+ }
5716
+ ) }) : rows.length === 0 ? /* @__PURE__ */ jsx17("div", { className: "py-10", children: /* @__PURE__ */ jsx17(
5717
+ StateMessage,
5718
+ {
5719
+ title: labels.emptyTitle,
5720
+ description: labels.emptyDescription,
5721
+ icon: /* @__PURE__ */ jsx17(Icon, { name: "search-empty" })
5722
+ }
5723
+ ) }) : null,
5724
+ (hasNextPage || showInlineError) && !isLoading ? /* @__PURE__ */ jsx17(
5725
+ "div",
5726
+ {
5727
+ className: cn(
5728
+ "agg-leaderboard-footer relative flex items-center justify-center gap-3 border-t border-agg-separator p-3.5",
5729
+ classNames == null ? void 0 : classNames.footer
5730
+ ),
5731
+ children: showInlineError ? /* @__PURE__ */ jsxs17(Fragment5, { children: [
5732
+ /* @__PURE__ */ jsx17("span", { role: "alert", className: "text-agg-sm leading-agg-5 text-agg-error", children: labels.errorTitle }),
5733
+ /* @__PURE__ */ jsx17(Button, { variant: "tertiary", size: "small", onClick: retry != null ? retry : onLoadMore, children: allLabels.common.retry })
5734
+ ] }) : /* @__PURE__ */ jsxs17(Fragment5, { children: [
5735
+ /* @__PURE__ */ jsx17(
5736
+ "div",
5737
+ {
5738
+ ref: setSentinel,
5739
+ className: "agg-leaderboard-sentinel absolute inset-x-0 top-0 h-px",
5740
+ "aria-hidden": true
5741
+ }
5742
+ ),
5743
+ /* @__PURE__ */ jsx17(
5744
+ Button,
5745
+ {
5746
+ variant: "tertiary",
5747
+ size: "small",
5748
+ onClick: onLoadMore,
5749
+ disabled: isLoadingMore,
5750
+ isLoading: isLoadingMore,
5751
+ "aria-label": labels.showMore,
5752
+ children: labels.showMore
5753
+ }
5754
+ )
5755
+ ] })
5756
+ }
5757
+ ) : null
5758
+ ]
5759
+ }
5760
+ ),
5761
+ /* @__PURE__ */ jsx17("p", { className: "m-0 text-agg-xs leading-agg-4 text-agg-muted-foreground", children: labels.pnlFootnote })
5762
+ ]
5763
+ }
5764
+ );
5765
+ }
5766
+ LeaderboardPage.displayName = "LeaderboardPage";
5767
+
5319
5768
  export {
5320
5769
  DefaultAvatar,
5321
5770
  ConditionalWrapper,
@@ -5327,5 +5776,9 @@ export {
5327
5776
  USER_PROFILE_TAB_ACTIVITY,
5328
5777
  buildAggTxExplorerHref,
5329
5778
  formatShareAmount,
5330
- UserProfilePage
5779
+ UserProfilePage,
5780
+ LEADERBOARD_DEFAULT_PERIOD,
5781
+ LEADERBOARD_DEFAULT_METRIC,
5782
+ LEADERBOARD_METRICS,
5783
+ LeaderboardPage
5331
5784
  };
@@ -4,17 +4,17 @@ import {
4
4
  MarketDetails,
5
5
  MarketDetailsList,
6
6
  isErrorWithStatus
7
- } from "./chunk-2UPO6G3S.mjs";
7
+ } from "./chunk-DWPBGMVJ.mjs";
8
8
  import {
9
9
  PlaceOrder,
10
10
  SettlementDetails,
11
11
  useResolvedMarketClaim
12
- } from "./chunk-2OBJ7DYT.mjs";
12
+ } from "./chunk-5YHKIJ23.mjs";
13
13
  import {
14
14
  getDisplayOutcomePrice,
15
15
  resolveHeaderOutcomeItems,
16
16
  resolveMarketFromVenueMarkets
17
- } from "./chunk-JJ3VVCEP.mjs";
17
+ } from "./chunk-WOCZ4TVT.mjs";
18
18
  import {
19
19
  AggErrorBoundary,
20
20
  Button,
@@ -38,7 +38,7 @@ import {
38
38
  normalizeVenueMarketCluster,
39
39
  skeletonViews,
40
40
  useOptionalToast
41
- } from "./chunk-WIGSRHUG.mjs";
41
+ } from "./chunk-XZVGHKMW.mjs";
42
42
 
43
43
  // src/pages/event-market/index.tsx
44
44
  import {