@loafmarkets/ui 0.1.36 → 0.1.38

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
@@ -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) => /* @__PURE__ */ jsx(
6955
- PropertySelectorOption,
6956
- {
6957
- onClick: (event) => {
6958
- event.stopPropagation();
6959
- handleAddressSelect(option.id);
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
- children: /* @__PURE__ */ jsx(PropertySelectorName, { children: option.label })
6962
- },
6963
- option.id
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
- width: 100%;
7068
- max-width: 400px;
7069
- background-color: var(--color-card, #1f232b);
7070
- border-radius: 8px;
7071
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
7072
- z-index: 100;
7073
- overflow: hidden;
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: 0.75rem 1rem;
7078
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
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
- &:hover {
7083
- background-color: rgba(255, 255, 255, 0.05);
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
- &:last-child {
7087
- border-bottom: none;
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: "4", label: "Beds" },
7511
- { icon: BathIcon, value: "5", label: "Baths" },
7512
- { icon: CarIcon, value: "4", label: "Cars" },
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: "Contemporary House" },
7519
- { label: "Built", value: "2015" },
7520
- { label: "Ownership", value: "Freehold" },
7521
- { label: "Zoning", value: "R2 Low Density" },
7522
- { label: "Levels", value: "3" },
7523
- { label: "Status", value: "Rented", status: "active" }
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 = "A sweeping panorama across Sydney Harbour stretching from Manly to the iconic city skyline creates a spectacular backdrop from every level of this contemporary masterpiece.";
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
- // src/components/property-buy/constants.ts
8816
- var mockIPOList = [
8817
- { id: "musgrave", name: "8C Mcleod Street (Musgrave)", location: "Mosman, Sydney", status: "live" },
8818
- { id: "ipo-002", name: "15 Ocean View Drive", location: "Bondi, Sydney", status: "coming_soon" },
8819
- { id: "ipo-003", name: "42 Harbour Lane", location: "Mosman, Sydney", status: "coming_soon" }
8820
- ];
8821
- var allNewsItems = [
8822
- { id: 1, title: "RBA signals potential rate cut in Q1 2026 - property stocks rally", type: "market" },
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__ */ jsxs(SelectorMetrics, { children: [
8887
- /* @__PURE__ */ jsxs("div", { children: [
8888
- /* @__PURE__ */ jsx(MetricLabel2, { children: "Unit Price" }),
8889
- /* @__PURE__ */ jsxs(MetricValue, { $accent: true, children: [
8890
- "$",
8891
- tokenPrice.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
8892
- ] })
8893
- ] }),
8894
- /* @__PURE__ */ jsx(Separator, { children: "|" }),
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
- offeringValuation.toLocaleString()
8896
+ Math.abs(m.change).toLocaleString(void 0, { maximumFractionDigits: 0 })
8900
8897
  ] })
8901
8898
  ] })
8902
- ] }),
8903
- isDropdownOpen && /* @__PURE__ */ jsx(IPODropdown, { children: mockIPOList.map((ipo) => {
8904
- const isDisabled = ipo.status === "coming_soon";
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 (!isDisabled) setIsDropdownOpen(false);
8908
+ if (!isCurrent && onSelect) {
8909
+ onSelect(item.tokenName);
8910
+ }
8911
+ setIsDropdownOpen(false);
8910
8912
  },
8911
- $selected: ipo.id === "musgrave",
8912
- style: { opacity: isDisabled ? 0.4 : 1, cursor: isDisabled ? "not-allowed" : "pointer" },
8913
+ $selected: isCurrent,
8914
+ style: { cursor: isCurrent ? "default" : "pointer" },
8913
8915
  children: [
8914
- /* @__PURE__ */ jsx(IPOOptionName, { children: ipo.name }),
8916
+ /* @__PURE__ */ jsxs(IPOOptionName, { children: [
8917
+ item.streetAddress,
8918
+ item.ticker ? ` (${item.ticker})` : ""
8919
+ ] }),
8915
8920
  /* @__PURE__ */ jsxs(IPOOptionLocation, { children: [
8916
- ipo.location,
8917
- isDisabled && /* @__PURE__ */ jsx("span", { children: "Coming Soon" })
8921
+ item.suburb,
8922
+ statusLabel && /* @__PURE__ */ jsx("span", { children: statusLabel })
8918
8923
  ] })
8919
8924
  ]
8920
8925
  },
8921
- ipo.id
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.65rem;
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.1rem;
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
- feeInTokens,
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 parsed = parseFloat(receiveInputValue) || 0;
9731
- const newOrderTotal = Math.round(parsed * tokenPrice);
9732
- if (newOrderTotal <= 0) {
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 (newOrderTotal >= availableBalance) {
9749
+ } else if (spend >= availableBalance) {
9736
9750
  setManualOrderAmount(null);
9737
9751
  setSliderValue(100);
9738
9752
  } else {
9739
- setManualOrderAmount(newOrderTotal);
9740
- const ratio = availableBalance === 0 ? 0 : Math.round(Math.max(0, newOrderTotal / availableBalance * 100));
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: "decimal",
9863
- value: isReceiveInputFocused ? receiveInputValue : tokenQuantity.toFixed(2),
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.toFixed(2));
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(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
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
- feeInTokens.toFixed(2),
9907
- " ",
9908
- tokenSymbol
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 ?? 125e3);
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 totalSpend = manualOrderAmount !== null ? manualOrderAmount : Math.round(sliderValue / 100 * availableBalance);
11314
- const grossTokens = totalSpend / tokenPrice;
11315
- const feeInTokens = grossTokens * feeRate;
11316
- const tokenQuantity = grossTokens - feeInTokens;
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) return;
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
- feeInTokens,
11538
+ feeInUsd,
11468
11539
  orderTotal,
11469
11540
  sliderValue,
11470
11541
  manualOrderAmount,
@@ -14036,6 +14107,6 @@ function useToast() {
14036
14107
  return ctx;
14037
14108
  }
14038
14109
 
14039
- export { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Header, HousePositionSlider, HousePositionSliderMobile, LoafLiquidityBadge, LoafLiquidityLogo, LoginPopup, MobileTradeNav, Orderbook, owner_booking_default as OwnerBooking, PaymentPopup, PortfolioActivityPanel, PortfolioSummary, PriceChart, PropertyBuy, PropertyCompareBar, PropertyDocuments, PropertyHeroHeader, PropertyHistory, PropertyInspectionTimes, PropertyNewsUpdates, PropertyOffers, PropertyOverview, PropertyPhotoGallery, PropertySubheader, PropertyTour, PropertyValuation, ToastProvider, TradeConfirmationModal, TradingSlider, YourOrders, badgeVariants, buttonVariants, useToast };
14110
+ export { AssetSelectorBar, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Header, HousePositionSlider, HousePositionSliderMobile, LoafLiquidityBadge, LoafLiquidityLogo, LoginPopup, MobileTradeNav, Orderbook, owner_booking_default as OwnerBooking, PaymentPopup, PortfolioActivityPanel, PortfolioSummary, PriceChart, PropertyBuy, PropertyCompareBar, PropertyDocuments, PropertyHeroHeader, PropertyHistory, PropertyInspectionTimes, PropertyNewsUpdates, PropertyOffers, PropertyOverview, PropertyPhotoGallery, PropertySubheader, PropertyTour, PropertyValuation, ToastProvider, TradeConfirmationModal, TradingSlider, YourOrders, badgeVariants, buttonVariants, useToast };
14040
14111
  //# sourceMappingURL=index.mjs.map
14041
14112
  //# sourceMappingURL=index.mjs.map