@loafmarkets/ui 0.1.277 → 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``;
@@ -14971,28 +14973,39 @@ var CDValue = styled9.div`
14971
14973
  font-variant-numeric: tabular-nums;
14972
14974
  `;
14973
14975
  var CActionRow = styled9.div`
14974
- display: grid;
14975
- grid-template-columns: 1fr 1fr;
14976
- gap: 0.5rem;
14976
+ display: flex;
14977
+ gap: 0.35rem;
14977
14978
  margin-top: 0.5rem;
14978
14979
  `;
14979
14980
  var CCloseBtn = styled9.button`
14980
14981
  background: transparent;
14981
14982
  border: 1px solid rgba(230, 200, 126, 0.25);
14982
- border-radius: 6px;
14983
- padding: 0.45rem 0.6rem;
14984
- font-size: 0.72rem;
14983
+ border-radius: 4px;
14984
+ padding: 0.2rem 0.5rem;
14985
+ font-size: 0.62rem;
14985
14986
  font-weight: 600;
14986
14987
  color: #E6C87E;
14987
14988
  cursor: pointer;
14988
14989
  white-space: nowrap;
14989
- text-align: center;
14990
14990
  transition: all 0.15s ease;
14991
14991
  &:hover {
14992
14992
  background: rgba(230, 200, 126, 0.1);
14993
14993
  border-color: rgba(230, 200, 126, 0.5);
14994
14994
  }
14995
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
+ };
14996
15009
  function PropertyBuy({
14997
15010
  propertyName = "Loaf Property",
14998
15011
  propertyLocation: propertyLocationLabel = "Sydney, NSW",
@@ -15039,6 +15052,7 @@ function PropertyBuy({
15039
15052
  const offeringValuation = saleData?.offeringValuation ?? tokenPrice * supplyToSell;
15040
15053
  const ipoStatus = saleData?.status ?? "PENDING";
15041
15054
  const ipoStarted = ipoStatus === "LIVE" || isPrivateClient && ipoStatus === "PENDING";
15055
+ const ipoEnded = ipoStatus === "CLOSED" || ipoStatus === "CANCELLED";
15042
15056
  const statusLabel = ipoStatus;
15043
15057
  const statusColor = STATUS_COLOR2[ipoStatus] ?? "#D4AF37";
15044
15058
  const displayStatusLabel = isPrivateClient && ipoStatus !== "LIVE" ? "Private Client Access" : statusLabel;
@@ -15076,6 +15090,10 @@ function PropertyBuy({
15076
15090
  setOrderPlacedSuccess(false);
15077
15091
  setOrderPendingAllocation(false);
15078
15092
  }, []);
15093
+ const sortedOrders = useMemo(
15094
+ () => [...recentOrders].sort((a, b) => b.timestamp - a.timestamp).slice(0, 7),
15095
+ [recentOrders]
15096
+ );
15079
15097
  const isPurchaseInFlight = purchaseStatus === "checking-allowance" || purchaseStatus === "approving" || purchaseStatus === "purchasing" || purchaseStatus === "pending-allocation";
15080
15098
  const getOrderButtonText = () => {
15081
15099
  if (!isAuthenticated) return "Sign In to Invest";
@@ -15162,6 +15180,35 @@ function PropertyBuy({
15162
15180
  isPrivateClient
15163
15181
  }
15164
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
+ ] }),
15165
15212
  /* @__PURE__ */ jsx(ActivityWrapper, { children: /* @__PURE__ */ jsx(
15166
15213
  PortfolioActivityPanel,
15167
15214
  {
@@ -15267,7 +15314,7 @@ function PropertyBuy({
15267
15314
  var HeroGrid = styled9.div`
15268
15315
  display: grid;
15269
15316
  grid-template-columns: 1fr auto;
15270
- grid-template-rows: auto auto minmax(450px, 520px);
15317
+ grid-template-rows: auto auto auto minmax(450px, 520px);
15271
15318
  gap: 1.5rem;
15272
15319
  width: 100%;
15273
15320
  max-width: 1800px;
@@ -15289,8 +15336,13 @@ var HeroGrid = styled9.div`
15289
15336
  }
15290
15337
 
15291
15338
  & > div:nth-child(4) {
15339
+ grid-column: 1 / 2;
15340
+ grid-row: 4 / 5;
15341
+ }
15342
+
15343
+ & > div:nth-child(5) {
15292
15344
  grid-column: 2 / 3;
15293
- grid-row: 1 / 4;
15345
+ grid-row: 1 / 5;
15294
15346
  display: flex;
15295
15347
  flex-direction: column;
15296
15348
  }
@@ -15311,7 +15363,7 @@ var HeroGrid = styled9.div`
15311
15363
  width: 100%;
15312
15364
  }
15313
15365
 
15314
- & > div:nth-child(4) {
15366
+ & > div:nth-child(5) {
15315
15367
  order: 2;
15316
15368
  min-width: 0;
15317
15369
  width: 100%;
@@ -15323,6 +15375,12 @@ var HeroGrid = styled9.div`
15323
15375
  min-width: 0;
15324
15376
  width: 100%;
15325
15377
  }
15378
+
15379
+ & > div:nth-child(4) {
15380
+ order: 4;
15381
+ min-width: 0;
15382
+ width: 100%;
15383
+ }
15326
15384
  }
15327
15385
 
15328
15386
  @media (max-width: 768px) {
@@ -15348,6 +15406,167 @@ var ActivityWrapper = styled9.div`
15348
15406
  min-height: auto;
15349
15407
  }
15350
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
+ `;
15351
15570
  var NewsVideoRow = styled9.div`
15352
15571
  display: flex;
15353
15572
  gap: 1.5rem;