@loafmarkets/ui 0.1.40 → 0.1.41

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
@@ -1,5 +1,5 @@
1
1
  import * as React5 from 'react';
2
- import React5__default, { createContext, useState, useEffect, useMemo, useRef, useCallback, useContext } from 'react';
2
+ import React5__default, { createContext, useState, useEffect, useMemo, useCallback, useRef, useContext } from 'react';
3
3
  import { Slot } from '@radix-ui/react-slot';
4
4
  import { cva } from 'class-variance-authority';
5
5
  import { clsx } from 'clsx';
@@ -1984,7 +1984,7 @@ function DesktopOrderbookLayout({
1984
1984
  /* @__PURE__ */ jsx(
1985
1985
  "div",
1986
1986
  {
1987
- className: "divide-y divide-white/5 overflow-y-auto",
1987
+ className: "flex flex-col justify-end divide-y divide-white/5 overflow-y-auto",
1988
1988
  style: { height: `${sectionHeight}px`, scrollbarGutter: "stable" },
1989
1989
  children: asks.map((l, idx) => /* @__PURE__ */ jsx(
1990
1990
  DepthRow,
@@ -4850,6 +4850,7 @@ var Header = ({
4850
4850
  const portfolioActive = resolvedActiveTab === "portfolio";
4851
4851
  const learnActive = resolvedActiveTab === "learn";
4852
4852
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4853
+ /* @__PURE__ */ jsx(SafeAreaCover, {}),
4853
4854
  /* @__PURE__ */ jsx(Overlay, { $isOpen: isMobileMenuOpen, onClick: () => setIsMobileMenuOpen(false) }),
4854
4855
  /* @__PURE__ */ jsxs(HeaderContainer, { children: [
4855
4856
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
@@ -5099,6 +5100,17 @@ var Header = ({
5099
5100
  ] });
5100
5101
  };
5101
5102
  Header.displayName = "Header";
5103
+ var SafeAreaCover = styled24.div`
5104
+ position: fixed;
5105
+ top: 0;
5106
+ left: 0;
5107
+ right: 0;
5108
+ height: env(safe-area-inset-top, 0px);
5109
+ min-height: env(safe-area-inset-top, 0px);
5110
+ background-color: #0d1117;
5111
+ z-index: 1001;
5112
+ pointer-events: none;
5113
+ `;
5102
5114
  var Overlay = styled24.div`
5103
5115
  display: ${(props) => props.$isOpen ? "block" : "none"};
5104
5116
  position: fixed;
@@ -5145,20 +5157,24 @@ var HeaderContainer = styled24.header`
5145
5157
  display: flex;
5146
5158
  justify-content: space-between;
5147
5159
  align-items: center;
5160
+ /* Split padding so browsers that don't support env() inside shorthand
5161
+ still get the horizontal padding — only the top falls back to 0 */
5148
5162
  padding: 0 2rem;
5163
+ padding-top: env(safe-area-inset-top, 0px);
5149
5164
  background-color: #0d1117;
5150
5165
  border-bottom: 1px solid #232a32;
5151
5166
  position: sticky;
5152
5167
  top: 0;
5153
- left: 0;
5154
- right: 0;
5155
5168
  z-index: 1000;
5156
5169
  width: 100%;
5157
- height: 56px;
5170
+ /* Fallback min-height for browsers that can't evaluate calc+env */
5171
+ min-height: 56px;
5172
+ min-height: calc(56px + env(safe-area-inset-top, 0px));
5158
5173
  box-sizing: border-box;
5159
5174
 
5160
5175
  @media (max-width: 768px) {
5161
5176
  padding: 0 1rem;
5177
+ padding-top: env(safe-area-inset-top, 0px);
5162
5178
  }
5163
5179
  `;
5164
5180
  var Logo = styled24.div`
@@ -9756,6 +9772,7 @@ function OrderPanel({
9756
9772
  displayedOwnedTokens,
9757
9773
  ownedTokensJustUpdated,
9758
9774
  lastOrderQuantity,
9775
+ orderPendingAllocation,
9759
9776
  orderPlacedSuccess,
9760
9777
  lastOrderDetails,
9761
9778
  tokenQuantity,
@@ -9818,7 +9835,40 @@ function OrderPanel({
9818
9835
  statusLabel
9819
9836
  ] })
9820
9837
  ] }),
9821
- orderPlacedSuccess ? /* @__PURE__ */ jsxs(OrderSuccessCard, { children: [
9838
+ orderPendingAllocation ? /* @__PURE__ */ jsxs(OrderPendingCard, { children: [
9839
+ /* @__PURE__ */ jsxs("div", { className: "pending-header", children: [
9840
+ /* @__PURE__ */ jsx("div", { className: "spinner" }),
9841
+ /* @__PURE__ */ jsxs("div", { children: [
9842
+ /* @__PURE__ */ jsx("p", { children: "Processing Order" }),
9843
+ /* @__PURE__ */ jsx("small", { children: "Awaiting allocation..." })
9844
+ ] })
9845
+ ] }),
9846
+ /* @__PURE__ */ jsxs("div", { className: "pending-body", children: [
9847
+ [
9848
+ { label: "Units Requested", value: /* @__PURE__ */ jsxs(Fragment, { children: [
9849
+ lastOrderDetails?.tokens?.toFixed(2) || "0.00",
9850
+ " ",
9851
+ /* @__PURE__ */ jsx("span", { style: { color: "rgba(255,255,255,0.4)", fontWeight: 400 }, children: tokenSymbol })
9852
+ ] }) },
9853
+ { label: "Price Per Unit", value: `$${tokenPrice.toFixed(2)}` },
9854
+ {
9855
+ label: `${tokenDisplayName} Exposure`,
9856
+ value: `${((lastOrderDetails?.tokens ?? 0) / supplyToSell * 100).toFixed(3)}%`
9857
+ }
9858
+ ].map((row) => /* @__PURE__ */ jsxs("div", { className: "pending-row", children: [
9859
+ /* @__PURE__ */ jsx("span", { children: row.label }),
9860
+ /* @__PURE__ */ jsx("strong", { children: row.value })
9861
+ ] }, row.label)),
9862
+ /* @__PURE__ */ jsxs("div", { className: "pending-total", children: [
9863
+ /* @__PURE__ */ jsx("span", { children: "Total Investment" }),
9864
+ /* @__PURE__ */ jsxs("strong", { children: [
9865
+ "$",
9866
+ lastOrderDetails?.total?.toLocaleString() || "0"
9867
+ ] })
9868
+ ] })
9869
+ ] }),
9870
+ /* @__PURE__ */ jsx("div", { className: "pending-footnote", children: "Your order has been submitted and is being processed. This usually takes a few seconds." })
9871
+ ] }) : orderPlacedSuccess ? /* @__PURE__ */ jsxs(OrderSuccessCard, { children: [
9822
9872
  /* @__PURE__ */ jsxs("div", { className: "success-header", children: [
9823
9873
  /* @__PURE__ */ jsx("div", { className: "icon", children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "#D4AF37", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) }) }),
9824
9874
  /* @__PURE__ */ jsxs("div", { children: [
@@ -9997,7 +10047,7 @@ function OrderPanel({
9997
10047
  ] })
9998
10048
  ] })
9999
10049
  ] }),
10000
- !orderPlacedSuccess && /* @__PURE__ */ jsx(
10050
+ !orderPlacedSuccess && !orderPendingAllocation && /* @__PURE__ */ jsx(
10001
10051
  SubscribeButton,
10002
10052
  {
10003
10053
  type: "button",
@@ -10320,6 +10370,110 @@ var BalanceSub = styled24.div`
10320
10370
  color: var(--color-text-secondary);
10321
10371
  margin-top: 0.25rem;
10322
10372
  `;
10373
+ var OrderPendingCard = styled24.div`
10374
+ margin-bottom: 1.5rem;
10375
+ background: linear-gradient(180deg, rgba(25,27,31,0.95) 0%, rgba(18,20,24,0.98) 100%);
10376
+ border: 1px solid rgba(212,175,55,0.08);
10377
+ border-radius: 12px;
10378
+ overflow: hidden;
10379
+ box-shadow: 0 4px 20px rgba(0,0,0,0.3);
10380
+
10381
+ @keyframes spin {
10382
+ to { transform: rotate(360deg); }
10383
+ }
10384
+
10385
+ @keyframes pulse {
10386
+ 0%, 100% { opacity: 1; }
10387
+ 50% { opacity: 0.6; }
10388
+ }
10389
+
10390
+ .pending-header {
10391
+ border-bottom: 1px solid rgba(255,255,255,0.06);
10392
+ padding: 1.25rem 1.5rem;
10393
+ display: flex;
10394
+ align-items: center;
10395
+ gap: 0.875rem;
10396
+ background: linear-gradient(135deg, rgba(212,175,55,0.04) 0%, transparent 100%);
10397
+
10398
+ .spinner {
10399
+ width: 32px;
10400
+ height: 32px;
10401
+ border-radius: 50%;
10402
+ border: 2.5px solid rgba(212,175,55,0.15);
10403
+ border-top-color: #D4AF37;
10404
+ animation: spin 0.8s linear infinite;
10405
+ flex-shrink: 0;
10406
+ }
10407
+
10408
+ p {
10409
+ font-size: 0.95rem;
10410
+ font-weight: 600;
10411
+ color: #fff;
10412
+ margin: 0;
10413
+ animation: pulse 2s ease-in-out infinite;
10414
+ }
10415
+ small {
10416
+ font-size: 0.7rem;
10417
+ color: rgba(255,255,255,0.4);
10418
+ }
10419
+ }
10420
+
10421
+ .pending-body {
10422
+ padding: 1.25rem 1.5rem;
10423
+ }
10424
+ .pending-row {
10425
+ display: flex;
10426
+ justify-content: space-between;
10427
+ align-items: center;
10428
+ padding-bottom: 0.875rem;
10429
+ margin-bottom: 0.875rem;
10430
+ border-bottom: 1px solid rgba(255,255,255,0.06);
10431
+ span {
10432
+ font-size: 0.75rem;
10433
+ color: rgba(255,255,255,0.4);
10434
+ text-transform: uppercase;
10435
+ letter-spacing: 0.05em;
10436
+ font-weight: 500;
10437
+ }
10438
+ strong {
10439
+ font-size: 0.95rem;
10440
+ font-weight: 500;
10441
+ color: rgba(255,255,255,0.5);
10442
+ font-family: monospace;
10443
+ }
10444
+ }
10445
+ .pending-total {
10446
+ display: flex;
10447
+ justify-content: space-between;
10448
+ align-items: center;
10449
+ padding: 0.875rem;
10450
+ background: rgba(212,175,55,0.03);
10451
+ border-radius: 8px;
10452
+ border: 1px solid rgba(212,175,55,0.06);
10453
+ span {
10454
+ font-size: 0.75rem;
10455
+ color: rgba(255,255,255,0.5);
10456
+ text-transform: uppercase;
10457
+ letter-spacing: 0.05em;
10458
+ font-weight: 500;
10459
+ }
10460
+ strong {
10461
+ font-size: 1.05rem;
10462
+ font-weight: 700;
10463
+ color: rgba(212,175,55,0.7);
10464
+ font-family: monospace;
10465
+ }
10466
+ }
10467
+ .pending-footnote {
10468
+ padding: 1rem 1.5rem;
10469
+ border-top: 1px solid rgba(255,255,255,0.06);
10470
+ background: rgba(0,0,0,0.2);
10471
+ font-size: 0.75rem;
10472
+ color: rgba(255,255,255,0.4);
10473
+ line-height: 1.6;
10474
+ animation: pulse 2s ease-in-out infinite;
10475
+ }
10476
+ `;
10323
10477
  var OrderSuccessCard = styled24.div`
10324
10478
  margin-bottom: 1.5rem;
10325
10479
  background: linear-gradient(180deg, rgba(25,27,31,0.95) 0%, rgba(18,20,24,0.98) 100%);
@@ -11175,6 +11329,7 @@ function OrderConfirmationModal({
11175
11329
  tokenQuantity,
11176
11330
  tokenPrice,
11177
11331
  propertyName,
11332
+ tokenSymbol,
11178
11333
  estExposure,
11179
11334
  orderTotal,
11180
11335
  availableBalance,
@@ -11189,7 +11344,7 @@ function OrderConfirmationModal({
11189
11344
  /* @__PURE__ */ jsx(ModalBody, { children: [
11190
11345
  { label: "Order Type", value: "Primary Offering" },
11191
11346
  { label: "Property", value: propertyName },
11192
- { label: "Units", value: `${tokenQuantity.toLocaleString()} MUS`, highlight: true },
11347
+ { label: "Units", value: `${tokenQuantity.toLocaleString()} ${tokenSymbol}`, highlight: true },
11193
11348
  {
11194
11349
  label: "Unit Price",
11195
11350
  value: `$${tokenPrice.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
@@ -11220,7 +11375,9 @@ function OrderConfirmationModal({
11220
11375
  "Your order for ",
11221
11376
  /* @__PURE__ */ jsxs("strong", { children: [
11222
11377
  tokenQuantity.toLocaleString(),
11223
- " MUS units"
11378
+ " ",
11379
+ tokenSymbol,
11380
+ " units"
11224
11381
  ] }),
11225
11382
  " in the",
11226
11383
  " ",
@@ -11449,6 +11606,7 @@ function PropertyBuy({
11449
11606
  const [displayedOwnedTokens, setDisplayedOwnedTokens] = useState(0);
11450
11607
  const [ownedTokensJustUpdated, setOwnedTokensJustUpdated] = useState(false);
11451
11608
  const [lastOrderQuantity, setLastOrderQuantity] = useState(0);
11609
+ const [orderPendingAllocation, setOrderPendingAllocation] = useState(false);
11452
11610
  const [orderPlacedSuccess, setOrderPlacedSuccess] = useState(false);
11453
11611
  const [lastOrderDetails, setLastOrderDetails] = useState(null);
11454
11612
  const [showOrderConfirmModal, setShowOrderConfirmModal] = useState(false);
@@ -11496,12 +11654,23 @@ function PropertyBuy({
11496
11654
  }
11497
11655
  setShowOrderConfirmModal(true);
11498
11656
  };
11499
- const isPurchaseInFlight = purchaseStatus === "checking-allowance" || purchaseStatus === "approving" || purchaseStatus === "purchasing";
11657
+ useEffect(() => {
11658
+ if (purchaseStatus === "success" && orderPendingAllocation) {
11659
+ setOrderPendingAllocation(false);
11660
+ setOrderPlacedSuccess(true);
11661
+ }
11662
+ }, [purchaseStatus, orderPendingAllocation]);
11663
+ const handlePlaceAnotherOrder = useCallback(() => {
11664
+ setOrderPlacedSuccess(false);
11665
+ setOrderPendingAllocation(false);
11666
+ }, []);
11667
+ const isPurchaseInFlight = purchaseStatus === "checking-allowance" || purchaseStatus === "approving" || purchaseStatus === "purchasing" || purchaseStatus === "pending-allocation";
11500
11668
  const getOrderButtonText = () => {
11501
11669
  if (!isAuthenticated) return "Sign In to Invest";
11502
11670
  if (purchaseStatus === "checking-allowance") return "Checking allowance\u2026";
11503
11671
  if (purchaseStatus === "approving") return "Approving USDC\u2026";
11504
11672
  if (purchaseStatus === "purchasing") return "Confirming purchase\u2026";
11673
+ if (purchaseStatus === "pending-allocation") return "Awaiting allocation\u2026";
11505
11674
  if (ipoStatus === "PENDING" && !isPrivateClient) return "Sale Not Open Yet";
11506
11675
  if (ipoStatus === "CLOSED") return "Sale Completed";
11507
11676
  if (ipoStatus === "CANCELLED") return "Sale Cancelled";
@@ -11544,7 +11713,7 @@ function PropertyBuy({
11544
11713
  total: orderTotal,
11545
11714
  price: tokenPrice
11546
11715
  });
11547
- setOrderPlacedSuccess(true);
11716
+ setOrderPendingAllocation(true);
11548
11717
  setSliderValue(0);
11549
11718
  setManualOrderAmount(null);
11550
11719
  };
@@ -11630,6 +11799,7 @@ function PropertyBuy({
11630
11799
  displayedOwnedTokens,
11631
11800
  ownedTokensJustUpdated,
11632
11801
  lastOrderQuantity,
11802
+ orderPendingAllocation,
11633
11803
  orderPlacedSuccess,
11634
11804
  lastOrderDetails,
11635
11805
  tokenQuantity,
@@ -11644,7 +11814,7 @@ function PropertyBuy({
11644
11814
  orderButtonText: getOrderButtonText(),
11645
11815
  isOrderButtonDisabled: isOrderButtonDisabled(),
11646
11816
  hasInsufficientFunds,
11647
- onPlaceAnotherOrder: () => setOrderPlacedSuccess(false),
11817
+ onPlaceAnotherOrder: handlePlaceAnotherOrder,
11648
11818
  onDeposit
11649
11819
  }
11650
11820
  ),
@@ -11678,6 +11848,7 @@ function PropertyBuy({
11678
11848
  tokenQuantity,
11679
11849
  tokenPrice,
11680
11850
  propertyName,
11851
+ tokenSymbol,
11681
11852
  estExposure,
11682
11853
  orderTotal,
11683
11854
  availableBalance,