@loafmarkets/ui 0.1.405 → 0.1.406
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 +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +127 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +127 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -706,6 +706,11 @@ type HeaderProps = {
|
|
|
706
706
|
onOrdersNavigate?: () => void;
|
|
707
707
|
onWalletNavigate?: () => void;
|
|
708
708
|
onSettingsClick?: () => void;
|
|
709
|
+
/** Fired by the "Refer" CTA button + user-menu "Refer" item. When omitted, both
|
|
710
|
+
* fall back to `onSettingsClick` (so existing consumers are unchanged). Lets a
|
|
711
|
+
* consumer route Refer somewhere other than Settings (e.g. an invite modal)
|
|
712
|
+
* without DOM-level click interception. */
|
|
713
|
+
onReferClick?: () => void;
|
|
709
714
|
portfolioSummary?: HeaderPortfolioData | null;
|
|
710
715
|
/**
|
|
711
716
|
* True while a brand-new user's test funds (100k mock USD) are being deposited
|
|
@@ -716,7 +721,7 @@ type HeaderProps = {
|
|
|
716
721
|
/**
|
|
717
722
|
* The bar's authed CTA button. Defaults to "deposit" (the funding flow) so
|
|
718
723
|
* existing consumers are unchanged. "refer" swaps it for a Refer button that
|
|
719
|
-
*
|
|
724
|
+
* fires `onReferClick` (falling back to `onSettingsClick` when not provided).
|
|
720
725
|
*/
|
|
721
726
|
headerCta?: "deposit" | "refer";
|
|
722
727
|
/** Show the "Refer" user-menu item. Off by default — referral is feature-flagged
|
|
@@ -1093,7 +1098,7 @@ type ToastData = {
|
|
|
1093
1098
|
amount?: string;
|
|
1094
1099
|
/** On-chain tx hash — shown truncated with a block explorer link */
|
|
1095
1100
|
txHash?: string;
|
|
1096
|
-
/** Explorer base URL, defaults to
|
|
1101
|
+
/** Explorer base URL, defaults to Arbitrum Sepolia */
|
|
1097
1102
|
explorerUrl?: string;
|
|
1098
1103
|
/** Auto-dismiss after ms. 0 = never. Default 6000 */
|
|
1099
1104
|
duration?: number;
|
|
@@ -1269,11 +1274,13 @@ type PropertyPhotoGalleryProps = {
|
|
|
1269
1274
|
isOpen: boolean;
|
|
1270
1275
|
onClose: () => void;
|
|
1271
1276
|
startIndex?: number;
|
|
1277
|
+
startWithVideo?: boolean;
|
|
1272
1278
|
images?: PropertyGalleryImage[];
|
|
1273
1279
|
title?: string;
|
|
1274
1280
|
subtitle?: string;
|
|
1281
|
+
videoUrl?: string;
|
|
1275
1282
|
};
|
|
1276
|
-
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, title, subtitle, images, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1283
|
+
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, startWithVideo, title, subtitle, images, videoUrl, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1277
1284
|
|
|
1278
1285
|
type UseAdaptivePollingOptions = {
|
|
1279
1286
|
enabled: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -706,6 +706,11 @@ type HeaderProps = {
|
|
|
706
706
|
onOrdersNavigate?: () => void;
|
|
707
707
|
onWalletNavigate?: () => void;
|
|
708
708
|
onSettingsClick?: () => void;
|
|
709
|
+
/** Fired by the "Refer" CTA button + user-menu "Refer" item. When omitted, both
|
|
710
|
+
* fall back to `onSettingsClick` (so existing consumers are unchanged). Lets a
|
|
711
|
+
* consumer route Refer somewhere other than Settings (e.g. an invite modal)
|
|
712
|
+
* without DOM-level click interception. */
|
|
713
|
+
onReferClick?: () => void;
|
|
709
714
|
portfolioSummary?: HeaderPortfolioData | null;
|
|
710
715
|
/**
|
|
711
716
|
* True while a brand-new user's test funds (100k mock USD) are being deposited
|
|
@@ -716,7 +721,7 @@ type HeaderProps = {
|
|
|
716
721
|
/**
|
|
717
722
|
* The bar's authed CTA button. Defaults to "deposit" (the funding flow) so
|
|
718
723
|
* existing consumers are unchanged. "refer" swaps it for a Refer button that
|
|
719
|
-
*
|
|
724
|
+
* fires `onReferClick` (falling back to `onSettingsClick` when not provided).
|
|
720
725
|
*/
|
|
721
726
|
headerCta?: "deposit" | "refer";
|
|
722
727
|
/** Show the "Refer" user-menu item. Off by default — referral is feature-flagged
|
|
@@ -1093,7 +1098,7 @@ type ToastData = {
|
|
|
1093
1098
|
amount?: string;
|
|
1094
1099
|
/** On-chain tx hash — shown truncated with a block explorer link */
|
|
1095
1100
|
txHash?: string;
|
|
1096
|
-
/** Explorer base URL, defaults to
|
|
1101
|
+
/** Explorer base URL, defaults to Arbitrum Sepolia */
|
|
1097
1102
|
explorerUrl?: string;
|
|
1098
1103
|
/** Auto-dismiss after ms. 0 = never. Default 6000 */
|
|
1099
1104
|
duration?: number;
|
|
@@ -1269,11 +1274,13 @@ type PropertyPhotoGalleryProps = {
|
|
|
1269
1274
|
isOpen: boolean;
|
|
1270
1275
|
onClose: () => void;
|
|
1271
1276
|
startIndex?: number;
|
|
1277
|
+
startWithVideo?: boolean;
|
|
1272
1278
|
images?: PropertyGalleryImage[];
|
|
1273
1279
|
title?: string;
|
|
1274
1280
|
subtitle?: string;
|
|
1281
|
+
videoUrl?: string;
|
|
1275
1282
|
};
|
|
1276
|
-
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, title, subtitle, images, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1283
|
+
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, startWithVideo, title, subtitle, images, videoUrl, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1277
1284
|
|
|
1278
1285
|
type UseAdaptivePollingOptions = {
|
|
1279
1286
|
enabled: boolean;
|
package/dist/index.js
CHANGED
|
@@ -5101,6 +5101,7 @@ var Header = ({
|
|
|
5101
5101
|
onOrdersNavigate: _onOrdersNavigate,
|
|
5102
5102
|
onWalletNavigate: _onWalletNavigate,
|
|
5103
5103
|
onSettingsClick,
|
|
5104
|
+
onReferClick,
|
|
5104
5105
|
portfolioSummary,
|
|
5105
5106
|
fundsPending = false,
|
|
5106
5107
|
transparentOnTop = false,
|
|
@@ -5539,7 +5540,7 @@ var Header = ({
|
|
|
5539
5540
|
onClick: (event) => {
|
|
5540
5541
|
event?.preventDefault();
|
|
5541
5542
|
closeMenus();
|
|
5542
|
-
onSettingsClick?.();
|
|
5543
|
+
(onReferClick ?? onSettingsClick)?.();
|
|
5543
5544
|
},
|
|
5544
5545
|
children: "Refer"
|
|
5545
5546
|
}
|
|
@@ -5582,7 +5583,7 @@ var Header = ({
|
|
|
5582
5583
|
onClick: (event) => {
|
|
5583
5584
|
event?.preventDefault();
|
|
5584
5585
|
closeMenus();
|
|
5585
|
-
onSettingsClick?.();
|
|
5586
|
+
(onReferClick ?? onSettingsClick)?.();
|
|
5586
5587
|
},
|
|
5587
5588
|
children: /* @__PURE__ */ jsxRuntime.jsx(MenuItem, { children: "Refer" })
|
|
5588
5589
|
}
|
|
@@ -7700,12 +7701,12 @@ var LoginPopup = ({
|
|
|
7700
7701
|
marginBottom: "1.25rem"
|
|
7701
7702
|
}, children: [
|
|
7702
7703
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 7, height: 7, borderRadius: "50%", background: "#0052FF", flexShrink: 0 } }),
|
|
7703
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.72rem", fontWeight: 600, color: "#6b9fff", letterSpacing: "0.02em" }, children: "
|
|
7704
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.72rem", fontWeight: 600, color: "#6b9fff", letterSpacing: "0.02em" }, children: "Arbitrum Sepolia" })
|
|
7704
7705
|
] }),
|
|
7705
7706
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.82rem", color: "rgba(255,255,255,0.5)", textAlign: "center", marginBottom: "1.1rem", lineHeight: 1.5, maxWidth: 320 }, children: [
|
|
7706
7707
|
"Send ",
|
|
7707
7708
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: "rgba(255,255,255,0.8)" }, children: "USDC" }),
|
|
7708
|
-
" on
|
|
7709
|
+
" on Arbitrum Sepolia to the address below. Only send on this network."
|
|
7709
7710
|
] }),
|
|
7710
7711
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
7711
7712
|
width: "100%",
|
|
@@ -10350,7 +10351,7 @@ function PropertyOverview({
|
|
|
10350
10351
|
isLoading = false,
|
|
10351
10352
|
ticker,
|
|
10352
10353
|
contractAddress,
|
|
10353
|
-
chain = "
|
|
10354
|
+
chain = "Arbitrum (Ethereum L2)",
|
|
10354
10355
|
volume24h,
|
|
10355
10356
|
priceHistory: priceHistoryProp,
|
|
10356
10357
|
beta = false,
|
|
@@ -10389,13 +10390,13 @@ function PropertyOverview({
|
|
|
10389
10390
|
const resolvedPropertyType = rawPropertyType?.toLowerCase() === "house" ? "Residential" : rawPropertyType;
|
|
10390
10391
|
const galleryImages = images ?? [];
|
|
10391
10392
|
const chainValue = /* @__PURE__ */ jsxRuntime.jsxs(ChainLogos, { children: [
|
|
10392
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChainLogoImg, { src: "/
|
|
10393
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChainLogoImg, { src: "/Arbitrum-Symbol.svg", alt: "Arbitrum" }),
|
|
10393
10394
|
/* @__PURE__ */ jsxRuntime.jsx(ChainLogoImg, { src: "/Ethereum-Logo.png", alt: "Ethereum", style: { filter: "brightness(0) invert(1)" } }),
|
|
10394
10395
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: chain })
|
|
10395
10396
|
] });
|
|
10396
10397
|
const tokenDetailsItems = [
|
|
10397
10398
|
{ label: "Chain", value: chainValue },
|
|
10398
|
-
{ label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://sepolia.
|
|
10399
|
+
{ label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://sepolia.arbiscan.io/address/${contractAddress}` : void 0, copyValue: contractAddress },
|
|
10399
10400
|
{ label: "Token Ticker", value: ticker ?? "\u2014" },
|
|
10400
10401
|
{ label: "Total Circulating Tokens", value: isLoading && resolvedTokensIssued == null ? loadingSkeleton : resolvedTokensIssued?.toLocaleString() ?? "\u2014" },
|
|
10401
10402
|
{ label: "Legal Structuring", value: "See Documents", docLink: true },
|
|
@@ -10415,7 +10416,9 @@ function PropertyOverview({
|
|
|
10415
10416
|
];
|
|
10416
10417
|
const growthPct = overviewData?.growth5Yr;
|
|
10417
10418
|
const propertyStats = [
|
|
10418
|
-
|
|
10419
|
+
// Property Value = the API offeringValuation (OverviewResponse.offeringValuation), NOT
|
|
10420
|
+
// midPrice×tokensIssued market cap (fixed 2026-07-22). null → '—', never a fabricated cap.
|
|
10421
|
+
{ label: "Property Value", value: isLoading && overviewData?.offeringValuation == null ? loadingSkeleton : overviewData?.offeringValuation ? fmtDollar(overviewData.offeringValuation) : "\u2014" },
|
|
10419
10422
|
...beta ? [] : [{ label: "Offers", value: "3" }],
|
|
10420
10423
|
{ label: "Growth (5yr)", value: growthPct != null ? `${growthPct > 0 ? "+" : ""}${growthPct}%` : "\u2014" },
|
|
10421
10424
|
{ label: "Last Dividend", value: overviewData?.lastDividend != null ? `$${overviewData.lastDividend.toFixed(2)}` : "\u2014" },
|
|
@@ -14916,7 +14919,7 @@ var getOrderStatusMeta = (statusRaw) => {
|
|
|
14916
14919
|
return { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" };
|
|
14917
14920
|
};
|
|
14918
14921
|
var ChevronDown = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "rgba(255,255,255,0.5)", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" }) });
|
|
14919
|
-
var
|
|
14922
|
+
var ArbiscanIconLink = ({ url }) => /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: url, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
14920
14923
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
14921
14924
|
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
14922
14925
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
@@ -14941,7 +14944,7 @@ function PortfolioActivityPanel({
|
|
|
14941
14944
|
defaultTab,
|
|
14942
14945
|
onTabChange,
|
|
14943
14946
|
pageSize = ACTIVITY_PAGE_SIZE_DEFAULT,
|
|
14944
|
-
blockExplorerBaseUrl: _blockExplorerBaseUrl = "https://sepolia.
|
|
14947
|
+
blockExplorerBaseUrl: _blockExplorerBaseUrl = "https://sepolia.arbiscan.io/tx",
|
|
14945
14948
|
className,
|
|
14946
14949
|
style
|
|
14947
14950
|
}) {
|
|
@@ -15385,7 +15388,7 @@ function PortfolioActivityPanel({
|
|
|
15385
15388
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
|
|
15386
15389
|
formatNumber2(order.quantity),
|
|
15387
15390
|
order.ticker && /* @__PURE__ */ jsxRuntime.jsx(TickerTag, { style: { marginLeft: 0 }, children: order.ticker.toUpperCase() }),
|
|
15388
|
-
order.txHash && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15391
|
+
order.txHash && /* @__PURE__ */ jsxRuntime.jsx(ArbiscanIconLink, { url: `${_blockExplorerBaseUrl}/${order.txHash}` })
|
|
15389
15392
|
] })
|
|
15390
15393
|
] }),
|
|
15391
15394
|
/* @__PURE__ */ jsxRuntime.jsxs(CUnitsCell, { children: [
|
|
@@ -15438,7 +15441,7 @@ function PortfolioActivityPanel({
|
|
|
15438
15441
|
order.status === "REJECTED" && order.rejectionReason && /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, style: { fontSize: "0.62rem", marginTop: "0.2rem", maxWidth: "120px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, title: order.rejectionReason, children: order.rejectionReason })
|
|
15439
15442
|
] }),
|
|
15440
15443
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatTimestamp(order.createdAt) }) }),
|
|
15441
|
-
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: order.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${order.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on
|
|
15444
|
+
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: order.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${order.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
15442
15445
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
15443
15446
|
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
15444
15447
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
@@ -15682,7 +15685,7 @@ function PortfolioActivityPanel({
|
|
|
15682
15685
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
|
|
15683
15686
|
formatNumber2(trade.quantity),
|
|
15684
15687
|
trade.ticker && /* @__PURE__ */ jsxRuntime.jsx(TickerTag, { style: { marginLeft: 0 }, children: trade.ticker.toUpperCase() }),
|
|
15685
|
-
trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15688
|
+
trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(ArbiscanIconLink, { url: `${_blockExplorerBaseUrl}/${trade.txHash}` })
|
|
15686
15689
|
] })
|
|
15687
15690
|
] }),
|
|
15688
15691
|
/* @__PURE__ */ jsxRuntime.jsxs(CUnitsCell, { children: [
|
|
@@ -15749,7 +15752,7 @@ function PortfolioActivityPanel({
|
|
|
15749
15752
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { children: formatCurrency4(trade.price * trade.quantity) }) }),
|
|
15750
15753
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: settlementMeta ? /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: "\u2014" }) }),
|
|
15751
15754
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatTimestamp(trade.executedAt) }) }),
|
|
15752
|
-
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on
|
|
15755
|
+
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
15753
15756
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
15754
15757
|
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
15755
15758
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
@@ -15796,7 +15799,7 @@ function PortfolioActivityPanel({
|
|
|
15796
15799
|
/* @__PURE__ */ jsxRuntime.jsx(CDValue, { children: formatTimestamp(t.createdAt) })
|
|
15797
15800
|
] })
|
|
15798
15801
|
] }),
|
|
15799
|
-
txUrl && /* @__PURE__ */ jsxRuntime.jsx(CExpandedLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: "View on
|
|
15802
|
+
txUrl && /* @__PURE__ */ jsxRuntime.jsx(CExpandedLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: "View on Arbiscan \u2197" })
|
|
15800
15803
|
] })
|
|
15801
15804
|
] }, rowKey);
|
|
15802
15805
|
}),
|
|
@@ -15822,7 +15825,7 @@ function PortfolioActivityPanel({
|
|
|
15822
15825
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatAddress(t.address) }) }),
|
|
15823
15826
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(ActivityTag, { $color: statusMeta.color, $bg: statusMeta.bg, children: prettyLabel(t.status) }) }),
|
|
15824
15827
|
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: /* @__PURE__ */ jsxRuntime.jsx(CellText, { $muted: true, children: formatTimestamp(t.createdAt) }) }),
|
|
15825
|
-
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: txUrl && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", title: "View on
|
|
15828
|
+
/* @__PURE__ */ jsxRuntime.jsx(GridCell, { children: txUrl && /* @__PURE__ */ jsxRuntime.jsx(TxLink, { href: txUrl, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
15826
15829
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
15827
15830
|
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
15828
15831
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
@@ -18925,13 +18928,14 @@ var CloseButton3 = styled10__default.default.button`
|
|
|
18925
18928
|
var MainImageContainer = styled10__default.default.div`
|
|
18926
18929
|
position: relative;
|
|
18927
18930
|
flex: 1;
|
|
18931
|
+
min-height: 0;
|
|
18928
18932
|
display: flex;
|
|
18929
18933
|
align-items: center;
|
|
18930
18934
|
justify-content: center;
|
|
18931
|
-
padding:
|
|
18935
|
+
padding: 20px 20px 160px;
|
|
18932
18936
|
|
|
18933
18937
|
@media (max-width: 768px) {
|
|
18934
|
-
padding:
|
|
18938
|
+
padding: 10px 0 130px;
|
|
18935
18939
|
}
|
|
18936
18940
|
`;
|
|
18937
18941
|
var MainImage = styled10__default.default.img`
|
|
@@ -18943,8 +18947,11 @@ var MainImage = styled10__default.default.img`
|
|
|
18943
18947
|
opacity: ${(p) => p.$visible ? 1 : 0};
|
|
18944
18948
|
pointer-events: ${(p) => p.$visible ? "auto" : "none"};
|
|
18945
18949
|
transition: opacity 300ms ease;
|
|
18946
|
-
/*
|
|
18947
|
-
|
|
18950
|
+
/* All slides share the same absolute box so switching only crossfades opacity —
|
|
18951
|
+
no relative↔absolute size jump (the "grow then shrink" on navigation).
|
|
18952
|
+
The inset box excludes the bottom thumbnail strip so margin:auto centres the image
|
|
18953
|
+
in the space ABOVE the thumbnails (absolute positioning ignores the parent's padding,
|
|
18954
|
+
which otherwise let the image sink behind the thumbnails / "lean down"). */
|
|
18948
18955
|
position: absolute;
|
|
18949
18956
|
top: 24px;
|
|
18950
18957
|
left: 24px;
|
|
@@ -19138,9 +19145,11 @@ function PropertyPhotoGallery({
|
|
|
19138
19145
|
isOpen,
|
|
19139
19146
|
onClose,
|
|
19140
19147
|
startIndex = 0,
|
|
19148
|
+
startWithVideo = false,
|
|
19141
19149
|
title = "28 Derby Street, Vaucluse",
|
|
19142
19150
|
subtitle = "Elara \u2014 Luxury Harbour Residence",
|
|
19143
|
-
images
|
|
19151
|
+
images,
|
|
19152
|
+
videoUrl
|
|
19144
19153
|
}) {
|
|
19145
19154
|
const galleryImages = images?.length ? images : DEFAULT_IMAGES;
|
|
19146
19155
|
if (!isOpen) return null;
|
|
@@ -19149,16 +19158,19 @@ function PropertyPhotoGallery({
|
|
|
19149
19158
|
{
|
|
19150
19159
|
galleryImages,
|
|
19151
19160
|
startIndex,
|
|
19161
|
+
startWithVideo,
|
|
19152
19162
|
title,
|
|
19153
19163
|
subtitle,
|
|
19154
|
-
onClose
|
|
19164
|
+
onClose,
|
|
19165
|
+
videoUrl
|
|
19155
19166
|
},
|
|
19156
|
-
`${startIndex}-${galleryImages.length}`
|
|
19167
|
+
`${startIndex}-${galleryImages.length}-${startWithVideo}`
|
|
19157
19168
|
);
|
|
19158
19169
|
}
|
|
19159
|
-
function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose }) {
|
|
19170
|
+
function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subtitle, onClose, videoUrl }) {
|
|
19160
19171
|
const [currentIndex, setCurrentIndex] = React5.useState(() => clampIndex(startIndex, galleryImages.length));
|
|
19161
19172
|
const [activeHotspotId, setActiveHotspotId] = React5.useState(null);
|
|
19173
|
+
const [showVideo, setShowVideo] = React5.useState(startWithVideo ?? false);
|
|
19162
19174
|
const sliderRef = React5.useRef(null);
|
|
19163
19175
|
const [isDragging, setIsDragging] = React5.useState(false);
|
|
19164
19176
|
const wasDraggingRef = React5.useRef(false);
|
|
@@ -19208,7 +19220,7 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
19208
19220
|
] }),
|
|
19209
19221
|
/* @__PURE__ */ jsxRuntime.jsx(CloseButton3, { onClick: onClose, "aria-label": "Close gallery", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 6l12 12M6 18L18 6" }) }) })
|
|
19210
19222
|
] }),
|
|
19211
|
-
/* @__PURE__ */ jsxRuntime.jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
19223
|
+
!showVideo && /* @__PURE__ */ jsxRuntime.jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
19212
19224
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
19213
19225
|
SliderTrack,
|
|
19214
19226
|
{
|
|
@@ -19271,7 +19283,21 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
19271
19283
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6" }) })
|
|
19272
19284
|
}
|
|
19273
19285
|
),
|
|
19274
|
-
|
|
19286
|
+
showVideo && videoUrl ? /* @__PURE__ */ jsxRuntime.jsx(GalleryVideoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
19287
|
+
"video",
|
|
19288
|
+
{
|
|
19289
|
+
autoPlay: true,
|
|
19290
|
+
loop: true,
|
|
19291
|
+
playsInline: true,
|
|
19292
|
+
muted: true,
|
|
19293
|
+
controls: true,
|
|
19294
|
+
onVolumeChange: (e) => {
|
|
19295
|
+
if (!e.currentTarget.muted) e.currentTarget.muted = true;
|
|
19296
|
+
},
|
|
19297
|
+
style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" },
|
|
19298
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("source", { src: videoUrl, type: "video/mp4" })
|
|
19299
|
+
}
|
|
19300
|
+
) }) : galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
|
|
19275
19301
|
galleryImages[currentIndex]?.hotspots?.map((hotspot) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
19276
19302
|
Hotspot,
|
|
19277
19303
|
{
|
|
@@ -19316,11 +19342,83 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
19316
19342
|
]
|
|
19317
19343
|
}
|
|
19318
19344
|
),
|
|
19319
|
-
/* @__PURE__ */ jsxRuntime.
|
|
19345
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: [
|
|
19346
|
+
galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(Thumbnail3, { $active: !showVideo && idx === currentIndex, onClick: () => {
|
|
19347
|
+
setShowVideo(false);
|
|
19348
|
+
setCurrentIndex(idx);
|
|
19349
|
+
}, "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: image.src, alt: image.alt }) }, image.alt)),
|
|
19350
|
+
videoUrl && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
19351
|
+
/* @__PURE__ */ jsxRuntime.jsx(ThumbnailDivider, {}),
|
|
19352
|
+
/* @__PURE__ */ jsxRuntime.jsxs(VideoBtn, { $active: showVideo, onClick: () => setShowVideo(true), children: [
|
|
19353
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
19354
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "4", width: "14", height: "16", rx: "2" }),
|
|
19355
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 8l6-4v16l-6-4z" })
|
|
19356
|
+
] }),
|
|
19357
|
+
"Video"
|
|
19358
|
+
] })
|
|
19359
|
+
] })
|
|
19360
|
+
] })
|
|
19320
19361
|
]
|
|
19321
19362
|
}
|
|
19322
19363
|
);
|
|
19323
19364
|
}
|
|
19365
|
+
var GalleryVideoWrap = styled10__default.default.div`
|
|
19366
|
+
position: absolute;
|
|
19367
|
+
inset: 0;
|
|
19368
|
+
display: flex;
|
|
19369
|
+
align-items: center;
|
|
19370
|
+
justify-content: center;
|
|
19371
|
+
padding: 20px 20px 160px;
|
|
19372
|
+
|
|
19373
|
+
video {
|
|
19374
|
+
max-width: 90%;
|
|
19375
|
+
max-height: 100%;
|
|
19376
|
+
}
|
|
19377
|
+
|
|
19378
|
+
/* Property videos stay permanently muted — remove the volume + mute buttons
|
|
19379
|
+
from the native player (Chrome/Edge/Safari/iOS/Android). Firefox ignores
|
|
19380
|
+
these and is covered by the onVolumeChange force-mute fallback. */
|
|
19381
|
+
video::-webkit-media-controls-mute-button,
|
|
19382
|
+
video::-webkit-media-controls-volume-slider,
|
|
19383
|
+
video::-webkit-media-controls-volume-control-container {
|
|
19384
|
+
display: none !important;
|
|
19385
|
+
}
|
|
19386
|
+
|
|
19387
|
+
@media (max-width: 768px) {
|
|
19388
|
+
padding: 10px 0 130px;
|
|
19389
|
+
|
|
19390
|
+
video {
|
|
19391
|
+
max-width: 100%;
|
|
19392
|
+
}
|
|
19393
|
+
}
|
|
19394
|
+
`;
|
|
19395
|
+
var ThumbnailDivider = styled10__default.default.div`
|
|
19396
|
+
width: 1px;
|
|
19397
|
+
height: 48px;
|
|
19398
|
+
background: rgba(255, 255, 255, 0.15);
|
|
19399
|
+
flex-shrink: 0;
|
|
19400
|
+
align-self: center;
|
|
19401
|
+
`;
|
|
19402
|
+
var VideoBtn = styled10__default.default.button`
|
|
19403
|
+
display: flex;
|
|
19404
|
+
align-items: center;
|
|
19405
|
+
gap: 6px;
|
|
19406
|
+
padding: 8px 14px;
|
|
19407
|
+
border-radius: 8px;
|
|
19408
|
+
border: 1px solid ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "rgba(255, 255, 255, 0.2)"};
|
|
19409
|
+
background: ${(p) => p.$active ? "rgba(240, 185, 11, 0.15)" : "rgba(255, 255, 255, 0.08)"};
|
|
19410
|
+
color: ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "#fff"};
|
|
19411
|
+
font-size: 0.82rem;
|
|
19412
|
+
font-weight: 500;
|
|
19413
|
+
cursor: pointer;
|
|
19414
|
+
flex-shrink: 0;
|
|
19415
|
+
transition: all 0.2s ease;
|
|
19416
|
+
|
|
19417
|
+
&:hover {
|
|
19418
|
+
background: rgba(255, 255, 255, 0.15);
|
|
19419
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
19420
|
+
}
|
|
19421
|
+
`;
|
|
19324
19422
|
var slideIn2 = styled10.keyframes`
|
|
19325
19423
|
from { transform: translateX(110%); opacity: 0; }
|
|
19326
19424
|
to { transform: translateX(0); opacity: 1; }
|
|
@@ -19489,7 +19587,7 @@ var Container3 = styled10__default.default.div`
|
|
|
19489
19587
|
gap: 8px;
|
|
19490
19588
|
}
|
|
19491
19589
|
`;
|
|
19492
|
-
var DEFAULT_EXPLORER = "https://sepolia.
|
|
19590
|
+
var DEFAULT_EXPLORER = "https://sepolia.arbiscan.io/tx/";
|
|
19493
19591
|
function truncateHash(hash) {
|
|
19494
19592
|
return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
|
|
19495
19593
|
}
|
|
@@ -20056,8 +20154,7 @@ var SiteFooter = () => {
|
|
|
20056
20154
|
/* @__PURE__ */ jsxRuntime.jsxs(LegalLinks, { children: [
|
|
20057
20155
|
/* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/privacy", children: "Privacy Policy" }),
|
|
20058
20156
|
/* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/terms", children: "Terms of Use" }),
|
|
20059
|
-
/* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" })
|
|
20060
|
-
/* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/risk", children: "Risk Warning" })
|
|
20157
|
+
/* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" })
|
|
20061
20158
|
] })
|
|
20062
20159
|
] }),
|
|
20063
20160
|
/* @__PURE__ */ jsxRuntime.jsx(Disclaimer2, { children: /* @__PURE__ */ jsxRuntime.jsx(DisclaimerText, { children: "Warning: Digital asset prices can be volatile. The value of your investment can go down or up and you may not get back the amount invested. Past gains are not indicative of future returns. You are solely responsible for your investment decisions and Loaf is not liable for any losses you may incur. The information here should not be regarded as financial or investment advice. For more information, see our Terms of Use and Risk Warning." }) })
|