@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.js CHANGED
@@ -14907,9 +14907,10 @@ var CToolbarLink = styled9__default.default.button`
14907
14907
  `;
14908
14908
  var CRow = styled9__default.default.button`
14909
14909
  display: grid;
14910
- grid-template-columns: 1fr 1fr 1fr 24px;
14910
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) 24px;
14911
14911
  align-items: center;
14912
14912
  width: calc(100% - 1rem);
14913
+ max-width: 420px;
14913
14914
  margin: 0.25rem 0.5rem;
14914
14915
  margin-bottom: ${(p) => p.$expanded ? "0" : "0.25rem"};
14915
14916
  padding: 0.55rem 0.65rem;
@@ -14973,6 +14974,7 @@ var CChevronWrap = styled9__default.default.span`
14973
14974
  `;
14974
14975
  var CExpandedWrap = styled9__default.default.div`
14975
14976
  margin: 0 0.5rem 0.25rem;
14977
+ max-width: 420px;
14976
14978
  padding: 0.4rem 0.65rem 0.5rem;
14977
14979
  background: rgba(255, 255, 255, 0.035);
14978
14980
  border: 1px solid rgba(255, 255, 255, 0.06);
@@ -14981,7 +14983,7 @@ var CExpandedWrap = styled9__default.default.div`
14981
14983
  `;
14982
14984
  var CDetailGrid = styled9__default.default.div`
14983
14985
  display: grid;
14984
- grid-template-columns: 1fr 1fr 1fr 24px;
14986
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) 24px;
14985
14987
  gap: 0.45rem 0;
14986
14988
  `;
14987
14989
  var CDetailItem = styled9__default.default.div``;
@@ -14997,28 +14999,39 @@ var CDValue = styled9__default.default.div`
14997
14999
  font-variant-numeric: tabular-nums;
14998
15000
  `;
14999
15001
  var CActionRow = styled9__default.default.div`
15000
- display: grid;
15001
- grid-template-columns: 1fr 1fr;
15002
- gap: 0.5rem;
15002
+ display: flex;
15003
+ gap: 0.35rem;
15003
15004
  margin-top: 0.5rem;
15004
15005
  `;
15005
15006
  var CCloseBtn = styled9__default.default.button`
15006
15007
  background: transparent;
15007
15008
  border: 1px solid rgba(230, 200, 126, 0.25);
15008
- border-radius: 6px;
15009
- padding: 0.45rem 0.6rem;
15010
- font-size: 0.72rem;
15009
+ border-radius: 4px;
15010
+ padding: 0.2rem 0.5rem;
15011
+ font-size: 0.62rem;
15011
15012
  font-weight: 600;
15012
15013
  color: #E6C87E;
15013
15014
  cursor: pointer;
15014
15015
  white-space: nowrap;
15015
- text-align: center;
15016
15016
  transition: all 0.15s ease;
15017
15017
  &:hover {
15018
15018
  background: rgba(230, 200, 126, 0.1);
15019
15019
  border-color: rgba(230, 200, 126, 0.5);
15020
15020
  }
15021
15021
  `;
