@loafmarkets/ui 0.1.36 → 0.1.37
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 +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +212 -141
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +212 -141
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -6951,17 +6951,27 @@ var PropertyCompareBar = React5.forwardRef(
|
|
|
6951
6951
|
}
|
|
6952
6952
|
)
|
|
6953
6953
|
] }),
|
|
6954
|
-
/* @__PURE__ */ jsx(PropertySelectorDropdown, { $isOpen: isDropdownOpen && hasAddresses, children: normalizedAddresses.map((option) =>
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6954
|
+
/* @__PURE__ */ jsx(PropertySelectorDropdown, { $isOpen: isDropdownOpen && hasAddresses, children: normalizedAddresses.map((option) => {
|
|
6955
|
+
const isSelected = option.id === resolvedSelectedId;
|
|
6956
|
+
return /* @__PURE__ */ jsxs(
|
|
6957
|
+
PropertySelectorOption,
|
|
6958
|
+
{
|
|
6959
|
+
$selected: isSelected,
|
|
6960
|
+
onClick: (event) => {
|
|
6961
|
+
event.stopPropagation();
|
|
6962
|
+
handleAddressSelect(option.id);
|
|
6963
|
+
},
|
|
6964
|
+
children: [
|
|
6965
|
+
/* @__PURE__ */ jsx(PropertySelectorName, { children: option.label }),
|
|
6966
|
+
option.subtitle && /* @__PURE__ */ jsxs(PropertySelectorSubtitle, { children: [
|
|
6967
|
+
option.subtitle,
|
|
6968
|
+
option.status && option.status !== "LIVE" && /* @__PURE__ */ jsx("span", { children: option.status === "PENDING" ? "Coming Soon" : option.status })
|
|
6969
|
+
] })
|
|
6970
|
+
]
|
|
6960
6971
|
},
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
)) })
|
|
6972
|
+
option.id
|
|
6973
|
+
);
|
|
6974
|
+
}) })
|
|
6965
6975
|
] }),
|
|
6966
6976
|
propertyValueVariant === "pill" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6967
6977
|
priceContent,
|
|
@@ -7062,33 +7072,64 @@ var PropertyAddress = styled24.div`
|
|
|
7062
7072
|
`;
|
|
7063
7073
|
var PropertySelectorDropdown = styled24.div`
|
|
7064
7074
|
position: absolute;
|
|
7065
|
-
top: 100
|
|
7075
|
+
top: calc(100% + 12px);
|
|
7066
7076
|
left: 0;
|
|
7067
|
-
|
|
7068
|
-
max-width:
|
|
7069
|
-
background
|
|
7070
|
-
border-radius:
|
|
7071
|
-
box-shadow: 0
|
|
7072
|
-
z-index:
|
|
7073
|
-
|
|
7077
|
+
right: 0;
|
|
7078
|
+
max-width: 420px;
|
|
7079
|
+
background: #0a0a0a;
|
|
7080
|
+
border-radius: 16px;
|
|
7081
|
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.8), 0 4px 12px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
7082
|
+
z-index: 1000;
|
|
7083
|
+
max-height: 360px;
|
|
7084
|
+
overflow-y: auto;
|
|
7085
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
7074
7086
|
display: ${(props) => props.$isOpen ? "block" : "none"};
|
|
7087
|
+
animation: compareSlideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
7088
|
+
@keyframes compareSlideDown {
|
|
7089
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
7090
|
+
to { opacity: 1; transform: translateY(0); }
|
|
7091
|
+
}
|
|
7075
7092
|
`;
|
|
7076
7093
|
var PropertySelectorOption = styled24.div`
|
|
7077
|
-
padding:
|
|
7078
|
-
|
|
7094
|
+
padding: 1.25rem 1.5rem;
|
|
7095
|
+
transition: all 0.2s ease;
|
|
7096
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
|
7097
|
+
position: relative;
|
|
7079
7098
|
cursor: pointer;
|
|
7080
|
-
transition: background-color 0.2s;
|
|
7081
7099
|
|
|
7082
|
-
&:
|
|
7083
|
-
|
|
7100
|
+
&:last-child { border-bottom: none; }
|
|
7101
|
+
|
|
7102
|
+
&::before {
|
|
7103
|
+
content: '';
|
|
7104
|
+
position: absolute;
|
|
7105
|
+
left: 0;
|
|
7106
|
+
top: 0;
|
|
7107
|
+
bottom: 0;
|
|
7108
|
+
width: 3px;
|
|
7109
|
+
background: ${(p) => p.$selected ? "var(--color-accent, #e6c87e)" : "transparent"};
|
|
7110
|
+
transition: all 0.2s ease;
|
|
7084
7111
|
}
|
|
7085
7112
|
|
|
7086
|
-
|
|
7087
|
-
|
|
7113
|
+
${(p) => p.$selected && `background: linear-gradient(90deg, rgba(230, 200, 126, 0.08) 0%, transparent 100%);`}
|
|
7114
|
+
|
|
7115
|
+
&:hover {
|
|
7116
|
+
background: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 0%, transparent 100%);
|
|
7088
7117
|
}
|
|
7089
7118
|
`;
|
|
7090
7119
|
var PropertySelectorName = styled24.div`
|
|
7091
7120
|
font-weight: 600;
|
|
7121
|
+
font-size: 1rem;
|
|
7122
|
+
color: #ffffff;
|
|
7123
|
+
margin-bottom: 0.15rem;
|
|
7124
|
+
`;
|
|
7125
|
+
var PropertySelectorSubtitle = styled24.div`
|
|
7126
|
+
font-size: 0.875rem;
|
|
7127
|
+
color: rgba(255, 255, 255, 0.5);
|
|
7128
|
+
span {
|
|
7129
|
+
margin-left: 0.5rem;
|
|
7130
|
+
color: var(--color-accent, #e6c87e);
|
|
7131
|
+
font-size: 0.75rem;
|
|
7132
|
+
}
|
|
7092
7133
|
`;
|
|
7093
7134
|
var PropertyValueBlock = styled24.div`
|
|
7094
7135
|
display: flex;
|
|
@@ -7507,22 +7548,22 @@ var GymIcon = /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox:
|
|
|
7507
7548
|
/* @__PURE__ */ jsx("path", { d: "M10 18h4" })
|
|
7508
7549
|
] });
|
|
7509
7550
|
var DEFAULT_FEATURES = [
|
|
7510
|
-
{ icon: BedIcon, value: "
|
|
7511
|
-
{ icon: BathIcon, value: "
|
|
7512
|
-
{ icon: CarIcon, value: "
|
|
7551
|
+
{ icon: BedIcon, value: "\u2014", label: "Beds" },
|
|
7552
|
+
{ icon: BathIcon, value: "\u2014", label: "Baths" },
|
|
7553
|
+
{ icon: CarIcon, value: "\u2014", label: "Cars" },
|
|
7513
7554
|
{ icon: PoolIcon, label: "Pool" },
|
|
7514
7555
|
{ icon: GardenIcon, label: "Garden" },
|
|
7515
7556
|
{ icon: GymIcon, label: "Gym" }
|
|
7516
7557
|
];
|
|
7517
7558
|
var DEFAULT_PROPERTY_INFO = [
|
|
7518
|
-
{ label: "Property Type", value: "
|
|
7519
|
-
{ label: "Built", value: "
|
|
7520
|
-
{ label: "Ownership", value: "
|
|
7521
|
-
{ label: "Zoning", value: "
|
|
7522
|
-
{ label: "Levels", value: "
|
|
7523
|
-
{ label: "Status", value: "
|
|
7559
|
+
{ label: "Property Type", value: "N/A" },
|
|
7560
|
+
{ label: "Built", value: "N/A" },
|
|
7561
|
+
{ label: "Ownership", value: "N/A" },
|
|
7562
|
+
{ label: "Zoning", value: "N/A" },
|
|
7563
|
+
{ label: "Levels", value: "N/A" },
|
|
7564
|
+
{ label: "Status", value: "N/A" }
|
|
7524
7565
|
];
|
|
7525
|
-
var DEFAULT_DESCRIPTION = "
|
|
7566
|
+
var DEFAULT_DESCRIPTION = "Property description not available.";
|
|
7526
7567
|
function PropertyOverview({
|
|
7527
7568
|
propertyName,
|
|
7528
7569
|
location,
|
|
@@ -8811,66 +8852,25 @@ var SignInButton = styled24.button`
|
|
|
8811
8852
|
background: rgba(240, 185, 11, 0.1);
|
|
8812
8853
|
}
|
|
8813
8854
|
`;
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
{ id: 2, title: "Sydney unemployment drops to 3.1% - Eastern suburbs lead recovery", type: "market" },
|
|
8824
|
-
{ id: 3, title: "Musgrave heritage listing confirmed - protects architectural value", type: "property" },
|
|
8825
|
-
{ id: 4, title: "Mosman Council approves DA for Musgrave restoration works", type: "property" },
|
|
8826
|
-
{ id: 5, title: "Nearby 12 Mcleod St sells for $18.5M - sets new street record", type: "market" },
|
|
8827
|
-
{ id: 6, title: "Eastern suburbs rental yields reach 3.8% - highest in 5 years", type: "market" },
|
|
8828
|
-
{ id: 7, title: "Musgrave pool resurfacing completed - heritage sandstone preserved", type: "property" },
|
|
8829
|
-
{ id: 8, title: "Mosman median house price hits $7.2M - up 9% YoY", type: "market" },
|
|
8830
|
-
{ id: 9, title: "Musgrave gardens featured in Heritage NSW annual report", type: "property" },
|
|
8831
|
-
{ id: 10, title: "Lower North Shore vacancy rates drop to 1.2% - rental demand surges", type: "market" },
|
|
8832
|
-
{ id: 11, title: "Musgrave structural inspection complete - excellent condition confirmed", type: "property" },
|
|
8833
|
-
{ id: 12, title: "Sydney harbour views premium reaches 35% - Mosman leads growth", type: "market" },
|
|
8834
|
-
{ id: 13, title: "New security system installed at Musgrave - smart home integration", type: "property" },
|
|
8835
|
-
{ id: 14, title: "Heritage property demand up 22% - pre-Federation homes most sought", type: "market" }
|
|
8836
|
-
];
|
|
8837
|
-
var musgraveGalleryImages = [
|
|
8838
|
-
{ src: "/properties/Musgrave/ExteriorFront_Musgrave_Loafmarkets.jpg", title: "Exterior Front", subtitle: "Grand entrance" },
|
|
8839
|
-
{ src: "/properties/Musgrave/ExteriorDusk_Musgrave_Loafmarkets.jpg", title: "Exterior Dusk", subtitle: "Evening ambiance" },
|
|
8840
|
-
{ src: "/properties/Musgrave/LivingRoom_Musgrave_Loafmarkets.jpg", title: "Living Room", subtitle: "Spacious living" },
|
|
8841
|
-
{ src: "/properties/Musgrave/Kitchen_Musgrave_Loafmarkets.jpg", title: "Kitchen", subtitle: "Modern design" },
|
|
8842
|
-
{ src: "/properties/Musgrave/DiningRoom_Musgrave_Loafmarkets.jpg", title: "Dining Room", subtitle: "Elegant dining" },
|
|
8843
|
-
{ src: "/properties/Musgrave/BreakfastRoom_Musgrave_Loafmarkets.jpg", title: "Breakfast Room", subtitle: "Morning light" },
|
|
8844
|
-
{ src: "/properties/Musgrave/MainBedroom_Musgrave_Loafmarkets.jpg", title: "Main Bedroom", subtitle: "Master suite" },
|
|
8845
|
-
{ src: "/properties/Musgrave/GuestBedroom_Musgrave_Loafmarkets.jpg", title: "Guest Bedroom", subtitle: "Comfortable stay" },
|
|
8846
|
-
{ src: "/properties/Musgrave/Bathroom_Musgrave_Loafmarkets.jpg", title: "Bathroom", subtitle: "Luxury finishes" },
|
|
8847
|
-
{ src: "/properties/Musgrave/PoolArea_Musgrave_Loafmarkets.jpg", title: "Pool Area", subtitle: "Resort living" },
|
|
8848
|
-
{ src: "/properties/Musgrave/GardenView_Musgrave_Loafmarkets.jpg", title: "Garden View", subtitle: "Lush gardens" },
|
|
8849
|
-
{ src: "/properties/Musgrave/SideGarden_Musgrave_Loafmarkets.jpg", title: "Side Garden", subtitle: "Private retreat" },
|
|
8850
|
-
{ src: "/properties/Musgrave/AerialView_Musgrave_Loafmarkets.jpg", title: "Aerial View", subtitle: "Property overview" },
|
|
8851
|
-
{ src: "/properties/Musgrave/AerialLocation_Musgrave_Loafmarkets.jpg", title: "Aerial Location", subtitle: "Neighborhood" },
|
|
8852
|
-
{ src: "/properties/Musgrave/Floorplan_Musgrave_Loafmarkets.jpg", title: "Floorplan", subtitle: "Layout" }
|
|
8853
|
-
];
|
|
8854
|
-
var galleryCategories = [
|
|
8855
|
-
{ name: "Exterior", startIndex: 0 },
|
|
8856
|
-
{ name: "Living", startIndex: 2 },
|
|
8857
|
-
{ name: "Bedrooms", startIndex: 6 },
|
|
8858
|
-
{ name: "Outdoor", startIndex: 9 },
|
|
8859
|
-
{ name: "Aerial", startIndex: 12 },
|
|
8860
|
-
{ name: "Floorplan", startIndex: 14 }
|
|
8861
|
-
];
|
|
8862
|
-
var STATUS_COLOR2 = {
|
|
8863
|
-
PENDING: "#D4AF37",
|
|
8864
|
-
LIVE: "#0ecb81",
|
|
8865
|
-
CLOSED: "#848e9c",
|
|
8866
|
-
CANCELLED: "#f6465d"
|
|
8867
|
-
};
|
|
8868
|
-
function AssetSelectorBar({ propertyName, tokenPrice, offeringValuation }) {
|
|
8855
|
+
function AssetSelectorBar({
|
|
8856
|
+
propertyName,
|
|
8857
|
+
tokenPrice,
|
|
8858
|
+
offeringValuation,
|
|
8859
|
+
metrics: metricsProp,
|
|
8860
|
+
currentTokenName,
|
|
8861
|
+
selectorItems,
|
|
8862
|
+
onSelect
|
|
8863
|
+
}) {
|
|
8869
8864
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
8865
|
+
const hasItems = selectorItems && selectorItems.length > 0;
|
|
8866
|
+
const metrics = metricsProp ?? [
|
|
8867
|
+
...tokenPrice != null ? [{ label: "Unit Price", value: `$${tokenPrice.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`, accent: true }] : [],
|
|
8868
|
+
...offeringValuation != null ? [{ label: "Offering Valuation", value: `$${offeringValuation.toLocaleString()}` }] : []
|
|
8869
|
+
];
|
|
8870
8870
|
return /* @__PURE__ */ jsx(AssetSelectorWrapper, { children: /* @__PURE__ */ jsxs(IPOAssetSelector, { children: [
|
|
8871
|
-
/* @__PURE__ */ jsx(AssetSelectorDropdown, { onClick: () => setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxs(AssetName, { children: [
|
|
8871
|
+
/* @__PURE__ */ jsx(AssetSelectorDropdown, { onClick: () => hasItems && setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxs(AssetName, { children: [
|
|
8872
8872
|
propertyName,
|
|
8873
|
-
/* @__PURE__ */ jsx(
|
|
8873
|
+
hasItems && /* @__PURE__ */ jsx(
|
|
8874
8874
|
"svg",
|
|
8875
8875
|
{
|
|
8876
8876
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -8883,42 +8883,47 @@ function AssetSelectorBar({ propertyName, tokenPrice, offeringValuation }) {
|
|
|
8883
8883
|
}
|
|
8884
8884
|
)
|
|
8885
8885
|
] }) }),
|
|
8886
|
-
/* @__PURE__ */
|
|
8887
|
-
/* @__PURE__ */
|
|
8888
|
-
|
|
8889
|
-
/* @__PURE__ */ jsxs(
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
] })
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
8896
|
-
/* @__PURE__ */ jsx(MetricLabel2, { children: "Offering Valuation" }),
|
|
8897
|
-
/* @__PURE__ */ jsxs(MetricValue, { children: [
|
|
8886
|
+
metrics.length > 0 && /* @__PURE__ */ jsx(SelectorMetrics, { children: metrics.map((m, i) => /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
|
|
8887
|
+
i > 0 && /* @__PURE__ */ jsx(Separator, { children: "|" }),
|
|
8888
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
8889
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
8890
|
+
/* @__PURE__ */ jsx(MetricLabel2, { children: m.label }),
|
|
8891
|
+
/* @__PURE__ */ jsx(MetricValue, { $accent: !!m.accent, children: m.value })
|
|
8892
|
+
] }),
|
|
8893
|
+
m.change != null && /* @__PURE__ */ jsxs(MetricChange, { $positive: m.change >= 0, children: [
|
|
8894
|
+
m.change >= 0 ? "\u2191" : "\u2193",
|
|
8898
8895
|
"$",
|
|
8899
|
-
|
|
8896
|
+
Math.abs(m.change).toLocaleString(void 0, { maximumFractionDigits: 0 })
|
|
8900
8897
|
] })
|
|
8901
8898
|
] })
|
|
8902
|
-
] }),
|
|
8903
|
-
isDropdownOpen && /* @__PURE__ */ jsx(IPODropdown, { children:
|
|
8904
|
-
const
|
|
8899
|
+
] }, m.label)) }),
|
|
8900
|
+
isDropdownOpen && hasItems && /* @__PURE__ */ jsx(IPODropdown, { children: selectorItems.map((item) => {
|
|
8901
|
+
const isCurrent = item.tokenName === currentTokenName;
|
|
8902
|
+
const status = item.status?.toUpperCase();
|
|
8903
|
+
const statusLabel = status === "PENDING" ? "Coming Soon" : status === "CLOSED" ? "Closed" : status === "CANCELLED" ? "Cancelled" : null;
|
|
8905
8904
|
return /* @__PURE__ */ jsxs(
|
|
8906
8905
|
IPOOption,
|
|
8907
8906
|
{
|
|
8908
8907
|
onClick: () => {
|
|
8909
|
-
if (!
|
|
8908
|
+
if (!isCurrent && onSelect) {
|
|
8909
|
+
onSelect(item.tokenName);
|
|
8910
|
+
}
|
|
8911
|
+
setIsDropdownOpen(false);
|
|
8910
8912
|
},
|
|
8911
|
-
$selected:
|
|
8912
|
-
style: {
|
|
8913
|
+
$selected: isCurrent,
|
|
8914
|
+
style: { cursor: isCurrent ? "default" : "pointer" },
|
|
8913
8915
|
children: [
|
|
8914
|
-
/* @__PURE__ */
|
|
8916
|
+
/* @__PURE__ */ jsxs(IPOOptionName, { children: [
|
|
8917
|
+
item.streetAddress,
|
|
8918
|
+
item.ticker ? ` (${item.ticker})` : ""
|
|
8919
|
+
] }),
|
|
8915
8920
|
/* @__PURE__ */ jsxs(IPOOptionLocation, { children: [
|
|
8916
|
-
|
|
8917
|
-
|
|
8921
|
+
item.suburb,
|
|
8922
|
+
statusLabel && /* @__PURE__ */ jsx("span", { children: statusLabel })
|
|
8918
8923
|
] })
|
|
8919
8924
|
]
|
|
8920
8925
|
},
|
|
8921
|
-
|
|
8926
|
+
item.tokenName
|
|
8922
8927
|
);
|
|
8923
8928
|
}) })
|
|
8924
8929
|
] }) });
|
|
@@ -8972,17 +8977,26 @@ var SelectorMetrics = styled24.div`
|
|
|
8972
8977
|
border: 1px solid rgba(255,255,255,0.05);
|
|
8973
8978
|
`;
|
|
8974
8979
|
var MetricLabel2 = styled24.span`
|
|
8975
|
-
font-size: 0.
|
|
8980
|
+
font-size: 0.75rem;
|
|
8976
8981
|
color: var(--color-text-secondary);
|
|
8977
8982
|
text-transform: uppercase;
|
|
8978
8983
|
letter-spacing: 0.05em;
|
|
8979
8984
|
font-weight: 500;
|
|
8985
|
+
margin-right: 0.5rem;
|
|
8980
8986
|
`;
|
|
8981
8987
|
var MetricValue = styled24.span`
|
|
8982
|
-
font-size: 1.
|
|
8988
|
+
font-size: 1.25rem;
|
|
8983
8989
|
font-weight: 700;
|
|
8984
8990
|
color: ${(p) => p.$accent ? "#D4AF37" : "#fff"};
|
|
8985
8991
|
`;
|
|
8992
|
+
var MetricChange = styled24.span`
|
|
8993
|
+
font-size: 0.85rem;
|
|
8994
|
+
font-weight: 600;
|
|
8995
|
+
color: ${(p) => p.$positive ? "var(--color-positive, #0ecb81)" : "var(--color-negative, #f6465d)"};
|
|
8996
|
+
display: flex;
|
|
8997
|
+
align-items: center;
|
|
8998
|
+
gap: 0.25rem;
|
|
8999
|
+
`;
|
|
8986
9000
|
var Separator = styled24.span`
|
|
8987
9001
|
font-size: 1rem;
|
|
8988
9002
|
color: rgba(255,255,255,0.2);
|
|
@@ -9690,7 +9704,7 @@ function OrderPanel({
|
|
|
9690
9704
|
orderPlacedSuccess,
|
|
9691
9705
|
lastOrderDetails,
|
|
9692
9706
|
tokenQuantity,
|
|
9693
|
-
|
|
9707
|
+
feeInUsd,
|
|
9694
9708
|
orderTotal,
|
|
9695
9709
|
sliderValue,
|
|
9696
9710
|
manualOrderAmount,
|
|
@@ -9727,17 +9741,17 @@ function OrderPanel({
|
|
|
9727
9741
|
};
|
|
9728
9742
|
const handleReceiveBlur = () => {
|
|
9729
9743
|
setIsReceiveInputFocused(false);
|
|
9730
|
-
const
|
|
9731
|
-
const
|
|
9732
|
-
if (
|
|
9744
|
+
const units = Math.floor(parseInt(receiveInputValue.replace(/[^0-9]/g, ""), 10) || 0);
|
|
9745
|
+
const spend = units * tokenPrice;
|
|
9746
|
+
if (units <= 0) {
|
|
9733
9747
|
setManualOrderAmount(null);
|
|
9734
9748
|
setSliderValue(0);
|
|
9735
|
-
} else if (
|
|
9749
|
+
} else if (spend >= availableBalance) {
|
|
9736
9750
|
setManualOrderAmount(null);
|
|
9737
9751
|
setSliderValue(100);
|
|
9738
9752
|
} else {
|
|
9739
|
-
setManualOrderAmount(
|
|
9740
|
-
const ratio = availableBalance === 0 ? 0 : Math.round(Math.max(0,
|
|
9753
|
+
setManualOrderAmount(spend);
|
|
9754
|
+
const ratio = availableBalance === 0 ? 0 : Math.round(Math.max(0, spend / availableBalance * 100));
|
|
9741
9755
|
setSliderValue(ratio);
|
|
9742
9756
|
}
|
|
9743
9757
|
};
|
|
@@ -9859,12 +9873,12 @@ function OrderPanel({
|
|
|
9859
9873
|
"input",
|
|
9860
9874
|
{
|
|
9861
9875
|
type: "text",
|
|
9862
|
-
inputMode: "
|
|
9863
|
-
value: isReceiveInputFocused ? receiveInputValue : tokenQuantity.
|
|
9876
|
+
inputMode: "numeric",
|
|
9877
|
+
value: isReceiveInputFocused ? receiveInputValue : tokenQuantity.toString(),
|
|
9864
9878
|
style: { color: "#0ecb81" },
|
|
9865
9879
|
onFocus: (e) => {
|
|
9866
9880
|
setIsReceiveInputFocused(true);
|
|
9867
|
-
setReceiveInputValue(tokenQuantity.
|
|
9881
|
+
setReceiveInputValue(tokenQuantity.toString());
|
|
9868
9882
|
e.target.select();
|
|
9869
9883
|
},
|
|
9870
9884
|
onBlur: handleReceiveBlur,
|
|
@@ -9891,7 +9905,7 @@ function OrderPanel({
|
|
|
9891
9905
|
/* @__PURE__ */ jsxs(SummaryRow, { children: [
|
|
9892
9906
|
/* @__PURE__ */ jsx("span", { children: "Buying" }),
|
|
9893
9907
|
/* @__PURE__ */ jsxs("strong", { children: [
|
|
9894
|
-
tokenQuantity.toLocaleString(
|
|
9908
|
+
tokenQuantity.toLocaleString(),
|
|
9895
9909
|
" ",
|
|
9896
9910
|
tokenSymbol
|
|
9897
9911
|
] })
|
|
@@ -9903,9 +9917,9 @@ function OrderPanel({
|
|
|
9903
9917
|
"%)"
|
|
9904
9918
|
] }),
|
|
9905
9919
|
/* @__PURE__ */ jsxs("strong", { children: [
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9920
|
+
"$",
|
|
9921
|
+
feeInUsd.toFixed(2),
|
|
9922
|
+
" USD"
|
|
9909
9923
|
] })
|
|
9910
9924
|
] }),
|
|
9911
9925
|
/* @__PURE__ */ jsxs(SummaryTotal, { children: [
|
|
@@ -11257,6 +11271,55 @@ var ButtonRow2 = styled24.div`
|
|
|
11257
11271
|
box-shadow: 0 4px 12px rgba(14,203,129,0.3);
|
|
11258
11272
|
}
|
|
11259
11273
|
`;
|
|
11274
|
+
|
|
11275
|
+
// src/components/property-buy/constants.ts
|
|
11276
|
+
var allNewsItems = [
|
|
11277
|
+
{ id: 1, title: "RBA signals potential rate cut in Q1 2026 - property stocks rally", type: "market" },
|
|
11278
|
+
{ id: 2, title: "Sydney unemployment drops to 3.1% - Eastern suburbs lead recovery", type: "market" },
|
|
11279
|
+
{ id: 3, title: "Musgrave heritage listing confirmed - protects architectural value", type: "property" },
|
|
11280
|
+
{ id: 4, title: "Mosman Council approves DA for Musgrave restoration works", type: "property" },
|
|
11281
|
+
{ id: 5, title: "Nearby 12 Mcleod St sells for $18.5M - sets new street record", type: "market" },
|
|
11282
|
+
{ id: 6, title: "Eastern suburbs rental yields reach 3.8% - highest in 5 years", type: "market" },
|
|
11283
|
+
{ id: 7, title: "Musgrave pool resurfacing completed - heritage sandstone preserved", type: "property" },
|
|
11284
|
+
{ id: 8, title: "Mosman median house price hits $7.2M - up 9% YoY", type: "market" },
|
|
11285
|
+
{ id: 9, title: "Musgrave gardens featured in Heritage NSW annual report", type: "property" },
|
|
11286
|
+
{ id: 10, title: "Lower North Shore vacancy rates drop to 1.2% - rental demand surges", type: "market" },
|
|
11287
|
+
{ id: 11, title: "Musgrave structural inspection complete - excellent condition confirmed", type: "property" },
|
|
11288
|
+
{ id: 12, title: "Sydney harbour views premium reaches 35% - Mosman leads growth", type: "market" },
|
|
11289
|
+
{ id: 13, title: "New security system installed at Musgrave - smart home integration", type: "property" },
|
|
11290
|
+
{ id: 14, title: "Heritage property demand up 22% - pre-Federation homes most sought", type: "market" }
|
|
11291
|
+
];
|
|
11292
|
+
var musgraveGalleryImages = [
|
|
11293
|
+
{ src: "/properties/Musgrave/ExteriorFront_Musgrave_Loafmarkets.jpg", title: "Exterior Front", subtitle: "Grand entrance" },
|
|
11294
|
+
{ src: "/properties/Musgrave/ExteriorDusk_Musgrave_Loafmarkets.jpg", title: "Exterior Dusk", subtitle: "Evening ambiance" },
|
|
11295
|
+
{ src: "/properties/Musgrave/LivingRoom_Musgrave_Loafmarkets.jpg", title: "Living Room", subtitle: "Spacious living" },
|
|
11296
|
+
{ src: "/properties/Musgrave/Kitchen_Musgrave_Loafmarkets.jpg", title: "Kitchen", subtitle: "Modern design" },
|
|
11297
|
+
{ src: "/properties/Musgrave/DiningRoom_Musgrave_Loafmarkets.jpg", title: "Dining Room", subtitle: "Elegant dining" },
|
|
11298
|
+
{ src: "/properties/Musgrave/BreakfastRoom_Musgrave_Loafmarkets.jpg", title: "Breakfast Room", subtitle: "Morning light" },
|
|
11299
|
+
{ src: "/properties/Musgrave/MainBedroom_Musgrave_Loafmarkets.jpg", title: "Main Bedroom", subtitle: "Master suite" },
|
|
11300
|
+
{ src: "/properties/Musgrave/GuestBedroom_Musgrave_Loafmarkets.jpg", title: "Guest Bedroom", subtitle: "Comfortable stay" },
|
|
11301
|
+
{ src: "/properties/Musgrave/Bathroom_Musgrave_Loafmarkets.jpg", title: "Bathroom", subtitle: "Luxury finishes" },
|
|
11302
|
+
{ src: "/properties/Musgrave/PoolArea_Musgrave_Loafmarkets.jpg", title: "Pool Area", subtitle: "Resort living" },
|
|
11303
|
+
{ src: "/properties/Musgrave/GardenView_Musgrave_Loafmarkets.jpg", title: "Garden View", subtitle: "Lush gardens" },
|
|
11304
|
+
{ src: "/properties/Musgrave/SideGarden_Musgrave_Loafmarkets.jpg", title: "Side Garden", subtitle: "Private retreat" },
|
|
11305
|
+
{ src: "/properties/Musgrave/AerialView_Musgrave_Loafmarkets.jpg", title: "Aerial View", subtitle: "Property overview" },
|
|
11306
|
+
{ src: "/properties/Musgrave/AerialLocation_Musgrave_Loafmarkets.jpg", title: "Aerial Location", subtitle: "Neighborhood" },
|
|
11307
|
+
{ src: "/properties/Musgrave/Floorplan_Musgrave_Loafmarkets.jpg", title: "Floorplan", subtitle: "Layout" }
|
|
11308
|
+
];
|
|
11309
|
+
var galleryCategories = [
|
|
11310
|
+
{ name: "Exterior", startIndex: 0 },
|
|
11311
|
+
{ name: "Living", startIndex: 2 },
|
|
11312
|
+
{ name: "Bedrooms", startIndex: 6 },
|
|
11313
|
+
{ name: "Outdoor", startIndex: 9 },
|
|
11314
|
+
{ name: "Aerial", startIndex: 12 },
|
|
11315
|
+
{ name: "Floorplan", startIndex: 14 }
|
|
11316
|
+
];
|
|
11317
|
+
var STATUS_COLOR2 = {
|
|
11318
|
+
PENDING: "#D4AF37",
|
|
11319
|
+
LIVE: "#0ecb81",
|
|
11320
|
+
CLOSED: "#848e9c",
|
|
11321
|
+
CANCELLED: "#f6465d"
|
|
11322
|
+
};
|
|
11260
11323
|
function PropertyBuy({
|
|
11261
11324
|
propertyName = "Loaf Property",
|
|
11262
11325
|
propertyLocation: propertyLocationLabel = "Sydney, NSW",
|
|
@@ -11277,10 +11340,12 @@ function PropertyBuy({
|
|
|
11277
11340
|
recentOrders = [],
|
|
11278
11341
|
ordersAllocated = 0,
|
|
11279
11342
|
subscribers = 0,
|
|
11343
|
+
selectorItems,
|
|
11344
|
+
onSelectorSelect,
|
|
11280
11345
|
portfolioActivity
|
|
11281
11346
|
}) {
|
|
11282
11347
|
const [sliderValue, setSliderValue] = useState(0);
|
|
11283
|
-
const [availableBalance, setAvailableBalance] = useState(walletUsdcBalance ??
|
|
11348
|
+
const [availableBalance, setAvailableBalance] = useState(walletUsdcBalance ?? 0);
|
|
11284
11349
|
const [manualOrderAmount, setManualOrderAmount] = useState(null);
|
|
11285
11350
|
const [ownedTokens, setOwnedTokens] = useState(0);
|
|
11286
11351
|
const [displayedOwnedTokens, setDisplayedOwnedTokens] = useState(0);
|
|
@@ -11310,11 +11375,10 @@ function PropertyBuy({
|
|
|
11310
11375
|
const statusColor = STATUS_COLOR2[ipoStatus] ?? "#D4AF37";
|
|
11311
11376
|
const displayStatusLabel = isPrivateClient && ipoStatus !== "LIVE" ? "Private Client Access" : statusLabel;
|
|
11312
11377
|
const displayStatusColor = isPrivateClient && ipoStatus !== "LIVE" ? "#D4AF37" : statusColor;
|
|
11313
|
-
const
|
|
11314
|
-
const
|
|
11315
|
-
const
|
|
11316
|
-
const
|
|
11317
|
-
const orderTotal = totalSpend;
|
|
11378
|
+
const rawSpend = manualOrderAmount !== null ? manualOrderAmount : Math.round(sliderValue / 100 * availableBalance);
|
|
11379
|
+
const tokenQuantity = Math.floor(rawSpend / tokenPrice);
|
|
11380
|
+
const feeInUsd = tokenQuantity * tokenPrice * feeRate;
|
|
11381
|
+
const orderTotal = tokenQuantity * tokenPrice + feeInUsd;
|
|
11318
11382
|
const estExposure = (tokenQuantity / supplyToSell * 100).toFixed(4);
|
|
11319
11383
|
const hasInsufficientFunds = orderTotal > availableBalance;
|
|
11320
11384
|
useEffect(() => {
|
|
@@ -11354,16 +11418,20 @@ function PropertyBuy({
|
|
|
11354
11418
|
return false;
|
|
11355
11419
|
};
|
|
11356
11420
|
const confirmOrder = async () => {
|
|
11357
|
-
setShowOrderConfirmModal(false);
|
|
11358
11421
|
const tokenAmountInt = Math.floor(tokenQuantity);
|
|
11359
|
-
if (tokenAmountInt <= 0)
|
|
11422
|
+
if (tokenAmountInt <= 0) {
|
|
11423
|
+
setShowOrderConfirmModal(false);
|
|
11424
|
+
return;
|
|
11425
|
+
}
|
|
11360
11426
|
if (onPurchase) {
|
|
11361
11427
|
try {
|
|
11362
11428
|
await onPurchase(tokenAmountInt);
|
|
11363
11429
|
} catch {
|
|
11430
|
+
setShowOrderConfirmModal(false);
|
|
11364
11431
|
return;
|
|
11365
11432
|
}
|
|
11366
11433
|
}
|
|
11434
|
+
setShowOrderConfirmModal(false);
|
|
11367
11435
|
if (walletUsdcBalance == null) {
|
|
11368
11436
|
setAvailableBalance((prev) => prev - orderTotal);
|
|
11369
11437
|
}
|
|
@@ -11415,7 +11483,10 @@ function PropertyBuy({
|
|
|
11415
11483
|
{
|
|
11416
11484
|
propertyName,
|
|
11417
11485
|
tokenPrice,
|
|
11418
|
-
offeringValuation
|
|
11486
|
+
offeringValuation,
|
|
11487
|
+
currentTokenName: tokenName,
|
|
11488
|
+
selectorItems,
|
|
11489
|
+
onSelect: onSelectorSelect
|
|
11419
11490
|
}
|
|
11420
11491
|
) }),
|
|
11421
11492
|
/* @__PURE__ */ jsx(
|
|
@@ -11464,7 +11535,7 @@ function PropertyBuy({
|
|
|
11464
11535
|
orderPlacedSuccess,
|
|
11465
11536
|
lastOrderDetails,
|
|
11466
11537
|
tokenQuantity,
|
|
11467
|
-
|
|
11538
|
+
feeInUsd,
|
|
11468
11539
|
orderTotal,
|
|
11469
11540
|
sliderValue,
|
|
11470
11541
|
manualOrderAmount,
|