@loafmarkets/ui 0.1.13 → 0.1.16
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 +90 -4
- package/dist/index.d.ts +90 -4
- package/dist/index.js +546 -152
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +546 -154
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3374,6 +3374,7 @@ var YourOrders = React5__namespace.forwardRef(
|
|
|
3374
3374
|
onTabChange,
|
|
3375
3375
|
renderOrderActions,
|
|
3376
3376
|
renderTabContent,
|
|
3377
|
+
pageSize: pageSizeOverride,
|
|
3377
3378
|
...props
|
|
3378
3379
|
}, ref) => {
|
|
3379
3380
|
const [internalActiveTab, setInternalActiveTab] = React5__namespace.useState(tabs?.[0]?.id ?? "portfolio");
|
|
@@ -3394,7 +3395,8 @@ var YourOrders = React5__namespace.forwardRef(
|
|
|
3394
3395
|
const activeOrders = activeTab?.orders ?? orders ?? [];
|
|
3395
3396
|
const DEFAULT_PAGE_SIZE = 5;
|
|
3396
3397
|
const HISTORY_PAGE_SIZE = 3;
|
|
3397
|
-
const
|
|
3398
|
+
const resolvedPageSize = pageSizeOverride ?? (activeTab?.id === "order-history" || activeTab?.id === "trade-history" ? HISTORY_PAGE_SIZE : DEFAULT_PAGE_SIZE);
|
|
3399
|
+
const pageSize = Math.max(1, resolvedPageSize);
|
|
3398
3400
|
const totalOrders = activeOrders.length;
|
|
3399
3401
|
const totalPages = Math.max(1, Math.ceil(totalOrders / pageSize));
|
|
3400
3402
|
const safePage = Math.min(page, totalPages - 1);
|
|
@@ -4090,6 +4092,10 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
|
|
|
4090
4092
|
propertyTypeLabel,
|
|
4091
4093
|
onTrade,
|
|
4092
4094
|
onMakeOffer,
|
|
4095
|
+
tradeButtonLabel = "Trade",
|
|
4096
|
+
makeOfferButtonLabel = "Make Offer",
|
|
4097
|
+
makeOfferDisabled = false,
|
|
4098
|
+
hideMakeOfferButton = false,
|
|
4093
4099
|
...props
|
|
4094
4100
|
}, ref) => {
|
|
4095
4101
|
const isPositive = changePercent == null ? void 0 : changePercent >= 0;
|
|
@@ -4098,6 +4104,17 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
|
|
|
4098
4104
|
const [isTradeInteracting, setIsTradeInteracting] = React5__namespace.useState(false);
|
|
4099
4105
|
const [isOfferInteracting, setIsOfferInteracting] = React5__namespace.useState(false);
|
|
4100
4106
|
const hasAmenities = beds != null || baths != null || cars != null || propertyTypeLabel != null;
|
|
4107
|
+
const isTradeDisabled = !onTrade;
|
|
4108
|
+
const isMakeOfferButtonDisabled = makeOfferDisabled || !onMakeOffer;
|
|
4109
|
+
const showMakeOfferButton = !hideMakeOfferButton;
|
|
4110
|
+
const setTradeInteraction = (state) => {
|
|
4111
|
+
if (isTradeDisabled) return;
|
|
4112
|
+
setIsTradeInteracting(state);
|
|
4113
|
+
};
|
|
4114
|
+
const setOfferInteraction = (state) => {
|
|
4115
|
+
if (isMakeOfferButtonDisabled) return;
|
|
4116
|
+
setIsOfferInteracting(state);
|
|
4117
|
+
};
|
|
4101
4118
|
const headingStyle = {
|
|
4102
4119
|
fontSize: "clamp(1.6rem, 4vw, 2.5rem)",
|
|
4103
4120
|
marginBottom: "0.5rem",
|
|
@@ -4182,54 +4199,60 @@ var PropertyHeroHeader = React5__namespace.forwardRef(
|
|
|
4182
4199
|
"button",
|
|
4183
4200
|
{
|
|
4184
4201
|
type: "button",
|
|
4185
|
-
onClick: onTrade,
|
|
4202
|
+
onClick: isTradeDisabled ? void 0 : onTrade,
|
|
4186
4203
|
className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
|
|
4187
4204
|
style: {
|
|
4188
4205
|
backgroundColor: isTradeInteracting ? tradeHoverColor : accentColor,
|
|
4189
4206
|
color: "black",
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
minWidth: "88.06px",
|
|
4207
|
+
minWidth: "140px",
|
|
4208
|
+
padding: "0.65rem 1.5rem",
|
|
4193
4209
|
borderColor: isTradeInteracting ? accentColor : "transparent",
|
|
4194
|
-
boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none"
|
|
4210
|
+
boxShadow: isTradeInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
|
|
4211
|
+
opacity: isTradeDisabled ? 0.5 : 1,
|
|
4212
|
+
cursor: isTradeDisabled ? "not-allowed" : "pointer"
|
|
4195
4213
|
},
|
|
4196
|
-
onMouseEnter: () =>
|
|
4197
|
-
onMouseLeave: () =>
|
|
4198
|
-
onMouseDown: () =>
|
|
4199
|
-
onMouseUp: () =>
|
|
4200
|
-
onFocus: () =>
|
|
4201
|
-
onBlur: () =>
|
|
4202
|
-
onTouchStart: () =>
|
|
4203
|
-
onTouchEnd: () =>
|
|
4204
|
-
|
|
4214
|
+
onMouseEnter: () => setTradeInteraction(true),
|
|
4215
|
+
onMouseLeave: () => setTradeInteraction(false),
|
|
4216
|
+
onMouseDown: () => setTradeInteraction(true),
|
|
4217
|
+
onMouseUp: () => setTradeInteraction(false),
|
|
4218
|
+
onFocus: () => setTradeInteraction(true),
|
|
4219
|
+
onBlur: () => setTradeInteraction(false),
|
|
4220
|
+
onTouchStart: () => setTradeInteraction(true),
|
|
4221
|
+
onTouchEnd: () => setTradeInteraction(false),
|
|
4222
|
+
disabled: isTradeDisabled,
|
|
4223
|
+
"aria-disabled": isTradeDisabled,
|
|
4224
|
+
children: tradeButtonLabel
|
|
4205
4225
|
}
|
|
4206
4226
|
),
|
|
4207
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4227
|
+
showMakeOfferButton ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4208
4228
|
"button",
|
|
4209
4229
|
{
|
|
4210
4230
|
type: "button",
|
|
4211
|
-
onClick: onMakeOffer,
|
|
4231
|
+
onClick: isMakeOfferButtonDisabled ? void 0 : onMakeOffer,
|
|
4212
4232
|
className: "flex items-center justify-center rounded border font-semibold transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_4px_8px_rgba(0,0,0,0.2)] active:translate-y-0 active:shadow-[0_2px_4px_rgba(0,0,0,0.1)] text-[0.95rem] max-[480px]:text-[0.9rem]",
|
|
4213
4233
|
style: {
|
|
4214
4234
|
backgroundColor: isOfferInteracting ? accentColor : "transparent",
|
|
4215
4235
|
borderColor: accentColor,
|
|
4216
4236
|
color: isOfferInteracting ? "black" : accentColor,
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4237
|
+
minWidth: "140px",
|
|
4238
|
+
padding: "0.65rem 1.5rem",
|
|
4239
|
+
boxShadow: isOfferInteracting ? `0 0 0 2px rgba(0,0,0,0.4), 0 0 0 4px ${accentColor}` : "none",
|
|
4240
|
+
opacity: isMakeOfferButtonDisabled ? 0.5 : 1,
|
|
4241
|
+
cursor: isMakeOfferButtonDisabled ? "not-allowed" : "pointer"
|
|
4221
4242
|
},
|
|
4222
|
-
onMouseEnter: () =>
|
|
4223
|
-
onMouseLeave: () =>
|
|
4224
|
-
onMouseDown: () =>
|
|
4225
|
-
onMouseUp: () =>
|
|
4226
|
-
onFocus: () =>
|
|
4227
|
-
onBlur: () =>
|
|
4228
|
-
onTouchStart: () =>
|
|
4229
|
-
onTouchEnd: () =>
|
|
4230
|
-
|
|
4243
|
+
onMouseEnter: () => setOfferInteraction(true),
|
|
4244
|
+
onMouseLeave: () => setOfferInteraction(false),
|
|
4245
|
+
onMouseDown: () => setOfferInteraction(true),
|
|
4246
|
+
onMouseUp: () => setOfferInteraction(false),
|
|
4247
|
+
onFocus: () => setOfferInteraction(true),
|
|
4248
|
+
onBlur: () => setOfferInteraction(false),
|
|
4249
|
+
onTouchStart: () => setOfferInteraction(true),
|
|
4250
|
+
onTouchEnd: () => setOfferInteraction(false),
|
|
4251
|
+
disabled: isMakeOfferButtonDisabled,
|
|
4252
|
+
"aria-disabled": isMakeOfferButtonDisabled,
|
|
4253
|
+
children: makeOfferButtonLabel
|
|
4231
4254
|
}
|
|
4232
|
-
)
|
|
4255
|
+
) : null
|
|
4233
4256
|
] })
|
|
4234
4257
|
] })
|
|
4235
4258
|
] }),
|
|
@@ -4535,10 +4558,22 @@ var Header = ({
|
|
|
4535
4558
|
closeMenus();
|
|
4536
4559
|
console.log("[Header] Add funding selected");
|
|
4537
4560
|
if (LoginPopupComponent) {
|
|
4538
|
-
setLoginPopupInitialView(
|
|
4561
|
+
setLoginPopupInitialView("funding");
|
|
4539
4562
|
setShowLoginPopup(true);
|
|
4540
4563
|
}
|
|
4541
4564
|
};
|
|
4565
|
+
const handlePortfolioNavigate = (event) => {
|
|
4566
|
+
event?.preventDefault();
|
|
4567
|
+
closeMenus();
|
|
4568
|
+
console.log("[Header] Portfolio selected");
|
|
4569
|
+
if (_onOrdersNavigate) {
|
|
4570
|
+
_onOrdersNavigate();
|
|
4571
|
+
return;
|
|
4572
|
+
}
|
|
4573
|
+
if (onNavigate) {
|
|
4574
|
+
onNavigate("/portfolio");
|
|
4575
|
+
}
|
|
4576
|
+
};
|
|
4542
4577
|
const userPrimaryLabel = currentUser?.displayName?.trim() || "User";
|
|
4543
4578
|
const resolveAuthReturnUrl = () => {
|
|
4544
4579
|
if (getAuthReturnUrl) {
|
|
@@ -4750,14 +4785,13 @@ var Header = ({
|
|
|
4750
4785
|
),
|
|
4751
4786
|
isUserMenuOpen && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { className: "user-menu-dropdown", children: [
|
|
4752
4787
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4753
|
-
"
|
|
4788
|
+
"button",
|
|
4754
4789
|
{
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
textAlign: "left"
|
|
4790
|
+
type: "button",
|
|
4791
|
+
onClick: (event) => {
|
|
4792
|
+
handlePortfolioNavigate(event);
|
|
4759
4793
|
},
|
|
4760
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4794
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(MenuItem, { children: "Portfolio" })
|
|
4761
4795
|
}
|
|
4762
4796
|
),
|
|
4763
4797
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6724,27 +6758,55 @@ var PriceChange = styled23__default.default.span`
|
|
|
6724
6758
|
gap: 0.35rem;
|
|
6725
6759
|
color: ${(props) => props.$isPositive == null ? "var(--color-text-secondary, rgba(255, 255, 255, 0.6))" : props.$isPositive ? "var(--color-positive, #0ecb81)" : "var(--color-negative, #f6465d)"};
|
|
6726
6760
|
`;
|
|
6727
|
-
function PropertyOverview({
|
|
6761
|
+
function PropertyOverview({
|
|
6762
|
+
propertyName: _propertyName,
|
|
6763
|
+
location: _location,
|
|
6764
|
+
midPrice: _midPrice,
|
|
6765
|
+
onTradeClick: _onTradeClick,
|
|
6766
|
+
overviewData,
|
|
6767
|
+
minimumParticipation,
|
|
6768
|
+
bedrooms,
|
|
6769
|
+
bathrooms,
|
|
6770
|
+
carSpaces,
|
|
6771
|
+
propertyTypeLabel
|
|
6772
|
+
}) {
|
|
6773
|
+
const description = overviewData?.description ?? "N/A";
|
|
6774
|
+
const tokensIssued = overviewData?.tokensIssued ?? null;
|
|
6775
|
+
const offeringValuation = overviewData?.offeringValuation ?? null;
|
|
6776
|
+
const weeklyRent = overviewData?.weeklyRent ?? null;
|
|
6777
|
+
const indicativeListing = overviewData?.indicativeListing ?? "N/A";
|
|
6778
|
+
const minParticipationValue = minimumParticipation ?? overviewData?.minimumParticipation ?? null;
|
|
6779
|
+
const landSize = overviewData?.landSizeSqm ?? null;
|
|
6780
|
+
const buildingSize = overviewData?.buildingSizeSqm ?? null;
|
|
6781
|
+
const propertyType = propertyTypeLabel ?? overviewData?.propertyType ?? "N/A";
|
|
6782
|
+
overviewData?.yearBuilt ?? null;
|
|
6783
|
+
const ownership = overviewData?.ownership ?? "N/A";
|
|
6784
|
+
const zoning = overviewData?.zoning ?? "N/A";
|
|
6785
|
+
const levels = overviewData?.levels ?? null;
|
|
6786
|
+
const daStatus = overviewData?.daStatus ?? "N/A";
|
|
6787
|
+
const unitPrice = tokensIssued && offeringValuation ? offeringValuation / tokensIssued : null;
|
|
6788
|
+
const formattedPropertyType = propertyType !== "N/A" ? propertyType.charAt(0).toUpperCase() + propertyType.slice(1).toLowerCase() : "N/A";
|
|
6728
6789
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6729
6790
|
/* @__PURE__ */ jsxRuntime.jsxs(TwoColGrid, { children: [
|
|
6730
6791
|
/* @__PURE__ */ jsxRuntime.jsxs(Section, { children: [
|
|
6731
6792
|
/* @__PURE__ */ jsxRuntime.jsx(SectionHeading, { children: "About This Property" }),
|
|
6732
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6733
|
-
|
|
6734
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6793
|
+
/* @__PURE__ */ jsxRuntime.jsx(BodyText, { children: description === "N/A" ? description : description.split("\n\n").map((paragraph, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
6794
|
+
paragraph,
|
|
6795
|
+
i < description.split("\n\n").length - 1 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6796
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
6797
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {})
|
|
6798
|
+
] })
|
|
6799
|
+
] }, i)) })
|
|
6738
6800
|
] }),
|
|
6739
6801
|
/* @__PURE__ */ jsxRuntime.jsxs(Section, { children: [
|
|
6740
6802
|
/* @__PURE__ */ jsxRuntime.jsx(SectionHeading, { children: "The Offering" }),
|
|
6741
6803
|
/* @__PURE__ */ jsxRuntime.jsx(OfferingGrid, { children: [
|
|
6742
|
-
{ label: "Units Issued", value: "
|
|
6743
|
-
{ label: "Issue Price", value:
|
|
6744
|
-
{ label: "Implied Value", value: "
|
|
6745
|
-
{ label: "Minimum Participation", value: "
|
|
6746
|
-
{ label: "Est. Cash Flow", value:
|
|
6747
|
-
{ label: "Indicative Listing Date", value:
|
|
6804
|
+
{ label: "Units Issued", value: tokensIssued?.toLocaleString() ?? "-", gold: false },
|
|
6805
|
+
{ label: "Issue Price", value: unitPrice ? `$${unitPrice.toFixed(2)} / Unit` : "-", gold: true },
|
|
6806
|
+
{ label: "Implied Value", value: offeringValuation ? `$${offeringValuation.toLocaleString()}` : "-", gold: false },
|
|
6807
|
+
{ label: "Minimum Participation", value: minParticipationValue != null ? `$${minParticipationValue.toLocaleString()}` : "-", gold: false },
|
|
6808
|
+
{ label: "Est. Cash Flow", value: weeklyRent ? `$${weeklyRent.toLocaleString()}/wk` : "-", gold: true },
|
|
6809
|
+
{ label: "Indicative Listing Date", value: indicativeListing, gold: false }
|
|
6748
6810
|
].map(({ label, value, gold }) => /* @__PURE__ */ jsxRuntime.jsxs(OfferingItem, { children: [
|
|
6749
6811
|
/* @__PURE__ */ jsxRuntime.jsx(OfferingLabel, { children: label }),
|
|
6750
6812
|
/* @__PURE__ */ jsxRuntime.jsx(OfferingValue, { $gold: gold, children: value })
|
|
@@ -6757,10 +6819,10 @@ function PropertyOverview({ propertyName: _propertyName, location: _location, mi
|
|
|
6757
6819
|
/* @__PURE__ */ jsxRuntime.jsx(AssetDetailsTitle, { children: "Asset Details" })
|
|
6758
6820
|
] }),
|
|
6759
6821
|
/* @__PURE__ */ jsxRuntime.jsx(StatGrid, { children: [
|
|
6760
|
-
{ label: "Bedrooms", value: "
|
|
6761
|
-
{ label: "Bathrooms", value: "
|
|
6762
|
-
{ type: "dual", label1: "Land", value1: "
|
|
6763
|
-
{ label: "Car Spaces", value: "
|
|
6822
|
+
{ label: "Bedrooms", value: bedrooms != null ? bedrooms.toString() : "-", icon: "\u{1F6CF}\uFE0F" },
|
|
6823
|
+
{ label: "Bathrooms", value: bathrooms != null ? bathrooms.toString() : "-", icon: "\u{1F6BF}" },
|
|
6824
|
+
{ type: "dual", label1: "Land", value1: landSize?.toString() ?? "-", label2: "Floor", value2: buildingSize?.toString() ?? "-", unit: "sqm", highlight: true },
|
|
6825
|
+
{ label: "Car Spaces", value: carSpaces != null ? carSpaces.toString() : "-", icon: "\u{1F697}" }
|
|
6764
6826
|
].map((stat, i) => /* @__PURE__ */ jsxRuntime.jsx(StatCard, { $highlight: !!stat.highlight, children: stat.type === "dual" ? /* @__PURE__ */ jsxRuntime.jsxs(DualStatInner, { children: [
|
|
6765
6827
|
/* @__PURE__ */ jsxRuntime.jsxs(DualStatCol, { children: [
|
|
6766
6828
|
/* @__PURE__ */ jsxRuntime.jsx(StatLabel, { $gold: true, children: stat.label1 }),
|
|
@@ -6782,14 +6844,14 @@ function PropertyOverview({ propertyName: _propertyName, location: _location, mi
|
|
|
6782
6844
|
/* @__PURE__ */ jsxRuntime.jsx(StatBigValue, { $gold: !!stat.highlight, children: stat.value })
|
|
6783
6845
|
] }) }, i)) }),
|
|
6784
6846
|
/* @__PURE__ */ jsxRuntime.jsx(DetailTable, { children: /* @__PURE__ */ jsxRuntime.jsx(DetailTableGrid, { children: [
|
|
6785
|
-
{ label: "Last Sale", value: "
|
|
6786
|
-
{ label: "Suburb Median", value: "
|
|
6787
|
-
{ label: "Replication Cost of Architecture", value: "
|
|
6788
|
-
{ label: "DA Status", value: "
|
|
6789
|
-
{ label: "Property Type", value:
|
|
6790
|
-
{ label: "Ownership", value: "
|
|
6791
|
-
{ label: "Zoning", value:
|
|
6792
|
-
{ label: "Levels", value: "
|
|
6847
|
+
{ label: "Last Sale", value: "-" },
|
|
6848
|
+
{ label: "Suburb Median", value: "-" },
|
|
6849
|
+
{ label: "Replication Cost of Architecture", value: "-" },
|
|
6850
|
+
{ label: "DA Status", value: daStatus, status: daStatus.toLowerCase() === "approved" ? "success" : "progress" },
|
|
6851
|
+
{ label: "Property Type", value: formattedPropertyType },
|
|
6852
|
+
{ label: "Ownership", value: ownership ?? "N/A" },
|
|
6853
|
+
{ label: "Zoning", value: zoning ?? "N/A" },
|
|
6854
|
+
{ label: "Levels", value: levels?.toString() ?? "N/A" }
|
|
6793
6855
|
].map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(DetailCell, { $borderBottom: i < 4, $borderRight: (i + 1) % 4 !== 0, children: [
|
|
6794
6856
|
/* @__PURE__ */ jsxRuntime.jsx(DetailCellLabel, { children: item.label }),
|
|
6795
6857
|
/* @__PURE__ */ jsxRuntime.jsxs(DetailCellValue, { $status: item.status, children: [
|
|
@@ -7675,7 +7737,7 @@ var DocIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height
|
|
|
7675
7737
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
|
|
7676
7738
|
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "10 9 9 9 8 9" })
|
|
7677
7739
|
] });
|
|
7678
|
-
var
|
|
7740
|
+
var fallbackDocs = [
|
|
7679
7741
|
{ href: "/documents/musgrave-valuation-report.pdf", label: "Valuation Report" },
|
|
7680
7742
|
{ href: "/documents/musgrave-offering-material.pdf", label: "Offering Material" },
|
|
7681
7743
|
{ href: "/documents/musgrave-mortgage-agreement.pdf", label: "Mortgage Agreement" },
|
|
@@ -7684,13 +7746,26 @@ var docs = [
|
|
|
7684
7746
|
{ href: "/documents/musgrave-risk-disclosure.pdf", label: "Risk Disclosure Statement" },
|
|
7685
7747
|
{ href: "/documents/musgrave-building-inspection.pdf", label: "Building & Pest Inspection Report" }
|
|
7686
7748
|
];
|
|
7687
|
-
function PropertyDocuments() {
|
|
7749
|
+
function PropertyDocuments({ documentsData }) {
|
|
7750
|
+
const backendDocuments = Array.isArray(documentsData?.documents) ? documentsData.documents : null;
|
|
7751
|
+
const hasBackendDocuments = !!backendDocuments?.length;
|
|
7752
|
+
const documents = hasBackendDocuments ? backendDocuments : fallbackDocs.map((doc) => ({
|
|
7753
|
+
title: doc.label,
|
|
7754
|
+
documentUrl: doc.href
|
|
7755
|
+
}));
|
|
7688
7756
|
return /* @__PURE__ */ jsxRuntime.jsxs(Section2, { children: [
|
|
7689
7757
|
/* @__PURE__ */ jsxRuntime.jsx(SectionHeading2, { children: "Investment Documents" }),
|
|
7690
|
-
/* @__PURE__ */ jsxRuntime.jsx(DocList, { children:
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7758
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocList, { children: documents.map(({ documentUrl, title }) => {
|
|
7759
|
+
const isAvailable = Boolean(documentUrl);
|
|
7760
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DocItem, { children: hasBackendDocuments && isAvailable ? /* @__PURE__ */ jsxRuntime.jsxs(DocLink, { href: documentUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
7761
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocIconWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(DocIcon, {}) }),
|
|
7762
|
+
title
|
|
7763
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(DocItemDisabled, { children: [
|
|
7764
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocIconWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(DocIcon, {}) }),
|
|
7765
|
+
title,
|
|
7766
|
+
/* @__PURE__ */ jsxRuntime.jsx(ComingSoonBadge, { children: "Coming Soon" })
|
|
7767
|
+
] }) }, `${title}-${documentUrl ?? "pending"}`);
|
|
7768
|
+
}) })
|
|
7694
7769
|
] });
|
|
7695
7770
|
}
|
|
7696
7771
|
var Section2 = styled23__default.default.section`
|
|
@@ -7734,11 +7809,29 @@ var DocLink = styled23__default.default.a`
|
|
|
7734
7809
|
color: var(--color-accent);
|
|
7735
7810
|
}
|
|
7736
7811
|
`;
|
|
7812
|
+
var DocItemDisabled = styled23__default.default.div`
|
|
7813
|
+
display: flex;
|
|
7814
|
+
align-items: center;
|
|
7815
|
+
color: var(--color-text-secondary);
|
|
7816
|
+
cursor: not-allowed;
|
|
7817
|
+
opacity: 0.6;
|
|
7818
|
+
`;
|
|
7737
7819
|
var DocIconWrapper = styled23__default.default.span`
|
|
7738
7820
|
margin-right: 0.75rem;
|
|
7739
7821
|
flex-shrink: 0;
|
|
7740
7822
|
color: var(--color-text-secondary);
|
|
7741
7823
|
`;
|
|
7824
|
+
var ComingSoonBadge = styled23__default.default.span`
|
|
7825
|
+
margin-left: auto;
|
|
7826
|
+
padding: 0.25rem 0.5rem;
|
|
7827
|
+
background: rgba(212, 175, 55, 0.1);
|
|
7828
|
+
color: #D4AF37;
|
|
7829
|
+
border-radius: 0.25rem;
|
|
7830
|
+
font-size: 0.7rem;
|
|
7831
|
+
font-weight: 500;
|
|
7832
|
+
text-transform: uppercase;
|
|
7833
|
+
letter-spacing: 0.05em;
|
|
7834
|
+
`;
|
|
7742
7835
|
var formatIsoDate = (value) => {
|
|
7743
7836
|
const parsed = new Date(value);
|
|
7744
7837
|
if (Number.isNaN(parsed.getTime())) return value;
|
|
@@ -8025,7 +8118,7 @@ function AssetSelectorBar({ propertyName, tokenPrice, offeringValuation }) {
|
|
|
8025
8118
|
/* @__PURE__ */ jsxRuntime.jsxs(SelectorMetrics, { children: [
|
|
8026
8119
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8027
8120
|
/* @__PURE__ */ jsxRuntime.jsx(MetricLabel, { children: "Unit Price" }),
|
|
8028
|
-
/* @__PURE__ */ jsxRuntime.jsxs(MetricValue, { accent: true, children: [
|
|
8121
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricValue, { $accent: true, children: [
|
|
8029
8122
|
"$",
|
|
8030
8123
|
tokenPrice.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
8031
8124
|
] })
|
|
@@ -8120,7 +8213,7 @@ var MetricLabel = styled23__default.default.span`
|
|
|
8120
8213
|
var MetricValue = styled23__default.default.span`
|
|
8121
8214
|
font-size: 1.1rem;
|
|
8122
8215
|
font-weight: 700;
|
|
8123
|
-
color: ${(p) => p
|
|
8216
|
+
color: ${(p) => p.$accent ? "#D4AF37" : "#fff"};
|
|
8124
8217
|
`;
|
|
8125
8218
|
var Separator = styled23__default.default.span`
|
|
8126
8219
|
font-size: 1rem;
|
|
@@ -8239,7 +8332,7 @@ function OfferingProgressCard({
|
|
|
8239
8332
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u24D8" })
|
|
8240
8333
|
] }),
|
|
8241
8334
|
/* @__PURE__ */ jsxRuntime.jsxs(LivePercent, { children: [
|
|
8242
|
-
percentSold.toFixed(1),
|
|
8335
|
+
percentSold < 0.1 && percentSold > 0 ? percentSold.toFixed(3) : percentSold.toFixed(1),
|
|
8243
8336
|
"%",
|
|
8244
8337
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u2191" })
|
|
8245
8338
|
] })
|
|
@@ -8612,7 +8705,8 @@ function OrderPanel({
|
|
|
8612
8705
|
orderButtonText,
|
|
8613
8706
|
isOrderButtonDisabled,
|
|
8614
8707
|
hasInsufficientFunds,
|
|
8615
|
-
onPlaceAnotherOrder
|
|
8708
|
+
onPlaceAnotherOrder,
|
|
8709
|
+
onDeposit
|
|
8616
8710
|
}) {
|
|
8617
8711
|
const [payInputValue, setPayInputValue] = React5.useState("");
|
|
8618
8712
|
const [receiveInputValue, setReceiveInputValue] = React5.useState("");
|
|
@@ -8621,11 +8715,14 @@ function OrderPanel({
|
|
|
8621
8715
|
const handlePayBlur = () => {
|
|
8622
8716
|
setIsPayInputFocused(false);
|
|
8623
8717
|
const parsed = parseInt(payInputValue.replace(/[^0-9]/g, ""), 10) || 0;
|
|
8624
|
-
if (parsed
|
|
8625
|
-
setManualOrderAmount(
|
|
8718
|
+
if (parsed <= 0) {
|
|
8719
|
+
setManualOrderAmount(null);
|
|
8720
|
+
setSliderValue(0);
|
|
8721
|
+
} else if (parsed >= availableBalance) {
|
|
8722
|
+
setManualOrderAmount(null);
|
|
8626
8723
|
setSliderValue(100);
|
|
8627
8724
|
} else {
|
|
8628
|
-
setManualOrderAmount(
|
|
8725
|
+
setManualOrderAmount(parsed);
|
|
8629
8726
|
const ratio = availableBalance === 0 ? 0 : Math.round(Math.max(0, parsed / availableBalance * 100));
|
|
8630
8727
|
setSliderValue(ratio);
|
|
8631
8728
|
}
|
|
@@ -8634,11 +8731,14 @@ function OrderPanel({
|
|
|
8634
8731
|
setIsReceiveInputFocused(false);
|
|
8635
8732
|
const parsed = parseFloat(receiveInputValue) || 0;
|
|
8636
8733
|
const newOrderTotal = Math.round(parsed * tokenPrice);
|
|
8637
|
-
if (newOrderTotal
|
|
8638
|
-
setManualOrderAmount(
|
|
8734
|
+
if (newOrderTotal <= 0) {
|
|
8735
|
+
setManualOrderAmount(null);
|
|
8736
|
+
setSliderValue(0);
|
|
8737
|
+
} else if (newOrderTotal >= availableBalance) {
|
|
8738
|
+
setManualOrderAmount(null);
|
|
8639
8739
|
setSliderValue(100);
|
|
8640
8740
|
} else {
|
|
8641
|
-
setManualOrderAmount(
|
|
8741
|
+
setManualOrderAmount(newOrderTotal);
|
|
8642
8742
|
const ratio = availableBalance === 0 ? 0 : Math.round(Math.max(0, newOrderTotal / availableBalance * 100));
|
|
8643
8743
|
setSliderValue(ratio);
|
|
8644
8744
|
}
|
|
@@ -8708,7 +8808,7 @@ function OrderPanel({
|
|
|
8708
8808
|
}
|
|
8709
8809
|
}
|
|
8710
8810
|
),
|
|
8711
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "
|
|
8811
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "USDC" })
|
|
8712
8812
|
] }),
|
|
8713
8813
|
/* @__PURE__ */ jsxRuntime.jsx(QuickSelectRow, { children: [25, 50, 75, 100].map((pct) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8714
8814
|
"button",
|
|
@@ -8735,7 +8835,7 @@ function OrderPanel({
|
|
|
8735
8835
|
availableBalance.toLocaleString()
|
|
8736
8836
|
] })
|
|
8737
8837
|
] }),
|
|
8738
|
-
/* @__PURE__ */ jsxRuntime.jsx(DepositButton, { type: "button", children: "+ Deposit" })
|
|
8838
|
+
/* @__PURE__ */ jsxRuntime.jsx(DepositButton, { type: "button", onClick: onDeposit, children: "+ Deposit" })
|
|
8739
8839
|
] }),
|
|
8740
8840
|
/* @__PURE__ */ jsxRuntime.jsx(Divider2, { children: "\u2193" }),
|
|
8741
8841
|
/* @__PURE__ */ jsxRuntime.jsxs(Card2, { children: [
|
|
@@ -8802,7 +8902,7 @@ function OrderPanel({
|
|
|
8802
8902
|
/* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
|
|
8803
8903
|
"$",
|
|
8804
8904
|
orderTotal.toLocaleString(),
|
|
8805
|
-
"
|
|
8905
|
+
" USDC"
|
|
8806
8906
|
] })
|
|
8807
8907
|
] })
|
|
8808
8908
|
] })
|
|
@@ -8824,7 +8924,7 @@ function OrderPanel({
|
|
|
8824
8924
|
"$",
|
|
8825
8925
|
availableBalance.toLocaleString()
|
|
8826
8926
|
] }),
|
|
8827
|
-
/* @__PURE__ */ jsxRuntime.jsx(BalanceAction, { children: "+ Deposit" })
|
|
8927
|
+
/* @__PURE__ */ jsxRuntime.jsx(BalanceAction, { onClick: onDeposit, style: { cursor: onDeposit ? "pointer" : "default" }, children: "+ Deposit" })
|
|
8828
8928
|
] }),
|
|
8829
8929
|
/* @__PURE__ */ jsxRuntime.jsxs(BalanceCard, { children: [
|
|
8830
8930
|
/* @__PURE__ */ jsxRuntime.jsx(BalanceLabel, { children: "Musgrave Owned" }),
|
|
@@ -9456,7 +9556,23 @@ var IframeShield = styled23__default.default.div`
|
|
|
9456
9556
|
z-index: 1;
|
|
9457
9557
|
cursor: pointer;
|
|
9458
9558
|
`;
|
|
9459
|
-
|
|
9559
|
+
var SUBSCRIPTIONS_PAGE_SIZE = 6;
|
|
9560
|
+
function NewsOrdersSection({ newsItems, userSubscriptions, tokenPrice }) {
|
|
9561
|
+
const [page, setPage] = React5.useState(0);
|
|
9562
|
+
const totalPages = Math.max(1, Math.ceil(userSubscriptions.length / SUBSCRIPTIONS_PAGE_SIZE));
|
|
9563
|
+
React5.useEffect(() => {
|
|
9564
|
+
if (page > totalPages - 1) {
|
|
9565
|
+
setPage(totalPages - 1);
|
|
9566
|
+
}
|
|
9567
|
+
}, [page, totalPages]);
|
|
9568
|
+
React5.useEffect(() => {
|
|
9569
|
+
setPage(0);
|
|
9570
|
+
}, [userSubscriptions]);
|
|
9571
|
+
const paginatedSubscriptions = React5.useMemo(() => {
|
|
9572
|
+
const start = page * SUBSCRIPTIONS_PAGE_SIZE;
|
|
9573
|
+
return userSubscriptions.slice(start, start + SUBSCRIPTIONS_PAGE_SIZE);
|
|
9574
|
+
}, [page, userSubscriptions]);
|
|
9575
|
+
const hasPagination = userSubscriptions.length > SUBSCRIPTIONS_PAGE_SIZE;
|
|
9460
9576
|
return /* @__PURE__ */ jsxRuntime.jsxs(Row2, { children: [
|
|
9461
9577
|
/* @__PURE__ */ jsxRuntime.jsxs(TradeNewsPanel, { children: [
|
|
9462
9578
|
/* @__PURE__ */ jsxRuntime.jsxs(TradeNewsHeader, { children: [
|
|
@@ -9483,34 +9599,57 @@ function NewsOrdersSection({ newsItems, userSubscription, tokenPrice }) {
|
|
|
9483
9599
|
] }),
|
|
9484
9600
|
/* @__PURE__ */ jsxRuntime.jsxs(TradeNewsPanel, { children: [
|
|
9485
9601
|
/* @__PURE__ */ jsxRuntime.jsxs(TradeNewsHeader, { children: [
|
|
9486
|
-
/* @__PURE__ */ jsxRuntime.
|
|
9487
|
-
|
|
9602
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9603
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { children: "Your Orders" }),
|
|
9604
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Offering Subscriptions" })
|
|
9605
|
+
] }),
|
|
9606
|
+
hasPagination ? /* @__PURE__ */ jsxRuntime.jsxs(Pagination, { children: [
|
|
9607
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => setPage((prev) => Math.max(prev - 1, 0)), disabled: page === 0, children: "Prev" }),
|
|
9608
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
9609
|
+
"Page ",
|
|
9610
|
+
page + 1,
|
|
9611
|
+
"/",
|
|
9612
|
+
totalPages
|
|
9613
|
+
] }),
|
|
9614
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9615
|
+
"button",
|
|
9616
|
+
{
|
|
9617
|
+
type: "button",
|
|
9618
|
+
onClick: () => setPage((prev) => Math.min(prev + 1, totalPages - 1)),
|
|
9619
|
+
disabled: page >= totalPages - 1,
|
|
9620
|
+
children: "Next"
|
|
9621
|
+
}
|
|
9622
|
+
)
|
|
9623
|
+
] }) : null
|
|
9488
9624
|
] }),
|
|
9489
9625
|
/* @__PURE__ */ jsxRuntime.jsxs(OrdersTable, { children: [
|
|
9490
9626
|
/* @__PURE__ */ jsxRuntime.jsx(OrdersHead, { children: ["Date", "Units", "Price", "Total", "Status"].map((h) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: h }, h)) }),
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
"
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9627
|
+
paginatedSubscriptions.length ? paginatedSubscriptions.map((subscription) => {
|
|
9628
|
+
const subscriptionDate = new Date(subscription.timestamp);
|
|
9629
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(OrdersRow, { children: [
|
|
9630
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9631
|
+
subscriptionDate.toLocaleDateString("en-AU", {
|
|
9632
|
+
day: "2-digit",
|
|
9633
|
+
month: "short",
|
|
9634
|
+
year: "numeric"
|
|
9635
|
+
}),
|
|
9636
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: subscriptionDate.toLocaleTimeString("en-AU", {
|
|
9637
|
+
hour: "2-digit",
|
|
9638
|
+
minute: "2-digit"
|
|
9639
|
+
}) })
|
|
9640
|
+
] }),
|
|
9641
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "units", children: subscription.tokens.toFixed(2) }),
|
|
9642
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9643
|
+
"$",
|
|
9644
|
+
tokenPrice.toFixed(2)
|
|
9645
|
+
] }),
|
|
9646
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "total", children: [
|
|
9647
|
+
"$",
|
|
9648
|
+
subscription.value.toLocaleString()
|
|
9649
|
+
] }),
|
|
9650
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "status", children: subscription.status ?? "Confirmed" })
|
|
9651
|
+
] }, `${subscription.timestamp}-${subscription.tokens}`);
|
|
9652
|
+
}) : /* @__PURE__ */ jsxRuntime.jsxs(OrdersEmpty, { children: [
|
|
9514
9653
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: "\u{1F4CB}" }),
|
|
9515
9654
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "No orders yet" }),
|
|
9516
9655
|
/* @__PURE__ */ jsxRuntime.jsx("small", { children: "Subscribe to the IPO above to place your first order" })
|
|
@@ -9637,6 +9776,28 @@ var OrdersTable = styled23__default.default.div`
|
|
|
9637
9776
|
flex: 1;
|
|
9638
9777
|
overflow: auto;
|
|
9639
9778
|
`;
|
|
9779
|
+
var Pagination = styled23__default.default.div`
|
|
9780
|
+
display: flex;
|
|
9781
|
+
align-items: center;
|
|
9782
|
+
gap: 0.75rem;
|
|
9783
|
+
font-size: 0.75rem;
|
|
9784
|
+
color: var(--color-text-secondary);
|
|
9785
|
+
|
|
9786
|
+
button {
|
|
9787
|
+
border: 1px solid rgba(255,255,255,0.2);
|
|
9788
|
+
background: rgba(255,255,255,0.05);
|
|
9789
|
+
color: #fff;
|
|
9790
|
+
border-radius: 9999px;
|
|
9791
|
+
padding: 0.25rem 0.9rem;
|
|
9792
|
+
font-size: 0.7rem;
|
|
9793
|
+
cursor: pointer;
|
|
9794
|
+
transition: opacity 0.2s;
|
|
9795
|
+
&:disabled {
|
|
9796
|
+
opacity: 0.4;
|
|
9797
|
+
cursor: not-allowed;
|
|
9798
|
+
}
|
|
9799
|
+
}
|
|
9800
|
+
`;
|
|
9640
9801
|
var OrdersHead = styled23__default.default.div`
|
|
9641
9802
|
display: grid;
|
|
9642
9803
|
grid-template-columns: 1fr 1fr 1fr 1fr 1.2fr;
|
|
@@ -9910,11 +10071,18 @@ function PropertyBuy({
|
|
|
9910
10071
|
propertyLocation: propertyLocationLabel = "Mosman, Sydney",
|
|
9911
10072
|
isAuthenticated,
|
|
9912
10073
|
onSignIn,
|
|
9913
|
-
saleData
|
|
10074
|
+
saleData,
|
|
10075
|
+
walletUsdcBalance,
|
|
10076
|
+
walletPropertyTokenBalance,
|
|
10077
|
+
onPurchase,
|
|
10078
|
+
purchaseStatus = "idle",
|
|
10079
|
+
purchaseError,
|
|
10080
|
+
onDeposit,
|
|
10081
|
+
initialUserSubscriptions = []
|
|
9914
10082
|
}) {
|
|
9915
10083
|
const [sliderValue, setSliderValue] = React5.useState(0);
|
|
9916
|
-
const [availableBalance, setAvailableBalance] = React5.useState(125e3);
|
|
9917
|
-
const [
|
|
10084
|
+
const [availableBalance, setAvailableBalance] = React5.useState(walletUsdcBalance ?? 125e3);
|
|
10085
|
+
const [optimisticUserSubscriptions, setOptimisticUserSubscriptions] = React5.useState([]);
|
|
9918
10086
|
const [manualOrderAmount, setManualOrderAmount] = React5.useState(null);
|
|
9919
10087
|
const [ownedTokens, setOwnedTokens] = React5.useState(0);
|
|
9920
10088
|
const [displayedOwnedTokens, setDisplayedOwnedTokens] = React5.useState(0);
|
|
@@ -9932,6 +10100,12 @@ function PropertyBuy({
|
|
|
9932
10100
|
isNew: false
|
|
9933
10101
|
}))
|
|
9934
10102
|
);
|
|
10103
|
+
const resolvedUserSubscriptions = initialUserSubscriptions && initialUserSubscriptions.length > 0 ? initialUserSubscriptions : optimisticUserSubscriptions;
|
|
10104
|
+
React5.useEffect(() => {
|
|
10105
|
+
if (initialUserSubscriptions?.length) {
|
|
10106
|
+
setOptimisticUserSubscriptions([]);
|
|
10107
|
+
}
|
|
10108
|
+
}, [initialUserSubscriptions]);
|
|
9935
10109
|
const tokenPrice = saleData?.tokenPrice ?? 250;
|
|
9936
10110
|
const feeRate = (saleData?.feePercent ?? 0.5) / 100;
|
|
9937
10111
|
const totalSold = saleData?.totalSold ?? 0;
|
|
@@ -9949,6 +10123,17 @@ function PropertyBuy({
|
|
|
9949
10123
|
const orderTotal = totalSpend;
|
|
9950
10124
|
const estExposure = (tokenQuantity / supplyToSell * 100).toFixed(4);
|
|
9951
10125
|
const hasInsufficientFunds = orderTotal > availableBalance;
|
|
10126
|
+
React5.useEffect(() => {
|
|
10127
|
+
if (walletUsdcBalance != null) {
|
|
10128
|
+
setAvailableBalance(walletUsdcBalance);
|
|
10129
|
+
}
|
|
10130
|
+
}, [walletUsdcBalance]);
|
|
10131
|
+
React5.useEffect(() => {
|
|
10132
|
+
if (walletPropertyTokenBalance != null) {
|
|
10133
|
+
setOwnedTokens(walletPropertyTokenBalance);
|
|
10134
|
+
setDisplayedOwnedTokens(walletPropertyTokenBalance);
|
|
10135
|
+
}
|
|
10136
|
+
}, [walletPropertyTokenBalance]);
|
|
9952
10137
|
const handleOrderButtonClick = () => {
|
|
9953
10138
|
if (!isAuthenticated) {
|
|
9954
10139
|
onSignIn();
|
|
@@ -9959,8 +10144,12 @@ function PropertyBuy({
|
|
|
9959
10144
|
}
|
|
9960
10145
|
setShowOrderConfirmModal(true);
|
|
9961
10146
|
};
|
|
10147
|
+
const isPurchaseInFlight = purchaseStatus === "checking-allowance" || purchaseStatus === "approving" || purchaseStatus === "purchasing";
|
|
9962
10148
|
const getOrderButtonText = () => {
|
|
9963
10149
|
if (!isAuthenticated) return "Sign In to Invest";
|
|
10150
|
+
if (purchaseStatus === "checking-allowance") return "Checking allowance\u2026";
|
|
10151
|
+
if (purchaseStatus === "approving") return "Approving USDC\u2026";
|
|
10152
|
+
if (purchaseStatus === "purchasing") return "Confirming purchase\u2026";
|
|
9964
10153
|
if (scStatus === 0) return "Sale Not Open Yet";
|
|
9965
10154
|
if (scStatus === 2) return "Sale Completed";
|
|
9966
10155
|
if (scStatus === 3) return "Sale Paused";
|
|
@@ -9969,30 +10158,44 @@ function PropertyBuy({
|
|
|
9969
10158
|
};
|
|
9970
10159
|
const isOrderButtonDisabled = () => {
|
|
9971
10160
|
if (!isAuthenticated) return false;
|
|
10161
|
+
if (isPurchaseInFlight) return true;
|
|
9972
10162
|
if (scStatus !== 1) return true;
|
|
9973
10163
|
if (tokenQuantity === 0) return true;
|
|
9974
10164
|
return false;
|
|
9975
10165
|
};
|
|
9976
|
-
const confirmOrder = () => {
|
|
10166
|
+
const confirmOrder = async () => {
|
|
9977
10167
|
setShowOrderConfirmModal(false);
|
|
9978
|
-
|
|
9979
|
-
|
|
10168
|
+
const tokenAmountInt = Math.floor(tokenQuantity);
|
|
10169
|
+
if (tokenAmountInt <= 0) return;
|
|
10170
|
+
if (onPurchase) {
|
|
10171
|
+
try {
|
|
10172
|
+
await onPurchase(tokenAmountInt);
|
|
10173
|
+
} catch {
|
|
10174
|
+
return;
|
|
10175
|
+
}
|
|
10176
|
+
}
|
|
10177
|
+
if (walletUsdcBalance == null) {
|
|
10178
|
+
setAvailableBalance((prev) => prev - orderTotal);
|
|
10179
|
+
}
|
|
10180
|
+
const newTokens = ownedTokens + tokenAmountInt;
|
|
9980
10181
|
setOwnedTokens(newTokens);
|
|
9981
10182
|
setDisplayedOwnedTokens(newTokens);
|
|
9982
10183
|
setOwnedTokensJustUpdated(true);
|
|
9983
|
-
setLastOrderQuantity(
|
|
10184
|
+
setLastOrderQuantity(tokenAmountInt);
|
|
9984
10185
|
setTimeout(() => setOwnedTokensJustUpdated(false), 2e3);
|
|
9985
|
-
|
|
10186
|
+
const optimisticEntry = {
|
|
9986
10187
|
propertyName,
|
|
9987
10188
|
tokenSymbol: "MUS",
|
|
9988
|
-
tokens:
|
|
10189
|
+
tokens: tokenAmountInt,
|
|
9989
10190
|
value: orderTotal,
|
|
9990
10191
|
avgPrice: tokenPrice,
|
|
9991
10192
|
percentOfProperty: estExposure,
|
|
9992
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
9993
|
-
|
|
10193
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10194
|
+
status: "pending"
|
|
10195
|
+
};
|
|
10196
|
+
setOptimisticUserSubscriptions((prev) => [optimisticEntry, ...prev]);
|
|
9994
10197
|
setLastOrderDetails({
|
|
9995
|
-
tokens:
|
|
10198
|
+
tokens: tokenAmountInt,
|
|
9996
10199
|
total: orderTotal,
|
|
9997
10200
|
price: tokenPrice,
|
|
9998
10201
|
orderNumber: Math.floor(1e7 + Math.random() * 9e7)
|
|
@@ -10052,36 +10255,40 @@ function PropertyBuy({
|
|
|
10052
10255
|
}
|
|
10053
10256
|
),
|
|
10054
10257
|
/* @__PURE__ */ jsxRuntime.jsx(VideoActivitySection, { ipoStarted }),
|
|
10055
|
-
/* @__PURE__ */ jsxRuntime.
|
|
10056
|
-
|
|
10057
|
-
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10258
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
|
|
10259
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10260
|
+
OrderPanel,
|
|
10261
|
+
{
|
|
10262
|
+
statusLabel,
|
|
10263
|
+
statusColor,
|
|
10264
|
+
ipoStarted,
|
|
10265
|
+
isAuthenticated,
|
|
10266
|
+
tokenPrice,
|
|
10267
|
+
feeRate,
|
|
10268
|
+
supplyToSell,
|
|
10269
|
+
availableBalance,
|
|
10270
|
+
displayedOwnedTokens,
|
|
10271
|
+
ownedTokensJustUpdated,
|
|
10272
|
+
lastOrderQuantity,
|
|
10273
|
+
orderPlacedSuccess,
|
|
10274
|
+
lastOrderDetails,
|
|
10275
|
+
tokenQuantity,
|
|
10276
|
+
feeInTokens,
|
|
10277
|
+
orderTotal,
|
|
10278
|
+
sliderValue,
|
|
10279
|
+
manualOrderAmount,
|
|
10280
|
+
setSliderValue,
|
|
10281
|
+
setManualOrderAmount,
|
|
10282
|
+
onOrderButtonClick: handleOrderButtonClick,
|
|
10283
|
+
orderButtonText: getOrderButtonText(),
|
|
10284
|
+
isOrderButtonDisabled: isOrderButtonDisabled(),
|
|
10285
|
+
hasInsufficientFunds,
|
|
10286
|
+
onPlaceAnotherOrder: () => setOrderPlacedSuccess(false),
|
|
10287
|
+
onDeposit
|
|
10288
|
+
}
|
|
10289
|
+
),
|
|
10290
|
+
purchaseError && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: "0.75rem", padding: "0.75rem 1rem", borderRadius: "8px", background: "rgba(246,70,93,0.1)", border: "1px solid rgba(246,70,93,0.3)", color: "#f6465d", fontSize: "0.8rem", fontWeight: 500 }, children: purchaseError })
|
|
10291
|
+
] })
|
|
10085
10292
|
] }),
|
|
10086
10293
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
10087
10294
|
/* @__PURE__ */ jsxRuntime.jsx(GalleryMapSection, { propertyLocation: propertyLocationLabel }),
|
|
@@ -10089,7 +10296,7 @@ function PropertyBuy({
|
|
|
10089
10296
|
NewsOrdersSection,
|
|
10090
10297
|
{
|
|
10091
10298
|
newsItems,
|
|
10092
|
-
|
|
10299
|
+
userSubscriptions: resolvedUserSubscriptions,
|
|
10093
10300
|
tokenPrice
|
|
10094
10301
|
}
|
|
10095
10302
|
)
|
|
@@ -12444,6 +12651,191 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
12444
12651
|
}
|
|
12445
12652
|
);
|
|
12446
12653
|
}
|
|
12654
|
+
var slideIn = styled23.keyframes`
|
|
12655
|
+
from { transform: translateX(110%); opacity: 0; }
|
|
12656
|
+
to { transform: translateX(0); opacity: 1; }
|
|
12657
|
+
`;
|
|
12658
|
+
var slideOut = styled23.keyframes`
|
|
12659
|
+
from { transform: translateX(0); opacity: 1; }
|
|
12660
|
+
to { transform: translateX(110%); opacity: 0; }
|
|
12661
|
+
`;
|
|
12662
|
+
var progressShrink = styled23.keyframes`
|
|
12663
|
+
from { width: 100%; }
|
|
12664
|
+
to { width: 0%; }
|
|
12665
|
+
`;
|
|
12666
|
+
var VARIANT_COLORS = {
|
|
12667
|
+
success: { accent: "#0ecb81", icon: "\u2713" },
|
|
12668
|
+
error: { accent: "#f6465d", icon: "\u2715" },
|
|
12669
|
+
info: { accent: "#E6C656", icon: "\u2139" },
|
|
12670
|
+
pending: { accent: "#7EB3E6", icon: "\u25CC" }
|
|
12671
|
+
};
|
|
12672
|
+
var Wrapper = styled23__default.default.div`
|
|
12673
|
+
position: relative;
|
|
12674
|
+
display: flex;
|
|
12675
|
+
flex-direction: column;
|
|
12676
|
+
gap: 0;
|
|
12677
|
+
width: 340px;
|
|
12678
|
+
background: #0d0f1a;
|
|
12679
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
12680
|
+
border-radius: 10px;
|
|
12681
|
+
overflow: hidden;
|
|
12682
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255,255,255,0.04);
|
|
12683
|
+
animation: ${({ $exiting }) => $exiting ? styled23.css`${slideOut} 0.28s cubic-bezier(0.4,0,1,1) forwards` : styled23.css`${slideIn} 0.32s cubic-bezier(0,0,0.2,1) forwards`};
|
|
12684
|
+
pointer-events: all;
|
|
12685
|
+
`;
|
|
12686
|
+
var Body = styled23__default.default.div`
|
|
12687
|
+
display: flex;
|
|
12688
|
+
align-items: flex-start;
|
|
12689
|
+
gap: 12px;
|
|
12690
|
+
padding: 14px 16px 12px;
|
|
12691
|
+
`;
|
|
12692
|
+
var IconDot = styled23__default.default.div`
|
|
12693
|
+
flex-shrink: 0;
|
|
12694
|
+
width: 28px;
|
|
12695
|
+
height: 28px;
|
|
12696
|
+
border-radius: 50%;
|
|
12697
|
+
background: ${({ $color }) => $color}1a;
|
|
12698
|
+
border: 1px solid ${({ $color }) => $color}55;
|
|
12699
|
+
display: flex;
|
|
12700
|
+
align-items: center;
|
|
12701
|
+
justify-content: center;
|
|
12702
|
+
font-size: 0.75rem;
|
|
12703
|
+
font-weight: 700;
|
|
12704
|
+
color: ${({ $color }) => $color};
|
|
12705
|
+
margin-top: 1px;
|
|
12706
|
+
`;
|
|
12707
|
+
var Content = styled23__default.default.div`
|
|
12708
|
+
flex: 1;
|
|
12709
|
+
min-width: 0;
|
|
12710
|
+
`;
|
|
12711
|
+
var Title2 = styled23__default.default.p`
|
|
12712
|
+
margin: 0 0 2px;
|
|
12713
|
+
font-size: 0.8rem;
|
|
12714
|
+
font-weight: 600;
|
|
12715
|
+
color: #fff;
|
|
12716
|
+
letter-spacing: 0.01em;
|
|
12717
|
+
`;
|
|
12718
|
+
var Amount = styled23__default.default.p`
|
|
12719
|
+
margin: 0 0 6px;
|
|
12720
|
+
font-size: 1.05rem;
|
|
12721
|
+
font-weight: 700;
|
|
12722
|
+
color: #E6C656;
|
|
12723
|
+
letter-spacing: -0.01em;
|
|
12724
|
+
`;
|
|
12725
|
+
var TxRow = styled23__default.default.a`
|
|
12726
|
+
display: inline-flex;
|
|
12727
|
+
align-items: center;
|
|
12728
|
+
gap: 5px;
|
|
12729
|
+
font-family: 'IBM Plex Mono', 'Space Mono', monospace;
|
|
12730
|
+
font-size: 0.68rem;
|
|
12731
|
+
color: rgba(255, 255, 255, 0.4);
|
|
12732
|
+
text-decoration: none;
|
|
12733
|
+
transition: color 0.15s;
|
|
12734
|
+
&:hover {
|
|
12735
|
+
color: #7EB3E6;
|
|
12736
|
+
}
|
|
12737
|
+
`;
|
|
12738
|
+
var TxArrow = styled23__default.default.span`
|
|
12739
|
+
font-size: 0.6rem;
|
|
12740
|
+
opacity: 0.6;
|
|
12741
|
+
`;
|
|
12742
|
+
var CloseBtn = styled23__default.default.button`
|
|
12743
|
+
flex-shrink: 0;
|
|
12744
|
+
background: none;
|
|
12745
|
+
border: none;
|
|
12746
|
+
padding: 2px 4px;
|
|
12747
|
+
cursor: pointer;
|
|
12748
|
+
color: rgba(255, 255, 255, 0.25);
|
|
12749
|
+
font-size: 0.9rem;
|
|
12750
|
+
line-height: 1;
|
|
12751
|
+
transition: color 0.15s;
|
|
12752
|
+
&:hover { color: rgba(255, 255, 255, 0.7); }
|
|
12753
|
+
`;
|
|
12754
|
+
var ProgressBar2 = styled23__default.default.div`
|
|
12755
|
+
height: 2px;
|
|
12756
|
+
background: rgba(255, 255, 255, 0.06);
|
|
12757
|
+
position: relative;
|
|
12758
|
+
&::after {
|
|
12759
|
+
content: '';
|
|
12760
|
+
position: absolute;
|
|
12761
|
+
left: 0;
|
|
12762
|
+
top: 0;
|
|
12763
|
+
height: 100%;
|
|
12764
|
+
background: ${({ $color }) => $color};
|
|
12765
|
+
animation: ${styled23.css`${progressShrink} ${({ $duration }) => $duration}ms linear forwards`};
|
|
12766
|
+
}
|
|
12767
|
+
`;
|
|
12768
|
+
var Container2 = styled23__default.default.div`
|
|
12769
|
+
position: fixed;
|
|
12770
|
+
bottom: 24px;
|
|
12771
|
+
right: 24px;
|
|
12772
|
+
z-index: 9999;
|
|
12773
|
+
display: flex;
|
|
12774
|
+
flex-direction: column-reverse;
|
|
12775
|
+
gap: 10px;
|
|
12776
|
+
pointer-events: none;
|
|
12777
|
+
`;
|
|
12778
|
+
var DEFAULT_EXPLORER = "https://sepolia.basescan.org/tx/";
|
|
12779
|
+
function truncateHash(hash) {
|
|
12780
|
+
return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
|
|
12781
|
+
}
|
|
12782
|
+
function ToastItem({ toast, onDismiss }) {
|
|
12783
|
+
const [exiting, setExiting] = React5.useState(false);
|
|
12784
|
+
const timerRef = React5.useRef(null);
|
|
12785
|
+
const dismiss = React5.useCallback(() => {
|
|
12786
|
+
setExiting(true);
|
|
12787
|
+
setTimeout(() => onDismiss(toast.id), 280);
|
|
12788
|
+
}, [onDismiss, toast.id]);
|
|
12789
|
+
React5.useEffect(() => {
|
|
12790
|
+
const duration2 = toast.duration ?? 6e3;
|
|
12791
|
+
if (duration2 > 0) {
|
|
12792
|
+
timerRef.current = setTimeout(dismiss, duration2);
|
|
12793
|
+
}
|
|
12794
|
+
return () => {
|
|
12795
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
12796
|
+
};
|
|
12797
|
+
}, [dismiss, toast.duration]);
|
|
12798
|
+
const { accent, icon } = VARIANT_COLORS[toast.variant];
|
|
12799
|
+
const duration = toast.duration ?? 6e3;
|
|
12800
|
+
const explorerBase = toast.explorerUrl ?? DEFAULT_EXPLORER;
|
|
12801
|
+
const txUrl = toast.txHash ? `${explorerBase}${toast.txHash}` : void 0;
|
|
12802
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Wrapper, { $exiting: exiting, children: [
|
|
12803
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Body, { children: [
|
|
12804
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconDot, { $color: accent, children: icon }),
|
|
12805
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Content, { children: [
|
|
12806
|
+
/* @__PURE__ */ jsxRuntime.jsx(Title2, { children: toast.title }),
|
|
12807
|
+
toast.amount && /* @__PURE__ */ jsxRuntime.jsx(Amount, { children: toast.amount }),
|
|
12808
|
+
toast.txHash && txUrl && /* @__PURE__ */ jsxRuntime.jsxs(TxRow, { href: txUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
12809
|
+
truncateHash(toast.txHash),
|
|
12810
|
+
/* @__PURE__ */ jsxRuntime.jsx(TxArrow, { children: "\u2197" })
|
|
12811
|
+
] })
|
|
12812
|
+
] }),
|
|
12813
|
+
/* @__PURE__ */ jsxRuntime.jsx(CloseBtn, { type: "button", onClick: dismiss, "aria-label": "Dismiss", children: "\u2715" })
|
|
12814
|
+
] }),
|
|
12815
|
+
duration > 0 && /* @__PURE__ */ jsxRuntime.jsx(ProgressBar2, { $color: accent, $duration: duration })
|
|
12816
|
+
] });
|
|
12817
|
+
}
|
|
12818
|
+
var ToastContext = React5.createContext(null);
|
|
12819
|
+
function ToastProvider({ children }) {
|
|
12820
|
+
const [toasts, setToasts] = React5.useState([]);
|
|
12821
|
+
const addToast = React5.useCallback((data) => {
|
|
12822
|
+
const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
12823
|
+
setToasts((prev) => [...prev, { ...data, id }]);
|
|
12824
|
+
return id;
|
|
12825
|
+
}, []);
|
|
12826
|
+
const dismiss = React5.useCallback((id) => {
|
|
12827
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
12828
|
+
}, []);
|
|
12829
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ToastContext.Provider, { value: { toast: addToast, dismiss }, children: [
|
|
12830
|
+
children,
|
|
12831
|
+
/* @__PURE__ */ jsxRuntime.jsx(Container2, { children: toasts.map((t) => /* @__PURE__ */ jsxRuntime.jsx(ToastItem, { toast: t, onDismiss: dismiss }, t.id)) })
|
|
12832
|
+
] });
|
|
12833
|
+
}
|
|
12834
|
+
function useToast() {
|
|
12835
|
+
const ctx = React5.useContext(ToastContext);
|
|
12836
|
+
if (!ctx) throw new Error("useToast must be used within a ToastProvider");
|
|
12837
|
+
return ctx;
|
|
12838
|
+
}
|
|
12447
12839
|
|
|
12448
12840
|
exports.Badge = Badge;
|
|
12449
12841
|
exports.Button = Button;
|
|
@@ -12478,10 +12870,12 @@ exports.PropertyPhotoGallery = PropertyPhotoGallery;
|
|
|
12478
12870
|
exports.PropertySubheader = PropertySubheader;
|
|
12479
12871
|
exports.PropertyTour = PropertyTour;
|
|
12480
12872
|
exports.PropertyValuation = PropertyValuation;
|
|
12873
|
+
exports.ToastProvider = ToastProvider;
|
|
12481
12874
|
exports.TradeConfirmationModal = TradeConfirmationModal;
|
|
12482
12875
|
exports.TradingSlider = TradingSlider;
|
|
12483
12876
|
exports.YourOrders = YourOrders;
|
|
12484
12877
|
exports.badgeVariants = badgeVariants;
|
|
12485
12878
|
exports.buttonVariants = buttonVariants;
|
|
12879
|
+
exports.useToast = useToast;
|
|
12486
12880
|
//# sourceMappingURL=index.js.map
|
|
12487
12881
|
//# sourceMappingURL=index.js.map
|