15022
+ var formatOrderCurrency = (amount) => {
15023
+ if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
15024
+ return `$${Math.round(amount).toLocaleString()}`;
15025
+ };
15026
+ var formatTimeAgo2 = (timestamp) => {
15027
+ const seconds = Math.floor(Date.now() / 1e3) - timestamp;
15028
+ if (seconds < 60) return "less than a minute ago";
15029
+ const minutes = Math.floor(seconds / 60);
15030
+ if (minutes < 60) return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
15031
+ const hours = Math.floor(minutes / 60);
15032
+ if (hours < 24) return `${hours} hour${hours === 1 ? "" : "s"} ago`;
15033
+ return `${Math.floor(hours / 24)}d ago`;
15034
+ };
15022
15035
  function PropertyBuy({
15023
15036
  propertyName = "Loaf Property",
15024
15037
  propertyLocation: propertyLocationLabel = "Sydney, NSW",
@@ -15065,6 +15078,7 @@ function PropertyBuy({
15065
15078
  const offeringValuation = saleData?.offeringValuation ?? tokenPrice * supplyToSell;
15066
15079
  const ipoStatus = saleData?.status ?? "PENDING";
15067
15080
  const ipoStarted = ipoStatus === "LIVE" || isPrivateClient && ipoStatus === "PENDING";
15081
+ const ipoEnded = ipoStatus === "CLOSED" || ipoStatus === "CANCELLED";
15068
15082
  const statusLabel = ipoStatus;
15069
15083
  const statusColor = STATUS_COLOR2[ipoStatus] ?? "#D4AF37";
15070
15084
  const displayStatusLabel = isPrivateClient && ipoStatus !== "LIVE" ? "Private Client Access" : statusLabel;
@@ -15102,6 +15116,10 @@ function PropertyBuy({
15102
15116
  setOrderPlacedSuccess(false);
15103
15117
  setOrderPendingAllocation(false);
15104
15118
  }, []);
15119
+ const sortedOrders = React5.useMemo(
15120
+ () => [...recentOrders].sort((a, b) => b.timestamp - a.timestamp).slice(0, 7),
15121
+ [recentOrders]
15122
+ );
15105
15123
  const isPurchaseInFlight = purchaseStatus === "checking-allowance" || purchaseStatus === "approving" || purchaseStatus === "purchasing" || purchaseStatus === "pending-allocation";
15106
15124
  const getOrderButtonText = () => {
15107
15125
  if (!isAuthenticated) return "Sign In to Invest";
@@ -15188,6 +15206,35 @@ function PropertyBuy({
15188
15206
  isPrivateClient
15189
15207
  }
15190
15208
  ),
15209
+ /* @__PURE__ */ jsxRuntime.jsxs(RecentOrderPanel, { children: [
15210
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "roa-header", children: [
15211
+ /* @__PURE__ */ jsxRuntime.jsxs("h3", { children: [
15212
+ /* @__PURE__ */ jsxRuntime.jsx(LiveDot, { $active: ipoStarted && !ipoEnded }),
15213
+ "Recent Order Activity"
15214
+ ] }),
15215
+ /* @__PURE__ */ jsxRuntime.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" })
15216
+ ] }),
15217
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "roa-content", children: ipoStarted && isLoadingActivity && sortedOrders.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(FeedList, { children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs(SkeletonFeedRow, { children: [
15218
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "info-col", children: [
15219
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 110, height: 14 }),
15220
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 56, height: 10 })
15221
+ ] }),
15222
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { width: 70, height: 14 })
15223
+ ] }, `skel-${i}`)) }) : ipoStarted || ipoEnded && sortedOrders.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(FeedList, { children: sortedOrders.map((order, index) => {
15224
+ const amount = tokenPrice * order.quantity;
15225
+ const barPercent = Math.min(85, Math.max(15, amount / 6e4 * 100));
15226
+ return /* @__PURE__ */ jsxRuntime.jsxs(PurchaseItem, { $barWidth: `${barPercent}%`, $isAlternate: index % 2 === 1, children: [
15227
+ /* @__PURE__ */ jsxRuntime.jsxs(PurchaseInfo, { children: [
15228
+ /* @__PURE__ */ jsxRuntime.jsx(PurchaseName, { children: order.buyerHandle || `${order.buyerAddress.slice(0, 6)}...${order.buyerAddress.slice(-4)}` }),
15229
+ /* @__PURE__ */ jsxRuntime.jsx(PurchaseTime, { children: formatTimeAgo2(order.timestamp) })
15230
+ ] }),
15231
+ /* @__PURE__ */ jsxRuntime.jsx(PurchaseAmount, { children: formatOrderCurrency(amount) })
15232
+ ] }, order.txHash);
15233
+ }) }) : ipoEnded ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "roa-empty", children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Sale ended \u2014 no orders were placed." }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "roa-empty", children: [
15234
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "roa-spinner" }),
15235
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Activity will appear once the Offering opens" })
15236
+ ] }) })
15237
+ ] }),
15191
15238
  /* @__PURE__ */ jsxRuntime.jsx(ActivityWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
15192
15239
  PortfolioActivityPanel,
15193
15240
  {
@@ -15293,7 +15340,7 @@ function PropertyBuy({
15293
15340
  var HeroGrid = styled9__default.default.div`
15294
15341
  display: grid;
15295
15342
  grid-template-columns: 1fr auto;
15296
- grid-template-rows: auto auto minmax(450px, 520px);
15343
+ grid-template-rows: auto auto auto minmax(450px, 520px);
15297
15344
  gap: 1.5rem;
15298
15345
  width: 100%;
15299
15346
  max-width: 1800px;
@@ -15315,8 +15362,13 @@ var HeroGrid = styled9__default.default.div`
15315
15362
  }
15316
15363
 
15317
15364
  & > div:nth-child(4) {
15365
+ grid-column: 1 / 2;
15366
+ grid-row: 4 / 5;
15367
+ }
15368
+
15369
+ & > div:nth-child(5) {
15318
15370
  grid-column: 2 / 3;
15319
- grid-row: 1 / 4;
15371
+ grid-row: 1 / 5;
15320
15372
  display: flex;
15321
15373
  flex-direction: column;
15322
15374
  }
@@ -15337,7 +15389,7 @@ var HeroGrid = styled9__default.default.div`
15337
15389
  width: 100%;
15338
15390
  }
15339
15391
 
15340
- & > div:nth-child(4) {
15392
+ & > div:nth-child(5) {
15341
15393
  order: 2;
15342
15394
  min-width: 0;
15343
15395
  width: 100%;
@@ -15349,6 +15401,12 @@ var HeroGrid = styled9__default.default.div`
15349
15401
  min-width: 0;
15350
15402
  width: 100%;
15351
15403
  }
15404
+
15405
+ & > div:nth-child(4) {
15406
+ order: 4;
15407
+ min-width: 0;
15408
+ width: 100%;
15409
+ }
15352
15410
  }
15353
15411
 
15354
15412
  @media (max-width: 768px) {
@@ -15374,6 +15432,167 @@ var ActivityWrapper = styled9__default.default.div`
15374
15432
  min-height: auto;
15375
15433
  }
15376
15434
  `;
15435
+ var RecentOrderPanel = styled9__default.default.div`
15436
+ background-color: var(--color-card-darker, #111);
15437
+ border-radius: 8px;
15438
+ padding: 1.5rem;
15439
+ display: flex;
15440
+ flex-direction: column;
15441
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
15442
+ border: 1px solid var(--color-border);
15443
+ overflow: hidden;
15444
+ @media (max-width: 768px) {
15445
+ padding: 1rem;
15446
+ }
15447
+
15448
+ .roa-header {
15449
+ display: flex;
15450
+ justify-content: space-between;
15451
+ align-items: center;
15452
+ padding-bottom: 0.75rem;
15453
+ margin-bottom: 1rem;
15454
+ border-bottom: 1px solid rgba(255,255,255,0.1);
15455
+ h3 {
15456
+ font-size: 0.9rem;
15457
+ font-weight: 600;
15458
+ color: var(--color-text);
15459
+ margin: 0;
15460
+ display: flex;
15461
+ align-items: center;
15462
+ gap: 0.5rem;
15463
+ }
15464
+ span {
15465
+ font-size: 0.75rem;
15466
+ color: var(--color-text-secondary);
15467
+ font-weight: 500;
15468
+ }
15469
+ }
15470
+
15471
+ .roa-content {
15472
+ flex: 1;
15473
+ overflow-y: auto;
15474
+ scrollbar-width: none;
15475
+ -ms-overflow-style: none;
15476
+ &::-webkit-scrollbar { display: none; }
15477
+ }
15478
+
15479
+ .roa-empty {
15480
+ display: flex;
15481
+ flex-direction: column;
15482
+ align-items: center;
15483
+ justify-content: center;
15484
+ height: 200px;
15485
+ color: var(--color-text-secondary);
15486
+ text-align: center;
15487
+ gap: 0.75rem;
15488
+ p { font-size: 0.85rem; margin: 0; }
15489
+ }
15490
+
15491
+ .roa-spinner {
15492
+ width: 40px;
15493
+ height: 40px;
15494
+ border-radius: 50%;
15495
+ border: 2px solid rgba(212,175,55,0.3);
15496
+ border-top-color: #D4AF37;
15497
+ animation: roaSpin 1s linear infinite;
15498
+ }
15499
+
15500
+ @keyframes roaSpin {
15501
+ from { transform: rotate(0deg); }
15502
+ to { transform: rotate(360deg); }
15503
+ }
15504
+ `;
15505
+ var LiveDot = styled9__default.default.span`
15506
+ display: inline-block;
15507
+ width: 8px;
15508
+ height: 8px;
15509
+ background-color: ${(p) => p.$active ? "#0ecb81" : "#848e9c"};
15510
+ border-radius: 50%;
15511
+ position: relative;
15512
+ &:after {
15513
+ content: '';
15514
+ position: absolute;
15515
+ width: 100%;
15516
+ height: 100%;
15517
+ border-radius: 50%;
15518
+ background-color: ${(p) => p.$active ? "#0ecb81" : "transparent"};
15519
+ animation: ${(p) => p.$active ? "livePulse 2s infinite" : "none"};
15520
+ }
15521
+ @keyframes livePulse {
15522
+ 0% { box-shadow: 0 0 0 0 rgba(14,203,129,0.4); }
15523
+ 70% { box-shadow: 0 0 0 10px rgba(14,203,129,0); }
15524
+ 100% { box-shadow: 0 0 0 0 rgba(14,203,129,0); }
15525
+ }
15526
+ `;
15527
+ var FeedList = styled9__default.default.div`
15528
+ width: 100%;
15529
+ overflow-y: auto;
15530
+ scrollbar-width: none;
15531
+ -ms-overflow-style: none;
15532
+ &::-webkit-scrollbar { display: none; }
15533
+ `;
15534
+ var SkeletonFeedRow = styled9__default.default.div`
15535
+ padding: 0.625rem 0.75rem;
15536
+ border-bottom: 1px solid rgba(255,255,255,0.04);
15537
+ display: flex;
15538
+ justify-content: space-between;
15539
+ align-items: center;
15540
+ gap: 1rem;
15541
+ &:last-child { border-bottom: none; }
15542
+ .info-col {
15543
+ display: flex;
15544
+ flex-direction: column;
15545
+ gap: 0.3rem;
15546
+ min-width: 0;
15547
+ flex: 1;
15548
+ }
15549
+ `;
15550
+ var PurchaseItem = styled9__default.default.div`
15551
+ padding: 0.625rem 0.75rem;
15552
+ border-bottom: 1px solid rgba(255,255,255,0.05);
15553
+ display: flex;
15554
+ justify-content: space-between;
15555
+ align-items: center;
15556
+ position: relative;
15557
+ overflow: hidden;
15558
+ background-color: ${(p) => p.$isAlternate ? "rgba(255,255,255,0.03)" : "transparent"};
15559
+ &::before {
15560
+ content: '';
15561
+ position: absolute;
15562
+ top: 0;
15563
+ right: 0;
15564
+ bottom: 0;
15565
+ width: ${(p) => p.$barWidth || "20%"};
15566
+ background: linear-gradient(90deg, transparent 0%, rgba(14,203,129,0.15) 100%);
15567
+ pointer-events: none;
15568
+ }
15569
+ &:last-child { border-bottom: none; }
15570
+ `;
15571
+ var PurchaseInfo = styled9__default.default.div`
15572
+ display: flex;
15573
+ flex-direction: column;
15574
+ min-width: 0;
15575
+ `;
15576
+ var PurchaseName = styled9__default.default.div`
15577
+ font-weight: 500;
15578
+ font-size: 0.875rem;
15579
+ color: #fff;
15580
+ white-space: nowrap;
15581
+ overflow: hidden;
15582
+ text-overflow: ellipsis;
15583
+ `;
15584
+ var PurchaseTime = styled9__default.default.div`
15585
+ font-size: 0.7rem;
15586
+ color: var(--color-text-secondary);
15587
+ margin-top: 0.125rem;
15588
+ `;
15589
+ var PurchaseAmount = styled9__default.default.div`
15590
+ font-weight: 600;
15591
+ font-size: 0.875rem;
15592
+ color: #fff;
15593
+ white-space: nowrap;
15594
+ margin-left: 1rem;
15595
+ `;
15377
15596
  var NewsVideoRow = styled9__default.default.div`
15378
15597
  display: flex;
15379
15598
  gap: 1.5rem;