@loafmarkets/ui 0.1.164 → 0.1.166
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 +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +57 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +57 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -758,8 +758,12 @@ type PropertyOverviewProps = {
|
|
|
758
758
|
volume24h?: number | null;
|
|
759
759
|
openOrdersValue?: number | null;
|
|
760
760
|
holderCount?: number | null;
|
|
761
|
+
priceHistory?: {
|
|
762
|
+
time: number;
|
|
763
|
+
close: number;
|
|
764
|
+
}[] | null;
|
|
761
765
|
};
|
|
762
|
-
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, volume24h, openOrdersValue, holderCount, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
766
|
+
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, volume24h, openOrdersValue, holderCount, priceHistory: priceHistoryProp, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
763
767
|
|
|
764
768
|
type OfferStatus = 'active' | 'rejected' | 'expired' | 'historical' | 'pending';
|
|
765
769
|
type PropertyOffer = {
|
package/dist/index.d.ts
CHANGED
|
@@ -758,8 +758,12 @@ type PropertyOverviewProps = {
|
|
|
758
758
|
volume24h?: number | null;
|
|
759
759
|
openOrdersValue?: number | null;
|
|
760
760
|
holderCount?: number | null;
|
|
761
|
+
priceHistory?: {
|
|
762
|
+
time: number;
|
|
763
|
+
close: number;
|
|
764
|
+
}[] | null;
|
|
761
765
|
};
|
|
762
|
-
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, volume24h, openOrdersValue, holderCount, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
766
|
+
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, volume24h, openOrdersValue, holderCount, priceHistory: priceHistoryProp, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
763
767
|
|
|
764
768
|
type OfferStatus = 'active' | 'rejected' | 'expired' | 'historical' | 'pending';
|
|
765
769
|
type PropertyOffer = {
|
package/dist/index.js
CHANGED
|
@@ -7972,6 +7972,7 @@ function GalleryMapSection({
|
|
|
7972
7972
|
const [showVideo, setShowVideo] = React5.useState(false);
|
|
7973
7973
|
const [autoPlaying, setAutoPlaying] = React5.useState(autoPlay);
|
|
7974
7974
|
const [showFullMap, setShowFullMap] = React5.useState(false);
|
|
7975
|
+
const [showFullVideo, setShowFullVideo] = React5.useState(false);
|
|
7975
7976
|
const resolvedMapUrl = mapUrl ?? (tokenName ? `/map/${tokenName}?embed=true&zoom=14&hideOthers=true` : "about:blank");
|
|
7976
7977
|
React5.useEffect(() => {
|
|
7977
7978
|
if (!autoPlaying || images.length <= 1) return;
|
|
@@ -8030,7 +8031,7 @@ function GalleryMapSection({
|
|
|
8030
8031
|
setCarouselIndex(actualIndex);
|
|
8031
8032
|
}, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: img.src, alt: img.title }) }, actualIndex);
|
|
8032
8033
|
}) }),
|
|
8033
|
-
|
|
8034
|
+
/* @__PURE__ */ jsxRuntime.jsx(ThumbDivider, {}),
|
|
8034
8035
|
/* @__PURE__ */ jsxRuntime.jsxs(FixedButtons, { children: [
|
|
8035
8036
|
floorplanIndex !== -1 && /* @__PURE__ */ jsxRuntime.jsxs(FixedBtn, { $active: isFloorplan, onClick: () => {
|
|
8036
8037
|
stopAutoPlay();
|
|
@@ -8044,9 +8045,13 @@ function GalleryMapSection({
|
|
|
8044
8045
|
] }),
|
|
8045
8046
|
"Floor Plan"
|
|
8046
8047
|
] }),
|
|
8047
|
-
videoUrl && /* @__PURE__ */ jsxRuntime.jsxs(FixedBtn, { $active:
|
|
8048
|
+
videoUrl && /* @__PURE__ */ jsxRuntime.jsxs(FixedBtn, { $active: false, onClick: () => setShowFullVideo(true), children: [
|
|
8048
8049
|
/* @__PURE__ */ jsxRuntime.jsx(bi.BiVideo, { size: 16 }),
|
|
8049
8050
|
" Video"
|
|
8051
|
+
] }),
|
|
8052
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FixedBtn, { $active: false, onClick: () => setShowFullMap(true), children: [
|
|
8053
|
+
/* @__PURE__ */ jsxRuntime.jsx(bi.BiMap, { size: 16 }),
|
|
8054
|
+
" Map View"
|
|
8050
8055
|
] })
|
|
8051
8056
|
] })
|
|
8052
8057
|
] }),
|
|
@@ -8115,7 +8120,8 @@ function GalleryMapSection({
|
|
|
8115
8120
|
/* @__PURE__ */ jsxRuntime.jsx(SuburbDesc, { children: "Premium harbourside suburb on Sydney's Lower North Shore. Known for heritage homes, village atmosphere, and proximity to Taronga Zoo and Balmoral Beach." })
|
|
8116
8121
|
] })
|
|
8117
8122
|
] }),
|
|
8118
|
-
showFullMap && /* @__PURE__ */ jsxRuntime.jsx(FullMapPopup, { onClose: () => setShowFullMap(false) })
|
|
8123
|
+
showFullMap && /* @__PURE__ */ jsxRuntime.jsx(FullMapPopup, { onClose: () => setShowFullMap(false) }),
|
|
8124
|
+
showFullVideo && videoUrl && /* @__PURE__ */ jsxRuntime.jsx(FullVideoPopup, { videoUrl, onClose: () => setShowFullVideo(false) })
|
|
8119
8125
|
] });
|
|
8120
8126
|
}
|
|
8121
8127
|
function FullMapPopup({ onClose }) {
|
|
@@ -8171,6 +8177,25 @@ function FullMapPopup({ onClose }) {
|
|
|
8171
8177
|
) })
|
|
8172
8178
|
] }) });
|
|
8173
8179
|
}
|
|
8180
|
+
function FullVideoPopup({ videoUrl, onClose }) {
|
|
8181
|
+
React5.useEffect(() => {
|
|
8182
|
+
const handleEsc = (e) => {
|
|
8183
|
+
if (e.key === "Escape") onClose();
|
|
8184
|
+
};
|
|
8185
|
+
window.addEventListener("keydown", handleEsc);
|
|
8186
|
+
return () => window.removeEventListener("keydown", handleEsc);
|
|
8187
|
+
}, [onClose]);
|
|
8188
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FullMapOverlay, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(FullMapPanel, { onClick: (e) => e.stopPropagation(), style: { maxWidth: 1e3 }, children: [
|
|
8189
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FullMapHeader, { children: [
|
|
8190
|
+
/* @__PURE__ */ jsxRuntime.jsxs(FullMapTitle, { children: [
|
|
8191
|
+
/* @__PURE__ */ jsxRuntime.jsx(bi.BiVideo, {}),
|
|
8192
|
+
" Property Video"
|
|
8193
|
+
] }),
|
|
8194
|
+
/* @__PURE__ */ jsxRuntime.jsx(FullMapClose, { onClick: onClose, "aria-label": "Close video", children: "\u2715" })
|
|
8195
|
+
] }),
|
|
8196
|
+
/* @__PURE__ */ jsxRuntime.jsx(FullVideoFrame, { children: /* @__PURE__ */ jsxRuntime.jsx("video", { autoPlay: true, loop: true, playsInline: true, controls: true, style: { width: "100%", height: "100%", objectFit: "contain", background: "#000", borderRadius: 8 }, children: /* @__PURE__ */ jsxRuntime.jsx("source", { src: videoUrl, type: "video/mp4" }) }) })
|
|
8197
|
+
] }) });
|
|
8198
|
+
}
|
|
8174
8199
|
var Row = styled9__default.default.div`
|
|
8175
8200
|
display: grid;
|
|
8176
8201
|
grid-template-columns: 2fr 1fr;
|
|
@@ -8393,6 +8418,14 @@ var FullMapFrame = styled9__default.default.div`
|
|
|
8393
8418
|
flex: 1;
|
|
8394
8419
|
min-height: 0;
|
|
8395
8420
|
`;
|
|
8421
|
+
var FullVideoFrame = styled9__default.default.div`
|
|
8422
|
+
flex: 1;
|
|
8423
|
+
min-height: 0;
|
|
8424
|
+
display: flex;
|
|
8425
|
+
align-items: center;
|
|
8426
|
+
justify-content: center;
|
|
8427
|
+
padding: 0 1rem 1rem;
|
|
8428
|
+
`;
|
|
8396
8429
|
var BedIcon = /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
8397
8430
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 4v16" }),
|
|
8398
8431
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 8h18a2 2 0 0 1 2 2v10" }),
|
|
@@ -8454,32 +8487,36 @@ function truncateAddress(addr) {
|
|
|
8454
8487
|
if (addr.length <= 12) return addr;
|
|
8455
8488
|
return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
|
|
8456
8489
|
}
|
|
8457
|
-
function generateDividendHistory(valuation, totalTokens, tokenPrice) {
|
|
8490
|
+
function generateDividendHistory(valuation, totalTokens, tokenPrice, realPriceHistory) {
|
|
8458
8491
|
if (valuation <= 0 || !totalTokens || !tokenPrice) return { records: [], priceHistory: [] };
|
|
8459
8492
|
const annualDiv = valuation * 0.02;
|
|
8460
8493
|
const monthlyDivPerShare = annualDiv / 12 / totalTokens;
|
|
8461
8494
|
const records = [];
|
|
8462
|
-
const priceHistory =
|
|
8495
|
+
const priceHistory = realPriceHistory?.length ? realPriceHistory.map((c) => ({ time: typeof c.time === "number" && c.time < 1e12 ? c.time * 1e3 : c.time, price: c.close })) : (() => {
|
|
8496
|
+
const pts = [];
|
|
8497
|
+
let price = tokenPrice * 0.84;
|
|
8498
|
+
for (let i = 365; i >= 0; i--) {
|
|
8499
|
+
const t = Date.now() - i * 864e5;
|
|
8500
|
+
const progress = (365 - i) / 365;
|
|
8501
|
+
const target = tokenPrice * (0.84 + progress * 0.16);
|
|
8502
|
+
price += (target - price) * 0.03 + (Math.random() - 0.5) * 0.8;
|
|
8503
|
+
price = Math.max(tokenPrice * 0.75, price);
|
|
8504
|
+
pts.push({ time: t, price: Math.round(price * 100) / 100 });
|
|
8505
|
+
}
|
|
8506
|
+
return pts;
|
|
8507
|
+
})();
|
|
8463
8508
|
const now = /* @__PURE__ */ new Date();
|
|
8464
|
-
let price = tokenPrice * 0.84;
|
|
8465
|
-
for (let i = 365; i >= 0; i--) {
|
|
8466
|
-
const t = Date.now() - i * 864e5;
|
|
8467
|
-
const progress = (365 - i) / 365;
|
|
8468
|
-
const target = tokenPrice * (0.84 + progress * 0.16);
|
|
8469
|
-
price += (target - price) * 0.03 + (Math.random() - 0.5) * 0.8;
|
|
8470
|
-
price = Math.max(tokenPrice * 0.75, price);
|
|
8471
|
-
priceHistory.push({ time: t, price: Math.round(price * 100) / 100 });
|
|
8472
|
-
}
|
|
8473
8509
|
for (let i = 11; i >= 0; i--) {
|
|
8474
8510
|
const exDate = new Date(now.getFullYear(), now.getMonth() - i, 1);
|
|
8475
8511
|
const exTime = exDate.getTime();
|
|
8476
8512
|
const closest = priceHistory.reduce((best, p) => Math.abs(p.time - exTime) < Math.abs(best.time - exTime) ? p : best);
|
|
8477
8513
|
const priceAtEx = closest.price;
|
|
8514
|
+
const annualisedYield = priceAtEx > 0 ? monthlyDivPerShare * 12 / priceAtEx * 100 : 2;
|
|
8478
8515
|
records.push({
|
|
8479
8516
|
exDate: exDate.toLocaleDateString("en-AU", { day: "2-digit", month: "short", year: "numeric" }),
|
|
8480
8517
|
payDate: new Date(exDate.getFullYear(), exDate.getMonth(), 15).toLocaleDateString("en-AU", { day: "2-digit", month: "short", year: "numeric" }),
|
|
8481
8518
|
perShare: monthlyDivPerShare,
|
|
8482
|
-
yieldPct:
|
|
8519
|
+
yieldPct: annualisedYield
|
|
8483
8520
|
});
|
|
8484
8521
|
}
|
|
8485
8522
|
return { records, priceHistory };
|
|
@@ -8513,7 +8550,8 @@ function PropertyOverview({
|
|
|
8513
8550
|
percentageTokenized,
|
|
8514
8551
|
volume24h,
|
|
8515
8552
|
openOrdersValue,
|
|
8516
|
-
holderCount
|
|
8553
|
+
holderCount,
|
|
8554
|
+
priceHistory: priceHistoryProp
|
|
8517
8555
|
}) {
|
|
8518
8556
|
const [isDescExpanded, setDescExpanded] = React5.useState(false);
|
|
8519
8557
|
const [showDividendHistory, setShowDividendHistory] = React5.useState(false);
|
|
@@ -8673,6 +8711,7 @@ function PropertyOverview({
|
|
|
8673
8711
|
totalTokens: resolvedTokensIssued,
|
|
8674
8712
|
tokenPrice: tokenPriceValue,
|
|
8675
8713
|
ticker,
|
|
8714
|
+
priceHistory: priceHistoryProp,
|
|
8676
8715
|
onClose: () => setShowDividendHistory(false)
|
|
8677
8716
|
}
|
|
8678
8717
|
),
|
|
@@ -8805,9 +8844,10 @@ function DividendHistoryPopup({
|
|
|
8805
8844
|
totalTokens,
|
|
8806
8845
|
tokenPrice,
|
|
8807
8846
|
ticker,
|
|
8847
|
+
priceHistory: realPriceHistory,
|
|
8808
8848
|
onClose
|
|
8809
8849
|
}) {
|
|
8810
|
-
const { records, priceHistory } = generateDividendHistory(valuation ?? 0, totalTokens ?? 0, tokenPrice ?? 0);
|
|
8850
|
+
const { records, priceHistory } = generateDividendHistory(valuation ?? 0, totalTokens ?? 0, tokenPrice ?? 0, realPriceHistory);
|
|
8811
8851
|
React5.useEffect(() => {
|
|
8812
8852
|
const handleEsc = (e) => {
|
|
8813
8853
|
if (e.key === "Escape") onClose();
|