@loafmarkets/ui 0.1.278 → 0.1.280

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
@@ -14881,9 +14881,10 @@ var CToolbarLink = styled9.button`
14881
14881
  `;
14882
14882
  var CRow = styled9.button`
14883
14883
  display: grid;
14884
- grid-template-columns: 1fr 1fr 1fr 24px;
14884
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) 24px;
14885
14885
  align-items: center;
14886
14886
  width: calc(100% - 1rem);
14887
+ max-width: 420px;
14887
14888
  margin: 0.25rem 0.5rem;
14888
14889
  margin-bottom: ${(p) => p.$expanded ? "0" : "0.25rem"};
14889
14890
  padding: 0.55rem 0.65rem;
@@ -14947,6 +14948,7 @@ var CChevronWrap = styled9.span`
14947
14948
  `;
14948
14949
  var CExpandedWrap = styled9.div`
14949
14950
  margin: 0 0.5rem 0.25rem;
14951
+ max-width: 420px;
14950
14952
  padding: 0.4rem 0.65rem 0.5rem;
14951
14953
  background: rgba(255, 255, 255, 0.035);
14952
14954
  border: 1px solid rgba(255, 255, 255, 0.06);
@@ -14955,7 +14957,7 @@ var CExpandedWrap = styled9.div`
14955
14957
  `;
14956
14958
  var CDetailGrid = styled9.div`
14957
14959
  display: grid;
14958
- grid-template-columns: 1fr 1fr 1fr 24px;
14960
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) 24px;
14959
14961
  gap: 0.45rem 0;
14960
14962
  `;
14961
14963
  var CDetailItem = styled9.div``;
@@ -14991,6 +14993,19 @@ var CCloseBtn = styled9.button`
14991
14993
  border-color: rgba(230, 200, 126, 0.5);
14992
14994
  }
14993
14995
  `;
