@loafmarkets/ui 0.1.50 → 0.1.52
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/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +311 -267
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +190 -146
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React5 = require('react');
|
|
4
4
|
var reactSlot = require('@radix-ui/react-slot');
|
|
5
5
|
var classVarianceAuthority = require('class-variance-authority');
|
|
6
6
|
var clsx = require('clsx');
|
|
@@ -33,7 +33,7 @@ function _interopNamespace(e) {
|
|
|
33
33
|
return Object.freeze(n);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
var
|
|
36
|
+
var React5__namespace = /*#__PURE__*/_interopNamespace(React5);
|
|
37
37
|
var styled24__default = /*#__PURE__*/_interopDefault(styled24);
|
|
38
38
|
var LightweightCharts__namespace = /*#__PURE__*/_interopNamespace(LightweightCharts);
|
|
39
39
|
|
|
@@ -75,7 +75,7 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
);
|
|
78
|
-
var Button =
|
|
78
|
+
var Button = React5__namespace.forwardRef(
|
|
79
79
|
({ className, variant, size, radius, asChild = false, ...props }, ref) => {
|
|
80
80
|
const Comp = asChild ? reactSlot.Slot : "button";
|
|
81
81
|
const coercedRadius = radius ?? (variant === "onboarding" || variant === "onboardingOutline" ? "square" : void 0);
|
|
@@ -114,11 +114,11 @@ var badgeVariants = classVarianceAuthority.cva(
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
);
|
|
117
|
-
var Badge =
|
|
117
|
+
var Badge = React5__namespace.forwardRef(
|
|
118
118
|
({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn(badgeVariants({ variant, size }), className), ...props })
|
|
119
119
|
);
|
|
120
120
|
Badge.displayName = "Badge";
|
|
121
|
-
var Card =
|
|
121
|
+
var Card = React5__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
122
122
|
"div",
|
|
123
123
|
{
|
|
124
124
|
ref,
|
|
@@ -130,11 +130,11 @@ var Card = React9__namespace.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
130
130
|
}
|
|
131
131
|
));
|
|
132
132
|
Card.displayName = "Card";
|
|
133
|
-
var CardHeader =
|
|
133
|
+
var CardHeader = React5__namespace.forwardRef(
|
|
134
134
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
|
|
135
135
|
);
|
|
136
136
|
CardHeader.displayName = "CardHeader";
|
|
137
|
-
var CardTitle =
|
|
137
|
+
var CardTitle = React5__namespace.forwardRef(
|
|
138
138
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
139
139
|
"h3",
|
|
140
140
|
{
|
|
@@ -145,15 +145,15 @@ var CardTitle = React9__namespace.forwardRef(
|
|
|
145
145
|
)
|
|
146
146
|
);
|
|
147
147
|
CardTitle.displayName = "CardTitle";
|
|
148
|
-
var CardDescription =
|
|
148
|
+
var CardDescription = React5__namespace.forwardRef(
|
|
149
149
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("p", { ref, className: cn("text-sm text-slate-500", className), ...props })
|
|
150
150
|
);
|
|
151
151
|
CardDescription.displayName = "CardDescription";
|
|
152
|
-
var CardContent =
|
|
152
|
+
var CardContent = React5__namespace.forwardRef(
|
|
153
153
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("px-6 pb-6 pt-2 text-sm text-slate-600", className), ...props })
|
|
154
154
|
);
|
|
155
155
|
CardContent.displayName = "CardContent";
|
|
156
|
-
var CardFooter =
|
|
156
|
+
var CardFooter = React5__namespace.forwardRef(
|
|
157
157
|
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex items-center border-t border-slate-100 px-6 py-4", className), ...props })
|
|
158
158
|
);
|
|
159
159
|
CardFooter.displayName = "CardFooter";
|
|
@@ -171,7 +171,7 @@ var defaultFormatSignedCurrency = (value) => {
|
|
|
171
171
|
const sign = value >= 0 ? "+" : "-";
|
|
172
172
|
return `${sign}${defaultFormatCurrency(Math.abs(value))}`;
|
|
173
173
|
};
|
|
174
|
-
var PortfolioSummary =
|
|
174
|
+
var PortfolioSummary = React5__namespace.forwardRef(
|
|
175
175
|
({
|
|
176
176
|
availableCash,
|
|
177
177
|
portfolioValue,
|
|
@@ -321,23 +321,23 @@ function HousePositionSlider({
|
|
|
321
321
|
className,
|
|
322
322
|
...props
|
|
323
323
|
}) {
|
|
324
|
-
const [orderMode, setOrderMode] =
|
|
325
|
-
const [buyTrackingMode, setBuyTrackingMode] =
|
|
326
|
-
const [deltaDollars, setDeltaDollars] =
|
|
327
|
-
const [deltaTokensBuy, setDeltaTokensBuy] =
|
|
328
|
-
const [deltaTokensSell, setDeltaTokensSell] =
|
|
329
|
-
const [_isDragging, setIsDragging] =
|
|
330
|
-
const [visualTargetPct, setVisualTargetPct] =
|
|
331
|
-
const [orderType, setOrderType] =
|
|
332
|
-
const [limitPrice, setLimitPrice] =
|
|
333
|
-
const [limitPriceInput, setLimitPriceInput] =
|
|
334
|
-
const [limitPriceDirty, setLimitPriceDirty] =
|
|
335
|
-
const [ownershipInput, setOwnershipInput] =
|
|
336
|
-
const [tokenAmountInput, setTokenAmountInput] =
|
|
337
|
-
const houseRef =
|
|
324
|
+
const [orderMode, setOrderMode] = React5__namespace.useState("none");
|
|
325
|
+
const [buyTrackingMode, setBuyTrackingMode] = React5__namespace.useState("dollars");
|
|
326
|
+
const [deltaDollars, setDeltaDollars] = React5__namespace.useState(0);
|
|
327
|
+
const [deltaTokensBuy, setDeltaTokensBuy] = React5__namespace.useState(0);
|
|
328
|
+
const [deltaTokensSell, setDeltaTokensSell] = React5__namespace.useState(0);
|
|
329
|
+
const [_isDragging, setIsDragging] = React5__namespace.useState(false);
|
|
330
|
+
const [visualTargetPct, setVisualTargetPct] = React5__namespace.useState(null);
|
|
331
|
+
const [orderType, setOrderType] = React5__namespace.useState(defaultOrderType);
|
|
332
|
+
const [limitPrice, setLimitPrice] = React5__namespace.useState(currentPrice);
|
|
333
|
+
const [limitPriceInput, setLimitPriceInput] = React5__namespace.useState(currentPrice.toFixed(2));
|
|
334
|
+
const [limitPriceDirty, setLimitPriceDirty] = React5__namespace.useState(false);
|
|
335
|
+
const [ownershipInput, setOwnershipInput] = React5__namespace.useState("");
|
|
336
|
+
const [tokenAmountInput, setTokenAmountInput] = React5__namespace.useState("");
|
|
337
|
+
const houseRef = React5__namespace.useRef(null);
|
|
338
338
|
const asks = orderbook?.asks ?? [];
|
|
339
339
|
const bids = orderbook?.bids ?? [];
|
|
340
|
-
|
|
340
|
+
React5__namespace.useEffect(() => {
|
|
341
341
|
if (orderType !== "limit") return;
|
|
342
342
|
if (limitPriceDirty) return;
|
|
343
343
|
setLimitPrice(currentPrice);
|
|
@@ -412,7 +412,7 @@ function HousePositionSlider({
|
|
|
412
412
|
const impliedDisplayTargetOwnership = clamp(targetOwnership + ownershipShift, 0, 100);
|
|
413
413
|
const displayTargetOwnership = visualTargetPct ?? impliedDisplayTargetOwnership;
|
|
414
414
|
const estFeeTokens = Math.abs(deltaValue) * 5e-3 / (effectivePrice || 1);
|
|
415
|
-
const resetOrder =
|
|
415
|
+
const resetOrder = React5__namespace.useCallback(() => {
|
|
416
416
|
setOrderMode("none");
|
|
417
417
|
setBuyTrackingMode("dollars");
|
|
418
418
|
setDeltaDollars(0);
|
|
@@ -420,7 +420,7 @@ function HousePositionSlider({
|
|
|
420
420
|
setDeltaTokensSell(0);
|
|
421
421
|
setVisualTargetPct(null);
|
|
422
422
|
}, []);
|
|
423
|
-
const updateOrderFromTargetValue =
|
|
423
|
+
const updateOrderFromTargetValue = React5__namespace.useCallback(
|
|
424
424
|
(newTargetValue) => {
|
|
425
425
|
const newDeltaValue = newTargetValue - holdingsValue;
|
|
426
426
|
if (newDeltaValue > 0) {
|
|
@@ -444,7 +444,7 @@ function HousePositionSlider({
|
|
|
444
444
|
},
|
|
445
445
|
[effectiveAvailableCash, effectivePrice, effectiveTokensHeld, holdingsValue, resetOrder, tokensHeld]
|
|
446
446
|
);
|
|
447
|
-
const updateOrderFromOwnership =
|
|
447
|
+
const updateOrderFromOwnership = React5__namespace.useCallback(
|
|
448
448
|
(newOwnershipPercent) => {
|
|
449
449
|
const nextOwnership = clamp(newOwnershipPercent, 0, 100);
|
|
450
450
|
const newTargetTokens = nextOwnership / 100 * totalTokens;
|
|
@@ -453,7 +453,7 @@ function HousePositionSlider({
|
|
|
453
453
|
},
|
|
454
454
|
[effectivePrice, totalTokens, updateOrderFromTargetValue]
|
|
455
455
|
);
|
|
456
|
-
const updateOrderFromTokenAmount =
|
|
456
|
+
const updateOrderFromTokenAmount = React5__namespace.useCallback(
|
|
457
457
|
(tokenAmountSigned) => {
|
|
458
458
|
if (tokenAmountSigned > 0) {
|
|
459
459
|
const maxTokens = effectiveAvailableCash / (effectivePrice || 1);
|
|
@@ -476,7 +476,7 @@ function HousePositionSlider({
|
|
|
476
476
|
},
|
|
477
477
|
[effectiveAvailableCash, effectivePrice, effectiveTokensHeld, resetOrder]
|
|
478
478
|
);
|
|
479
|
-
const updateOrderFromSlider =
|
|
479
|
+
const updateOrderFromSlider = React5__namespace.useCallback(
|
|
480
480
|
(pct) => {
|
|
481
481
|
const normalized = (pct - 50) / 50;
|
|
482
482
|
const magnitude = Math.min(Math.abs(normalized), 1);
|
|
@@ -520,7 +520,7 @@ function HousePositionSlider({
|
|
|
520
520
|
},
|
|
521
521
|
[effectiveAvailableCash, effectiveTokensHeld, resetOrder]
|
|
522
522
|
);
|
|
523
|
-
const handleDragAtClientY =
|
|
523
|
+
const handleDragAtClientY = React5__namespace.useCallback(
|
|
524
524
|
(clientY) => {
|
|
525
525
|
if (!houseRef.current) return;
|
|
526
526
|
const rect = houseRef.current.getBoundingClientRect();
|
|
@@ -1036,18 +1036,18 @@ function HousePositionSliderMobile({
|
|
|
1036
1036
|
className,
|
|
1037
1037
|
...props
|
|
1038
1038
|
}) {
|
|
1039
|
-
const [orderMode, setOrderMode] =
|
|
1040
|
-
const [deltaDollars, setDeltaDollars] =
|
|
1041
|
-
const [deltaTokensSell, setDeltaTokensSell] =
|
|
1042
|
-
const [deltaTokensBuy, setDeltaTokensBuy] =
|
|
1043
|
-
const [buyTrackingMode, setBuyTrackingMode] =
|
|
1044
|
-
const [orderType, setOrderType] =
|
|
1045
|
-
const [limitPrice, setLimitPrice] =
|
|
1046
|
-
const [limitPriceInput, setLimitPriceInput] =
|
|
1047
|
-
const [limitPriceDirty, setLimitPriceDirty] =
|
|
1048
|
-
const [tokenAmountInput, setTokenAmountInput] =
|
|
1049
|
-
const houseRef =
|
|
1050
|
-
|
|
1039
|
+
const [orderMode, setOrderMode] = React5__namespace.useState("none");
|
|
1040
|
+
const [deltaDollars, setDeltaDollars] = React5__namespace.useState(0);
|
|
1041
|
+
const [deltaTokensSell, setDeltaTokensSell] = React5__namespace.useState(0);
|
|
1042
|
+
const [deltaTokensBuy, setDeltaTokensBuy] = React5__namespace.useState(0);
|
|
1043
|
+
const [buyTrackingMode, setBuyTrackingMode] = React5__namespace.useState("dollars");
|
|
1044
|
+
const [orderType, setOrderType] = React5__namespace.useState(defaultOrderType);
|
|
1045
|
+
const [limitPrice, setLimitPrice] = React5__namespace.useState(currentPrice);
|
|
1046
|
+
const [limitPriceInput, setLimitPriceInput] = React5__namespace.useState(currentPrice.toFixed(2));
|
|
1047
|
+
const [limitPriceDirty, setLimitPriceDirty] = React5__namespace.useState(false);
|
|
1048
|
+
const [tokenAmountInput, setTokenAmountInput] = React5__namespace.useState("");
|
|
1049
|
+
const houseRef = React5__namespace.useRef(null);
|
|
1050
|
+
React5__namespace.useEffect(() => {
|
|
1051
1051
|
if (orderType !== "limit") return;
|
|
1052
1052
|
if (limitPriceDirty) return;
|
|
1053
1053
|
setLimitPrice(currentPrice);
|
|
@@ -1089,7 +1089,7 @@ function HousePositionSliderMobile({
|
|
|
1089
1089
|
const hasChange = orderMode !== "none" && (Math.abs(deltaTokens) > 1e-3 || Math.abs(deltaValue) > 0.01);
|
|
1090
1090
|
const targetOwnership = totalTokens > 0 ? targetTokens / totalTokens * 100 : 0;
|
|
1091
1091
|
const estFeeTokens = effectivePrice > 0 ? Math.abs(deltaValue) * 5e-3 / effectivePrice : 0;
|
|
1092
|
-
const updateOrderFromTargetValue =
|
|
1092
|
+
const updateOrderFromTargetValue = React5__namespace.useCallback(
|
|
1093
1093
|
(newTargetValue) => {
|
|
1094
1094
|
const newDeltaValue = newTargetValue - holdingsValue;
|
|
1095
1095
|
if (newDeltaValue > 0.01) {
|
|
@@ -1117,7 +1117,7 @@ function HousePositionSliderMobile({
|
|
|
1117
1117
|
},
|
|
1118
1118
|
[holdingsValue, availableCash, effectivePrice, tokensHeld]
|
|
1119
1119
|
);
|
|
1120
|
-
const updateOrderFromTokenAmount =
|
|
1120
|
+
const updateOrderFromTokenAmount = React5__namespace.useCallback(
|
|
1121
1121
|
(tokenAmount) => {
|
|
1122
1122
|
if (tokenAmount > 0) {
|
|
1123
1123
|
const maxTokens = effectivePrice > 0 ? availableCash / effectivePrice : 0;
|
|
@@ -1144,14 +1144,14 @@ function HousePositionSliderMobile({
|
|
|
1144
1144
|
},
|
|
1145
1145
|
[effectivePrice, availableCash, tokensHeld]
|
|
1146
1146
|
);
|
|
1147
|
-
const handleMarkerClick =
|
|
1147
|
+
const handleMarkerClick = React5__namespace.useCallback(
|
|
1148
1148
|
(pct) => {
|
|
1149
1149
|
const newTargetValue = pct / 100 * totalCapacity;
|
|
1150
1150
|
updateOrderFromTargetValue(newTargetValue);
|
|
1151
1151
|
},
|
|
1152
1152
|
[totalCapacity, updateOrderFromTargetValue]
|
|
1153
1153
|
);
|
|
1154
|
-
const onMouseDown =
|
|
1154
|
+
const onMouseDown = React5__namespace.useCallback(
|
|
1155
1155
|
(e) => {
|
|
1156
1156
|
e.preventDefault();
|
|
1157
1157
|
const move = (ev) => {
|
|
@@ -1171,7 +1171,7 @@ function HousePositionSliderMobile({
|
|
|
1171
1171
|
},
|
|
1172
1172
|
[totalCapacity, updateOrderFromTargetValue]
|
|
1173
1173
|
);
|
|
1174
|
-
const onTouchStart =
|
|
1174
|
+
const onTouchStart = React5__namespace.useCallback(
|
|
1175
1175
|
(e) => {
|
|
1176
1176
|
e.preventDefault();
|
|
1177
1177
|
e.stopPropagation();
|
|
@@ -1729,7 +1729,7 @@ var LiquidityText = styled24__default.default.span`
|
|
|
1729
1729
|
letter-spacing: 0.1px;
|
|
1730
1730
|
}
|
|
1731
1731
|
`;
|
|
1732
|
-
var LoafLiquidityBadge =
|
|
1732
|
+
var LoafLiquidityBadge = React5__namespace.forwardRef(
|
|
1733
1733
|
({ className, isGlowing, onClick, children, ...props }, ref) => {
|
|
1734
1734
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1735
1735
|
LogoContainer,
|
|
@@ -1758,7 +1758,7 @@ var LoafLiquidityBadge = React9__namespace.forwardRef(
|
|
|
1758
1758
|
);
|
|
1759
1759
|
LoafLiquidityBadge.displayName = "LoafLiquidityBadge";
|
|
1760
1760
|
var toSize = (v, fallback) => v == null ? fallback : typeof v === "number" ? `${v}px` : v;
|
|
1761
|
-
var Skeleton =
|
|
1761
|
+
var Skeleton = React5__namespace.forwardRef(
|
|
1762
1762
|
({ width, height, radius, className, style, ...props }, ref) => {
|
|
1763
1763
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1764
1764
|
"div",
|
|
@@ -1783,8 +1783,8 @@ var Skeleton = React9__namespace.forwardRef(
|
|
|
1783
1783
|
);
|
|
1784
1784
|
Skeleton.displayName = "Skeleton";
|
|
1785
1785
|
function useViewportCompact(breakpoint) {
|
|
1786
|
-
const [isCompact, setIsCompact] =
|
|
1787
|
-
|
|
1786
|
+
const [isCompact, setIsCompact] = React5__namespace.useState(false);
|
|
1787
|
+
React5__namespace.useEffect(() => {
|
|
1788
1788
|
if (typeof window === "undefined") return;
|
|
1789
1789
|
const check = () => setIsCompact(window.innerWidth <= breakpoint);
|
|
1790
1790
|
check();
|
|
@@ -1803,8 +1803,8 @@ function getTradeKey(trade, fallbackIndex) {
|
|
|
1803
1803
|
return `idx-${fallbackIndex}-${trade.type}-${trade.price}-${trade.amount}`;
|
|
1804
1804
|
}
|
|
1805
1805
|
function useAmountChangeFlash(ref, amount, side) {
|
|
1806
|
-
const prevAmountRef =
|
|
1807
|
-
|
|
1806
|
+
const prevAmountRef = React5__namespace.useRef(amount);
|
|
1807
|
+
React5__namespace.useEffect(() => {
|
|
1808
1808
|
const prev = prevAmountRef.current;
|
|
1809
1809
|
const node = ref.current;
|
|
1810
1810
|
if (prev !== amount && node && typeof node.animate === "function") {
|
|
@@ -1818,8 +1818,8 @@ function useAmountChangeFlash(ref, amount, side) {
|
|
|
1818
1818
|
}, [amount, ref, side]);
|
|
1819
1819
|
}
|
|
1820
1820
|
function useMidPriceFlash(ref, midPrice, restBgColor) {
|
|
1821
|
-
const prevMidRef =
|
|
1822
|
-
|
|
1821
|
+
const prevMidRef = React5__namespace.useRef(midPrice);
|
|
1822
|
+
React5__namespace.useEffect(() => {
|
|
1823
1823
|
const prev = prevMidRef.current;
|
|
1824
1824
|
const node = ref.current;
|
|
1825
1825
|
if (prev !== midPrice && prev > 0 && midPrice > 0 && node && typeof node.animate === "function") {
|
|
@@ -1840,9 +1840,9 @@ function TradeRow({
|
|
|
1840
1840
|
seenTradeKeysRef,
|
|
1841
1841
|
compact
|
|
1842
1842
|
}) {
|
|
1843
|
-
const rowRef =
|
|
1843
|
+
const rowRef = React5__namespace.useRef(null);
|
|
1844
1844
|
const { type } = trade;
|
|
1845
|
-
|
|
1845
|
+
React5__namespace.useEffect(() => {
|
|
1846
1846
|
if (seenTradeKeysRef.current.has(tradeKey)) return;
|
|
1847
1847
|
seenTradeKeysRef.current.add(tradeKey);
|
|
1848
1848
|
const node = rowRef.current;
|
|
@@ -1904,7 +1904,7 @@ function DepthRow({
|
|
|
1904
1904
|
hasUserOrder
|
|
1905
1905
|
}) {
|
|
1906
1906
|
const isAsk = side === "ask";
|
|
1907
|
-
const rowRef =
|
|
1907
|
+
const rowRef = React5__namespace.useRef(null);
|
|
1908
1908
|
useAmountChangeFlash(rowRef, amount, side);
|
|
1909
1909
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1910
1910
|
"div",
|
|
@@ -1951,7 +1951,7 @@ var DEPTH_ROW_HEIGHT_PX = 26;
|
|
|
1951
1951
|
var COMPACT_ROWS_VISIBLE = 5;
|
|
1952
1952
|
var COMPACT_ROW_HEIGHT_PX = 30;
|
|
1953
1953
|
var COMPACT_BREAKPOINT_PX = 1024;
|
|
1954
|
-
var Orderbook =
|
|
1954
|
+
var Orderbook = React5__namespace.forwardRef(
|
|
1955
1955
|
({
|
|
1956
1956
|
asks,
|
|
1957
1957
|
bids,
|
|
@@ -1973,10 +1973,10 @@ var Orderbook = React9__namespace.forwardRef(
|
|
|
1973
1973
|
...props
|
|
1974
1974
|
}, ref) => {
|
|
1975
1975
|
const resolvedRightHeader = rightHeader ?? /* @__PURE__ */ jsxRuntime.jsx(LoafLiquidityBadge, { className: "text-[0.6rem]", onClick: onLoafLiquidityClick });
|
|
1976
|
-
const [tab, setTab] =
|
|
1977
|
-
const [tradeFilter, setTradeFilter] =
|
|
1976
|
+
const [tab, setTab] = React5__namespace.useState(defaultTab);
|
|
1977
|
+
const [tradeFilter, setTradeFilter] = React5__namespace.useState("all");
|
|
1978
1978
|
const viewportCompact = useViewportCompact(COMPACT_BREAKPOINT_PX);
|
|
1979
|
-
const { userAskPrices, userBidPrices } =
|
|
1979
|
+
const { userAskPrices, userBidPrices } = React5__namespace.useMemo(() => {
|
|
1980
1980
|
const ask = /* @__PURE__ */ new Set();
|
|
1981
1981
|
const bid = /* @__PURE__ */ new Set();
|
|
1982
1982
|
if (!userOrderPrices) return { userAskPrices: ask, userBidPrices: bid };
|
|
@@ -1986,15 +1986,15 @@ var Orderbook = React9__namespace.forwardRef(
|
|
|
1986
1986
|
}
|
|
1987
1987
|
return { userAskPrices: ask, userBidPrices: bid };
|
|
1988
1988
|
}, [userOrderPrices]);
|
|
1989
|
-
const seenTradeKeysRef =
|
|
1990
|
-
const initializedRef =
|
|
1989
|
+
const seenTradeKeysRef = React5__namespace.useRef(/* @__PURE__ */ new Set());
|
|
1990
|
+
const initializedRef = React5__namespace.useRef(false);
|
|
1991
1991
|
if (!initializedRef.current && trades.length > 0) {
|
|
1992
1992
|
for (let i = 0; i < trades.length; i++) {
|
|
1993
1993
|
seenTradeKeysRef.current.add(getTradeKey(trades[i], i));
|
|
1994
1994
|
}
|
|
1995
1995
|
initializedRef.current = true;
|
|
1996
1996
|
}
|
|
1997
|
-
|
|
1997
|
+
React5__namespace.useEffect(() => {
|
|
1998
1998
|
if (!initializedRef.current) return;
|
|
1999
1999
|
const live = /* @__PURE__ */ new Set();
|
|
2000
2000
|
for (let i = 0; i < trades.length; i++) {
|
|
@@ -2005,7 +2005,7 @@ var Orderbook = React9__namespace.forwardRef(
|
|
|
2005
2005
|
if (!live.has(key)) seen.delete(key);
|
|
2006
2006
|
}
|
|
2007
2007
|
}, [trades]);
|
|
2008
|
-
|
|
2008
|
+
React5__namespace.useEffect(() => {
|
|
2009
2009
|
setTab(defaultTab);
|
|
2010
2010
|
}, [defaultTab]);
|
|
2011
2011
|
const handleTab = (next) => {
|
|
@@ -2014,8 +2014,26 @@ var Orderbook = React9__namespace.forwardRef(
|
|
|
2014
2014
|
};
|
|
2015
2015
|
const isCompact = variant === "compact" || variant === "auto" && viewportCompact;
|
|
2016
2016
|
const sectionHeight = isCompact ? COMPACT_ROWS_VISIBLE * COMPACT_ROW_HEIGHT_PX : LEVEL_ROWS_VISIBLE * DEPTH_ROW_HEIGHT_PX;
|
|
2017
|
-
const
|
|
2018
|
-
const
|
|
2017
|
+
const rowCount = isCompact ? COMPACT_ROWS_VISIBLE : LEVEL_ROWS_VISIBLE;
|
|
2018
|
+
const askVisibleLevels = asks.slice(-rowCount);
|
|
2019
|
+
const bidVisibleLevels = bids.slice(0, rowCount);
|
|
2020
|
+
const askCumDepths = new Array(askVisibleLevels.length);
|
|
2021
|
+
{
|
|
2022
|
+
let acc = 0;
|
|
2023
|
+
for (let i = askVisibleLevels.length - 1; i >= 0; i--) {
|
|
2024
|
+
acc += askVisibleLevels[i].amount;
|
|
2025
|
+
askCumDepths[i] = acc;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
const bidCumDepths = new Array(bidVisibleLevels.length);
|
|
2029
|
+
{
|
|
2030
|
+
let acc = 0;
|
|
2031
|
+
for (let i = 0; i < bidVisibleLevels.length; i++) {
|
|
2032
|
+
acc += bidVisibleLevels[i].amount;
|
|
2033
|
+
bidCumDepths[i] = acc;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
const combinedMaxCumDepth = Math.max(1, ...askCumDepths, ...bidCumDepths);
|
|
2019
2037
|
const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
|
|
2020
2038
|
const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
|
|
2021
2039
|
const layoutProps = {
|
|
@@ -2031,8 +2049,11 @@ var Orderbook = React9__namespace.forwardRef(
|
|
|
2031
2049
|
amountPrecision,
|
|
2032
2050
|
asks,
|
|
2033
2051
|
bids,
|
|
2034
|
-
|
|
2035
|
-
|
|
2052
|
+
askVisibleLevels,
|
|
2053
|
+
bidVisibleLevels,
|
|
2054
|
+
askCumDepths,
|
|
2055
|
+
bidCumDepths,
|
|
2056
|
+
combinedMaxCumDepth,
|
|
2036
2057
|
midPrice,
|
|
2037
2058
|
midChangePercent,
|
|
2038
2059
|
midClass,
|
|
@@ -2092,10 +2113,11 @@ function DesktopOrderbookLayout({
|
|
|
2092
2113
|
tradeFiltered,
|
|
2093
2114
|
precision,
|
|
2094
2115
|
amountPrecision,
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2116
|
+
askVisibleLevels,
|
|
2117
|
+
bidVisibleLevels,
|
|
2118
|
+
askCumDepths,
|
|
2119
|
+
bidCumDepths,
|
|
2120
|
+
combinedMaxCumDepth,
|
|
2099
2121
|
midPrice,
|
|
2100
2122
|
midChangePercent,
|
|
2101
2123
|
midClass,
|
|
@@ -2105,7 +2127,7 @@ function DesktopOrderbookLayout({
|
|
|
2105
2127
|
isLoading,
|
|
2106
2128
|
seenTradeKeysRef
|
|
2107
2129
|
}) {
|
|
2108
|
-
const midRef =
|
|
2130
|
+
const midRef = React5__namespace.useRef(null);
|
|
2109
2131
|
useMidPriceFlash(midRef, midPrice, "#0b1a24");
|
|
2110
2132
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2111
2133
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 pt-4", children: [
|
|
@@ -2211,13 +2233,13 @@ function DesktopOrderbookLayout({
|
|
|
2211
2233
|
{
|
|
2212
2234
|
className: "flex flex-col justify-end divide-y divide-white/5 overflow-hidden",
|
|
2213
2235
|
style: { height: `${sectionHeight}px` },
|
|
2214
|
-
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `ask-skel-${i}`)) :
|
|
2236
|
+
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `ask-skel-${i}`)) : askVisibleLevels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No asks" }) : askVisibleLevels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2215
2237
|
DepthRow,
|
|
2216
2238
|
{
|
|
2217
2239
|
side: "ask",
|
|
2218
2240
|
price: l.price,
|
|
2219
2241
|
amount: l.amount,
|
|
2220
|
-
depthPct:
|
|
2242
|
+
depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2221
2243
|
precision,
|
|
2222
2244
|
amountPrecision,
|
|
2223
2245
|
hasUserOrder: userAskPrices.has(l.price)
|
|
@@ -2250,13 +2272,13 @@ function DesktopOrderbookLayout({
|
|
|
2250
2272
|
{
|
|
2251
2273
|
className: "divide-y divide-white/5 overflow-hidden",
|
|
2252
2274
|
style: { height: `${sectionHeight}px` },
|
|
2253
|
-
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `bid-skel-${i}`)) :
|
|
2275
|
+
children: isLoading ? Array.from({ length: LEVEL_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, {}, `bid-skel-${i}`)) : bidVisibleLevels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center px-3 text-xs text-white/40", children: "No bids" }) : bidVisibleLevels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2254
2276
|
DepthRow,
|
|
2255
2277
|
{
|
|
2256
2278
|
side: "bid",
|
|
2257
2279
|
price: l.price,
|
|
2258
2280
|
amount: l.amount,
|
|
2259
|
-
depthPct:
|
|
2281
|
+
depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2260
2282
|
precision,
|
|
2261
2283
|
amountPrecision,
|
|
2262
2284
|
hasUserOrder: userBidPrices.has(l.price)
|
|
@@ -2280,10 +2302,11 @@ function MobileOrderbookLayout({
|
|
|
2280
2302
|
tradeFiltered,
|
|
2281
2303
|
precision,
|
|
2282
2304
|
amountPrecision,
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2305
|
+
askVisibleLevels: visibleAsks,
|
|
2306
|
+
bidVisibleLevels: visibleBids,
|
|
2307
|
+
askCumDepths,
|
|
2308
|
+
bidCumDepths,
|
|
2309
|
+
combinedMaxCumDepth,
|
|
2287
2310
|
midPrice,
|
|
2288
2311
|
midChangePercent,
|
|
2289
2312
|
midClass,
|
|
@@ -2293,10 +2316,8 @@ function MobileOrderbookLayout({
|
|
|
2293
2316
|
isLoading,
|
|
2294
2317
|
seenTradeKeysRef
|
|
2295
2318
|
}) {
|
|
2296
|
-
const midRef =
|
|
2319
|
+
const midRef = React5__namespace.useRef(null);
|
|
2297
2320
|
useMidPriceFlash(midRef, midPrice, "transparent");
|
|
2298
|
-
const visibleAsks = React9__namespace.useMemo(() => asks.slice(-COMPACT_ROWS_VISIBLE), [asks]);
|
|
2299
|
-
const visibleBids = React9__namespace.useMemo(() => bids.slice(0, COMPACT_ROWS_VISIBLE), [bids]);
|
|
2300
2321
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2301
2322
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2302
2323
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -2365,13 +2386,13 @@ function MobileOrderbookLayout({
|
|
|
2365
2386
|
]
|
|
2366
2387
|
}
|
|
2367
2388
|
),
|
|
2368
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-ask-skel-${i}`)) : visibleAsks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No asks" }) : visibleAsks.map((l) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2389
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-ask-skel-${i}`)) : visibleAsks.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No asks" }) : visibleAsks.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2369
2390
|
MobileDepthRow,
|
|
2370
2391
|
{
|
|
2371
2392
|
side: "ask",
|
|
2372
2393
|
price: l.price,
|
|
2373
2394
|
amount: l.amount,
|
|
2374
|
-
depthPct:
|
|
2395
|
+
depthPct: askCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2375
2396
|
precision,
|
|
2376
2397
|
amountPrecision,
|
|
2377
2398
|
hasUserOrder: userAskPrices.has(l.price)
|
|
@@ -2411,13 +2432,13 @@ function MobileOrderbookLayout({
|
|
|
2411
2432
|
]
|
|
2412
2433
|
}
|
|
2413
2434
|
),
|
|
2414
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-bid-skel-${i}`)) : visibleBids.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No bids" }) : visibleBids.map((l) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2435
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column" }, children: isLoading ? Array.from({ length: COMPACT_ROWS_VISIBLE }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(SkeletonRow, { compact: true }, `m-bid-skel-${i}`)) : visibleBids.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0.75rem 0", textAlign: "center", color: "rgba(255,255,255,0.4)", fontSize: "0.72rem" }, children: "No bids" }) : visibleBids.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2415
2436
|
MobileDepthRow,
|
|
2416
2437
|
{
|
|
2417
2438
|
side: "bid",
|
|
2418
2439
|
price: l.price,
|
|
2419
2440
|
amount: l.amount,
|
|
2420
|
-
depthPct:
|
|
2441
|
+
depthPct: bidCumDepths[i] / combinedMaxCumDepth * 100,
|
|
2421
2442
|
precision,
|
|
2422
2443
|
amountPrecision,
|
|
2423
2444
|
hasUserOrder: userBidPrices.has(l.price)
|
|
@@ -2464,7 +2485,7 @@ function MobileDepthRow({
|
|
|
2464
2485
|
hasUserOrder
|
|
2465
2486
|
}) {
|
|
2466
2487
|
const isAsk = side === "ask";
|
|
2467
|
-
const rowRef =
|
|
2488
|
+
const rowRef = React5__namespace.useRef(null);
|
|
2468
2489
|
useAmountChangeFlash(rowRef, amount, side);
|
|
2469
2490
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2470
2491
|
"div",
|
|
@@ -2521,7 +2542,7 @@ function MobileDepthRow({
|
|
|
2521
2542
|
}
|
|
2522
2543
|
);
|
|
2523
2544
|
}
|
|
2524
|
-
var PropertyTour =
|
|
2545
|
+
var PropertyTour = React5__namespace.forwardRef(
|
|
2525
2546
|
({
|
|
2526
2547
|
className,
|
|
2527
2548
|
title,
|
|
@@ -2534,8 +2555,8 @@ var PropertyTour = React9__namespace.forwardRef(
|
|
|
2534
2555
|
playsInline = true,
|
|
2535
2556
|
...props
|
|
2536
2557
|
}, ref) => {
|
|
2537
|
-
const videoRef =
|
|
2538
|
-
|
|
2558
|
+
const videoRef = React5__namespace.useRef(null);
|
|
2559
|
+
React5__namespace.useEffect(() => {
|
|
2539
2560
|
const video = videoRef.current;
|
|
2540
2561
|
if (!video) return;
|
|
2541
2562
|
const handleFullscreenChange = () => {
|
|
@@ -2667,7 +2688,7 @@ var formatTimeAgo = (timestamp) => {
|
|
|
2667
2688
|
if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
|
|
2668
2689
|
return `${Math.floor(diff / 3600)}h ago`;
|
|
2669
2690
|
};
|
|
2670
|
-
var PropertyNewsUpdates =
|
|
2691
|
+
var PropertyNewsUpdates = React5__namespace.forwardRef(
|
|
2671
2692
|
({
|
|
2672
2693
|
className,
|
|
2673
2694
|
heading,
|
|
@@ -2679,20 +2700,21 @@ var PropertyNewsUpdates = React9__namespace.forwardRef(
|
|
|
2679
2700
|
purchases: purchasesProp,
|
|
2680
2701
|
viewAllHref,
|
|
2681
2702
|
viewAllLabel = "View All News",
|
|
2703
|
+
connectionStatus = "live",
|
|
2682
2704
|
...props
|
|
2683
2705
|
}, ref) => {
|
|
2684
2706
|
const isPurchaseVariant = variant === "purchases";
|
|
2685
2707
|
const isHomeVariant = variant === "home";
|
|
2686
2708
|
const resolvedHeading = heading ?? (isPurchaseVariant ? "Live Purchases" : "Property News & Headlines");
|
|
2687
|
-
const [homeTab, setHomeTab] =
|
|
2709
|
+
const [homeTab, setHomeTab] = React5__namespace.useState("all");
|
|
2688
2710
|
const purchaseItems = purchasesProp ?? [];
|
|
2689
|
-
const [page, setPage] =
|
|
2690
|
-
|
|
2711
|
+
const [page, setPage] = React5__namespace.useState(0);
|
|
2712
|
+
React5__namespace.useEffect(() => {
|
|
2691
2713
|
ensureAnimationsInjected();
|
|
2692
2714
|
}, []);
|
|
2693
2715
|
const hasItems = Array.isArray(items) && items.length > 0;
|
|
2694
|
-
const totalPages =
|
|
2695
|
-
|
|
2716
|
+
const totalPages = React5__namespace.useMemo(() => hasItems ? Math.max(1, Math.ceil(items.length / ITEMS_PER_PAGE)) : 1, [hasItems, items.length]);
|
|
2717
|
+
React5__namespace.useEffect(() => {
|
|
2696
2718
|
setPage((prev) => Math.min(prev, totalPages - 1));
|
|
2697
2719
|
}, [totalPages]);
|
|
2698
2720
|
const paginatedItems = hasItems ? items.slice(page * ITEMS_PER_PAGE, page * ITEMS_PER_PAGE + ITEMS_PER_PAGE) : [];
|
|
@@ -2746,7 +2768,30 @@ var PropertyNewsUpdates = React9__namespace.forwardRef(
|
|
|
2746
2768
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })
|
|
2747
2769
|
]
|
|
2748
2770
|
}
|
|
2749
|
-
) : !isHomeVariant && !isPurchaseVariant ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2771
|
+
) : !isHomeVariant && !isPurchaseVariant ? connectionStatus === "connecting" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2772
|
+
"div",
|
|
2773
|
+
{
|
|
2774
|
+
className: "inline-flex items-center font-semibold uppercase",
|
|
2775
|
+
style: { gap: "0.35rem", fontSize: "0.8rem", letterSpacing: "0.15em", color: "#f97316" },
|
|
2776
|
+
children: [
|
|
2777
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2778
|
+
"span",
|
|
2779
|
+
{
|
|
2780
|
+
style: {
|
|
2781
|
+
display: "inline-block",
|
|
2782
|
+
width: "10px",
|
|
2783
|
+
height: "10px",
|
|
2784
|
+
borderRadius: "50%",
|
|
2785
|
+
border: "2px solid rgba(249,115,22,0.3)",
|
|
2786
|
+
borderTopColor: "#f97316",
|
|
2787
|
+
animation: "propertyNewsSpin 0.8s linear infinite"
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
),
|
|
2791
|
+
"CONNECTING"
|
|
2792
|
+
]
|
|
2793
|
+
}
|
|
2794
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2750
2795
|
"div",
|
|
2751
2796
|
{
|
|
2752
2797
|
className: "inline-flex items-center font-semibold uppercase text-emerald-300",
|
|
@@ -3000,7 +3045,7 @@ var defaultFormat = (value) => new Intl.NumberFormat("en-US", {
|
|
|
3000
3045
|
notation: value >= 1e5 ? "compact" : "standard",
|
|
3001
3046
|
maximumFractionDigits: value >= 1e3 ? 0 : 2
|
|
3002
3047
|
}).format(value);
|
|
3003
|
-
var TradingSlider =
|
|
3048
|
+
var TradingSlider = React5__namespace.forwardRef(
|
|
3004
3049
|
({
|
|
3005
3050
|
label = "Trade size",
|
|
3006
3051
|
helperText = "Drag to pick the desired notional.",
|
|
@@ -3018,7 +3063,7 @@ var TradingSlider = React9__namespace.forwardRef(
|
|
|
3018
3063
|
...rest
|
|
3019
3064
|
}, ref) => {
|
|
3020
3065
|
const isControlled = value !== void 0;
|
|
3021
|
-
const [internalValue, setInternalValue] =
|
|
3066
|
+
const [internalValue, setInternalValue] = React5__namespace.useState(
|
|
3022
3067
|
defaultValue ?? (typeof min === "number" ? min : 0)
|
|
3023
3068
|
);
|
|
3024
3069
|
const currentValue = isControlled ? Number(value) : internalValue;
|
|
@@ -3121,7 +3166,7 @@ var MobileToggleButton = styled24__default.default.button`
|
|
|
3121
3166
|
padding: 0.6rem 0.5rem;
|
|
3122
3167
|
}
|
|
3123
3168
|
`;
|
|
3124
|
-
var MobileTradeNav =
|
|
3169
|
+
var MobileTradeNav = React5__namespace.forwardRef(
|
|
3125
3170
|
({ className, items, activeId, onChange, ...props }, ref) => {
|
|
3126
3171
|
return /* @__PURE__ */ jsxRuntime.jsx(MobileToggleContainer, { ref, className: cn(className), ...props, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3127
3172
|
MobileToggleButton,
|
|
@@ -3772,7 +3817,7 @@ var formatPercent = (value, fractionDigits = 2) => {
|
|
|
3772
3817
|
if (value == null || Number.isNaN(value)) return "\u2014";
|
|
3773
3818
|
return `${value.toFixed(fractionDigits)}%`;
|
|
3774
3819
|
};
|
|
3775
|
-
var YourOrders =
|
|
3820
|
+
var YourOrders = React5__namespace.forwardRef(
|
|
3776
3821
|
({
|
|
3777
3822
|
className,
|
|
3778
3823
|
title,
|
|
@@ -3785,10 +3830,10 @@ var YourOrders = React9__namespace.forwardRef(
|
|
|
3785
3830
|
pageSize: pageSizeOverride,
|
|
3786
3831
|
...props
|
|
3787
3832
|
}, ref) => {
|
|
3788
|
-
const [internalActiveTab, setInternalActiveTab] =
|
|
3789
|
-
const [page, setPage] =
|
|
3833
|
+
const [internalActiveTab, setInternalActiveTab] = React5__namespace.useState(tabs?.[0]?.id ?? "portfolio");
|
|
3834
|
+
const [page, setPage] = React5__namespace.useState(0);
|
|
3790
3835
|
const effectiveActiveTabId = activeTabId ?? internalActiveTab;
|
|
3791
|
-
|
|
3836
|
+
React5__namespace.useEffect(() => {
|
|
3792
3837
|
setPage(0);
|
|
3793
3838
|
}, [effectiveActiveTabId]);
|
|
3794
3839
|
const handleTabChange = (tabId) => {
|
|
@@ -4170,7 +4215,7 @@ function createCandlestickSeries(chart, options) {
|
|
|
4170
4215
|
}
|
|
4171
4216
|
throw new Error("Candlestick series API is not available in the current lightweight-charts version.");
|
|
4172
4217
|
}
|
|
4173
|
-
var PriceChart =
|
|
4218
|
+
var PriceChart = React5__namespace.forwardRef(
|
|
4174
4219
|
({
|
|
4175
4220
|
className,
|
|
4176
4221
|
title = "Price Chart",
|
|
@@ -4184,18 +4229,18 @@ var PriceChart = React9__namespace.forwardRef(
|
|
|
4184
4229
|
height = 301.52,
|
|
4185
4230
|
...props
|
|
4186
4231
|
}, ref) => {
|
|
4187
|
-
const containerRef =
|
|
4188
|
-
const chartRef =
|
|
4189
|
-
const seriesRef =
|
|
4190
|
-
const priceLineRef =
|
|
4191
|
-
const [hoveredRange, setHoveredRange] =
|
|
4192
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
4193
|
-
const dropdownRef =
|
|
4194
|
-
const isAutoScrollRef =
|
|
4232
|
+
const containerRef = React5__namespace.useRef(null);
|
|
4233
|
+
const chartRef = React5__namespace.useRef(null);
|
|
4234
|
+
const seriesRef = React5__namespace.useRef(null);
|
|
4235
|
+
const priceLineRef = React5__namespace.useRef(null);
|
|
4236
|
+
const [hoveredRange, setHoveredRange] = React5__namespace.useState(null);
|
|
4237
|
+
const [dropdownOpen, setDropdownOpen] = React5__namespace.useState(false);
|
|
4238
|
+
const dropdownRef = React5__namespace.useRef(null);
|
|
4239
|
+
const isAutoScrollRef = React5__namespace.useRef(true);
|
|
4195
4240
|
const visibleRanges = ranges.slice(0, VISIBLE_RANGE_COUNT);
|
|
4196
4241
|
const dropdownRanges = ranges.slice(VISIBLE_RANGE_COUNT);
|
|
4197
4242
|
const selectedInDropdown = dropdownRanges.includes(selectedRange);
|
|
4198
|
-
|
|
4243
|
+
React5__namespace.useEffect(() => {
|
|
4199
4244
|
const handleClickOutside = (e) => {
|
|
4200
4245
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
4201
4246
|
setDropdownOpen(false);
|
|
@@ -4204,25 +4249,25 @@ var PriceChart = React9__namespace.forwardRef(
|
|
|
4204
4249
|
document.addEventListener("mousedown", handleClickOutside);
|
|
4205
4250
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
4206
4251
|
}, []);
|
|
4207
|
-
const resolvedPrice =
|
|
4252
|
+
const resolvedPrice = React5__namespace.useMemo(() => {
|
|
4208
4253
|
if (price != null) return price;
|
|
4209
4254
|
const last = data.at(-1);
|
|
4210
4255
|
return last?.close;
|
|
4211
4256
|
}, [data, price]);
|
|
4212
|
-
const inferredChangePercent =
|
|
4257
|
+
const inferredChangePercent = React5__namespace.useMemo(() => {
|
|
4213
4258
|
if (changePercent != null) return changePercent;
|
|
4214
4259
|
const first = data[0]?.open;
|
|
4215
4260
|
const last = data.at(-1)?.close;
|
|
4216
4261
|
if (first == null || last == null || first === 0) return void 0;
|
|
4217
4262
|
return (last - first) / first * 100;
|
|
4218
4263
|
}, [changePercent, data]);
|
|
4219
|
-
const dollarChange =
|
|
4264
|
+
const dollarChange = React5__namespace.useMemo(() => {
|
|
4220
4265
|
const first = data[0]?.open;
|
|
4221
4266
|
const last = data.at(-1)?.close;
|
|
4222
4267
|
if (first == null || last == null) return void 0;
|
|
4223
4268
|
return last - first;
|
|
4224
4269
|
}, [data]);
|
|
4225
|
-
|
|
4270
|
+
React5__namespace.useEffect(() => {
|
|
4226
4271
|
const el = containerRef.current;
|
|
4227
4272
|
if (!el) return;
|
|
4228
4273
|
const chart = LightweightCharts__namespace.createChart(el, {
|
|
@@ -4267,7 +4312,7 @@ var PriceChart = React9__namespace.forwardRef(
|
|
|
4267
4312
|
chart.remove();
|
|
4268
4313
|
};
|
|
4269
4314
|
}, []);
|
|
4270
|
-
|
|
4315
|
+
React5__namespace.useEffect(() => {
|
|
4271
4316
|
const chart = chartRef.current;
|
|
4272
4317
|
if (!chart) return;
|
|
4273
4318
|
const effectiveRange = selectedRange ?? ranges?.[0] ?? "1D";
|
|
@@ -4275,7 +4320,7 @@ var PriceChart = React9__namespace.forwardRef(
|
|
|
4275
4320
|
timeScale: getTimeScaleOptions(effectiveRange)
|
|
4276
4321
|
});
|
|
4277
4322
|
}, [selectedRange, ranges]);
|
|
4278
|
-
|
|
4323
|
+
React5__namespace.useEffect(() => {
|
|
4279
4324
|
const chart = chartRef.current;
|
|
4280
4325
|
const series = seriesRef.current;
|
|
4281
4326
|
if (!chart || !series) return;
|
|
@@ -4480,7 +4525,7 @@ var formatPrice3 = (value, currencySymbol) => {
|
|
|
4480
4525
|
maximumFractionDigits: 3
|
|
4481
4526
|
})}`;
|
|
4482
4527
|
};
|
|
4483
|
-
var PropertyHeroHeader =
|
|
4528
|
+
var PropertyHeroHeader = React5__namespace.forwardRef(
|
|
4484
4529
|
({
|
|
4485
4530
|
className,
|
|
4486
4531
|
imageUrl,
|
|
@@ -4507,8 +4552,8 @@ var PropertyHeroHeader = React9__namespace.forwardRef(
|
|
|
4507
4552
|
const isPositive = changePercent == null ? void 0 : changePercent >= 0;
|
|
4508
4553
|
const accentColor = "#e6c87e";
|
|
4509
4554
|
const tradeHoverColor = "#f5dd9a";
|
|
4510
|
-
const [isTradeInteracting, setIsTradeInteracting] =
|
|
4511
|
-
const [isOfferInteracting, setIsOfferInteracting] =
|
|
4555
|
+
const [isTradeInteracting, setIsTradeInteracting] = React5__namespace.useState(false);
|
|
4556
|
+
const [isOfferInteracting, setIsOfferInteracting] = React5__namespace.useState(false);
|
|
4512
4557
|
const hasAmenities = isLoading || beds != null || baths != null || cars != null || propertyTypeLabel != null;
|
|
4513
4558
|
const isTradeDisabled = !onTrade;
|
|
4514
4559
|
const isMakeOfferButtonDisabled = makeOfferDisabled || !onMakeOffer;
|
|
@@ -4954,12 +4999,12 @@ var Header = ({
|
|
|
4954
4999
|
onWalletNavigate: _onWalletNavigate,
|
|
4955
5000
|
showTradeTab = true
|
|
4956
5001
|
}) => {
|
|
4957
|
-
const [isUserMenuOpen, setIsUserMenuOpen] =
|
|
4958
|
-
const [isMobileMenuOpen, setIsMobileMenuOpen] =
|
|
4959
|
-
const [isMoreMenuOpen, setIsMoreMenuOpen] =
|
|
4960
|
-
const [showLoginPopup, setShowLoginPopup] =
|
|
4961
|
-
const [loginPopupInitialView, setLoginPopupInitialView] =
|
|
4962
|
-
|
|
5002
|
+
const [isUserMenuOpen, setIsUserMenuOpen] = React5.useState(false);
|
|
5003
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = React5.useState(false);
|
|
5004
|
+
const [isMoreMenuOpen, setIsMoreMenuOpen] = React5.useState(false);
|
|
5005
|
+
const [showLoginPopup, setShowLoginPopup] = React5.useState(false);
|
|
5006
|
+
const [loginPopupInitialView, setLoginPopupInitialView] = React5.useState(void 0);
|
|
5007
|
+
React5.useEffect(() => {
|
|
4963
5008
|
if (typeof window === "undefined") return;
|
|
4964
5009
|
const ua = navigator.userAgent;
|
|
4965
5010
|
const isTelegram = /Telegram/i.test(ua);
|
|
@@ -4968,7 +5013,7 @@ var Header = ({
|
|
|
4968
5013
|
document.documentElement.style.setProperty("--telegram-safe-top", "59px");
|
|
4969
5014
|
}
|
|
4970
5015
|
}, []);
|
|
4971
|
-
|
|
5016
|
+
React5.useEffect(() => {
|
|
4972
5017
|
const handleClickOutside = (event) => {
|
|
4973
5018
|
const target = event.target;
|
|
4974
5019
|
if (!target) return;
|
|
@@ -4988,7 +5033,7 @@ var Header = ({
|
|
|
4988
5033
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
4989
5034
|
};
|
|
4990
5035
|
}, [isUserMenuOpen, isMobileMenuOpen, isMoreMenuOpen]);
|
|
4991
|
-
|
|
5036
|
+
React5.useEffect(() => {
|
|
4992
5037
|
if (typeof window === "undefined") return;
|
|
4993
5038
|
const handleExternalLoginPopup = (event) => {
|
|
4994
5039
|
const customEvent = event;
|
|
@@ -5118,7 +5163,7 @@ var Header = ({
|
|
|
5118
5163
|
setShowLoginPopup(true);
|
|
5119
5164
|
}
|
|
5120
5165
|
};
|
|
5121
|
-
const handleLoginPopupClose =
|
|
5166
|
+
const handleLoginPopupClose = React5__namespace.default.useCallback(() => {
|
|
5122
5167
|
setShowLoginPopup(false);
|
|
5123
5168
|
setLoginPopupInitialView(void 0);
|
|
5124
5169
|
}, []);
|
|
@@ -5834,10 +5879,10 @@ var MobileNavItem = styled24__default.default.div`
|
|
|
5834
5879
|
padding-left: 24px;
|
|
5835
5880
|
}
|
|
5836
5881
|
`;
|
|
5837
|
-
var PropertySubheader =
|
|
5882
|
+
var PropertySubheader = React5__namespace.forwardRef(
|
|
5838
5883
|
({ className, tabs, activeTabId, onTabChange, actions, ...props }, ref) => {
|
|
5839
|
-
const tabsContainerRef =
|
|
5840
|
-
|
|
5884
|
+
const tabsContainerRef = React5__namespace.useRef(null);
|
|
5885
|
+
React5__namespace.useEffect(() => {
|
|
5841
5886
|
const container = tabsContainerRef.current;
|
|
5842
5887
|
if (!container) return;
|
|
5843
5888
|
const isMobile = window.innerWidth <= 768;
|
|
@@ -5979,27 +6024,27 @@ var LoginPopup = ({
|
|
|
5979
6024
|
onFundWallet,
|
|
5980
6025
|
initialView
|
|
5981
6026
|
}) => {
|
|
5982
|
-
const [view, setView] =
|
|
5983
|
-
const [email, setEmail] =
|
|
5984
|
-
const [handle, setHandle] =
|
|
5985
|
-
const [otp, setOtp] =
|
|
5986
|
-
const [error, setError] =
|
|
5987
|
-
const [loading, setLoading] =
|
|
5988
|
-
const [isSignUp, setIsSignUp] =
|
|
5989
|
-
const [fundingAmount] =
|
|
5990
|
-
const [kycLoading, setKycLoading] =
|
|
5991
|
-
const [showKycWidget, setShowKycWidget] =
|
|
5992
|
-
const [cryptoFundingLoading, setCryptoFundingLoading] =
|
|
5993
|
-
const [fiatFundingLoading, setFiatFundingLoading] =
|
|
5994
|
-
const [fundingError, setFundingError] =
|
|
5995
|
-
const [transakWidgetUrl, setTransakWidgetUrl] =
|
|
5996
|
-
const suppressAutoCloseRef =
|
|
5997
|
-
|
|
6027
|
+
const [view, setView] = React5.useState(() => initialView ?? "main");
|
|
6028
|
+
const [email, setEmail] = React5.useState("");
|
|
6029
|
+
const [handle, setHandle] = React5.useState("");
|
|
6030
|
+
const [otp, setOtp] = React5.useState(Array(OTP_INPUT_LENGTH).fill(""));
|
|
6031
|
+
const [error, setError] = React5.useState("");
|
|
6032
|
+
const [loading, setLoading] = React5.useState(false);
|
|
6033
|
+
const [isSignUp, setIsSignUp] = React5.useState(false);
|
|
6034
|
+
const [fundingAmount] = React5.useState("");
|
|
6035
|
+
const [kycLoading, setKycLoading] = React5.useState(false);
|
|
6036
|
+
const [showKycWidget, setShowKycWidget] = React5.useState(false);
|
|
6037
|
+
const [cryptoFundingLoading, setCryptoFundingLoading] = React5.useState(false);
|
|
6038
|
+
const [fiatFundingLoading, setFiatFundingLoading] = React5.useState(false);
|
|
6039
|
+
const [fundingError, setFundingError] = React5.useState("");
|
|
6040
|
+
const [transakWidgetUrl, setTransakWidgetUrl] = React5.useState(null);
|
|
6041
|
+
const suppressAutoCloseRef = React5__namespace.default.useRef(false);
|
|
6042
|
+
React5.useEffect(() => {
|
|
5998
6043
|
if (typeof initialView === "string") {
|
|
5999
6044
|
setView(initialView);
|
|
6000
6045
|
}
|
|
6001
6046
|
}, [initialView]);
|
|
6002
|
-
|
|
6047
|
+
React5.useEffect(() => {
|
|
6003
6048
|
if (!transakWidgetUrl) return;
|
|
6004
6049
|
const handleTransakMessage = (event) => {
|
|
6005
6050
|
if (!event.origin.includes("transak.com") && !event.origin.includes("global.transak.com")) {
|
|
@@ -6024,7 +6069,7 @@ var LoginPopup = ({
|
|
|
6024
6069
|
window.addEventListener("message", handleTransakMessage);
|
|
6025
6070
|
return () => window.removeEventListener("message", handleTransakMessage);
|
|
6026
6071
|
}, [transakWidgetUrl, onClose]);
|
|
6027
|
-
|
|
6072
|
+
React5.useEffect(() => {
|
|
6028
6073
|
if (!autoCloseOnAuth) {
|
|
6029
6074
|
return;
|
|
6030
6075
|
}
|
|
@@ -6245,13 +6290,12 @@ var LoginPopup = ({
|
|
|
6245
6290
|
}
|
|
6246
6291
|
setFundingError("");
|
|
6247
6292
|
setCryptoFundingLoading(true);
|
|
6293
|
+
const fundPromise = onFundWallet({ amount: fundingAmount, mode: "crypto" });
|
|
6294
|
+
onClose();
|
|
6248
6295
|
try {
|
|
6249
|
-
|
|
6250
|
-
if (result?.funded) {
|
|
6251
|
-
onClose();
|
|
6252
|
-
}
|
|
6296
|
+
await fundPromise;
|
|
6253
6297
|
} catch (err) {
|
|
6254
|
-
|
|
6298
|
+
console.error("[LoginPopup] crypto fund flow failed", err);
|
|
6255
6299
|
} finally {
|
|
6256
6300
|
setCryptoFundingLoading(false);
|
|
6257
6301
|
}
|
|
@@ -6996,8 +7040,8 @@ var TransakIframe = styled24__default.default.iframe`
|
|
|
6996
7040
|
border-radius: var(--border-radius, 12px);
|
|
6997
7041
|
`;
|
|
6998
7042
|
var MiniLiveFeed = () => {
|
|
6999
|
-
const [purchases, setPurchases] =
|
|
7000
|
-
|
|
7043
|
+
const [purchases, setPurchases] = React5.useState([]);
|
|
7044
|
+
React5.useEffect(() => {
|
|
7001
7045
|
const handles = [
|
|
7002
7046
|
"Landlord",
|
|
7003
7047
|
"PropertyKing",
|
|
@@ -7173,7 +7217,7 @@ var MiniLiveFeed = () => {
|
|
|
7173
7217
|
);
|
|
7174
7218
|
};
|
|
7175
7219
|
LoginPopup.displayName = "LoginPopup";
|
|
7176
|
-
var PropertyCompareBar =
|
|
7220
|
+
var PropertyCompareBar = React5__namespace.forwardRef(
|
|
7177
7221
|
({
|
|
7178
7222
|
className,
|
|
7179
7223
|
addresses,
|
|
@@ -7184,7 +7228,7 @@ var PropertyCompareBar = React9__namespace.forwardRef(
|
|
|
7184
7228
|
price,
|
|
7185
7229
|
...props
|
|
7186
7230
|
}, ref) => {
|
|
7187
|
-
const normalizedAddresses =
|
|
7231
|
+
const normalizedAddresses = React5__namespace.useMemo(() => {
|
|
7188
7232
|
return addresses.map(
|
|
7189
7233
|
(option) => typeof option === "string" ? { id: option, label: option } : option
|
|
7190
7234
|
);
|
|
@@ -7192,11 +7236,11 @@ var PropertyCompareBar = React9__namespace.forwardRef(
|
|
|
7192
7236
|
const hasAddresses = normalizedAddresses.length > 0;
|
|
7193
7237
|
const firstAddressId = normalizedAddresses[0]?.id;
|
|
7194
7238
|
const isControlled = selectedAddressId !== void 0;
|
|
7195
|
-
const [internalSelectedId, setInternalSelectedId] =
|
|
7239
|
+
const [internalSelectedId, setInternalSelectedId] = React5__namespace.useState(
|
|
7196
7240
|
() => isControlled ? void 0 : firstAddressId
|
|
7197
7241
|
);
|
|
7198
7242
|
const resolvedSelectedId = isControlled ? selectedAddressId : internalSelectedId;
|
|
7199
|
-
|
|
7243
|
+
React5__namespace.useEffect(() => {
|
|
7200
7244
|
if (!isControlled) {
|
|
7201
7245
|
setInternalSelectedId((current) => {
|
|
7202
7246
|
if (current != null && normalizedAddresses.some((option) => option.id === current)) {
|
|
@@ -7207,9 +7251,9 @@ var PropertyCompareBar = React9__namespace.forwardRef(
|
|
|
7207
7251
|
}
|
|
7208
7252
|
}, [firstAddressId, isControlled, normalizedAddresses]);
|
|
7209
7253
|
const selectedOption = normalizedAddresses.find((option) => option.id === resolvedSelectedId) ?? normalizedAddresses[0];
|
|
7210
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
7211
|
-
const dropdownRef =
|
|
7212
|
-
|
|
7254
|
+
const [isDropdownOpen, setIsDropdownOpen] = React5__namespace.useState(false);
|
|
7255
|
+
const dropdownRef = React5__namespace.useRef(null);
|
|
7256
|
+
React5__namespace.useEffect(() => {
|
|
7213
7257
|
if (!isDropdownOpen) return;
|
|
7214
7258
|
const handleClick = (event) => {
|
|
7215
7259
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
@@ -7612,11 +7656,11 @@ function GalleryMapSection({
|
|
|
7612
7656
|
autoPlay = true,
|
|
7613
7657
|
autoPlayInterval = 4e3
|
|
7614
7658
|
}) {
|
|
7615
|
-
const [carouselIndex, setCarouselIndex] =
|
|
7616
|
-
const [showVideo, setShowVideo] =
|
|
7617
|
-
const [autoPlaying, setAutoPlaying] =
|
|
7659
|
+
const [carouselIndex, setCarouselIndex] = React5.useState(0);
|
|
7660
|
+
const [showVideo, setShowVideo] = React5.useState(false);
|
|
7661
|
+
const [autoPlaying, setAutoPlaying] = React5.useState(autoPlay);
|
|
7618
7662
|
const resolvedMapUrl = mapUrl ?? (tokenName ? `/map/${tokenName}?embed=true&zoom=14&hideOthers=true` : "about:blank");
|
|
7619
|
-
|
|
7663
|
+
React5.useEffect(() => {
|
|
7620
7664
|
if (!autoPlaying || images.length <= 1) return;
|
|
7621
7665
|
const interval = setInterval(() => {
|
|
7622
7666
|
setCarouselIndex((p) => (p + 1) % images.length);
|
|
@@ -7935,7 +7979,7 @@ function PropertyOverview({
|
|
|
7935
7979
|
tokensIssued: tokensIssuedProp,
|
|
7936
7980
|
isLoading = false
|
|
7937
7981
|
}) {
|
|
7938
|
-
const [isDescExpanded, setDescExpanded] =
|
|
7982
|
+
const [isDescExpanded, setDescExpanded] = React5.useState(false);
|
|
7939
7983
|
const description = descriptionProp ?? overviewData?.description ?? DEFAULT_DESCRIPTION;
|
|
7940
7984
|
const landSize = landProp ?? overviewData?.landSizeSqm ?? null;
|
|
7941
7985
|
const buildingSize = buildingProp ?? overviewData?.buildingSizeSqm ?? null;
|
|
@@ -8282,8 +8326,8 @@ var OfferPricePulse = styled24__default.default.span`
|
|
|
8282
8326
|
`;
|
|
8283
8327
|
var eventTypes = ["Leased", "Renovated", "Extended", "Rebuilt", "Rezoned", "DA Approval"];
|
|
8284
8328
|
function PropertyHistory() {
|
|
8285
|
-
const [historyFilter, setHistoryFilter] =
|
|
8286
|
-
const pastSales =
|
|
8329
|
+
const [historyFilter, setHistoryFilter] = React5.useState("all");
|
|
8330
|
+
const pastSales = React5.useMemo(() => generateMockPastSales(), []);
|
|
8287
8331
|
const loafListing = pastSales.find((sale) => sale.type === "Listed");
|
|
8288
8332
|
const loafEvents = pastSales.filter(
|
|
8289
8333
|
(sale) => sale.ownershipPeriod === "current" && sale.type !== "Listed" && (sale.id === "leased-current" || sale.id === "da-approval")
|
|
@@ -8420,7 +8464,7 @@ function PropertyHistory() {
|
|
|
8420
8464
|
] });
|
|
8421
8465
|
}
|
|
8422
8466
|
function EventDetails({ event }) {
|
|
8423
|
-
const [expanded, setExpanded] =
|
|
8467
|
+
const [expanded, setExpanded] = React5.useState(false);
|
|
8424
8468
|
const toggleExpand = () => {
|
|
8425
8469
|
setExpanded((prev) => !prev);
|
|
8426
8470
|
};
|
|
@@ -9208,7 +9252,7 @@ function AssetSelectorBar({
|
|
|
9208
9252
|
selectorItems,
|
|
9209
9253
|
onSelect
|
|
9210
9254
|
}) {
|
|
9211
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
9255
|
+
const [isDropdownOpen, setIsDropdownOpen] = React5.useState(false);
|
|
9212
9256
|
const hasItems = selectorItems && selectorItems.length > 0;
|
|
9213
9257
|
const metrics = metricsProp ?? [
|
|
9214
9258
|
...tokenPrice != null ? [{ label: "Unit Price", value: `$${tokenPrice.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`, accent: true }] : [],
|
|
@@ -9477,15 +9521,15 @@ function OfferingProgressCard({
|
|
|
9477
9521
|
targetAmount,
|
|
9478
9522
|
isPrivateClient = false
|
|
9479
9523
|
}) {
|
|
9480
|
-
const [currentTime, setCurrentTime] =
|
|
9481
|
-
const [countdown, setCountdown] =
|
|
9524
|
+
const [currentTime, setCurrentTime] = React5.useState(/* @__PURE__ */ new Date());
|
|
9525
|
+
const [countdown, setCountdown] = React5.useState(null);
|
|
9482
9526
|
const computedRaised = raisedAmount ?? totalSold * tokenPrice;
|
|
9483
9527
|
const computedTarget = targetAmount ?? supplyToSell * tokenPrice;
|
|
9484
|
-
|
|
9528
|
+
React5.useEffect(() => {
|
|
9485
9529
|
const timer = setInterval(() => setCurrentTime(/* @__PURE__ */ new Date()), 1e3);
|
|
9486
9530
|
return () => clearInterval(timer);
|
|
9487
9531
|
}, []);
|
|
9488
|
-
|
|
9532
|
+
React5.useEffect(() => {
|
|
9489
9533
|
if (!opensAt) {
|
|
9490
9534
|
setCountdown(null);
|
|
9491
9535
|
return;
|
|
@@ -9828,7 +9872,7 @@ function VideoActivitySection({
|
|
|
9828
9872
|
ordersAllocated = 0,
|
|
9829
9873
|
tokenPrice = 0
|
|
9830
9874
|
}) {
|
|
9831
|
-
const sortedOrders =
|
|
9875
|
+
const sortedOrders = React5.useMemo(
|
|
9832
9876
|
() => [...recentOrders].sort((a, b) => b.timestamp - a.timestamp).slice(0, 7),
|
|
9833
9877
|
[recentOrders]
|
|
9834
9878
|
);
|
|
@@ -10174,10 +10218,10 @@ function OrderPanel({
|
|
|
10174
10218
|
tokenDisplayName,
|
|
10175
10219
|
tokenSymbol
|
|
10176
10220
|
}) {
|
|
10177
|
-
const [payInputValue, setPayInputValue] =
|
|
10178
|
-
const [receiveInputValue, setReceiveInputValue] =
|
|
10179
|
-
const [isPayInputFocused, setIsPayInputFocused] =
|
|
10180
|
-
const [isReceiveInputFocused, setIsReceiveInputFocused] =
|
|
10221
|
+
const [payInputValue, setPayInputValue] = React5.useState("");
|
|
10222
|
+
const [receiveInputValue, setReceiveInputValue] = React5.useState("");
|
|
10223
|
+
const [isPayInputFocused, setIsPayInputFocused] = React5.useState(false);
|
|
10224
|
+
const [isReceiveInputFocused, setIsReceiveInputFocused] = React5.useState(false);
|
|
10181
10225
|
const handlePayBlur = () => {
|
|
10182
10226
|
setIsPayInputFocused(false);
|
|
10183
10227
|
const parsed = parseInt(payInputValue.replace(/[^0-9]/g, ""), 10) || 0;
|
|
@@ -11023,9 +11067,9 @@ function PortfolioActivityPanel({
|
|
|
11023
11067
|
style
|
|
11024
11068
|
}) {
|
|
11025
11069
|
const resolvedDefaultTab = defaultTab ?? (showPositionsTab ? "positions" : "subscriptions");
|
|
11026
|
-
const [activeTab, setActiveTab] =
|
|
11027
|
-
const [activityPage, setActivityPage] =
|
|
11028
|
-
const activeTabTotal =
|
|
11070
|
+
const [activeTab, setActiveTab] = React5.useState(resolvedDefaultTab);
|
|
11071
|
+
const [activityPage, setActivityPage] = React5.useState(0);
|
|
11072
|
+
const activeTabTotal = React5.useMemo(() => {
|
|
11029
11073
|
switch (activeTab) {
|
|
11030
11074
|
case "positions":
|
|
11031
11075
|
return positions.length;
|
|
@@ -11044,15 +11088,15 @@ function PortfolioActivityPanel({
|
|
|
11044
11088
|
}
|
|
11045
11089
|
}, [activeTab, positions.length, offeringOrders.length, openOrders.length, orderHistory.length, tradeHistory.length, transfers.length]);
|
|
11046
11090
|
const positionsCount = positions.length;
|
|
11047
|
-
const openOrdersCount =
|
|
11091
|
+
const openOrdersCount = React5.useMemo(
|
|
11048
11092
|
() => openOrders.filter((o) => o.status === "OPEN" || o.status === "PARTIALLY_FILLED").length,
|
|
11049
11093
|
[openOrders]
|
|
11050
11094
|
);
|
|
11051
|
-
const pendingHistoryCount =
|
|
11095
|
+
const pendingHistoryCount = React5.useMemo(
|
|
11052
11096
|
() => orderHistory.filter((o) => o.status === "OPEN" || o.status === "PARTIALLY_FILLED").length,
|
|
11053
11097
|
[orderHistory]
|
|
11054
11098
|
);
|
|
11055
|
-
const pendingOfferingsCount =
|
|
11099
|
+
const pendingOfferingsCount = React5.useMemo(
|
|
11056
11100
|
() => offeringOrders.filter((o) => {
|
|
11057
11101
|
const s = o.status.toUpperCase();
|
|
11058
11102
|
return s !== "FILLED" && s !== "ALLOCATED" && s !== "CONFIRMED" && s !== "CANCELLED" && s !== "CANCELED" && s !== "REJECTED";
|
|
@@ -12086,19 +12130,19 @@ function PropertyBuy({
|
|
|
12086
12130
|
onSelectorSelect,
|
|
12087
12131
|
portfolioActivity
|
|
12088
12132
|
}) {
|
|
12089
|
-
const [sliderValue, setSliderValue] =
|
|
12090
|
-
const [availableBalance, setAvailableBalance] =
|
|
12091
|
-
const [manualOrderAmount, setManualOrderAmount] =
|
|
12092
|
-
const [ownedTokens, setOwnedTokens] =
|
|
12093
|
-
const [displayedOwnedTokens, setDisplayedOwnedTokens] =
|
|
12094
|
-
const [ownedTokensJustUpdated, setOwnedTokensJustUpdated] =
|
|
12095
|
-
const [lastOrderQuantity, setLastOrderQuantity] =
|
|
12096
|
-
const [orderPendingAllocation, setOrderPendingAllocation] =
|
|
12097
|
-
const [orderPlacedSuccess, setOrderPlacedSuccess] =
|
|
12098
|
-
const [lastOrderDetails, setLastOrderDetails] =
|
|
12099
|
-
const [showOrderConfirmModal, setShowOrderConfirmModal] =
|
|
12100
|
-
const [, setLiveNewsIndex] =
|
|
12101
|
-
const [newsItems, setNewsItems] =
|
|
12133
|
+
const [sliderValue, setSliderValue] = React5.useState(0);
|
|
12134
|
+
const [availableBalance, setAvailableBalance] = React5.useState(walletUsdcBalance ?? 0);
|
|
12135
|
+
const [manualOrderAmount, setManualOrderAmount] = React5.useState(null);
|
|
12136
|
+
const [ownedTokens, setOwnedTokens] = React5.useState(0);
|
|
12137
|
+
const [displayedOwnedTokens, setDisplayedOwnedTokens] = React5.useState(0);
|
|
12138
|
+
const [ownedTokensJustUpdated, setOwnedTokensJustUpdated] = React5.useState(false);
|
|
12139
|
+
const [lastOrderQuantity, setLastOrderQuantity] = React5.useState(0);
|
|
12140
|
+
const [orderPendingAllocation, setOrderPendingAllocation] = React5.useState(false);
|
|
12141
|
+
const [orderPlacedSuccess, setOrderPlacedSuccess] = React5.useState(false);
|
|
12142
|
+
const [lastOrderDetails, setLastOrderDetails] = React5.useState(null);
|
|
12143
|
+
const [showOrderConfirmModal, setShowOrderConfirmModal] = React5.useState(false);
|
|
12144
|
+
const [, setLiveNewsIndex] = React5.useState(0);
|
|
12145
|
+
const [newsItems, setNewsItems] = React5.useState(
|
|
12102
12146
|
() => allNewsItems.slice(0, 4).map((item, index) => ({
|
|
12103
12147
|
...item,
|
|
12104
12148
|
displayId: `${item.id}-initial-${index}`,
|
|
@@ -12125,12 +12169,12 @@ function PropertyBuy({
|
|
|
12125
12169
|
const orderTotal = tokenQuantity * tokenPrice + feeInUsd;
|
|
12126
12170
|
const estExposure = (tokenQuantity / supplyToSell * 100).toFixed(4);
|
|
12127
12171
|
const hasInsufficientFunds = orderTotal > availableBalance;
|
|
12128
|
-
|
|
12172
|
+
React5.useEffect(() => {
|
|
12129
12173
|
if (walletUsdcBalance != null) {
|
|
12130
12174
|
setAvailableBalance(walletUsdcBalance);
|
|
12131
12175
|
}
|
|
12132
12176
|
}, [walletUsdcBalance]);
|
|
12133
|
-
|
|
12177
|
+
React5.useEffect(() => {
|
|
12134
12178
|
if (walletPropertyTokenBalance != null) {
|
|
12135
12179
|
setOwnedTokens(walletPropertyTokenBalance);
|
|
12136
12180
|
setDisplayedOwnedTokens(walletPropertyTokenBalance);
|
|
@@ -12142,13 +12186,13 @@ function PropertyBuy({
|
|
|
12142
12186
|
}
|
|
12143
12187
|
setShowOrderConfirmModal(true);
|
|
12144
12188
|
};
|
|
12145
|
-
|
|
12189
|
+
React5.useEffect(() => {
|
|
12146
12190
|
if (purchaseStatus === "success" && orderPendingAllocation) {
|
|
12147
12191
|
setOrderPendingAllocation(false);
|
|
12148
12192
|
setOrderPlacedSuccess(true);
|
|
12149
12193
|
}
|
|
12150
12194
|
}, [purchaseStatus, orderPendingAllocation]);
|
|
12151
|
-
const handlePlaceAnotherOrder =
|
|
12195
|
+
const handlePlaceAnotherOrder = React5.useCallback(() => {
|
|
12152
12196
|
setOrderPlacedSuccess(false);
|
|
12153
12197
|
setOrderPendingAllocation(false);
|
|
12154
12198
|
}, []);
|
|
@@ -12205,7 +12249,7 @@ function PropertyBuy({
|
|
|
12205
12249
|
setSliderValue(0);
|
|
12206
12250
|
setManualOrderAmount(null);
|
|
12207
12251
|
};
|
|
12208
|
-
|
|
12252
|
+
React5.useEffect(() => {
|
|
12209
12253
|
const newsInterval = setInterval(() => {
|
|
12210
12254
|
setLiveNewsIndex((prev) => {
|
|
12211
12255
|
const nextIndex = (prev + 1) % allNewsItems.length;
|
|
@@ -12503,7 +12547,7 @@ function PaymentPopup({
|
|
|
12503
12547
|
userTokenHoldings,
|
|
12504
12548
|
propertyName
|
|
12505
12549
|
}) {
|
|
12506
|
-
const [selectedPaymentMethod, setSelectedPaymentMethod] =
|
|
12550
|
+
const [selectedPaymentMethod, setSelectedPaymentMethod] = React5.useState(
|
|
12507
12551
|
"tokens"
|
|
12508
12552
|
);
|
|
12509
12553
|
if (!isOpen) return null;
|
|
@@ -12682,20 +12726,20 @@ function PaymentPopup({
|
|
|
12682
12726
|
var payment_popup_default = PaymentPopup;
|
|
12683
12727
|
var SUMMER_MONTHS = /* @__PURE__ */ new Set([11, 0, 1]);
|
|
12684
12728
|
var OwnerBooking = ({ propertyName, token }) => {
|
|
12685
|
-
const today =
|
|
12729
|
+
const today = React5.useMemo(() => {
|
|
12686
12730
|
const base = /* @__PURE__ */ new Date();
|
|
12687
12731
|
base.setHours(0, 0, 0, 0);
|
|
12688
12732
|
return base;
|
|
12689
12733
|
}, []);
|
|
12690
|
-
const [currentYear, setCurrentYear] =
|
|
12691
|
-
const [currentMonth, setCurrentMonth] =
|
|
12692
|
-
const [dateRanges, setDateRanges] =
|
|
12693
|
-
const [selectedDates, setSelectedDates] =
|
|
12694
|
-
const [hoverDate, setHoverDate] =
|
|
12695
|
-
const [isDateSelectorOpen, setIsDateSelectorOpen] =
|
|
12696
|
-
const [selectorYear, setSelectorYear] =
|
|
12697
|
-
const [isPaymentPopupOpen, setIsPaymentPopupOpen] =
|
|
12698
|
-
const dateSelectorRef =
|
|
12734
|
+
const [currentYear, setCurrentYear] = React5.useState(today.getFullYear());
|
|
12735
|
+
const [currentMonth, setCurrentMonth] = React5.useState(today.getMonth());
|
|
12736
|
+
const [dateRanges, setDateRanges] = React5.useState([]);
|
|
12737
|
+
const [selectedDates, setSelectedDates] = React5.useState([]);
|
|
12738
|
+
const [hoverDate, setHoverDate] = React5.useState(null);
|
|
12739
|
+
const [isDateSelectorOpen, setIsDateSelectorOpen] = React5.useState(false);
|
|
12740
|
+
const [selectorYear, setSelectorYear] = React5.useState(today.getFullYear());
|
|
12741
|
+
const [isPaymentPopupOpen, setIsPaymentPopupOpen] = React5.useState(false);
|
|
12742
|
+
const dateSelectorRef = React5.useRef(null);
|
|
12699
12743
|
const tokenPrice = token.price ?? 700;
|
|
12700
12744
|
const userTokenHoldings = 2.2;
|
|
12701
12745
|
const MIN_NIGHTS = 3;
|
|
@@ -12705,25 +12749,25 @@ var OwnerBooking = ({ propertyName, token }) => {
|
|
|
12705
12749
|
{ bg: "rgba(230, 126, 34, 0.25)", border: "rgba(230, 126, 34, 0.6)" },
|
|
12706
12750
|
{ bg: "rgba(46, 204, 113, 0.25)", border: "rgba(46, 204, 113, 0.6)" }
|
|
12707
12751
|
];
|
|
12708
|
-
const calculateTokensPerDayOwner =
|
|
12752
|
+
const calculateTokensPerDayOwner = React5.useCallback(() => {
|
|
12709
12753
|
if (tokenPrice <= 0) return 0;
|
|
12710
12754
|
const target = 650;
|
|
12711
12755
|
const raw = target / tokenPrice;
|
|
12712
12756
|
return Math.ceil(raw * 1e4) / 1e4;
|
|
12713
12757
|
}, [tokenPrice]);
|
|
12714
|
-
const calculateTokensPerDayMarket =
|
|
12758
|
+
const calculateTokensPerDayMarket = React5.useCallback(() => {
|
|
12715
12759
|
if (tokenPrice <= 0) return 0;
|
|
12716
12760
|
const target = 900;
|
|
12717
12761
|
const raw = target / tokenPrice;
|
|
12718
12762
|
return Math.ceil(raw * 1e4) / 1e4;
|
|
12719
12763
|
}, [tokenPrice]);
|
|
12720
12764
|
const qualifiesForOwnerRate = userTokenHoldings >= 0.1;
|
|
12721
|
-
const getTokensPerDay =
|
|
12765
|
+
const getTokensPerDay = React5.useCallback(
|
|
12722
12766
|
() => calculateTokensPerDayOwner() ,
|
|
12723
12767
|
[qualifiesForOwnerRate, calculateTokensPerDayOwner, calculateTokensPerDayMarket]
|
|
12724
12768
|
);
|
|
12725
12769
|
const getRateLabel = () => "Owner's Rate" ;
|
|
12726
|
-
const selectionStats =
|
|
12770
|
+
const selectionStats = React5.useMemo(() => {
|
|
12727
12771
|
if (selectedDates.length !== 2) return null;
|
|
12728
12772
|
const [a, b] = selectedDates;
|
|
12729
12773
|
const start = a < b ? a : b;
|
|
@@ -12734,10 +12778,10 @@ var OwnerBooking = ({ propertyName, token }) => {
|
|
|
12734
12778
|
const usd = tokens * tokenPrice;
|
|
12735
12779
|
return { nights, tokensPerDay, tokens, usd, start, end };
|
|
12736
12780
|
}, [selectedDates, getTokensPerDay, tokenPrice]);
|
|
12737
|
-
const totalNights =
|
|
12738
|
-
const totalTokens =
|
|
12781
|
+
const totalNights = React5.useMemo(() => dateRanges.reduce((sum, r) => sum + r.nights, 0), [dateRanges]);
|
|
12782
|
+
const totalTokens = React5.useMemo(() => dateRanges.reduce((sum, r) => sum + r.tokens, 0), [dateRanges]);
|
|
12739
12783
|
const totalUSD = totalTokens * tokenPrice;
|
|
12740
|
-
const generateCalendarDays =
|
|
12784
|
+
const generateCalendarDays = React5.useCallback(
|
|
12741
12785
|
(year, month) => {
|
|
12742
12786
|
const first = new Date(year, month, 1);
|
|
12743
12787
|
const last = new Date(year, month + 1, 0);
|
|
@@ -12766,11 +12810,11 @@ var OwnerBooking = ({ propertyName, token }) => {
|
|
|
12766
12810
|
},
|
|
12767
12811
|
[today]
|
|
12768
12812
|
);
|
|
12769
|
-
const calendarDays =
|
|
12813
|
+
const calendarDays = React5.useMemo(
|
|
12770
12814
|
() => generateCalendarDays(currentYear, currentMonth),
|
|
12771
12815
|
[currentYear, currentMonth, generateCalendarDays]
|
|
12772
12816
|
);
|
|
12773
|
-
const isDateReserved =
|
|
12817
|
+
const isDateReserved = React5.useCallback(
|
|
12774
12818
|
(date) => dateRanges.some((r) => date >= r.arrival && date <= r.departure),
|
|
12775
12819
|
[dateRanges]
|
|
12776
12820
|
);
|
|
@@ -12864,14 +12908,14 @@ var OwnerBooking = ({ propertyName, token }) => {
|
|
|
12864
12908
|
"December"
|
|
12865
12909
|
];
|
|
12866
12910
|
const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
12867
|
-
const setMonthYear =
|
|
12911
|
+
const setMonthYear = React5.useCallback(
|
|
12868
12912
|
(month, year) => {
|
|
12869
12913
|
setCurrentMonth(month);
|
|
12870
12914
|
setCurrentYear(year);
|
|
12871
12915
|
},
|
|
12872
12916
|
[setCurrentMonth, setCurrentYear]
|
|
12873
12917
|
);
|
|
12874
|
-
const shiftMonth =
|
|
12918
|
+
const shiftMonth = React5.useCallback(
|
|
12875
12919
|
(direction) => {
|
|
12876
12920
|
const delta = direction === "prev" ? -1 : 1;
|
|
12877
12921
|
let newMonth = currentMonth + delta;
|
|
@@ -12888,7 +12932,7 @@ var OwnerBooking = ({ propertyName, token }) => {
|
|
|
12888
12932
|
},
|
|
12889
12933
|
[currentMonth, currentYear, setMonthYear]
|
|
12890
12934
|
);
|
|
12891
|
-
const jumpToNextAvailable =
|
|
12935
|
+
const jumpToNextAvailable = React5.useCallback(() => {
|
|
12892
12936
|
for (let offset = 1; offset <= 12; offset++) {
|
|
12893
12937
|
const candidateMonth = (currentMonth + offset) % 12;
|
|
12894
12938
|
if (!SUMMER_MONTHS.has(candidateMonth)) continue;
|
|
@@ -12905,7 +12949,7 @@ var OwnerBooking = ({ propertyName, token }) => {
|
|
|
12905
12949
|
setMonthYear(month, selectorYear);
|
|
12906
12950
|
setIsDateSelectorOpen(false);
|
|
12907
12951
|
};
|
|
12908
|
-
|
|
12952
|
+
React5.useEffect(() => {
|
|
12909
12953
|
const handleClickOutside = (event) => {
|
|
12910
12954
|
if (dateSelectorRef.current && !dateSelectorRef.current.contains(event.target)) {
|
|
12911
12955
|
setIsDateSelectorOpen(false);
|
|
@@ -13349,21 +13393,21 @@ function PropertyValuation({
|
|
|
13349
13393
|
loading = false,
|
|
13350
13394
|
error = null
|
|
13351
13395
|
}) {
|
|
13352
|
-
const now =
|
|
13353
|
-
const lastPrice =
|
|
13396
|
+
const now = React5.useMemo(() => /* @__PURE__ */ new Date(), []);
|
|
13397
|
+
const lastPrice = React5.useMemo(() => {
|
|
13354
13398
|
const fallback = Number.isFinite(tokenPrice) && tokenPrice > 0 ? tokenPrice : 0;
|
|
13355
13399
|
if (!summary?.lastPrice || summary.lastPrice <= 0) {
|
|
13356
13400
|
return fallback;
|
|
13357
13401
|
}
|
|
13358
13402
|
return summary.lastPrice;
|
|
13359
13403
|
}, [summary, tokenPrice]);
|
|
13360
|
-
const fairValue =
|
|
13404
|
+
const fairValue = React5.useMemo(() => {
|
|
13361
13405
|
if (summary?.fairValue && summary.fairValue > 0) {
|
|
13362
13406
|
return summary.fairValue;
|
|
13363
13407
|
}
|
|
13364
13408
|
return lastPrice || 1;
|
|
13365
13409
|
}, [summary, lastPrice]);
|
|
13366
|
-
const tokensOutstanding =
|
|
13410
|
+
const tokensOutstanding = React5.useMemo(() => {
|
|
13367
13411
|
if (summary?.totalTokens && summary.totalTokens > 0) {
|
|
13368
13412
|
return summary.totalTokens;
|
|
13369
13413
|
}
|
|
@@ -13378,8 +13422,8 @@ function PropertyValuation({
|
|
|
13378
13422
|
const valuationStatus = summary?.valuationStatus ?? (lastPrice < fairValue ? "Undervalued" : lastPrice > fairValue ? "Overvalued" : "Fair Value");
|
|
13379
13423
|
const valuationDelta = summary?.valuationDeltaPercent ?? (lastPrice - fairValue) / fairValue * 100;
|
|
13380
13424
|
const valuationDeltaFormatted = `${valuationDelta >= 0 ? "+" : ""}${valuationDelta.toFixed(1)}%`;
|
|
13381
|
-
const { valuationPath, fairValuePath, axisLabels } =
|
|
13382
|
-
const recentSales =
|
|
13425
|
+
const { valuationPath, fairValuePath, axisLabels } = React5.useMemo(() => buildChartPaths(history, fairValue), [history, fairValue]);
|
|
13426
|
+
const recentSales = React5.useMemo(() => {
|
|
13383
13427
|
if (summary?.recentSales?.length) {
|
|
13384
13428
|
return summary.recentSales;
|
|
13385
13429
|
}
|
|
@@ -14531,19 +14575,19 @@ function PropertyPhotoGallery({
|
|
|
14531
14575
|
);
|
|
14532
14576
|
}
|
|
14533
14577
|
function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose }) {
|
|
14534
|
-
const [currentIndex, setCurrentIndex] =
|
|
14535
|
-
const [activeHotspotId, setActiveHotspotId] =
|
|
14536
|
-
const sliderRef =
|
|
14537
|
-
const [isDragging, setIsDragging] =
|
|
14538
|
-
const wasDraggingRef =
|
|
14539
|
-
const touchStartX =
|
|
14540
|
-
const touchStartY =
|
|
14541
|
-
const isSwiping =
|
|
14542
|
-
const progress =
|
|
14578
|
+
const [currentIndex, setCurrentIndex] = React5.useState(() => clampIndex(startIndex, galleryImages.length));
|
|
14579
|
+
const [activeHotspotId, setActiveHotspotId] = React5.useState(null);
|
|
14580
|
+
const sliderRef = React5.useRef(null);
|
|
14581
|
+
const [isDragging, setIsDragging] = React5.useState(false);
|
|
14582
|
+
const wasDraggingRef = React5.useRef(false);
|
|
14583
|
+
const touchStartX = React5.useRef(null);
|
|
14584
|
+
const touchStartY = React5.useRef(null);
|
|
14585
|
+
const isSwiping = React5.useRef(false);
|
|
14586
|
+
const progress = React5.useMemo(() => {
|
|
14543
14587
|
if (galleryImages.length <= 1) return 0;
|
|
14544
14588
|
return currentIndex / (galleryImages.length - 1) * 100;
|
|
14545
14589
|
}, [currentIndex, galleryImages.length]);
|
|
14546
|
-
|
|
14590
|
+
React5.useEffect(() => {
|
|
14547
14591
|
document.body.style.overflow = "hidden";
|
|
14548
14592
|
document.body.style.touchAction = "none";
|
|
14549
14593
|
return () => {
|
|
@@ -14551,7 +14595,7 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
14551
14595
|
document.body.style.touchAction = "";
|
|
14552
14596
|
};
|
|
14553
14597
|
}, []);
|
|
14554
|
-
|
|
14598
|
+
React5.useEffect(() => {
|
|
14555
14599
|
const handleKey = (event) => {
|
|
14556
14600
|
if (event.key === "Escape") onClose();
|
|
14557
14601
|
if (event.key === "ArrowLeft") setCurrentIndex((i) => i === 0 ? galleryImages.length - 1 : i - 1);
|
|
@@ -14824,13 +14868,13 @@ function truncateHash(hash) {
|
|
|
14824
14868
|
return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
|
|
14825
14869
|
}
|
|
14826
14870
|
function ToastItem({ toast, onDismiss }) {
|
|
14827
|
-
const [exiting, setExiting] =
|
|
14828
|
-
const timerRef =
|
|
14829
|
-
const dismiss =
|
|
14871
|
+
const [exiting, setExiting] = React5.useState(false);
|
|
14872
|
+
const timerRef = React5.useRef(null);
|
|
14873
|
+
const dismiss = React5.useCallback(() => {
|
|
14830
14874
|
setExiting(true);
|
|
14831
14875
|
setTimeout(() => onDismiss(toast.id), 280);
|
|
14832
14876
|
}, [onDismiss, toast.id]);
|
|
14833
|
-
|
|
14877
|
+
React5.useEffect(() => {
|
|
14834
14878
|
const duration2 = toast.duration ?? 6e3;
|
|
14835
14879
|
if (duration2 > 0) {
|
|
14836
14880
|
timerRef.current = setTimeout(dismiss, duration2);
|
|
@@ -14859,15 +14903,15 @@ function ToastItem({ toast, onDismiss }) {
|
|
|
14859
14903
|
duration > 0 && /* @__PURE__ */ jsxRuntime.jsx(ProgressBar, { $color: accent, $duration: duration })
|
|
14860
14904
|
] });
|
|
14861
14905
|
}
|
|
14862
|
-
var ToastContext =
|
|
14906
|
+
var ToastContext = React5.createContext(null);
|
|
14863
14907
|
function ToastProvider({ children }) {
|
|
14864
|
-
const [toasts, setToasts] =
|
|
14865
|
-
const addToast =
|
|
14908
|
+
const [toasts, setToasts] = React5.useState([]);
|
|
14909
|
+
const addToast = React5.useCallback((data) => {
|
|
14866
14910
|
const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
14867
14911
|
setToasts((prev) => [...prev, { ...data, id }]);
|
|
14868
14912
|
return id;
|
|
14869
14913
|
}, []);
|
|
14870
|
-
const dismiss =
|
|
14914
|
+
const dismiss = React5.useCallback((id) => {
|
|
14871
14915
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
14872
14916
|
}, []);
|
|
14873
14917
|
return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: { toast: addToast, dismiss }, children: [
|
|
@@ -14876,15 +14920,15 @@ function ToastProvider({ children }) {
|
|
|
14876
14920
|
] });
|
|
14877
14921
|
}
|
|
14878
14922
|
function useToast() {
|
|
14879
|
-
const ctx =
|
|
14923
|
+
const ctx = React5.useContext(ToastContext);
|
|
14880
14924
|
if (!ctx) throw new Error("useToast must be used within a ToastProvider");
|
|
14881
14925
|
return ctx;
|
|
14882
14926
|
}
|
|
14883
14927
|
var INTERVALS = [1e3, 2e3, 4e3, 5e3, 7e3, 1e4, 12e3];
|
|
14884
14928
|
function useAdaptivePolling({ enabled, onPoll }) {
|
|
14885
|
-
const onPollRef =
|
|
14929
|
+
const onPollRef = React5.useRef(onPoll);
|
|
14886
14930
|
onPollRef.current = onPoll;
|
|
14887
|
-
|
|
14931
|
+
React5.useEffect(() => {
|
|
14888
14932
|
if (!enabled) return;
|
|
14889
14933
|
let cancelled = false;
|
|
14890
14934
|
let timeoutId = null;
|