@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.mjs CHANGED
@@ -8496,6 +8496,7 @@ function PropertyOverview({
8496
8496
  }) {
8497
8497
  const [isDescExpanded, setDescExpanded] = useState(false);
8498
8498
  const [showDividendHistory, setShowDividendHistory] = useState(false);
8499
+ const [copiedAddress, setCopiedAddress] = useState(false);
8499
8500
  const description = descriptionProp ?? overviewData?.description ?? DEFAULT_DESCRIPTION;
8500
8501
  const landSize = landProp ?? overviewData?.landSizeSqm ?? null;
8501
8502
  const buildingSize = buildingProp ?? overviewData?.buildingSizeSqm ?? null;
@@ -8545,7 +8546,7 @@ function PropertyOverview({
8545
8546
  ] });
8546
8547
  const tokenDetailsItems = [
8547
8548
  { label: "Chain", value: chainValue },
8548
- { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://basescan.org/address/${contractAddress}` : void 0 },
8549
+ { label: "On-Chain Address", value: contractAddress ? truncateAddress(contractAddress) : "\u2014", mono: true, link: contractAddress ? `https://basescan.org/address/${contractAddress}` : void 0, copyValue: contractAddress },
8549
8550
  { label: "Token Ticker", value: ticker ?? "\u2014" },
8550
8551
  { label: "Total Circulating Tokens", value: isLoading && resolvedTokensIssued == null ? loadingSkeleton : resolvedTokensIssued?.toLocaleString() ?? "\u2014" },
8551
8552
  { label: "Percentage Tokenized", value: percentageTokenized != null ? `${percentageTokenized}%` : "\u2014" },
@@ -8559,21 +8560,26 @@ function PropertyOverview({
8559
8560
  const holdPct = Math.max(0, Math.min(100, (1 - turnover) * 100));
8560
8561
  return { holdPct, tradePct: +(100 - holdPct).toFixed(1) };
8561
8562
  })();
8563
+ const fmtDollar = (v) => {
8564
+ if (v >= 1e6) return `$${(v / 1e6).toFixed(2)}M`;
8565
+ if (v >= 1e3) return `$${Math.round(v).toLocaleString()}`;
8566
+ return `$${v.toFixed(2)}`;
8567
+ };
8562
8568
  const tokenStats = [
8563
- { label: "Token Price", value: isLoading && tokenPriceValue == null ? loadingSkeleton : tokenPriceValue ? `$${tokenPriceValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014", gold: true },
8564
- { label: "24h Volume", value: isLoading && vol24hDollar == null ? loadingSkeleton : vol24hDollar != null && vol24hDollar > 0 ? `$${vol24hDollar.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014" },
8565
- { label: "Current Dividend Yield", value: isLoading && currentDividendYield == null ? loadingSkeleton : currentDividendYield ? `${currentDividendYield}%` : "\u2014" },
8566
- { label: "Open Orders", value: isLoading && openOrdersValue == null ? loadingSkeleton : openOrdersValue != null && openOrdersValue > 0 ? `$${openOrdersValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014" },
8567
- { label: "Token Holders", value: isLoading && holderCount == null ? loadingSkeleton : holderCount != null ? holderCount.toLocaleString() : "\u2014" }
8569
+ { label: "Token Price", value: isLoading && tokenPriceValue == null ? loadingSkeleton : tokenPriceValue ? `$${tokenPriceValue.toFixed(2)}` : "\u2014", gold: true },
8570
+ { label: "24h Volume", value: isLoading && vol24hDollar == null ? loadingSkeleton : vol24hDollar != null && vol24hDollar > 0 ? fmtDollar(vol24hDollar) : "\u2014" },
8571
+ { label: "Dividend Yield", value: isLoading && currentDividendYield == null ? loadingSkeleton : currentDividendYield ? `${currentDividendYield}%` : "\u2014" },
8572
+ { label: "Open Orders", value: isLoading && openOrdersValue == null ? loadingSkeleton : openOrdersValue != null && openOrdersValue > 0 ? fmtDollar(openOrdersValue) : "\u2014" },
8573
+ { label: "Holders", value: isLoading && holderCount == null ? loadingSkeleton : holderCount != null ? holderCount.toLocaleString() : "\u2014" }
8568
8574
  ];
8569
8575
  const annualDividend = resolvedValuation ? resolvedValuation * 0.02 : null;
8570
8576
  const monthlyDivPerShare = annualDividend && resolvedTokensIssued ? annualDividend / 12 / resolvedTokensIssued : null;
8571
8577
  const propertyStats = [
8572
- { label: "Property Value", value: isLoading && tokenMarketCap == null ? loadingSkeleton : tokenMarketCap ? tokenMarketCap >= 1e6 ? `$${(tokenMarketCap / 1e6).toFixed(1)}M` : `$${tokenMarketCap.toLocaleString()}` : "\u2014" },
8573
- { label: "Number of Offers", value: "3" },
8574
- { label: "Growth (Past 5 Years)", value: "+90%" },
8575
- { label: "Last Dividend", value: isLoading && monthlyDivPerShare == null ? loadingSkeleton : monthlyDivPerShare != null ? `${(monthlyDivPerShare * 100).toFixed(1)}c per Share` : "\u2014" },
8576
- { label: "Upcoming Dividend", value: (() => {
8578
+ { label: "Property Value", value: isLoading && tokenMarketCap == null ? loadingSkeleton : tokenMarketCap ? fmtDollar(tokenMarketCap) : "\u2014" },
8579
+ { label: "Offers", value: "3" },
8580
+ { label: "Growth (5yr)", value: "+90%" },
8581
+ { label: "Last Dividend", value: isLoading && monthlyDivPerShare == null ? loadingSkeleton : monthlyDivPerShare != null ? `$${monthlyDivPerShare.toFixed(2)}` : "\u2014" },
8582
+ { label: "Next Dividend", value: (() => {
8577
8583
  const now = /* @__PURE__ */ new Date();
8578
8584
  const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0);
8579
8585
  while (lastDay.getDay() === 0 || lastDay.getDay() === 6) lastDay.setDate(lastDay.getDate() - 1);
@@ -8599,7 +8605,24 @@ function PropertyOverview({
8599
8605
  /* @__PURE__ */ jsx(TokenDetailsTitle, { children: "Token Details" }),
8600
8606
  tokenDetailsItems.map((item) => /* @__PURE__ */ jsxs(TokenDetailRow, { children: [
8601
8607
  /* @__PURE__ */ jsx(TokenDetailLabel, { children: item.label }),
8602
- /* @__PURE__ */ jsx(TokenDetailValue, { $mono: !!item.mono, children: item.link ? /* @__PURE__ */ jsx("a", { href: item.link, target: "_blank", rel: "noopener noreferrer", style: { color: "#3380FF", textDecoration: "none" }, children: item.value }) : item.value })
8608
+ /* @__PURE__ */ jsxs(TokenDetailValue, { $mono: !!item.mono, children: [
8609
+ item.link ? /* @__PURE__ */ jsx("a", { href: item.link, target: "_blank", rel: "noopener noreferrer", style: { color: "#3380FF", textDecoration: "none" }, children: item.value }) : item.value,
8610
+ item.copyValue && /* @__PURE__ */ jsx(
8611
+ CopyBtn,
8612
+ {
8613
+ onClick: () => {
8614
+ navigator.clipboard.writeText(item.copyValue);
8615
+ setCopiedAddress(true);
8616
+ setTimeout(() => setCopiedAddress(false), 1500);
8617
+ },
8618
+ title: copiedAddress ? "Copied!" : "Copy address",
8619
+ children: copiedAddress ? /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" }) }) : /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
8620
+ /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
8621
+ /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
8622
+ ] })
8623
+ }
8624
+ )
8625
+ ] })
8603
8626
  ] }, item.label))
8604
8627
  ] }),
8605
8628
  /* @__PURE__ */ jsxs(TrustBadgesCard, { children: [
@@ -8614,7 +8637,7 @@ function PropertyOverview({
8614
8637
  /* @__PURE__ */ jsx(TrustBadgeLabel, { children: "Land Title" })
8615
8638
  ] }),
8616
8639
  /* @__PURE__ */ jsxs(TrustBadge, { children: [
8617
- /* @__PURE__ */ jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsx("img", { src: "/savills.png", alt: "Savills", style: { height: 38, borderRadius: 3, opacity: 0.85 } }) }),
8640
+ /* @__PURE__ */ jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsx("img", { src: "/savills.png", alt: "Savills", style: { height: 38, borderRadius: 3, filter: "grayscale(1) brightness(1.2) contrast(1.6)", opacity: 0.7 } }) }),
8618
8641
  /* @__PURE__ */ jsx(TrustBadgeLabel, { children: "Valuation" })
8619
8642
  ] })
8620
8643
  ] })
@@ -9307,6 +9330,18 @@ var TrustBadgeLabel = styled9.span`
9307
9330
  font-weight: 400;
9308
9331
  text-align: center;
9309
9332
  `;
9333
+ var CopyBtn = styled9.button`
9334
+ background: none;
9335
+ border: none;
9336
+ color: rgba(255,255,255,0.3);
9337
+ cursor: pointer;
9338
+ padding: 2px;
9339
+ margin-left: 6px;
9340
+ display: inline-flex;
9341
+ align-items: center;
9342
+ transition: color 0.15s;
9343
+ &:hover { color: rgba(255,255,255,0.7); }
9344
+ `;
9310
9345
  var ChainLogos = styled9.span`
9311
9346
  display: inline-flex;
9312
9347
  align-items: center;