14996
+ var formatOrderCurrency = (amount) => {
14997
+ if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
14998
+ return `$${Math.round(amount).toLocaleString()}`;
14999
+ };
15000
+ var formatTimeAgo2 = (timestamp) => {
15001
+ const seconds = Math.floor(Date.now() / 1e3) - timestamp;
15002
+ if (seconds < 60) return "less than a minute ago";
15003
+ const minutes = Math.floor(seconds / 60);
15004
+ if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
15005
+ const hours = Math.floor(minutes / 60);
15006
+ if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
15007
+ return `${Math.floor(hours / 24)}d ago`;
15008
+ };
14994
15009
  function PropertyBuy({
14995
15010
  propertyName = "Loaf Property",
14996
15011
  propertyLocation: propertyLocationLabel = "Sydney, NSW",
@@ -15037,6 +15052,7 @@ function PropertyBuy({
15037
15052
  const offeringValuation = saleData?.offeringValuation ?? tokenPrice * supplyToSell;
15038
15053
  const ipoStatus = saleData?.status ?? "PENDING";
15039
15054
  const ipoStarted = ipoStatus === "LIVE" || isPrivateClient && ipoStatus === "PENDING";
15055
+ const ipoEnded = ipoStatus === "CLOSED" || ipoStatus === "CANCELLED";
15040
15056
  const statusLabel = ipoStatus;
15041
15057
  const statusColor = STATUS_COLOR2[ipoStatus] ?? "#D4AF37";
15042
15058
  const displayStatusLabel = isPrivateClient && ipoStatus !== "LIVE" ? "Private Client Access" : statusLabel;
@@ -15074,6 +15090,10 @@ function PropertyBuy({
15074
15090
  setOrderPlacedSuccess(false);
15075
15091
  setOrderPendingAllocation(false);
15076
15092
  }, []);
15093
+ const sortedOrders = useMemo(
15094
+ () => [...recentOrders].sort((a, b) => b.timestamp - a.timestamp).slice(0, 7),
15095
+ [recentOrders]
15096
+ );
15077
15097
  const isPurchaseInFlight = purchaseStatus === "checking-allowance" || purchaseStatus === "approving" || purchaseStatus === "purchasing" || purchaseStatus === "pending-allocation";
15078
15098
  const getOrderButtonText = () => {
15079
15099
  if (!isAuthenticated) return "Sign In to Invest";
@@ -15160,6 +15180,35 @@ function PropertyBuy({
15160
15180
  isPrivateClient
15161
15181
  }
15162
15182
  ),
15183
+ /* @__PURE__ */ jsxs(RecentOrderPanel, { children: [
15184
+ /* @__PURE__ */ jsxs("div", { className: "roa-header", children: [
15185
+ /* @__PURE__ */ jsxs("h3", { children: [
15186
+ /* @__PURE__ */ jsx(LiveDot, { $active: ipoStarted && !ipoEnded }),
15187
+ "Recent Order Activity"
15188
+ ] }),
15189
+ /* @__PURE__ */ jsx("span", { children: ipoEnded ? `Sale ended${ordersAllocated > 0 ? ` \xB7 ${ordersAllocated.toLocaleString()} orders` : ""}` : ipoStarted ? isLoadingActivity && sortedOrders.length === 0 ? "Loading orders\u2026" : `Active orders: ${ordersAllocated.toLocaleString()}` : "Waiting for Offer to Open" })
15190
+ ] }),
15191
+ /* @__PURE__ */ jsx("div", { className: "roa-content", children: ipoStarted && isLoadingActivity && sortedOrders.length === 0 ? /* @__PURE__ */ jsx(FeedList, { children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs(SkeletonFeedRow, { children: [
15192
+ /* @__PURE__ */ jsxs("div", { className: "info-col", children: [
15193
+ /* @__PURE__ */ jsx(Skeleton, { width: 110, height: 14 }),
15194
+ /* @__PURE__ */ jsx(Skeleton, { width: 56, height: 10 })
15195
+ ] }),
15196
+ /* @__PURE__ */ jsx(Skeleton, { width: 70, height: 14 })
15197
+ ] }, `skel-${i}`)) }) : ipoStarted || ipoEnded && sortedOrders.length > 0 ? /* @__PURE__ */ jsx(FeedList, { children: sortedOrders.map((order, index) => {
15198
+ const amount = tokenPrice * order.quantity;
15199
+ const barPercent = Math.min(85, Math.max(15, amount / 6e4 * 100));
15200
+ return /* @__PURE__ */ jsxs(PurchaseItem, { $barWidth: `${barPercent}%`, $isAlternate: index % 2 === 1, children: [
15201
+ /* @__PURE__ */ jsxs(PurchaseInfo, { children: [
15202
+ /* @__PURE__ */ jsx(PurchaseName, { children: order.buyerHandle || `${order.buyerAddress.slice(0, 6)}...${order.buyerAddress.slice(-4)}` }),
15203
+ /* @__PURE__ */ jsx(PurchaseTime, { children: formatTimeAgo2(order.timestamp) })
15204
+ ] }),
15205
+ /* @__PURE__ */ jsx(PurchaseAmount, { children: formatOrderCurrency(amount) })
15206
+ ] }, order.txHash);
15207
+ }) }) : ipoEnded ? /* @__PURE__ */ jsx("div", { className: "roa-empty", children: /* @__PURE__ */ jsx("p", { children: "Sale ended \u2014 no orders were placed." }) }) : /* @__PURE__ */ jsxs("div", { className: "roa-empty", children: [
15208
+ /* @__PURE__ */ jsx("div", { className: "roa-spinner" }),
15209
+ /* @__PURE__ */ jsx("p", { children: "Activity will appear once the Offering opens" })
15210
+ ] }) })
15211
+ ] }),
15163
15212
  /* @__PURE__ */ jsx(ActivityWrapper, { children: /* @__PURE__ */ jsx(
15164
15213
  PortfolioActivityPanel,
15165
15214
  {
@@ -15265,7 +15314,7 @@ function PropertyBuy({
15265
15314
  var HeroGrid = styled9.div`
15266
15315
  display: grid;
15267
15316
  grid-template-columns: 1fr auto;
15268
- grid-template-rows: auto auto minmax(450px, 520px);
15317
+ grid-template-rows: auto auto auto minmax(450px, 520px);
15269
15318
  gap: 1.5rem;
15270
15319
  width: 100%;
15271
15320
  max-width: 1800px;
@@ -15287,8 +15336,13 @@ var HeroGrid = styled9.div`
15287
15336
  }
15288
15337
 
15289
15338
  & > div:nth-child(4) {
15339
+ grid-column: 1 / 2;
15340
+ grid-row: 4 / 5;
15341
+ }
15342
+
15343
+ & > div:nth-child(5) {
15290
15344
  grid-column: 2 / 3;
15291
- grid-row: 1 / 4;
15345
+ grid-row: 1 / 5;
15292
15346
  display: flex;
15293
15347
  flex-direction: column;
15294
15348
  }
@@ -15309,7 +15363,7 @@ var HeroGrid = styled9.div`
15309
15363
  width: 100%;
15310
15364
  }
15311
15365
 
15312
- & > div:nth-child(4) {
15366
+ & > div:nth-child(5) {
15313
15367
  order: 2;
15314
15368
  min-width: 0;
15315
15369
  width: 100%;
@@ -15321,6 +15375,12 @@ var HeroGrid = styled9.div`
15321
15375
  min-width: 0;
15322
15376
  width: 100%;
15323
15377
  }
15378
+
15379
+ & > div:nth-child(4) {
15380
+ order: 4;
15381
+ min-width: 0;
15382
+ width: 100%;
15383
+ }
15324
15384
  }
15325
15385
 
15326
15386
  @media (max-width: 768px) {
@@ -15346,6 +15406,167 @@ var ActivityWrapper = styled9.div`
15346
15406
  min-height: auto;
15347
15407
  }
15348
15408
  `;
15409
+ var RecentOrderPanel = styled9.div`
15410
+ background-color: var(--color-card-darker, #111);
15411
+ border-radius: 8px;
15412
+ padding: 1.5rem;
15413
+ display: flex;
15414
+ flex-direction: column;
15415
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
15416
+ border: 1px solid var(--color-border);
15417
+ overflow: hidden;
15418
+ @media (max-width: 768px) {
15419
+ padding: 1rem;
15420
+ }
15421
+
15422
+ .roa-header {
15423
+ display: flex;
15424
+ justify-content: space-between;
15425
+ align-items: center;
15426
+ padding-bottom: 0.75rem;
15427
+ margin-bottom: 1rem;
15428
+ border-bottom: 1px solid rgba(255,255,255,0.1);
15429
+ h3 {
15430
+ font-size: 0.9rem;
15431
+ font-weight: 600;
15432
+ color: var(--color-text);
15433
+ margin: 0;
15434
+ display: flex;
15435
+ align-items: center;
15436
+ gap: 0.5rem;
15437
+ }
15438
+ span {
15439
+ font-size: 0.75rem;
15440
+ color: var(--color-text-secondary);
15441
+ font-weight: 500;
15442
+ }
15443
+ }
15444
+
15445
+ .roa-content {
15446
+ flex: 1;
15447
+ overflow-y: auto;
15448
+ scrollbar-width: none;
15449
+ -ms-overflow-style: none;
15450
+ &::-webkit-scrollbar { display: none; }
15451
+ }
15452
+
15453
+ .roa-empty {
15454
+ display: flex;
15455
+ flex-direction: column;
15456
+ align-items: center;
15457
+ justify-content: center;
15458
+ height: 200px;
15459
+ color: var(--color-text-secondary);
15460
+ text-align: center;
15461
+ gap: 0.75rem;
15462
+ p { font-size: 0.85rem; margin: 0; }
15463
+ }
15464
+
15465
+ .roa-spinner {
15466
+ width: 40px;
15467
+ height: 40px;
15468
+ border-radius: 50%;
15469
+ border: 2px solid rgba(212,175,55,0.3);
15470
+ border-top-color: #D4AF37;
15471
+ animation: roaSpin 1s linear infinite;
15472
+ }
15473
+
15474
+ @keyframes roaSpin {
15475
+ from { transform: rotate(0deg); }
15476
+ to { transform: rotate(360deg); }
15477
+ }
15478
+ `;
15479
+ var LiveDot = styled9.span`
15480
+ display: inline-block;
15481
+ width: 8px;
15482
+ height: 8px;
15483
+ background-color: ${(p) => p.$active ? "#0ecb81" : "#848e9c"};
15484
+ border-radius: 50%;
15485
+ position: relative;
15486
+ &:after {
15487
+ content: '';
15488
+ position: absolute;
15489
+ width: 100%;
15490
+ height: 100%;
15491
+ border-radius: 50%;
15492
+ background-color: ${(p) => p.$active ? "#0ecb81" : "transparent"};
15493
+ animation: ${(p) => p.$active ? "livePulse 2s infinite" : "none"};
15494
+ }
15495
+ @keyframes livePulse {
15496
+ 0% { box-shadow: 0 0 0 0 rgba(14,203,129,0.4); }
15497
+ 70% { box-shadow: 0 0 0 10px rgba(14,203,129,0); }
15498
+ 100% { box-shadow: 0 0 0 0 rgba(14,203,129,0); }
15499
+ }
15500
+ `;
15501
+ var FeedList = styled9.div`
15502
+ width: 100%;
15503
+ overflow-y: auto;
15504
+ scrollbar-width: none;
15505
+ -ms-overflow-style: none;
15506
+ &::-webkit-scrollbar { display: none; }
15507
+ `;
15508
+ var SkeletonFeedRow = styled9.div`
15509
+ padding: 0.625rem 0.75rem;
15510
+ border-bottom: 1px solid rgba(255,255,255,0.04);
15511
+ display: flex;
15512
+ justify-content: space-between;
15513
+ align-items: center;
15514
+ gap: 1rem;
15515
+ &:last-child { border-bottom: none; }
15516
+ .info-col {
15517
+ display: flex;
15518
+ flex-direction: column;
15519
+ gap: 0.3rem;
15520
+ min-width: 0;
15521
+ flex: 1;
15522
+ }
15523
+ `;
15524
+ var PurchaseItem = styled9.div`
15525
+ padding: 0.625rem 0.75rem;
15526
+ border-bottom: 1px solid rgba(255,255,255,0.05);
15527
+ display: flex;
15528
+ justify-content: space-between;
15529
+ align-items: center;
15530
+ position: relative;
15531
+ overflow: hidden;
15532
+ background-color: ${(p) => p.$isAlternate ? "rgba(255,255,255,0.03)" : "transparent"};
15533
+ &::before {
15534
+ content: '';
15535
+ position: absolute;
15536
+ top: 0;
15537
+ right: 0;
15538
+ bottom: 0;
15539
+ width: ${(p) => p.$barWidth || "20%"};
15540
+ background: linear-gradient(90deg, transparent 0%, rgba(14,203,129,0.15) 100%);
15541
+ pointer-events: none;
15542
+ }
15543
+ &:last-child { border-bottom: none; }
15544
+ `;
15545
+ var PurchaseInfo = styled9.div`
15546
+ display: flex;
15547
+ flex-direction: column;
15548
+ min-width: 0;
15549
+ `;
15550
+ var PurchaseName = styled9.div`
15551
+ font-weight: 500;
15552
+ font-size: 0.875rem;
15553
+ color: #fff;
15554
+ white-space: nowrap;
15555
+ overflow: hidden;
15556
+ text-overflow: ellipsis;
15557
+ `;
15558
+ var PurchaseTime = styled9.div`
15559
+ font-size: 0.7rem;
15560
+ color: var(--color-text-secondary);
15561
+ margin-top: 0.125rem;
15562
+ `;
15563
+ var PurchaseAmount = styled9.div`
15564
+ font-weight: 600;
15565
+ font-size: 0.875rem;
15566
+ color: #fff;
15567
+ white-space: nowrap;
15568
+ margin-left: 1rem;
15569
+ `;
15349
15570
  var NewsVideoRow = styled9.div`
15350
15571
  display: flex;
15351
15572
  gap: 1.5rem;