@loafmarkets/ui 0.1.191 → 0.1.193

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.js CHANGED
@@ -8522,6 +8522,7 @@ function PropertyOverview({
8522
8522
  }) {
8523
8523
  const [isDescExpanded, setDescExpanded] = React5.useState(false);
8524
8524
  const [showDividendHistory, setShowDividendHistory] = React5.useState(false);
8525
+ const [copiedAddress, setCopiedAddress] = React5.useState(false);
8525
8526
  const description = descriptionProp ?? overviewData?.description ?? DEFAULT_DESCRIPTION;
8526
8527
  const landSize = landProp ?? overviewData?.landSizeSqm ?? null;
8527
8528
  const buildingSize = buildingProp ?? overviewData?.buildingSizeSqm ?? null;
@@ -8571,7 +8572,7 @@ function PropertyOverview({
8571
8572
  ] });
8572
8573
  const tokenDetailsItems = [
8573
8574
  { label: "Chain", value: chainValue },
8574
- { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://basescan.org/address/${contractAddress}` : void 0 },
8575
+ { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://basescan.org/address/${contractAddress}` : void 0, copyValue: contractAddress },
8575
8576
  { label: "Token Ticker", value: ticker ?? "\u2014" },
8576
8577
  { label: "Total Circulating Tokens", value: isLoading && resolvedTokensIssued == null ? loadingSkeleton : resolvedTokensIssued?.toLocaleString() ?? "\u2014" },
8577
8578
  { label: "Percentage Tokenized", value: percentageTokenized != null ? `${percentageTokenized}%` : "\u2014" },
@@ -8585,21 +8586,26 @@ function PropertyOverview({
8585
8586
  const holdPct = Math.max(0, Math.min(100, (1 - turnover) * 100));
8586
8587
  return { holdPct, tradePct: +(100 - holdPct).toFixed(1) };
8587
8588
  })();
8589
+ const fmtDollar = (v) => {
8590
+ if (v >= 1e6) return `$${(v / 1e6).toFixed(2)}M`;
8591
+ if (v >= 1e3) return `$${Math.round(v).toLocaleString()}`;
8592
+ return `$${v.toFixed(2)}`;
8593
+ };
8588
8594
  const tokenStats = [
8589
- { label: "Token Price", value: isLoading && tokenPriceValue == null ? loadingSkeleton : tokenPriceValue ? `$${tokenPriceValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014", gold: true },
8590
- { label: "24h Volume", value: isLoading && vol24hDollar == null ? loadingSkeleton : vol24hDollar != null && vol24hDollar > 0 ? `$${vol24hDollar.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014" },
8591
- { label: "Current Dividend Yield", value: isLoading && currentDividendYield == null ? loadingSkeleton : currentDividendYield ? `${currentDividendYield}%` : "\u2014" },
8592
- { label: "Open Orders", value: isLoading && openOrdersValue == null ? loadingSkeleton : openOrdersValue != null && openOrdersValue > 0 ? `$${openOrdersValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014" },
8593
- { label: "Token Holders", value: isLoading && holderCount == null ? loadingSkeleton : holderCount != null ? holderCount.toLocaleString() : "\u2014" }
8595
+ { label: "Token Price", value: isLoading && tokenPriceValue == null ? loadingSkeleton : tokenPriceValue ? `$${tokenPriceValue.toFixed(2)}` : "\u2014", gold: true },
8596
+ { label: "24h Volume", value: isLoading && vol24hDollar == null ? loadingSkeleton : vol24hDollar != null && vol24hDollar > 0 ? fmtDollar(vol24hDollar) : "\u2014" },
8597
+ { label: "Dividend Yield", value: isLoading && currentDividendYield == null ? loadingSkeleton : currentDividendYield ? `${currentDividendYield}%` : "\u2014" },
8598
+ { label: "Open Orders", value: isLoading && openOrdersValue == null ? loadingSkeleton : openOrdersValue != null && openOrdersValue > 0 ? fmtDollar(openOrdersValue) : "\u2014" },
8599
+ { label: "Holders", value: isLoading && holderCount == null ? loadingSkeleton : holderCount != null ? holderCount.toLocaleString() : "\u2014" }
8594
8600
  ];
8595
8601
  const annualDividend = resolvedValuation ? resolvedValuation * 0.02 : null;
8596
8602
  const monthlyDivPerShare = annualDividend && resolvedTokensIssued ? annualDividend / 12 / resolvedTokensIssued : null;
8597
8603
  const propertyStats = [
8598
- { label: "Property Value", value: isLoading && tokenMarketCap == null ? loadingSkeleton : tokenMarketCap ? tokenMarketCap >= 1e6 ? `$${(tokenMarketCap / 1e6).toFixed(1)}M` : `$${tokenMarketCap.toLocaleString()}` : "\u2014" },
8599
- { label: "Number of Offers", value: "3" },
8600
- { label: "Growth (Past 5 Years)", value: "+90%" },
8601
- { label: "Last Dividend", value: isLoading && monthlyDivPerShare == null ? loadingSkeleton : monthlyDivPerShare != null ? `${(monthlyDivPerShare * 100).toFixed(1)}c per Share` : "\u2014" },
8602
- { label: "Upcoming Dividend", value: (() => {
8604
+ { label: "Property Value", value: isLoading && tokenMarketCap == null ? loadingSkeleton : tokenMarketCap ? fmtDollar(tokenMarketCap) : "\u2014" },
8605
+ { label: "Offers", value: "3" },
8606
+ { label: "Growth (5yr)", value: "+90%" },
8607
+ { label: "Last Dividend", value: isLoading && monthlyDivPerShare == null ? loadingSkeleton : monthlyDivPerShare != null ? `$${monthlyDivPerShare.toFixed(2)}` : "\u2014" },
8608
+ { label: "Next Dividend", value: (() => {
8603
8609
  const now = /* @__PURE__ */ new Date();
8604
8610
  const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
8605
8611
  while (lastDay.getDay() === 0 || lastDay.getDay() === 6) lastDay.setDate(lastDay.getDate() - 1);
@@ -8625,7 +8631,24 @@ function PropertyOverview({
8625
8631
  /* @__PURE__ */ jsxRuntime.jsx(TokenDetailsTitle, { children: "Token Details" }),
8626
8632
  tokenDetailsItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailRow, { children: [
8627
8633
  /* @__PURE__ */ jsxRuntime.jsx(TokenDetailLabel, { children: item.label }),
8628
- /* @__PURE__ */ jsxRuntime.jsx(TokenDetailValue, { $mono: !!item.mono, children: item.link ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.link, target: "_blank", rel: "noopener noreferrer", style: { color: "#3380FF", textDecoration: "none" }, children: item.value }) : item.value })
8634
+ /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailValue, { $mono: !!item.mono, children: [
8635
+ item.link ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.link, target: "_blank", rel: "noopener noreferrer", style: { color: "#3380FF", textDecoration: "none" }, children: item.value }) : item.value,
8636
+ item.copyValue && /* @__PURE__ */ jsxRuntime.jsx(
8637
+ CopyBtn,
8638
+ {
8639
+ onClick: () => {
8640
+ navigator.clipboard.writeText(item.copyValue);
8641
+ setCopiedAddress(true);
8642
+ setTimeout(() => setCopiedAddress(false), 1500);
8643
+ },
8644
+ title: copiedAddress ? "Copied!" : "Copy address",
8645
+ children: copiedAddress ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
8646
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
8647
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
8648
+ ] })
8649
+ }
8650
+ )
8651
+ ] })
8629
8652
  ] }, item.label))
8630
8653
  ] }),
8631
8654
  /* @__PURE__ */ jsxRuntime.jsxs(TrustBadgesCard, { children: [
@@ -8640,7 +8663,7 @@ function PropertyOverview({
8640
8663
  /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLabel, { children: "Land Title" })
8641
8664
  ] }),
8642
8665
  /* @__PURE__ */ jsxRuntime.jsxs(TrustBadge, { children: [
8643
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: "/savills.png", alt: "Savills", style: { height: 38, borderRadius: 3, opacity: 0.85 } }) }),
8666
+ /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: "/savills.png", alt: "Savills", style: { height: 38, borderRadius: 3, filter: "grayscale(1) brightness(1.2) contrast(1.6)", opacity: 0.7 } }) }),
8644
8667
  /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLabel, { children: "Valuation" })
8645
8668
  ] })
8646
8669
  ] })
@@ -9333,6 +9356,18 @@ var TrustBadgeLabel = styled9__default.default.span`
9333
9356
  font-weight: 400;
9334
9357
  text-align: center;
9335
9358
  `;
9359
+ var CopyBtn = styled9__default.default.button`
9360
+ background: none;
9361
+ border: none;
9362
+ color: rgba(255,255,255,0.3);
9363
+ cursor: pointer;
9364
+ padding: 2px;
9365
+ margin-left: 6px;
9366
+ display: inline-flex;
9367
+ align-items: center;
9368
+ transition: color 0.15s;
9369
+ &:hover { color: rgba(255,255,255,0.7); }
9370
+ `;
9336
9371
  var ChainLogos = styled9__default.default.span`
9337
9372
  display: inline-flex;
9338
9373
  align-items: center;