@agg-build/ui 4.18.2 → 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.
- package/README.md +1 -0
- package/dist/{chunk-RFMA5ABT.mjs → chunk-GT3DCFIT.mjs} +489 -36
- package/dist/index.js +1070 -603
- package/dist/index.mjs +9 -1
- package/dist/pages.js +502 -35
- package/dist/pages.mjs +9 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +1 -1
- package/dist/types/pages/index.d.mts +1 -0
- package/dist/types/pages/index.d.ts +1 -0
- package/dist/types/pages/leaderboard/components/leaderboard-header-row.d.mts +7 -0
- package/dist/types/pages/leaderboard/components/leaderboard-header-row.d.ts +7 -0
- package/dist/types/pages/leaderboard/components/leaderboard-row.d.mts +7 -0
- package/dist/types/pages/leaderboard/components/leaderboard-row.d.ts +7 -0
- package/dist/types/pages/leaderboard/components/leaderboard-skeleton.d.mts +3 -0
- package/dist/types/pages/leaderboard/components/leaderboard-skeleton.d.ts +3 -0
- package/dist/types/pages/leaderboard/components/segmented-control.d.mts +18 -0
- package/dist/types/pages/leaderboard/components/segmented-control.d.ts +18 -0
- package/dist/types/pages/leaderboard/index.d.mts +28 -0
- package/dist/types/pages/leaderboard/index.d.ts +28 -0
- package/dist/types/pages/leaderboard/leaderboard.constants.d.mts +8 -0
- package/dist/types/pages/leaderboard/leaderboard.constants.d.ts +8 -0
- package/dist/types/pages/leaderboard/leaderboard.types.d.mts +11 -0
- package/dist/types/pages/leaderboard/leaderboard.types.d.ts +11 -0
- package/dist/types/pages/user-profile/position-view-model.d.mts +2 -4
- package/dist/types/pages/user-profile/position-view-model.d.ts +2 -4
- package/dist/types/shared/pnl-format.d.mts +20 -0
- package/dist/types/shared/pnl-format.d.ts +20 -0
- package/package.json +3 -3
- /package/dist/types/{pages/user-profile/components → shared}/default-avatar.d.mts +0 -0
- /package/dist/types/{pages/user-profile/components → shared}/default-avatar.d.ts +0 -0
package/README.md
CHANGED
|
@@ -233,6 +233,7 @@ export function Home() {
|
|
|
233
233
|
| `HomePage` | Full home page with tabs, search, grid |
|
|
234
234
|
| `EventMarketPage` | Full event/market detail page |
|
|
235
235
|
| `UserProfilePage` | User profile page with tabs |
|
|
236
|
+
| `LeaderboardPage` | Trader leaderboard by P&L or volume |
|
|
236
237
|
|
|
237
238
|
### Modals — `@agg-build/ui/modals`
|
|
238
239
|
|
|
@@ -2101,24 +2101,58 @@ var USER_PROFILE_POSITION_FILTERS = [
|
|
|
2101
2101
|
{ value: "closed", label: "Closed" }
|
|
2102
2102
|
];
|
|
2103
2103
|
|
|
2104
|
-
// src/
|
|
2105
|
-
var
|
|
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
|
|
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
|
|
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 ||
|
|
2283
|
+
title: position.title || MISSING_VALUE_LABEL,
|
|
2264
2284
|
thumbnailSrc: position.thumbnailSrc,
|
|
2265
|
-
selectedOutcomeLabel: position.outcomeLabel ||
|
|
2266
|
-
resolutionLabel: position.resolutionLabel || position.outcomeLabel ||
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
};
|