@loafmarkets/ui 0.1.384 → 0.1.386
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.d.mts +34 -5
- package/dist/index.d.ts +34 -5
- package/dist/index.js +953 -512
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +954 -512
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -6
package/dist/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { twMerge } from 'tailwind-merge';
|
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import styled10, { keyframes, css } from 'styled-components';
|
|
9
9
|
import * as ReactDOM from 'react-dom';
|
|
10
|
+
import { createPortal } from 'react-dom';
|
|
10
11
|
import { Newspaper } from 'lucide-react';
|
|
11
12
|
import * as LightweightCharts from 'lightweight-charts';
|
|
12
13
|
import { MdKingBed, MdBathtub, MdDirectionsCar, MdPool, MdYard, MdFitnessCenter } from 'react-icons/md';
|
|
@@ -1874,6 +1875,7 @@ var Orderbook = React5.forwardRef(
|
|
|
1874
1875
|
amountPrecision = 2,
|
|
1875
1876
|
defaultTab = "orderbook",
|
|
1876
1877
|
onTabChange,
|
|
1878
|
+
showTradesTab = true,
|
|
1877
1879
|
rightHeader,
|
|
1878
1880
|
variant = "auto",
|
|
1879
1881
|
userOrderPrices,
|
|
@@ -1887,7 +1889,9 @@ var Orderbook = React5.forwardRef(
|
|
|
1887
1889
|
...props
|
|
1888
1890
|
}, ref) => {
|
|
1889
1891
|
const resolvedRightHeader = rightHeader ?? /* @__PURE__ */ jsx(LoafLiquidityBadge, { className: "text-[0.6rem] orderbook-ll-badge", onClick: onLoafLiquidityClick });
|
|
1890
|
-
const [tab,
|
|
1892
|
+
const [tab, setTabState] = React5.useState(defaultTab);
|
|
1893
|
+
const setTab = setTabState;
|
|
1894
|
+
const effectiveTab = showTradesTab ? tab : "orderbook";
|
|
1891
1895
|
const [tradeFilter, setTradeFilter] = React5.useState("all");
|
|
1892
1896
|
const viewportCompact = useViewportCompact(COMPACT_BREAKPOINT_PX);
|
|
1893
1897
|
const { userAskPrices, userBidPrices } = React5.useMemo(() => {
|
|
@@ -1981,7 +1985,8 @@ var Orderbook = React5.forwardRef(
|
|
|
1981
1985
|
const midClass = midChangePercent == null ? "text-white" : midChangePercent >= 0 ? "text-[#0ecb81]" : "text-[#f6465d]";
|
|
1982
1986
|
const tradeFiltered = trades.filter((t) => tradeFilter === "all" || t.type === tradeFilter);
|
|
1983
1987
|
const layoutProps = {
|
|
1984
|
-
tab,
|
|
1988
|
+
tab: effectiveTab,
|
|
1989
|
+
showTradesTab,
|
|
1985
1990
|
handleTab,
|
|
1986
1991
|
tradeFilter,
|
|
1987
1992
|
setTradeFilter,
|
|
@@ -2058,6 +2063,7 @@ function SkeletonRow({ compact }) {
|
|
|
2058
2063
|
}
|
|
2059
2064
|
function DesktopOrderbookLayout({
|
|
2060
2065
|
tab,
|
|
2066
|
+
showTradesTab = true,
|
|
2061
2067
|
handleTab,
|
|
2062
2068
|
tradeFilter,
|
|
2063
2069
|
setTradeFilter,
|
|
@@ -2107,7 +2113,7 @@ function DesktopOrderbookLayout({
|
|
|
2107
2113
|
]
|
|
2108
2114
|
}
|
|
2109
2115
|
),
|
|
2110
|
-
/* @__PURE__ */ jsxs(
|
|
2116
|
+
showTradesTab ? /* @__PURE__ */ jsxs(
|
|
2111
2117
|
"button",
|
|
2112
2118
|
{
|
|
2113
2119
|
type: "button",
|
|
@@ -2121,7 +2127,7 @@ function DesktopOrderbookLayout({
|
|
|
2121
2127
|
tab === "trades" ? /* @__PURE__ */ jsx("span", { className: "absolute -bottom-px left-0 h-[2px] w-full bg-[#E6C87E]" }) : null
|
|
2122
2128
|
]
|
|
2123
2129
|
}
|
|
2124
|
-
)
|
|
2130
|
+
) : null
|
|
2125
2131
|
] }),
|
|
2126
2132
|
tab === "trades" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs", children: [
|
|
2127
2133
|
/* @__PURE__ */ jsx(
|
|
@@ -2260,6 +2266,7 @@ function DesktopOrderbookLayout({
|
|
|
2260
2266
|
}
|
|
2261
2267
|
function MobileOrderbookLayout({
|
|
2262
2268
|
tab,
|
|
2269
|
+
showTradesTab = true,
|
|
2263
2270
|
handleTab,
|
|
2264
2271
|
tradeFilter,
|
|
2265
2272
|
setTradeFilter,
|
|
@@ -2308,7 +2315,7 @@ function MobileOrderbookLayout({
|
|
|
2308
2315
|
children: "Orderbook"
|
|
2309
2316
|
}
|
|
2310
2317
|
),
|
|
2311
|
-
/* @__PURE__ */ jsx(
|
|
2318
|
+
showTradesTab ? /* @__PURE__ */ jsx(
|
|
2312
2319
|
"span",
|
|
2313
2320
|
{
|
|
2314
2321
|
onClick: () => handleTab("trades"),
|
|
@@ -2322,7 +2329,7 @@ function MobileOrderbookLayout({
|
|
|
2322
2329
|
},
|
|
2323
2330
|
children: "Trades"
|
|
2324
2331
|
}
|
|
2325
|
-
)
|
|
2332
|
+
) : null
|
|
2326
2333
|
] }),
|
|
2327
2334
|
tab === "trades" ? /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 text-[0.6rem] text-white/70", children: ["all", "buy", "sell"].map((filter) => /* @__PURE__ */ jsx(
|
|
2328
2335
|
"button",
|
|
@@ -5010,9 +5017,9 @@ var PulsingDot = styled10.span`
|
|
|
5010
5017
|
`;
|
|
5011
5018
|
function fmtCompactUsd(n) {
|
|
5012
5019
|
const abs = Math.abs(n);
|
|
5013
|
-
if (abs >= 1e6) return
|
|
5014
|
-
if (abs >= 1e3) return
|
|
5015
|
-
return
|
|
5020
|
+
if (abs >= 1e6) return `${(abs / 1e6).toFixed(2)}M`;
|
|
5021
|
+
if (abs >= 1e3) return `${(abs / 1e3).toFixed(1)}K`;
|
|
5022
|
+
return `${abs.toFixed(2)}`;
|
|
5016
5023
|
}
|
|
5017
5024
|
function useIsNarrow(maxWidthPx = 768) {
|
|
5018
5025
|
const query = `(max-width:${maxWidthPx}px)`;
|
|
@@ -5035,8 +5042,6 @@ var DEFAULT_ABOUT_PATH = "/about";
|
|
|
5035
5042
|
var DEFAULT_LEARN_PATH = "/learn";
|
|
5036
5043
|
var DEFAULT_API_PATH = "/api";
|
|
5037
5044
|
var DEFAULT_PROPERTY_MAP_PATH = "/map";
|
|
5038
|
-
var DEFAULT_LEADERBOARD_PATH = "/league";
|
|
5039
|
-
var DEFAULT_LEADERBOARD_PAGE_PATH = "/leaderboard";
|
|
5040
5045
|
var DEFAULT_PORTFOLIO_PATH = "/portfolio";
|
|
5041
5046
|
var DEFAULT_LOAF_LIQUIDITY_PATH = "/loaf-liquidity";
|
|
5042
5047
|
var DEFAULT_AUTH_RETURN_PARAM = "returnTo";
|
|
@@ -5057,8 +5062,6 @@ var Header = ({
|
|
|
5057
5062
|
apiPath = DEFAULT_API_PATH,
|
|
5058
5063
|
offeringsPath,
|
|
5059
5064
|
propertyMapPath = DEFAULT_PROPERTY_MAP_PATH,
|
|
5060
|
-
leaderboardPath = DEFAULT_LEADERBOARD_PATH,
|
|
5061
|
-
leaderboardPagePath = DEFAULT_LEADERBOARD_PAGE_PATH,
|
|
5062
5065
|
portfolioPath = DEFAULT_PORTFOLIO_PATH,
|
|
5063
5066
|
loafLiquidityPath = DEFAULT_LOAF_LIQUIDITY_PATH,
|
|
5064
5067
|
authLoginUrl,
|
|
@@ -5332,8 +5335,6 @@ var Header = ({
|
|
|
5332
5335
|
const resolvedOfferingsPath = offeringsPath ?? void 0;
|
|
5333
5336
|
const offeringsHref = resolvedOfferingsPath ?? resolvedHomePath;
|
|
5334
5337
|
const resolvedPropertyMapPath = propertyMapPath ?? DEFAULT_PROPERTY_MAP_PATH;
|
|
5335
|
-
const resolvedLeaderboardPath = leaderboardPath ?? DEFAULT_LEADERBOARD_PATH;
|
|
5336
|
-
const resolvedLeaderboardPagePath = leaderboardPagePath ?? DEFAULT_LEADERBOARD_PAGE_PATH;
|
|
5337
5338
|
const resolvedPortfolioPath = portfolioPath ?? DEFAULT_PORTFOLIO_PATH;
|
|
5338
5339
|
const resolvedLoafLiquidityPath = loafLiquidityPath ?? DEFAULT_LOAF_LIQUIDITY_PATH;
|
|
5339
5340
|
const inferredActiveTab = (() => {
|
|
@@ -5344,8 +5345,6 @@ var Header = ({
|
|
|
5344
5345
|
if (locationPath === resolvedApiPath) return "api";
|
|
5345
5346
|
if (resolvedOfferingsPath && locationPath.startsWith(resolvedOfferingsPath)) return "offerings";
|
|
5346
5347
|
if (locationPath === resolvedPropertyMapPath) return "propertyMap";
|
|
5347
|
-
if (locationPath === resolvedLeaderboardPagePath) return "leaderboardPage";
|
|
5348
|
-
if (locationPath === resolvedLeaderboardPath) return "leaderboard";
|
|
5349
5348
|
if (locationPath === resolvedPortfolioPath) return "portfolio";
|
|
5350
5349
|
return null;
|
|
5351
5350
|
})();
|
|
@@ -5354,8 +5353,6 @@ var Header = ({
|
|
|
5354
5353
|
const homeActive = resolvedActiveTab === "home";
|
|
5355
5354
|
const offeringsActive = resolvedActiveTab === "offerings";
|
|
5356
5355
|
const propertyMapActive = resolvedActiveTab === "propertyMap";
|
|
5357
|
-
const leaderboardActive = resolvedActiveTab === "leaderboard";
|
|
5358
|
-
const leaderboardPageActive = resolvedActiveTab === "leaderboardPage";
|
|
5359
5356
|
const aboutActive = resolvedActiveTab === "about";
|
|
5360
5357
|
const portfolioActive = resolvedActiveTab === "portfolio";
|
|
5361
5358
|
const learnActive = resolvedActiveTab === "learn";
|
|
@@ -5363,7 +5360,7 @@ var Header = ({
|
|
|
5363
5360
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5364
5361
|
/* @__PURE__ */ jsx(SafeAreaCover, {}),
|
|
5365
5362
|
/* @__PURE__ */ jsx(Overlay, { $isOpen: isMobileMenuOpen, onClick: () => setIsMobileMenuOpen(false) }),
|
|
5366
|
-
/* @__PURE__ */ jsxs(HeaderContainer, { id: "loaf-header", $bgOpacity: headerBgOpacity, children: [
|
|
5363
|
+
/* @__PURE__ */ jsxs(HeaderContainer, { id: "loaf-header", $bgOpacity: headerBgOpacity, $menuOpen: isMobileMenuOpen, children: [
|
|
5367
5364
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
|
|
5368
5365
|
/* @__PURE__ */ jsxs(Logo, { children: [
|
|
5369
5366
|
/* @__PURE__ */ jsx(LogoLink, { href: logoHref ?? resolvedHomePath, onClick: handleLogoNavigation, children: /* @__PURE__ */ jsx("img", { src: Loaf_logo_Banner_default, alt: "LOAF Logo" }) }),
|
|
@@ -5439,91 +5436,48 @@ var Header = ({
|
|
|
5439
5436
|
/* @__PURE__ */ jsx(
|
|
5440
5437
|
NavLink,
|
|
5441
5438
|
{
|
|
5442
|
-
href:
|
|
5443
|
-
className:
|
|
5439
|
+
href: resolvedLearnPath,
|
|
5440
|
+
className: learnActive ? "active" : "",
|
|
5444
5441
|
onClick: (event) => {
|
|
5445
5442
|
event.preventDefault();
|
|
5446
|
-
handleNavigation(
|
|
5443
|
+
handleNavigation(resolvedLearnPath);
|
|
5447
5444
|
},
|
|
5448
|
-
children: "
|
|
5445
|
+
children: "Learn"
|
|
5449
5446
|
}
|
|
5450
5447
|
),
|
|
5451
5448
|
/* @__PURE__ */ jsx(
|
|
5452
5449
|
NavLink,
|
|
5453
5450
|
{
|
|
5454
|
-
href:
|
|
5455
|
-
className:
|
|
5451
|
+
href: resolvedAboutPath,
|
|
5452
|
+
className: aboutActive ? "active" : "",
|
|
5456
5453
|
onClick: (event) => {
|
|
5457
5454
|
event.preventDefault();
|
|
5458
|
-
handleNavigation(
|
|
5455
|
+
handleNavigation(resolvedAboutPath);
|
|
5459
5456
|
},
|
|
5460
|
-
children: "
|
|
5457
|
+
children: "About"
|
|
5461
5458
|
}
|
|
5462
5459
|
),
|
|
5463
5460
|
/* @__PURE__ */ jsx(
|
|
5464
5461
|
NavLink,
|
|
5465
5462
|
{
|
|
5466
|
-
href:
|
|
5467
|
-
className:
|
|
5463
|
+
href: resolvedApiPath,
|
|
5464
|
+
className: apiActive ? "active" : "",
|
|
5468
5465
|
onClick: (event) => {
|
|
5469
5466
|
event.preventDefault();
|
|
5470
|
-
handleNavigation(
|
|
5467
|
+
handleNavigation(resolvedApiPath);
|
|
5471
5468
|
},
|
|
5472
|
-
children: "
|
|
5469
|
+
children: "API"
|
|
5470
|
+
}
|
|
5471
|
+
),
|
|
5472
|
+
/* @__PURE__ */ jsx(
|
|
5473
|
+
NavLink,
|
|
5474
|
+
{
|
|
5475
|
+
href: "https://docs.loafmarkets.com/en/",
|
|
5476
|
+
target: "_blank",
|
|
5477
|
+
rel: "noopener noreferrer",
|
|
5478
|
+
children: "Docs"
|
|
5473
5479
|
}
|
|
5474
5480
|
),
|
|
5475
|
-
/* @__PURE__ */ jsxs(MoreMenu, { className: "more-menu", children: [
|
|
5476
|
-
/* @__PURE__ */ jsxs(
|
|
5477
|
-
MoreTrigger,
|
|
5478
|
-
{
|
|
5479
|
-
type: "button",
|
|
5480
|
-
className: `${isMoreMenuOpen ? "open" : ""} ${aboutActive || apiActive ? "active" : ""}`,
|
|
5481
|
-
"aria-haspopup": "true",
|
|
5482
|
-
"aria-expanded": isMoreMenuOpen,
|
|
5483
|
-
onClick: () => setIsMoreMenuOpen((open) => !open),
|
|
5484
|
-
children: [
|
|
5485
|
-
"More",
|
|
5486
|
-
/* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
5487
|
-
]
|
|
5488
|
-
}
|
|
5489
|
-
),
|
|
5490
|
-
isMoreMenuOpen && /* @__PURE__ */ jsxs(MoreDropdown, { children: [
|
|
5491
|
-
/* @__PURE__ */ jsx(
|
|
5492
|
-
MoreItem,
|
|
5493
|
-
{
|
|
5494
|
-
href: resolvedAboutPath,
|
|
5495
|
-
className: aboutActive ? "active" : "",
|
|
5496
|
-
onClick: (event) => {
|
|
5497
|
-
event.preventDefault();
|
|
5498
|
-
handleNavigation(resolvedAboutPath);
|
|
5499
|
-
},
|
|
5500
|
-
children: "About"
|
|
5501
|
-
}
|
|
5502
|
-
),
|
|
5503
|
-
/* @__PURE__ */ jsx(
|
|
5504
|
-
MoreItem,
|
|
5505
|
-
{
|
|
5506
|
-
href: resolvedApiPath,
|
|
5507
|
-
className: apiActive ? "active" : "",
|
|
5508
|
-
onClick: (event) => {
|
|
5509
|
-
event.preventDefault();
|
|
5510
|
-
handleNavigation(resolvedApiPath);
|
|
5511
|
-
},
|
|
5512
|
-
children: "API"
|
|
5513
|
-
}
|
|
5514
|
-
),
|
|
5515
|
-
/* @__PURE__ */ jsx(
|
|
5516
|
-
MoreItem,
|
|
5517
|
-
{
|
|
5518
|
-
href: "https://docs.loafmarkets.com/en/",
|
|
5519
|
-
target: "_blank",
|
|
5520
|
-
rel: "noopener noreferrer",
|
|
5521
|
-
onClick: () => setIsMoreMenuOpen(false),
|
|
5522
|
-
children: "Docs"
|
|
5523
|
-
}
|
|
5524
|
-
)
|
|
5525
|
-
] })
|
|
5526
|
-
] }),
|
|
5527
5481
|
/* @__PURE__ */ jsx("div", { style: { marginLeft: "auto", display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx(
|
|
5528
5482
|
"div",
|
|
5529
5483
|
{
|
|
@@ -5564,8 +5518,6 @@ var Header = ({
|
|
|
5564
5518
|
),
|
|
5565
5519
|
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(offeringsHref), children: "Initial Offerings" }),
|
|
5566
5520
|
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedPropertyMapPath), children: "Property Map" }),
|
|
5567
|
-
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedLeaderboardPath), children: "Competition" }),
|
|
5568
|
-
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedLeaderboardPagePath), children: "Leaderboard" }),
|
|
5569
5521
|
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedLearnPath), children: "Learn" }),
|
|
5570
5522
|
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedAboutPath), children: "About" }),
|
|
5571
5523
|
/* @__PURE__ */ jsx(MobileNavItem, { onClick: () => handleNavigation(resolvedApiPath), children: "API" }),
|
|
@@ -5839,7 +5791,8 @@ var Overlay = styled10.div`
|
|
|
5839
5791
|
height: 100%;
|
|
5840
5792
|
background-color: rgba(0, 0, 0, 0.7);
|
|
5841
5793
|
backdrop-filter: blur(3px);
|
|
5842
|
-
z
|
|
5794
|
+
/* Above the trade page's sticky/console layers (z 2000) + close modal (10001). */
|
|
5795
|
+
z-index: 10070;
|
|
5843
5796
|
`;
|
|
5844
5797
|
var MobileOnlyButton = styled10.button.attrs({ type: "button" })`
|
|
5845
5798
|
display: none;
|
|
@@ -5887,7 +5840,11 @@ var HeaderContainer = styled10.header`
|
|
|
5887
5840
|
top: 0;
|
|
5888
5841
|
left: 0;
|
|
5889
5842
|
right: 0;
|
|
5890
|
-
|
|
5843
|
+
/* Normally 1000. When the mobile menu is open, lift the whole header
|
|
5844
|
+
(and the Nav drawer trapped inside its stacking context) above the
|
|
5845
|
+
backdrop Overlay (10070) AND the trade page's modal layers (10001) so
|
|
5846
|
+
the drawer renders on top instead of being dimmed by the backdrop. */
|
|
5847
|
+
z-index: ${({ $menuOpen }) => $menuOpen ? 10075 : 1e3};
|
|
5891
5848
|
width: 100%;
|
|
5892
5849
|
/* Fallback min-height for browsers that can't evaluate calc+env */
|
|
5893
5850
|
min-height: 56px;
|
|
@@ -5981,7 +5938,8 @@ var Nav = styled10.nav`
|
|
|
5981
5938
|
max-width: 100%;
|
|
5982
5939
|
height: calc(100dvh - var(--loaf-menu-top, calc(56px + max(env(safe-area-inset-top, 0px), var(--telegram-safe-top, 0px)))));
|
|
5983
5940
|
background: rgb(17, 17, 19);
|
|
5984
|
-
z
|
|
5941
|
+
/* Above the trade page's sticky/console layers (z 2000) + close modal (10001). */
|
|
5942
|
+
z-index: 10080;
|
|
5985
5943
|
/* Gentle fade + slide-down instead of an abrupt slide-in. */
|
|
5986
5944
|
opacity: ${(props) => props.$isOpen ? "1" : "0"};
|
|
5987
5945
|
transform: ${(props) => props.$isOpen ? "translateY(0)" : "translateY(-14px)"};
|
|
@@ -5999,9 +5957,12 @@ var Nav = styled10.nav`
|
|
|
5999
5957
|
display: flex;
|
|
6000
5958
|
flex-direction: column;
|
|
6001
5959
|
align-items: center;
|
|
6002
|
-
|
|
5960
|
+
/* safe-center keeps centering when the menu fits, but top-aligns (honouring the
|
|
5961
|
+
2.5rem top padding) when the logged-in menu overflows — otherwise flex
|
|
5962
|
+
centering pushes the first item + padding above the scroll area and clips it. */
|
|
5963
|
+
justify-content: safe center;
|
|
6003
5964
|
min-height: 100%;
|
|
6004
|
-
padding:
|
|
5965
|
+
padding: 2.5rem 1.5rem 2.5rem;
|
|
6005
5966
|
gap: 0.4rem;
|
|
6006
5967
|
}
|
|
6007
5968
|
}
|
|
@@ -6074,77 +6035,6 @@ var NavLink = styled10.a`
|
|
|
6074
6035
|
}
|
|
6075
6036
|
}
|
|
6076
6037
|
`;
|
|
6077
|
-
var MoreMenu = styled10.div`
|
|
6078
|
-
position: relative;
|
|
6079
|
-
display: flex;
|
|
6080
|
-
align-items: center;
|
|
6081
|
-
height: 56px;
|
|
6082
|
-
`;
|
|
6083
|
-
var MoreTrigger = styled10.button`
|
|
6084
|
-
margin: 0 12px;
|
|
6085
|
-
padding: 0 4px;
|
|
6086
|
-
height: 56px;
|
|
6087
|
-
display: inline-flex;
|
|
6088
|
-
align-items: center;
|
|
6089
|
-
gap: 4px;
|
|
6090
|
-
background: none;
|
|
6091
|
-
border: none;
|
|
6092
|
-
cursor: pointer;
|
|
6093
|
-
color: #eaecef;
|
|
6094
|
-
font-weight: 500;
|
|
6095
|
-
font-size: 14px;
|
|
6096
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
|
|
6097
|
-
letter-spacing: 0.2px;
|
|
6098
|
-
transition: color 0.2s ease;
|
|
6099
|
-
|
|
6100
|
-
&:hover,
|
|
6101
|
-
&.active {
|
|
6102
|
-
color: #E6C87E;
|
|
6103
|
-
}
|
|
6104
|
-
|
|
6105
|
-
svg {
|
|
6106
|
-
width: 14px;
|
|
6107
|
-
height: 14px;
|
|
6108
|
-
transition: transform 0.2s ease;
|
|
6109
|
-
}
|
|
6110
|
-
&.open svg {
|
|
6111
|
-
transform: rotate(180deg);
|
|
6112
|
-
}
|
|
6113
|
-
`;
|
|
6114
|
-
var MoreDropdown = styled10.div`
|
|
6115
|
-
position: absolute;
|
|
6116
|
-
top: 100%;
|
|
6117
|
-
right: 0;
|
|
6118
|
-
min-width: 160px;
|
|
6119
|
-
padding: 6px;
|
|
6120
|
-
background: #1e2026;
|
|
6121
|
-
border: 1px solid #2b3139;
|
|
6122
|
-
border-radius: 10px;
|
|
6123
|
-
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
|
|
6124
|
-
display: flex;
|
|
6125
|
-
flex-direction: column;
|
|
6126
|
-
z-index: 1100;
|
|
6127
|
-
`;
|
|
6128
|
-
var MoreItem = styled10.a`
|
|
6129
|
-
padding: 10px 12px;
|
|
6130
|
-
border-radius: 6px;
|
|
6131
|
-
color: #eaecef;
|
|
6132
|
-
font-weight: 500;
|
|
6133
|
-
font-size: 14px;
|
|
6134
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
|
|
6135
|
-
letter-spacing: 0.2px;
|
|
6136
|
-
text-decoration: none;
|
|
6137
|
-
cursor: pointer;
|
|
6138
|
-
transition: background 0.15s ease, color 0.15s ease;
|
|
6139
|
-
|
|
6140
|
-
&:hover {
|
|
6141
|
-
background: #2b3139;
|
|
6142
|
-
color: #E6C87E;
|
|
6143
|
-
}
|
|
6144
|
-
&.active {
|
|
6145
|
-
color: #E6C87E;
|
|
6146
|
-
}
|
|
6147
|
-
`;
|
|
6148
6038
|
var Button2 = styled10.button.attrs({ type: "button" })`
|
|
6149
6039
|
padding: 0.5rem 1rem;
|
|
6150
6040
|
border-radius: 6px;
|
|
@@ -6711,6 +6601,17 @@ PropertySubheader.displayName = "PropertySubheader";
|
|
|
6711
6601
|
var DEFAULT_LOGO_SRC = Loaf_logo_Banner_default;
|
|
6712
6602
|
var DEFAULT_LOGO_ALT = "Loaf";
|
|
6713
6603
|
var OTP_INPUT_LENGTH = 6;
|
|
6604
|
+
var CODE_PREFIX = "LOAF-";
|
|
6605
|
+
var CODE_SUFFIX_LEN = 5;
|
|
6606
|
+
var normalizeAccessCode = (raw) => CODE_PREFIX + raw.toUpperCase().replace(/^LOAF-?/, "").replace(/[^A-Z0-9]/g, "").slice(0, CODE_SUFFIX_LEN);
|
|
6607
|
+
var friendlyError = (err, fallback) => {
|
|
6608
|
+
const data = err?.response?.data;
|
|
6609
|
+
if (typeof data?.error === "string" && data.error.trim()) return data.error;
|
|
6610
|
+
if (typeof data?.message === "string" && data.message.trim()) return data.message;
|
|
6611
|
+
const msg = err instanceof Error ? err.message : "";
|
|
6612
|
+
if (msg && !/request failed with status code/i.test(msg) && !/network error/i.test(msg)) return msg;
|
|
6613
|
+
return fallback;
|
|
6614
|
+
};
|
|
6714
6615
|
var LoginPopup = ({
|
|
6715
6616
|
onClose,
|
|
6716
6617
|
onOpenEarlyAccess,
|
|
@@ -6729,10 +6630,13 @@ var LoginPopup = ({
|
|
|
6729
6630
|
renderKycWidget,
|
|
6730
6631
|
onFundWallet,
|
|
6731
6632
|
initialView,
|
|
6633
|
+
initialCode,
|
|
6732
6634
|
kycStatus: kycStatusProp,
|
|
6733
6635
|
walletAddress,
|
|
6734
6636
|
onSubmitReferralCode,
|
|
6735
|
-
|
|
6637
|
+
onValidateCode,
|
|
6638
|
+
onCheckAccess,
|
|
6639
|
+
gate
|
|
6736
6640
|
}) => {
|
|
6737
6641
|
const [view, setView] = useState(() => initialView ?? "main");
|
|
6738
6642
|
const [email, setEmail] = useState("");
|
|
@@ -6740,19 +6644,17 @@ var LoginPopup = ({
|
|
|
6740
6644
|
const [otp, setOtp] = useState(Array(OTP_INPUT_LENGTH).fill(""));
|
|
6741
6645
|
const [error, setError] = useState("");
|
|
6742
6646
|
const [copied, setCopied] = useState(false);
|
|
6743
|
-
const [referralCode, setReferralCode] = useState(
|
|
6647
|
+
const [referralCode, setReferralCode] = useState(
|
|
6648
|
+
() => gate && initialCode ? normalizeAccessCode(initialCode) : ""
|
|
6649
|
+
);
|
|
6744
6650
|
const [referralLoading, setReferralLoading] = useState(false);
|
|
6745
6651
|
const [referralError, setReferralError] = useState("");
|
|
6746
|
-
const [
|
|
6747
|
-
const [
|
|
6652
|
+
const [codeStatus, setCodeStatus] = useState("idle");
|
|
6653
|
+
const [signInRevealed, setSignInRevealed] = useState(false);
|
|
6654
|
+
const [otpStatus, setOtpStatus] = useState("idle");
|
|
6655
|
+
const [signInMode, setSignInMode] = useState(false);
|
|
6748
6656
|
const [loading, setLoading] = useState(false);
|
|
6749
6657
|
const [isSignUp, setIsSignUp] = useState(false);
|
|
6750
|
-
const [loginTitle] = useState(() => {
|
|
6751
|
-
if (typeof window === "undefined") return null;
|
|
6752
|
-
const t = window.__LOAF_LOGIN_TITLE__ ?? null;
|
|
6753
|
-
if (t) delete window.__LOAF_LOGIN_TITLE__;
|
|
6754
|
-
return t;
|
|
6755
|
-
});
|
|
6756
6658
|
const [fundingAmount] = useState("");
|
|
6757
6659
|
const [kycLoading, setKycLoading] = useState(false);
|
|
6758
6660
|
const [showKycWidget, setShowKycWidget] = useState(false);
|
|
@@ -6762,6 +6664,64 @@ var LoginPopup = ({
|
|
|
6762
6664
|
const [fundingError, setFundingError] = useState("");
|
|
6763
6665
|
const [transakWidgetUrl, setTransakWidgetUrl] = useState(null);
|
|
6764
6666
|
const suppressAutoCloseRef = React5__default.useRef(false);
|
|
6667
|
+
const validatedCodeRef = React5__default.useRef(null);
|
|
6668
|
+
const finishGate = React5__default.useCallback(async () => {
|
|
6669
|
+
if (!gate) return true;
|
|
6670
|
+
const code = validatedCodeRef.current;
|
|
6671
|
+
if (code) {
|
|
6672
|
+
try {
|
|
6673
|
+
await onSubmitReferralCode?.(code);
|
|
6674
|
+
window.dispatchEvent(new CustomEvent("loaf:onboarding-start"));
|
|
6675
|
+
return true;
|
|
6676
|
+
} catch {
|
|
6677
|
+
}
|
|
6678
|
+
}
|
|
6679
|
+
const hasAccess = onCheckAccess ? await onCheckAccess() : true;
|
|
6680
|
+
if (hasAccess) return true;
|
|
6681
|
+
suppressAutoCloseRef.current = true;
|
|
6682
|
+
validatedCodeRef.current = null;
|
|
6683
|
+
setOtp(Array(OTP_INPUT_LENGTH).fill(""));
|
|
6684
|
+
setOtpStatus("idle");
|
|
6685
|
+
setSignInMode(false);
|
|
6686
|
+
setSignInRevealed(false);
|
|
6687
|
+
setCodeStatus(code ? "invalid" : "idle");
|
|
6688
|
+
setView("referral");
|
|
6689
|
+
setError(
|
|
6690
|
+
code ? "That code can't be redeemed anymore. Enter a different access code." : "Enter your access code to continue."
|
|
6691
|
+
);
|
|
6692
|
+
return false;
|
|
6693
|
+
}, [gate, onSubmitReferralCode, onCheckAccess]);
|
|
6694
|
+
const runCodeValidation = React5__default.useCallback(async (fullCode) => {
|
|
6695
|
+
setCodeStatus("checking");
|
|
6696
|
+
setError("");
|
|
6697
|
+
try {
|
|
6698
|
+
const ok = onValidateCode ? await onValidateCode(fullCode) : true;
|
|
6699
|
+
if (!ok) {
|
|
6700
|
+
validatedCodeRef.current = null;
|
|
6701
|
+
setCodeStatus("invalid");
|
|
6702
|
+
return;
|
|
6703
|
+
}
|
|
6704
|
+
validatedCodeRef.current = fullCode;
|
|
6705
|
+
setCodeStatus("valid");
|
|
6706
|
+
if (isAuthenticated) {
|
|
6707
|
+
if (await finishGate()) setTimeout(() => onClose(), 500);
|
|
6708
|
+
return;
|
|
6709
|
+
}
|
|
6710
|
+
setIsSignUp(true);
|
|
6711
|
+
setSignInRevealed(true);
|
|
6712
|
+
} catch {
|
|
6713
|
+
validatedCodeRef.current = null;
|
|
6714
|
+
setCodeStatus("invalid");
|
|
6715
|
+
}
|
|
6716
|
+
}, [onValidateCode, isAuthenticated, finishGate, onClose]);
|
|
6717
|
+
const autoCodeTriedRef = React5__default.useRef(false);
|
|
6718
|
+
useEffect(() => {
|
|
6719
|
+
if (autoCodeTriedRef.current || !gate || !initialCode) return;
|
|
6720
|
+
const full = normalizeAccessCode(initialCode);
|
|
6721
|
+
if (full.length !== CODE_PREFIX.length + CODE_SUFFIX_LEN) return;
|
|
6722
|
+
autoCodeTriedRef.current = true;
|
|
6723
|
+
void runCodeValidation(full);
|
|
6724
|
+
}, [gate, initialCode, runCodeValidation]);
|
|
6765
6725
|
useEffect(() => {
|
|
6766
6726
|
if (typeof initialView === "string") {
|
|
6767
6727
|
setView(initialView);
|
|
@@ -6816,11 +6776,11 @@ var LoginPopup = ({
|
|
|
6816
6776
|
}, [autoCloseOnAuth, currentUser, isAuthenticated, onClose, view]);
|
|
6817
6777
|
useEffect(() => {
|
|
6818
6778
|
const handleEsc = (e) => {
|
|
6819
|
-
if (e.key === "Escape") onClose();
|
|
6779
|
+
if (e.key === "Escape" && !gate) onClose();
|
|
6820
6780
|
};
|
|
6821
6781
|
window.addEventListener("keydown", handleEsc);
|
|
6822
6782
|
return () => window.removeEventListener("keydown", handleEsc);
|
|
6823
|
-
}, [onClose]);
|
|
6783
|
+
}, [onClose, gate]);
|
|
6824
6784
|
const handleWalletLogin = async () => {
|
|
6825
6785
|
if (onWalletLogin) {
|
|
6826
6786
|
suppressAutoCloseRef.current = true;
|
|
@@ -6832,12 +6792,16 @@ var LoginPopup = ({
|
|
|
6832
6792
|
setView("wallet-handle");
|
|
6833
6793
|
return;
|
|
6834
6794
|
}
|
|
6835
|
-
|
|
6836
|
-
|
|
6795
|
+
if (await finishGate()) {
|
|
6796
|
+
suppressAutoCloseRef.current = false;
|
|
6797
|
+
onClose();
|
|
6798
|
+
}
|
|
6837
6799
|
return;
|
|
6838
6800
|
} catch (err) {
|
|
6839
6801
|
console.error("[LoginTrace][Popup] Wallet login failed", err);
|
|
6840
6802
|
suppressAutoCloseRef.current = false;
|
|
6803
|
+
setError(friendlyError(err, "Wallet login failed. Please try again."));
|
|
6804
|
+
return;
|
|
6841
6805
|
}
|
|
6842
6806
|
}
|
|
6843
6807
|
onClose();
|
|
@@ -6859,6 +6823,13 @@ var LoginPopup = ({
|
|
|
6859
6823
|
setError("");
|
|
6860
6824
|
try {
|
|
6861
6825
|
await onWalletSignup(handle.trim());
|
|
6826
|
+
if (gate) {
|
|
6827
|
+
if (await finishGate()) {
|
|
6828
|
+
suppressAutoCloseRef.current = false;
|
|
6829
|
+
onClose();
|
|
6830
|
+
}
|
|
6831
|
+
return;
|
|
6832
|
+
}
|
|
6862
6833
|
if (onSubmitReferralCode) {
|
|
6863
6834
|
setView("referral");
|
|
6864
6835
|
} else {
|
|
@@ -6870,6 +6841,11 @@ var LoginPopup = ({
|
|
|
6870
6841
|
setLoading(false);
|
|
6871
6842
|
}
|
|
6872
6843
|
};
|
|
6844
|
+
const handleEmailClick = (signUp = false) => {
|
|
6845
|
+
setIsSignUp(signUp);
|
|
6846
|
+
setView("email");
|
|
6847
|
+
setError("");
|
|
6848
|
+
};
|
|
6873
6849
|
const handleSendCode = async (event) => {
|
|
6874
6850
|
event?.preventDefault();
|
|
6875
6851
|
if (!email || !email.includes("@")) {
|
|
@@ -6882,6 +6858,7 @@ var LoginPopup = ({
|
|
|
6882
6858
|
}
|
|
6883
6859
|
setLoading(true);
|
|
6884
6860
|
setError("");
|
|
6861
|
+
setOtpStatus("idle");
|
|
6885
6862
|
const normalizedHandle = isSignUp && handle.trim() ? handle.trim() : void 0;
|
|
6886
6863
|
try {
|
|
6887
6864
|
const demoResult = await onDemoLogin?.(email, normalizedHandle ?? null);
|
|
@@ -6902,11 +6879,15 @@ var LoginPopup = ({
|
|
|
6902
6879
|
setView("otp");
|
|
6903
6880
|
setOtp(Array(OTP_INPUT_LENGTH).fill(""));
|
|
6904
6881
|
} catch (err) {
|
|
6905
|
-
const message = err
|
|
6882
|
+
const message = friendlyError(err, "We couldn't send a code to that email. Please double-check it and try again.");
|
|
6906
6883
|
console.error("[LoginTrace][Popup] onSendEmailCode threw", err);
|
|
6907
6884
|
if (!isSignUp && message.includes("No account found")) {
|
|
6885
|
+
if (signInMode) {
|
|
6886
|
+
setError("No account found for this email. Go back and enter your access code to create one.");
|
|
6887
|
+
setLoading(false);
|
|
6888
|
+
return;
|
|
6889
|
+
}
|
|
6908
6890
|
setIsSignUp(true);
|
|
6909
|
-
setView("email");
|
|
6910
6891
|
setError("");
|
|
6911
6892
|
setLoading(false);
|
|
6912
6893
|
return;
|
|
@@ -6918,7 +6899,7 @@ var LoginPopup = ({
|
|
|
6918
6899
|
setView("otp");
|
|
6919
6900
|
setOtp(Array(OTP_INPUT_LENGTH).fill(""));
|
|
6920
6901
|
} catch (retryErr) {
|
|
6921
|
-
setError(retryErr
|
|
6902
|
+
setError(friendlyError(retryErr, "We couldn't send a code to that email. Please try again."));
|
|
6922
6903
|
}
|
|
6923
6904
|
setLoading(false);
|
|
6924
6905
|
return;
|
|
@@ -7012,6 +6993,30 @@ var LoginPopup = ({
|
|
|
7012
6993
|
setLoading(false);
|
|
7013
6994
|
}
|
|
7014
6995
|
};
|
|
6996
|
+
const runGateOtpVerify = React5__default.useCallback(async (code) => {
|
|
6997
|
+
if (!onVerifyEmailCode) return;
|
|
6998
|
+
setOtpStatus("checking");
|
|
6999
|
+
setError("");
|
|
7000
|
+
suppressAutoCloseRef.current = true;
|
|
7001
|
+
try {
|
|
7002
|
+
await onVerifyEmailCode({ code, email });
|
|
7003
|
+
if (await finishGate()) {
|
|
7004
|
+
setOtpStatus("valid");
|
|
7005
|
+
setTimeout(() => onClose(), 750);
|
|
7006
|
+
}
|
|
7007
|
+
} catch {
|
|
7008
|
+
suppressAutoCloseRef.current = false;
|
|
7009
|
+
setOtpStatus("invalid");
|
|
7010
|
+
}
|
|
7011
|
+
}, [onVerifyEmailCode, email, finishGate, onClose]);
|
|
7012
|
+
useEffect(() => {
|
|
7013
|
+
if (!gate || view !== "otp") return;
|
|
7014
|
+
if (otp.join("").length < OTP_INPUT_LENGTH) {
|
|
7015
|
+
if (otpStatus === "invalid") setOtpStatus("idle");
|
|
7016
|
+
return;
|
|
7017
|
+
}
|
|
7018
|
+
if (otpStatus === "idle") void runGateOtpVerify(otp.join(""));
|
|
7019
|
+
}, [gate, view, otp, otpStatus, runGateOtpVerify]);
|
|
7015
7020
|
const handleKycWidgetResult = (result) => {
|
|
7016
7021
|
setShowKycWidget(false);
|
|
7017
7022
|
if (result.passed) {
|
|
@@ -7108,35 +7113,36 @@ var LoginPopup = ({
|
|
|
7108
7113
|
setError("");
|
|
7109
7114
|
};
|
|
7110
7115
|
if (view === "main") {
|
|
7111
|
-
return /* @__PURE__ */ jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7116
|
+
return /* @__PURE__ */ jsx(Overlay2, { $transparent: gate, onClick: onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7112
7117
|
/* @__PURE__ */ jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
|
|
7113
|
-
/* @__PURE__ */
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
/* @__PURE__ */ jsx(
|
|
7118
|
-
GateInput,
|
|
7119
|
-
{
|
|
7120
|
-
type: "email",
|
|
7121
|
-
placeholder: "Enter your email",
|
|
7122
|
-
value: email,
|
|
7123
|
-
onChange: (event) => setEmail(event.target.value),
|
|
7124
|
-
autoFocus: true
|
|
7125
|
-
}
|
|
7126
|
-
),
|
|
7127
|
-
/* @__PURE__ */ jsx(GateSubmit, { type: "submit", disabled: loading || !email, "aria-label": "Continue with email", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) }) })
|
|
7118
|
+
/* @__PURE__ */ jsxs(Title, { children: [
|
|
7119
|
+
/* @__PURE__ */ jsxs(LogoContainer3, { children: [
|
|
7120
|
+
/* @__PURE__ */ jsx(LogoImage, { src: logoSrc, alt: logoAlt }),
|
|
7121
|
+
/* @__PURE__ */ jsx(LogoBeta, { children: "Private Beta" })
|
|
7128
7122
|
] }),
|
|
7129
|
-
|
|
7123
|
+
/* @__PURE__ */ jsx(TitleText, { children: "Welcome to Loaf" })
|
|
7130
7124
|
] }),
|
|
7131
|
-
/* @__PURE__ */ jsx(
|
|
7132
|
-
/* @__PURE__ */ jsxs(
|
|
7133
|
-
/* @__PURE__ */
|
|
7134
|
-
|
|
7125
|
+
/* @__PURE__ */ jsx(Subtitle, { children: "Sign in to claim 100k in test USD." }),
|
|
7126
|
+
/* @__PURE__ */ jsxs(ButtonsContainer, { children: [
|
|
7127
|
+
/* @__PURE__ */ jsxs(LoginButton, { onClick: () => handleEmailClick(false), children: [
|
|
7128
|
+
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z" }) }),
|
|
7129
|
+
"Sign in with Email"
|
|
7130
|
+
] }),
|
|
7131
|
+
/* @__PURE__ */ jsx("div", { style: { textAlign: "center", color: "var(--color-text-secondary, #848e9c)", fontSize: "0.875rem" }, children: "or" }),
|
|
7132
|
+
/* @__PURE__ */ jsxs(LoginButton, { onClick: handleWalletLogin, children: [
|
|
7133
|
+
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" }) }),
|
|
7134
|
+
"Sign in with Wallet"
|
|
7135
|
+
] })
|
|
7136
|
+
] }),
|
|
7137
|
+
/* @__PURE__ */ jsxs(SignUpPrompt, { children: [
|
|
7138
|
+
"New to Loaf?",
|
|
7139
|
+
" ",
|
|
7140
|
+
/* @__PURE__ */ jsx(SignUpLink, { type: "button", onClick: () => handleEmailClick(true), children: "Sign up" })
|
|
7135
7141
|
] })
|
|
7136
7142
|
] }) });
|
|
7137
7143
|
}
|
|
7138
7144
|
if (view === "email") {
|
|
7139
|
-
return /* @__PURE__ */ jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7145
|
+
return /* @__PURE__ */ jsx(Overlay2, { $transparent: gate, onClick: onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7140
7146
|
/* @__PURE__ */ jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
|
|
7141
7147
|
/* @__PURE__ */ jsxs(BackButton, { onClick: handleBack, children: [
|
|
7142
7148
|
/* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" }) }),
|
|
@@ -7175,7 +7181,7 @@ var LoginPopup = ({
|
|
|
7175
7181
|
] }) });
|
|
7176
7182
|
}
|
|
7177
7183
|
if (view === "wallet-handle") {
|
|
7178
|
-
return /* @__PURE__ */ jsx(Overlay2, { onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7184
|
+
return /* @__PURE__ */ jsx(Overlay2, { $transparent: gate, onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7179
7185
|
!loading && /* @__PURE__ */ jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
|
|
7180
7186
|
/* @__PURE__ */ jsxs(Title, { children: [
|
|
7181
7187
|
/* @__PURE__ */ jsx(LogoContainer3, { children: /* @__PURE__ */ jsx(LogoImage, { src: logoSrc, alt: logoAlt }) }),
|
|
@@ -7200,7 +7206,71 @@ var LoginPopup = ({
|
|
|
7200
7206
|
] }) });
|
|
7201
7207
|
}
|
|
7202
7208
|
if (view === "otp") {
|
|
7203
|
-
|
|
7209
|
+
if (gate) {
|
|
7210
|
+
return /* @__PURE__ */ jsxs(GateShell, { children: [
|
|
7211
|
+
/* @__PURE__ */ jsx(GateTint, { $reveal: otpStatus === "valid" ? 3 : 2 }),
|
|
7212
|
+
/* @__PURE__ */ jsxs(GateForm, { children: [
|
|
7213
|
+
/* @__PURE__ */ jsxs(GateBrand, { children: [
|
|
7214
|
+
/* @__PURE__ */ jsx(GateLogoLink, { href: "https://loafmarkets.com", "aria-label": "Go to loafmarkets.com", children: /* @__PURE__ */ jsx(GateLogo, { src: logoSrc, alt: logoAlt }) }),
|
|
7215
|
+
/* @__PURE__ */ jsx(GateBrandDivider, {}),
|
|
7216
|
+
/* @__PURE__ */ jsx(GateBetaTag, { children: "Private Beta" })
|
|
7217
|
+
] }),
|
|
7218
|
+
/* @__PURE__ */ jsxs(GateOtpText, { children: [
|
|
7219
|
+
"We sent a code to",
|
|
7220
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
7221
|
+
/* @__PURE__ */ jsx("strong", { children: email })
|
|
7222
|
+
] }),
|
|
7223
|
+
/* @__PURE__ */ jsx(OTPContainer, { children: otp.map((digit, index) => /* @__PURE__ */ jsx(
|
|
7224
|
+
OTPInput,
|
|
7225
|
+
{
|
|
7226
|
+
id: `otp-${index}`,
|
|
7227
|
+
type: "text",
|
|
7228
|
+
inputMode: "numeric",
|
|
7229
|
+
maxLength: 1,
|
|
7230
|
+
$status: otpStatus,
|
|
7231
|
+
readOnly: otpStatus === "valid" || otpStatus === "checking",
|
|
7232
|
+
value: digit,
|
|
7233
|
+
onChange: (event) => handleOTPChange(index, event.target.value),
|
|
7234
|
+
onKeyDown: (event) => handleOTPKeyDown(index, event),
|
|
7235
|
+
onInput: (event) => handleOTPInput(index, event),
|
|
7236
|
+
onPaste: handleOTPPaste,
|
|
7237
|
+
autoComplete: index === 0 ? "one-time-code" : "off",
|
|
7238
|
+
autoFocus: index === 0
|
|
7239
|
+
},
|
|
7240
|
+
index
|
|
7241
|
+
)) }),
|
|
7242
|
+
otpStatus === "invalid" && /* @__PURE__ */ jsx(StatusMessage, { $error: true, children: "That code isn't right. Try again." }),
|
|
7243
|
+
/* @__PURE__ */ jsxs(GateResendText, { children: [
|
|
7244
|
+
/* @__PURE__ */ jsx(
|
|
7245
|
+
"button",
|
|
7246
|
+
{
|
|
7247
|
+
type: "button",
|
|
7248
|
+
onClick: (event) => {
|
|
7249
|
+
event.preventDefault();
|
|
7250
|
+
void handleSendCode(event);
|
|
7251
|
+
},
|
|
7252
|
+
children: "Resend code"
|
|
7253
|
+
}
|
|
7254
|
+
),
|
|
7255
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " \xB7 " }),
|
|
7256
|
+
/* @__PURE__ */ jsx(
|
|
7257
|
+
"button",
|
|
7258
|
+
{
|
|
7259
|
+
type: "button",
|
|
7260
|
+
onClick: () => {
|
|
7261
|
+
setOtp(Array(OTP_INPUT_LENGTH).fill(""));
|
|
7262
|
+
setOtpStatus("idle");
|
|
7263
|
+
setError("");
|
|
7264
|
+
setView("referral");
|
|
7265
|
+
},
|
|
7266
|
+
children: "Back"
|
|
7267
|
+
}
|
|
7268
|
+
)
|
|
7269
|
+
] })
|
|
7270
|
+
] })
|
|
7271
|
+
] });
|
|
7272
|
+
}
|
|
7273
|
+
return /* @__PURE__ */ jsx(Overlay2, { $transparent: gate, onClick: loading ? void 0 : onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7204
7274
|
!loading && /* @__PURE__ */ jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
|
|
7205
7275
|
loading ? /* @__PURE__ */ jsxs(AccountCreationLoader, { children: [
|
|
7206
7276
|
/* @__PURE__ */ jsx(SpinnerRing, {}),
|
|
@@ -7289,8 +7359,8 @@ var LoginPopup = ({
|
|
|
7289
7359
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
|
|
7290
7360
|
/* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
|
|
7291
7361
|
] }) }),
|
|
7292
|
-
/* @__PURE__ */ jsx(KycHeading, { children: "Verify
|
|
7293
|
-
/* @__PURE__ */ jsx(KycSubline, { children: "Initial offerings are only available to
|
|
7362
|
+
/* @__PURE__ */ jsx(KycHeading, { children: "Verify Wholesale Status" }),
|
|
7363
|
+
/* @__PURE__ */ jsx(KycSubline, { children: "Initial offerings are only available to accredited or wholesale investors" }),
|
|
7294
7364
|
/* @__PURE__ */ jsx(KycStartButton, { type: "button", onClick: handleKycStart, disabled: kycLoading, children: kycLoading ? "Verifying\u2026" : kycStatusProp === "PENDING" || kycStatusProp === "ON_HOLD" ? "Resume Verification" : "Start Verification" }),
|
|
7295
7365
|
/* @__PURE__ */ jsx(KycDuration, { children: "Takes about 2 minutes" }),
|
|
7296
7366
|
/* @__PURE__ */ jsx(KycDivider, {}),
|
|
@@ -7376,7 +7446,7 @@ var LoginPopup = ({
|
|
|
7376
7446
|
/* @__PURE__ */ jsx("div", { style: { color: "rgba(255,255,255,0.5)", fontSize: "0.8rem" }, children: "Deposit USDC from an exchange or wallet" })
|
|
7377
7447
|
] })
|
|
7378
7448
|
] }),
|
|
7379
|
-
/* @__PURE__ */ jsxs(ModalOptionCard, { onClick: handleFiatFund, disabled:
|
|
7449
|
+
/* @__PURE__ */ jsxs(ModalOptionCard, { onClick: handleFiatFund, disabled: true, children: [
|
|
7380
7450
|
/* @__PURE__ */ jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", style: { color: "rgba(255,255,255,0.6)", flexShrink: 0 }, children: [
|
|
7381
7451
|
/* @__PURE__ */ jsx("line", { x1: "3", y1: "22", x2: "21", y2: "22" }),
|
|
7382
7452
|
/* @__PURE__ */ jsx("line", { x1: "6", y1: "18", x2: "6", y2: "11" }),
|
|
@@ -7386,7 +7456,10 @@ var LoginPopup = ({
|
|
|
7386
7456
|
/* @__PURE__ */ jsx("polygon", { points: "12 2 20 7 4 7" })
|
|
7387
7457
|
] }),
|
|
7388
7458
|
/* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
|
|
7389
|
-
/* @__PURE__ */
|
|
7459
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", marginBottom: "0.25rem" }, children: [
|
|
7460
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#fff", fontWeight: 600, fontSize: "0.95rem" }, children: fiatFundingLoading ? "Loading widget\u2026" : "Bank Deposit" }),
|
|
7461
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6rem", fontWeight: 700, color: "#E6C87E", background: "rgba(230,198,86,0.12)", padding: "0.12rem 0.4rem", borderRadius: "4px", textTransform: "uppercase", letterSpacing: "0.04em", whiteSpace: "nowrap" }, children: "Coming Soon" })
|
|
7462
|
+
] }),
|
|
7390
7463
|
/* @__PURE__ */ jsx("div", { style: { color: "rgba(255,255,255,0.5)", fontSize: "0.8rem" }, children: "Deposit to your account via card or bank transfer" })
|
|
7391
7464
|
] })
|
|
7392
7465
|
] })
|
|
@@ -7417,84 +7490,162 @@ var LoginPopup = ({
|
|
|
7417
7490
|
setReferralLoading(false);
|
|
7418
7491
|
}
|
|
7419
7492
|
};
|
|
7420
|
-
const
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
return;
|
|
7424
|
-
}
|
|
7493
|
+
const codeSuffix = referralCode.startsWith(CODE_PREFIX) ? referralCode.slice(CODE_PREFIX.length) : referralCode.replace(/^LOAF-?/i, "");
|
|
7494
|
+
const setCodeSuffix = (suffix) => {
|
|
7495
|
+
setReferralCode(CODE_PREFIX + suffix);
|
|
7425
7496
|
setReferralError("");
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
setWaitlistLoading(false);
|
|
7497
|
+
setError("");
|
|
7498
|
+
if (gate) {
|
|
7499
|
+
if (suffix.length === 5) void runCodeValidation(CODE_PREFIX + suffix);
|
|
7500
|
+
else {
|
|
7501
|
+
validatedCodeRef.current = null;
|
|
7502
|
+
setCodeStatus("idle");
|
|
7503
|
+
}
|
|
7434
7504
|
}
|
|
7435
7505
|
};
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7506
|
+
const handleCodeChange = (e) => {
|
|
7507
|
+
setCodeSuffix(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 5));
|
|
7508
|
+
};
|
|
7509
|
+
const handleCodePaste = (e) => {
|
|
7510
|
+
e.preventDefault();
|
|
7511
|
+
const text = (e.clipboardData.getData("text") || "").toUpperCase();
|
|
7512
|
+
setCodeSuffix(text.replace(/^LOAF-?/, "").replace(/[^A-Z0-9]/g, "").slice(0, 5));
|
|
7513
|
+
};
|
|
7514
|
+
const codeComplete = codeSuffix.length === 5;
|
|
7515
|
+
const codeInput = /* @__PURE__ */ jsx(
|
|
7516
|
+
CodeSuffixInput,
|
|
7517
|
+
{
|
|
7518
|
+
type: "text",
|
|
7519
|
+
inputMode: "text",
|
|
7520
|
+
autoComplete: "off",
|
|
7521
|
+
autoCapitalize: "characters",
|
|
7522
|
+
spellCheck: false,
|
|
7523
|
+
maxLength: 5,
|
|
7524
|
+
"aria-label": "Access code",
|
|
7525
|
+
readOnly: codeStatus === "valid",
|
|
7526
|
+
value: codeSuffix,
|
|
7527
|
+
onChange: handleCodeChange,
|
|
7528
|
+
onPaste: handleCodePaste,
|
|
7529
|
+
onKeyDown: (e) => {
|
|
7530
|
+
if (e.key !== "Enter" || !codeComplete) return;
|
|
7531
|
+
if (gate) void runCodeValidation(referralCode);
|
|
7532
|
+
else void handleReferralSubmit();
|
|
7533
|
+
},
|
|
7534
|
+
autoFocus: true
|
|
7535
|
+
}
|
|
7536
|
+
);
|
|
7537
|
+
const signInStep = /* @__PURE__ */ jsxs(GateReveal, { children: [
|
|
7538
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSendCode, style: { width: "100%" }, children: [
|
|
7539
|
+
/* @__PURE__ */ jsxs(CodeInputWrapper, { children: [
|
|
7458
7540
|
/* @__PURE__ */ jsx(
|
|
7459
|
-
|
|
7541
|
+
GateEmailInput,
|
|
7460
7542
|
{
|
|
7461
|
-
type: "
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
},
|
|
7468
|
-
onKeyDown: (e) => {
|
|
7469
|
-
if (e.key === "Enter") void handleReferralSubmit();
|
|
7470
|
-
},
|
|
7543
|
+
type: "email",
|
|
7544
|
+
inputMode: "email",
|
|
7545
|
+
autoComplete: "email",
|
|
7546
|
+
placeholder: "Enter your email",
|
|
7547
|
+
value: email,
|
|
7548
|
+
onChange: (event) => setEmail(event.target.value),
|
|
7471
7549
|
autoFocus: true
|
|
7472
7550
|
}
|
|
7473
7551
|
),
|
|
7474
|
-
/* @__PURE__ */ jsx(
|
|
7475
|
-
SubmitButton,
|
|
7476
|
-
{
|
|
7477
|
-
type: "button",
|
|
7478
|
-
onClick: () => void handleReferralSubmit(),
|
|
7479
|
-
disabled: referralLoading || !referralCode.trim(),
|
|
7480
|
-
children: referralLoading ? "Verifying\u2026" : "Apply Code"
|
|
7481
|
-
}
|
|
7482
|
-
),
|
|
7483
|
-
referralError && /* @__PURE__ */ jsx(StatusMessage, { $error: true, children: referralError })
|
|
7552
|
+
/* @__PURE__ */ jsx(GateSubmit, { type: "submit", "aria-label": "Continue", disabled: loading || !email, children: loading ? /* @__PURE__ */ jsx(GateSpinner, {}) : /* @__PURE__ */ jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) }) })
|
|
7484
7553
|
] }),
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7554
|
+
error && /* @__PURE__ */ jsx(StatusMessage, { $error: true, children: error })
|
|
7555
|
+
] }),
|
|
7556
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7557
|
+
/* @__PURE__ */ jsx(GateOr, { children: "or" }),
|
|
7558
|
+
/* @__PURE__ */ jsxs(GateWalletButton, { type: "button", onClick: handleWalletLogin, children: [
|
|
7559
|
+
/* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" }) }),
|
|
7560
|
+
signInMode ? "Sign in with Wallet" : "Connect Wallet"
|
|
7561
|
+
] })
|
|
7562
|
+
] })
|
|
7563
|
+
] });
|
|
7564
|
+
if (gate) {
|
|
7565
|
+
const codeAccepted = codeStatus === "valid";
|
|
7566
|
+
const showSignIn = signInMode || signInRevealed;
|
|
7567
|
+
return /* @__PURE__ */ jsxs(GateShell, { children: [
|
|
7568
|
+
/* @__PURE__ */ jsx(GateTint, { $reveal: showSignIn ? 1 : 0 }),
|
|
7569
|
+
/* @__PURE__ */ jsxs(GateForm, { children: [
|
|
7570
|
+
/* @__PURE__ */ jsxs(GateBrand, { children: [
|
|
7571
|
+
/* @__PURE__ */ jsx(GateLogoLink, { href: "https://loafmarkets.com", "aria-label": "Go to loafmarkets.com", children: /* @__PURE__ */ jsx(GateLogo, { src: logoSrc, alt: logoAlt }) }),
|
|
7572
|
+
/* @__PURE__ */ jsx(GateBrandDivider, {}),
|
|
7573
|
+
/* @__PURE__ */ jsx(GateBetaTag, { children: "Private Beta" })
|
|
7574
|
+
] }),
|
|
7575
|
+
signInMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7576
|
+
signInStep,
|
|
7577
|
+
/* @__PURE__ */ jsx(GateResendText, { children: /* @__PURE__ */ jsx(
|
|
7578
|
+
"button",
|
|
7579
|
+
{
|
|
7580
|
+
type: "button",
|
|
7581
|
+
onClick: () => {
|
|
7582
|
+
setError("");
|
|
7583
|
+
setSignInMode(false);
|
|
7584
|
+
},
|
|
7585
|
+
children: "\u2190 Enter access code instead"
|
|
7586
|
+
}
|
|
7587
|
+
) })
|
|
7588
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7589
|
+
/* @__PURE__ */ jsxs(CodeInputWrapper, { $status: codeStatus, children: [
|
|
7590
|
+
/* @__PURE__ */ jsx(CodePrefix, { children: CODE_PREFIX }),
|
|
7591
|
+
codeInput,
|
|
7592
|
+
/* @__PURE__ */ jsx(
|
|
7593
|
+
GateSubmit,
|
|
7594
|
+
{
|
|
7595
|
+
type: "button",
|
|
7596
|
+
"aria-label": "Submit access code",
|
|
7597
|
+
$status: codeStatus,
|
|
7598
|
+
disabled: codeStatus === "checking" || !codeComplete,
|
|
7599
|
+
onClick: () => void runCodeValidation(referralCode),
|
|
7600
|
+
children: codeAccepted ? /* @__PURE__ */ jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" }) }) : codeStatus === "checking" ? /* @__PURE__ */ jsx(GateSpinner, {}) : /* @__PURE__ */ jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) })
|
|
7601
|
+
}
|
|
7602
|
+
)
|
|
7603
|
+
] }),
|
|
7604
|
+
(codeStatus === "invalid" || error && !signInRevealed) && /* @__PURE__ */ jsx(StatusMessage, { $error: true, children: error || "That code isn't valid. Double-check and try again." }),
|
|
7605
|
+
signInRevealed ? signInStep : /* @__PURE__ */ jsxs(GateResendText, { children: [
|
|
7606
|
+
"Already have an account?",
|
|
7607
|
+
" ",
|
|
7608
|
+
/* @__PURE__ */ jsx(
|
|
7609
|
+
"button",
|
|
7610
|
+
{
|
|
7611
|
+
type: "button",
|
|
7612
|
+
onClick: () => {
|
|
7613
|
+
setError("");
|
|
7614
|
+
setIsSignUp(false);
|
|
7615
|
+
setSignInMode(true);
|
|
7616
|
+
},
|
|
7617
|
+
children: "Sign in"
|
|
7618
|
+
}
|
|
7619
|
+
)
|
|
7620
|
+
] })
|
|
7621
|
+
] })
|
|
7622
|
+
] })
|
|
7623
|
+
] });
|
|
7624
|
+
}
|
|
7625
|
+
return /* @__PURE__ */ jsx(Overlay2, { onClick: onClose, children: /* @__PURE__ */ jsxs(PopupContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
7626
|
+
/* @__PURE__ */ jsx(CloseButton, { onClick: onClose, "aria-label": "Close login popup", children: /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) }),
|
|
7627
|
+
/* @__PURE__ */ jsxs(Title, { children: [
|
|
7628
|
+
/* @__PURE__ */ jsxs(LogoContainer3, { children: [
|
|
7629
|
+
/* @__PURE__ */ jsx(LogoImage, { src: logoSrc, alt: logoAlt }),
|
|
7630
|
+
/* @__PURE__ */ jsx(LogoBeta, { children: "Private Beta" })
|
|
7631
|
+
] }),
|
|
7632
|
+
/* @__PURE__ */ jsx(TitleText, { children: "Enter your access code" })
|
|
7633
|
+
] }),
|
|
7634
|
+
/* @__PURE__ */ jsxs(EmailFormContainer, { style: { width: "100%", marginTop: "1.5rem", marginBottom: 0 }, children: [
|
|
7635
|
+
/* @__PURE__ */ jsxs(CodeInputWrapper, { children: [
|
|
7636
|
+
/* @__PURE__ */ jsx(CodePrefix, { children: CODE_PREFIX }),
|
|
7637
|
+
codeInput
|
|
7638
|
+
] }),
|
|
7639
|
+
/* @__PURE__ */ jsx(
|
|
7640
|
+
SubmitButton,
|
|
7490
7641
|
{
|
|
7491
7642
|
type: "button",
|
|
7492
|
-
onClick: () => void
|
|
7493
|
-
disabled:
|
|
7494
|
-
|
|
7495
|
-
children: waitlistLoading ? "Joining\u2026" : email ? "Skip for now & join Waitlist" : "Skip for now"
|
|
7643
|
+
onClick: () => void handleReferralSubmit(),
|
|
7644
|
+
disabled: referralLoading || !codeComplete,
|
|
7645
|
+
children: referralLoading ? "Verifying\u2026" : "Continue"
|
|
7496
7646
|
}
|
|
7497
|
-
)
|
|
7647
|
+
),
|
|
7648
|
+
referralError && /* @__PURE__ */ jsx(StatusMessage, { $error: true, children: referralError })
|
|
7498
7649
|
] })
|
|
7499
7650
|
] }) });
|
|
7500
7651
|
}
|
|
@@ -7614,8 +7765,9 @@ var Overlay2 = styled10.div`
|
|
|
7614
7765
|
left: 0;
|
|
7615
7766
|
right: 0;
|
|
7616
7767
|
bottom: 0;
|
|
7617
|
-
background-color: rgba(0, 0, 0, 0.8);
|
|
7618
|
-
backdrop-filter: blur(4px);
|
|
7768
|
+
background-color: ${(props) => props.$gate ? "var(--color-background, #0a0a0a)" : props.$transparent ? "rgba(0, 0, 0, 0.45)" : "rgba(0, 0, 0, 0.8)"};
|
|
7769
|
+
backdrop-filter: ${(props) => props.$gate ? "none" : props.$transparent ? "blur(2px)" : "blur(4px)"};
|
|
7770
|
+
transition: background-color 0.4s ease, backdrop-filter 0.4s ease;
|
|
7619
7771
|
display: flex;
|
|
7620
7772
|
justify-content: center;
|
|
7621
7773
|
align-items: center;
|
|
@@ -7632,15 +7784,15 @@ var Overlay2 = styled10.div`
|
|
|
7632
7784
|
}
|
|
7633
7785
|
`;
|
|
7634
7786
|
var PopupContainer = styled10.div`
|
|
7635
|
-
background-color: var(--color-background, #0a0a0a);
|
|
7636
|
-
border: 1px solid rgba(230, 198, 86, 0.3);
|
|
7787
|
+
background-color: ${(props) => props.$gate ? "transparent" : "var(--color-background, #0a0a0a)"};
|
|
7788
|
+
border: ${(props) => props.$gate ? "none" : "1px solid rgba(230, 198, 86, 0.3)"};
|
|
7637
7789
|
border-radius: var(--border-radius, 12px);
|
|
7638
7790
|
padding: 2.5rem;
|
|
7639
7791
|
max-width: 440px;
|
|
7640
7792
|
width: 90%;
|
|
7641
7793
|
position: relative;
|
|
7642
7794
|
animation: slideUp 0.3s ease-out;
|
|
7643
|
-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
|
7795
|
+
box-shadow: ${(props) => props.$gate ? "none" : "0 10px 30px rgba(0, 0, 0, 0.3)"};
|
|
7644
7796
|
|
|
7645
7797
|
@keyframes slideUp {
|
|
7646
7798
|
from {
|
|
@@ -7827,29 +7979,27 @@ var Title = styled10.h2`
|
|
|
7827
7979
|
flex-direction: column;
|
|
7828
7980
|
align-items: center;
|
|
7829
7981
|
justify-content: center;
|
|
7830
|
-
gap:
|
|
7982
|
+
gap: 1rem;
|
|
7831
7983
|
`;
|
|
7832
|
-
styled10.
|
|
7833
|
-
font-size: 0.9rem;
|
|
7834
|
-
font-weight: 400;
|
|
7835
|
-
color: var(--color-text-secondary, #848e9c);
|
|
7984
|
+
var TitleText = styled10.span`
|
|
7836
7985
|
text-align: center;
|
|
7837
|
-
|
|
7986
|
+
line-height: 1.2;
|
|
7838
7987
|
`;
|
|
7839
|
-
var
|
|
7840
|
-
|
|
7841
|
-
font-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7988
|
+
var LogoBeta = styled10.span`
|
|
7989
|
+
color: var(--color-accent, #E6C87E);
|
|
7990
|
+
font-size: 0.6rem;
|
|
7991
|
+
font-weight: 600;
|
|
7992
|
+
letter-spacing: 0.14em;
|
|
7993
|
+
text-transform: uppercase;
|
|
7994
|
+
white-space: nowrap;
|
|
7995
|
+
padding-bottom: 0.95rem;
|
|
7845
7996
|
`;
|
|
7846
|
-
var
|
|
7997
|
+
var Subtitle = styled10.p`
|
|
7847
7998
|
font-size: 0.9rem;
|
|
7848
7999
|
font-weight: 400;
|
|
7849
8000
|
color: var(--color-text-secondary, #848e9c);
|
|
7850
|
-
text-align:
|
|
7851
|
-
margin: 0 0
|
|
7852
|
-
line-height: 1.5;
|
|
8001
|
+
text-align: center;
|
|
8002
|
+
margin: 0 0 2rem;
|
|
7853
8003
|
`;
|
|
7854
8004
|
var LogoContainer3 = styled10.div`
|
|
7855
8005
|
display: flex;
|
|
@@ -7859,148 +8009,349 @@ var LogoContainer3 = styled10.div`
|
|
|
7859
8009
|
margin-bottom: 0.5rem;
|
|
7860
8010
|
`;
|
|
7861
8011
|
var LogoImage = styled10.img`
|
|
7862
|
-
height:
|
|
8012
|
+
height: 60px;
|
|
7863
8013
|
`;
|
|
7864
|
-
styled10.div`
|
|
8014
|
+
var ButtonsContainer = styled10.div`
|
|
7865
8015
|
display: flex;
|
|
7866
8016
|
flex-direction: column;
|
|
7867
8017
|
gap: 1rem;
|
|
7868
8018
|
margin-bottom: 1.5rem;
|
|
7869
8019
|
`;
|
|
7870
|
-
styled10.div`
|
|
8020
|
+
var SignUpPrompt = styled10.div`
|
|
7871
8021
|
text-align: center;
|
|
7872
8022
|
font-size: 0.875rem;
|
|
7873
8023
|
color: var(--color-text-secondary, #848e9c);
|
|
7874
8024
|
margin-bottom: 0.5rem;
|
|
7875
8025
|
`;
|
|
7876
|
-
styled10.button`
|
|
7877
|
-
background: none;
|
|
7878
|
-
border: none;
|
|
7879
|
-
padding: 0;
|
|
7880
|
-
font: inherit;
|
|
7881
|
-
color: var(--color-accent, #E6C87E);
|
|
7882
|
-
text-decoration: underline;
|
|
7883
|
-
cursor: pointer;
|
|
8026
|
+
var SignUpLink = styled10.button`
|
|
8027
|
+
background: none;
|
|
8028
|
+
border: none;
|
|
8029
|
+
padding: 0;
|
|
8030
|
+
font: inherit;
|
|
8031
|
+
color: var(--color-accent, #E6C87E);
|
|
8032
|
+
text-decoration: underline;
|
|
8033
|
+
cursor: pointer;
|
|
8034
|
+
|
|
8035
|
+
&:hover {
|
|
8036
|
+
opacity: 0.85;
|
|
8037
|
+
}
|
|
8038
|
+
`;
|
|
8039
|
+
var LoginButton = styled10.button`
|
|
8040
|
+
display: flex;
|
|
8041
|
+
align-items: center;
|
|
8042
|
+
justify-content: center;
|
|
8043
|
+
gap: 0.75rem;
|
|
8044
|
+
padding: 1rem 1.5rem;
|
|
8045
|
+
background-color: var(--color-background-light, #1a1a1a);
|
|
8046
|
+
border: 1px solid rgba(230, 198, 86, 0.2);
|
|
8047
|
+
border-radius: var(--border-radius, 8px);
|
|
8048
|
+
color: var(--color-text, #eaecef);
|
|
8049
|
+
font-size: 1rem;
|
|
8050
|
+
font-weight: 500;
|
|
8051
|
+
cursor: pointer;
|
|
8052
|
+
transition: all 0.2s ease;
|
|
8053
|
+
|
|
8054
|
+
&:hover {
|
|
8055
|
+
background-color: rgba(230, 198, 86, 0.1);
|
|
8056
|
+
border-color: var(--color-accent, #E6C87E);
|
|
8057
|
+
}
|
|
8058
|
+
|
|
8059
|
+
svg {
|
|
8060
|
+
width: 20px;
|
|
8061
|
+
height: 20px;
|
|
8062
|
+
color: var(--color-accent, #E6C87E);
|
|
8063
|
+
}
|
|
8064
|
+
`;
|
|
8065
|
+
var InfoText = styled10.p`
|
|
8066
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8067
|
+
font-size: 0.875rem;
|
|
8068
|
+
text-align: center;
|
|
8069
|
+
line-height: 1.5;
|
|
8070
|
+
`;
|
|
8071
|
+
var EmailFormContainer = styled10.div`
|
|
8072
|
+
display: flex;
|
|
8073
|
+
flex-direction: column;
|
|
8074
|
+
gap: 1rem;
|
|
8075
|
+
margin-bottom: 1.5rem;
|
|
8076
|
+
`;
|
|
8077
|
+
var EmailInput = styled10.input`
|
|
8078
|
+
width: 100%;
|
|
8079
|
+
padding: 1rem 1.25rem;
|
|
8080
|
+
background-color: var(--color-background-light, #1a1a1a);
|
|
8081
|
+
border: 1px solid rgba(230, 198, 86, 0.2);
|
|
8082
|
+
border-radius: var(--border-radius, 8px);
|
|
8083
|
+
color: var(--color-text, #eaecef);
|
|
8084
|
+
font-size: 1rem;
|
|
8085
|
+
transition: all 0.2s ease;
|
|
8086
|
+
|
|
8087
|
+
&:focus {
|
|
8088
|
+
outline: none;
|
|
8089
|
+
border-color: var(--color-accent, #E6C87E);
|
|
8090
|
+
}
|
|
8091
|
+
|
|
8092
|
+
&::placeholder {
|
|
8093
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8094
|
+
}
|
|
8095
|
+
`;
|
|
8096
|
+
var codeBorderColor = (status, focused) => {
|
|
8097
|
+
if (status === "valid") return "var(--color-positive, #00C076)";
|
|
8098
|
+
if (status === "invalid") return "var(--color-negative, #FF5757)";
|
|
8099
|
+
return focused ? "var(--color-accent, #E6C87E)" : "rgba(230, 198, 86, 0.2)";
|
|
8100
|
+
};
|
|
8101
|
+
var CodeInputWrapper = styled10.div`
|
|
8102
|
+
display: flex;
|
|
8103
|
+
align-items: center;
|
|
8104
|
+
width: 100%;
|
|
8105
|
+
padding: 1rem 1.25rem;
|
|
8106
|
+
background-color: var(--color-background-light, #1a1a1a);
|
|
8107
|
+
border: 1px solid ${(props) => codeBorderColor(props.$status, false)};
|
|
8108
|
+
border-radius: var(--border-radius, 8px);
|
|
8109
|
+
box-shadow: ${(props) => props.$status === "valid" ? "0 0 0 1px var(--color-positive, #00C076)" : props.$status === "invalid" ? "0 0 0 1px var(--color-negative, #FF5757)" : "none"};
|
|
8110
|
+
transition: all 0.2s ease;
|
|
8111
|
+
|
|
8112
|
+
&:focus-within {
|
|
8113
|
+
border-color: ${(props) => codeBorderColor(props.$status, true)};
|
|
8114
|
+
}
|
|
8115
|
+
`;
|
|
8116
|
+
var CodePrefix = styled10.span`
|
|
8117
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8118
|
+
font-size: 1.1rem;
|
|
8119
|
+
font-weight: 600;
|
|
8120
|
+
letter-spacing: 0.22em;
|
|
8121
|
+
font-family: 'Space Grotesk', monospace;
|
|
8122
|
+
user-select: none;
|
|
8123
|
+
`;
|
|
8124
|
+
var CodeSuffixInput = styled10.input`
|
|
8125
|
+
flex: 1;
|
|
8126
|
+
min-width: 0;
|
|
8127
|
+
border: none;
|
|
8128
|
+
background: transparent;
|
|
8129
|
+
color: var(--color-text, #eaecef);
|
|
8130
|
+
font-size: 1.1rem;
|
|
8131
|
+
font-weight: 600;
|
|
8132
|
+
letter-spacing: 0.22em;
|
|
8133
|
+
text-transform: uppercase;
|
|
8134
|
+
font-family: 'Space Grotesk', monospace;
|
|
8135
|
+
/* Explicit line-height so iOS in-app WebViews size the caret to the text
|
|
8136
|
+
box instead of rendering a short, top-aligned caret (line-height: normal
|
|
8137
|
+
+ webfont + letter-spacing miscomputes it in some WebViews). */
|
|
8138
|
+
line-height: 1.5;
|
|
8139
|
+
|
|
8140
|
+
&:focus {
|
|
8141
|
+
outline: none;
|
|
8142
|
+
}
|
|
8143
|
+
|
|
8144
|
+
&::placeholder {
|
|
8145
|
+
color: rgba(132, 142, 156, 0.45);
|
|
8146
|
+
letter-spacing: 0.22em;
|
|
8147
|
+
}
|
|
8148
|
+
`;
|
|
8149
|
+
var GateBrand = styled10.div`
|
|
8150
|
+
display: flex;
|
|
8151
|
+
align-items: center;
|
|
8152
|
+
justify-content: center;
|
|
8153
|
+
gap: 0.7rem;
|
|
8154
|
+
margin-bottom: 0.6rem;
|
|
8155
|
+
`;
|
|
8156
|
+
var GateLogoLink = styled10.a`
|
|
8157
|
+
display: inline-flex;
|
|
8158
|
+
align-items: center;
|
|
8159
|
+
cursor: pointer;
|
|
8160
|
+
transition: opacity 0.15s ease;
|
|
8161
|
+
|
|
8162
|
+
&:hover {
|
|
8163
|
+
opacity: 0.85;
|
|
8164
|
+
}
|
|
8165
|
+
`;
|
|
8166
|
+
var GateLogo = styled10.img`
|
|
8167
|
+
height: 44px;
|
|
8168
|
+
display: block;
|
|
8169
|
+
`;
|
|
8170
|
+
var GateBrandDivider = styled10.span`
|
|
8171
|
+
width: 1px;
|
|
8172
|
+
height: 26px;
|
|
8173
|
+
background: rgba(255, 255, 255, 0.18);
|
|
8174
|
+
`;
|
|
8175
|
+
var GateBetaTag = styled10.span`
|
|
8176
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8177
|
+
font-size: 0.8rem;
|
|
8178
|
+
font-weight: 500;
|
|
8179
|
+
letter-spacing: 0.28em;
|
|
8180
|
+
text-transform: uppercase;
|
|
8181
|
+
`;
|
|
8182
|
+
var GateForm = styled10.div`
|
|
8183
|
+
display: flex;
|
|
8184
|
+
flex-direction: column;
|
|
8185
|
+
align-items: center;
|
|
8186
|
+
gap: 0.9rem;
|
|
8187
|
+
width: 100%;
|
|
8188
|
+
max-width: 360px;
|
|
8189
|
+
position: relative;
|
|
8190
|
+
z-index: 1;
|
|
8191
|
+
`;
|
|
8192
|
+
var GateShell = styled10.div`
|
|
8193
|
+
position: fixed;
|
|
8194
|
+
inset: 0;
|
|
8195
|
+
display: flex;
|
|
8196
|
+
align-items: center;
|
|
8197
|
+
justify-content: center;
|
|
8198
|
+
z-index: 10000;
|
|
8199
|
+
background-color: rgba(10, 10, 12, 0.66);
|
|
8200
|
+
`;
|
|
8201
|
+
var GateTint = styled10.div`
|
|
8202
|
+
position: absolute;
|
|
8203
|
+
left: 0;
|
|
8204
|
+
right: 0;
|
|
8205
|
+
bottom: 0;
|
|
8206
|
+
height: calc(${(props) => (3 - Math.max(0, Math.min(3, props.$reveal))) / 3 * 100}% + 90px);
|
|
8207
|
+
background: linear-gradient(
|
|
8208
|
+
to top,
|
|
8209
|
+
var(--color-background, #0a0a0c) calc(100% - 90px),
|
|
8210
|
+
rgba(10, 10, 12, 0) 100%
|
|
8211
|
+
);
|
|
8212
|
+
transition: height 0.65s ease;
|
|
8213
|
+
pointer-events: none;
|
|
8214
|
+
`;
|
|
8215
|
+
var GateOtpText = styled10.p`
|
|
8216
|
+
margin: 0;
|
|
8217
|
+
text-align: center;
|
|
8218
|
+
font-size: 0.9rem;
|
|
8219
|
+
line-height: 1.5;
|
|
8220
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8221
|
+
|
|
8222
|
+
strong {
|
|
8223
|
+
color: var(--color-text, #eaecef);
|
|
8224
|
+
font-weight: 600;
|
|
8225
|
+
}
|
|
8226
|
+
`;
|
|
8227
|
+
var GateResendText = styled10.p`
|
|
8228
|
+
margin: 0.2rem 0 0;
|
|
8229
|
+
font-size: 0.85rem;
|
|
8230
|
+
color: var(--color-text-secondary, #848e9c);
|
|
7884
8231
|
|
|
7885
|
-
|
|
7886
|
-
|
|
8232
|
+
button {
|
|
8233
|
+
background: none;
|
|
8234
|
+
border: none;
|
|
8235
|
+
color: var(--color-accent, #E6C87E);
|
|
8236
|
+
cursor: pointer;
|
|
8237
|
+
text-decoration: underline;
|
|
8238
|
+
font-size: inherit;
|
|
7887
8239
|
}
|
|
7888
8240
|
`;
|
|
7889
|
-
var
|
|
8241
|
+
var GateSubmit = styled10.button`
|
|
7890
8242
|
display: flex;
|
|
7891
|
-
width: 100%;
|
|
7892
|
-
box-sizing: border-box;
|
|
7893
8243
|
align-items: center;
|
|
7894
8244
|
justify-content: center;
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
font-weight: 500;
|
|
8245
|
+
flex-shrink: 0;
|
|
8246
|
+
width: 28px;
|
|
8247
|
+
height: 28px;
|
|
8248
|
+
margin-left: 0.5rem;
|
|
8249
|
+
padding: 0;
|
|
8250
|
+
background: none;
|
|
8251
|
+
border: none;
|
|
7903
8252
|
cursor: pointer;
|
|
7904
|
-
|
|
8253
|
+
color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : props.$status === "invalid" ? "var(--color-negative, #FF5757)" : "var(--color-accent, #E6C87E)"};
|
|
8254
|
+
transition: color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
|
|
7905
8255
|
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
&:hover {
|
|
7909
|
-
background-color: rgba(230, 198, 86, 0.1);
|
|
7910
|
-
border-color: var(--color-accent, #E6C87E);
|
|
8256
|
+
&:not(:disabled):hover {
|
|
8257
|
+
transform: translateX(2px);
|
|
7911
8258
|
}
|
|
7912
8259
|
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
8260
|
+
&:disabled {
|
|
8261
|
+
opacity: ${(props) => props.$status === "valid" ? 1 : 0.35};
|
|
8262
|
+
color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : "var(--color-text-secondary, #848e9c)"};
|
|
8263
|
+
cursor: default;
|
|
7917
8264
|
}
|
|
7918
8265
|
`;
|
|
7919
|
-
var
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
`;
|
|
7925
|
-
var EmailFormContainer = styled10.div`
|
|
7926
|
-
display: flex;
|
|
7927
|
-
flex-direction: column;
|
|
7928
|
-
gap: 1rem;
|
|
7929
|
-
margin-bottom: 1.5rem;
|
|
7930
|
-
`;
|
|
7931
|
-
var EmailInput = styled10.input`
|
|
7932
|
-
width: 100%;
|
|
7933
|
-
padding: 1rem 1.25rem;
|
|
7934
|
-
background-color: var(--color-background-light, #1a1a1a);
|
|
7935
|
-
border: 1px solid rgba(230, 198, 86, 0.2);
|
|
7936
|
-
border-radius: var(--border-radius, 8px);
|
|
8266
|
+
var GateEmailInput = styled10.input`
|
|
8267
|
+
flex: 1;
|
|
8268
|
+
min-width: 0;
|
|
8269
|
+
border: none;
|
|
8270
|
+
background: transparent;
|
|
7937
8271
|
color: var(--color-text, #eaecef);
|
|
7938
8272
|
font-size: 1rem;
|
|
7939
|
-
transition: all 0.2s ease;
|
|
7940
8273
|
|
|
7941
8274
|
&:focus {
|
|
7942
8275
|
outline: none;
|
|
7943
|
-
border-color: var(--color-accent, #E6C87E);
|
|
7944
8276
|
}
|
|
7945
8277
|
|
|
7946
8278
|
&::placeholder {
|
|
7947
|
-
color:
|
|
8279
|
+
color: rgba(132, 142, 156, 0.5);
|
|
8280
|
+
}
|
|
8281
|
+
`;
|
|
8282
|
+
var GateSpinner = styled10.span`
|
|
8283
|
+
width: 18px;
|
|
8284
|
+
height: 18px;
|
|
8285
|
+
border: 2px solid rgba(230, 198, 86, 0.3);
|
|
8286
|
+
border-top-color: var(--color-accent, #E6C87E);
|
|
8287
|
+
border-radius: 50%;
|
|
8288
|
+
animation: gateSpin 0.7s linear infinite;
|
|
8289
|
+
|
|
8290
|
+
@keyframes gateSpin {
|
|
8291
|
+
to { transform: rotate(360deg); }
|
|
7948
8292
|
}
|
|
7949
8293
|
`;
|
|
7950
|
-
var
|
|
8294
|
+
var GateOr = styled10.div`
|
|
7951
8295
|
display: flex;
|
|
7952
|
-
|
|
8296
|
+
align-items: center;
|
|
7953
8297
|
gap: 0.6rem;
|
|
7954
8298
|
width: 100%;
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
width: 100%;
|
|
7959
|
-
`;
|
|
7960
|
-
var GateInput = styled10.input`
|
|
7961
|
-
width: 100%;
|
|
7962
|
-
box-sizing: border-box;
|
|
7963
|
-
padding: 1rem 3.25rem 1rem 1.25rem;
|
|
7964
|
-
background-color: var(--color-background-light, #1a1a1a);
|
|
7965
|
-
border: 1px solid rgba(230, 198, 86, 0.2);
|
|
7966
|
-
border-radius: var(--border-radius, 8px);
|
|
7967
|
-
color: var(--color-text, #eaecef);
|
|
7968
|
-
font-size: 1rem;
|
|
7969
|
-
transition: all 0.2s ease;
|
|
8299
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8300
|
+
font-size: 0.78rem;
|
|
8301
|
+
text-transform: lowercase;
|
|
7970
8302
|
|
|
7971
|
-
|
|
7972
|
-
&::
|
|
8303
|
+
&::before,
|
|
8304
|
+
&::after {
|
|
8305
|
+
content: "";
|
|
8306
|
+
flex: 1;
|
|
8307
|
+
height: 1px;
|
|
8308
|
+
background: rgba(255, 255, 255, 0.1);
|
|
8309
|
+
}
|
|
7973
8310
|
`;
|
|
7974
|
-
var
|
|
7975
|
-
|
|
7976
|
-
top: 50%;
|
|
7977
|
-
right: 0.55rem;
|
|
7978
|
-
transform: translateY(-50%);
|
|
7979
|
-
width: 34px;
|
|
7980
|
-
height: 34px;
|
|
7981
|
-
display: flex;
|
|
8311
|
+
var GateWalletButton = styled10.button`
|
|
8312
|
+
display: inline-flex;
|
|
7982
8313
|
align-items: center;
|
|
7983
8314
|
justify-content: center;
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
8315
|
+
gap: 0.5rem;
|
|
8316
|
+
margin-top: 0.1rem;
|
|
8317
|
+
padding: 0.55rem 1.1rem;
|
|
8318
|
+
background: transparent;
|
|
8319
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
8320
|
+
border-radius: var(--border-radius, 8px);
|
|
7987
8321
|
color: var(--color-text-secondary, #848e9c);
|
|
8322
|
+
font-size: 0.85rem;
|
|
8323
|
+
font-weight: 500;
|
|
7988
8324
|
cursor: pointer;
|
|
7989
|
-
transition: color 0.
|
|
8325
|
+
transition: border-color 0.15s ease, color 0.15s ease;
|
|
8326
|
+
|
|
8327
|
+
svg {
|
|
8328
|
+
width: 16px;
|
|
8329
|
+
height: 16px;
|
|
8330
|
+
}
|
|
7990
8331
|
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
8332
|
+
&:hover {
|
|
8333
|
+
border-color: rgba(230, 198, 86, 0.4);
|
|
8334
|
+
color: var(--color-text, #eaecef);
|
|
8335
|
+
}
|
|
7994
8336
|
`;
|
|
7995
|
-
var
|
|
8337
|
+
var GateReveal = styled10.div`
|
|
7996
8338
|
display: flex;
|
|
8339
|
+
flex-direction: column;
|
|
7997
8340
|
align-items: center;
|
|
7998
|
-
gap: 0.
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
margin: 0.4rem 0;
|
|
8341
|
+
gap: 0.9rem;
|
|
8342
|
+
width: 100%;
|
|
8343
|
+
animation: gateReveal 0.3s ease-out;
|
|
8002
8344
|
|
|
8003
|
-
|
|
8345
|
+
@keyframes gateReveal {
|
|
8346
|
+
from {
|
|
8347
|
+
opacity: 0;
|
|
8348
|
+
transform: translateY(-6px);
|
|
8349
|
+
}
|
|
8350
|
+
to {
|
|
8351
|
+
opacity: 1;
|
|
8352
|
+
transform: translateY(0);
|
|
8353
|
+
}
|
|
8354
|
+
}
|
|
8004
8355
|
`;
|
|
8005
8356
|
var OTPContainer = styled10.div`
|
|
8006
8357
|
display: flex;
|
|
@@ -8014,15 +8365,17 @@ var OTPInput = styled10.input`
|
|
|
8014
8365
|
font-size: 1.5rem;
|
|
8015
8366
|
font-weight: 600;
|
|
8016
8367
|
background-color: var(--color-background-light, #1a1a1a);
|
|
8017
|
-
border: 1px solid
|
|
8368
|
+
border: 1px solid ${(props) => codeBorderColor(props.$status, false)};
|
|
8018
8369
|
border-radius: var(--border-radius, 8px);
|
|
8019
|
-
color: var(--color-accent, #E6C87E);
|
|
8370
|
+
color: ${(props) => props.$status === "valid" ? "var(--color-positive, #00C076)" : props.$status === "invalid" ? "var(--color-negative, #FF5757)" : "var(--color-accent, #E6C87E)"};
|
|
8371
|
+
box-shadow: ${(props) => props.$status === "valid" ? "0 0 0 1px var(--color-positive, #00C076)" : props.$status === "invalid" ? "0 0 0 1px var(--color-negative, #FF5757)" : "none"};
|
|
8372
|
+
opacity: ${(props) => props.$status === "checking" ? 0.6 : 1};
|
|
8020
8373
|
transition: all 0.2s ease;
|
|
8021
8374
|
|
|
8022
8375
|
&:focus {
|
|
8023
8376
|
outline: none;
|
|
8024
|
-
border-color:
|
|
8025
|
-
box-shadow: 0 0 0 2px rgba(230, 198, 86, 0.2);
|
|
8377
|
+
border-color: ${(props) => codeBorderColor(props.$status, true)};
|
|
8378
|
+
box-shadow: 0 0 0 2px ${(props) => props.$status === "valid" ? "rgba(0, 192, 118, 0.25)" : props.$status === "invalid" ? "rgba(255, 87, 87, 0.25)" : "rgba(230, 198, 86, 0.2)"};
|
|
8026
8379
|
}
|
|
8027
8380
|
`;
|
|
8028
8381
|
var SubmitButton = styled10.button`
|
|
@@ -8390,15 +8743,24 @@ var SpinnerRing = styled10.div`
|
|
|
8390
8743
|
}
|
|
8391
8744
|
`;
|
|
8392
8745
|
var PREPARING_FACTS = [
|
|
8393
|
-
|
|
8394
|
-
"Loaf settles trades in about 1 second. Traditional property takes ~90 days.",
|
|
8746
|
+
// Exchange
|
|
8395
8747
|
"Our matching engine processes orders in 30 microseconds.",
|
|
8396
|
-
"
|
|
8397
|
-
"Own a slice of premium real estate \u2014 no mortgage, no paperwork.",
|
|
8748
|
+
"Loaf settles in 1 second. Traditional property takes 30-90 days.",
|
|
8398
8749
|
"Buy and sell property as easily as a stock, on a live orderbook.",
|
|
8399
|
-
"
|
|
8400
|
-
"
|
|
8401
|
-
|
|
8750
|
+
"Continuous price discovery, not a single buyer negotiating in a back room.",
|
|
8751
|
+
"Algo-trade property on our API. Build a bot with Claude using our docs.",
|
|
8752
|
+
// What you're holding
|
|
8753
|
+
"Hold shares secured 1:1 by the underlying property, as regulated securities.",
|
|
8754
|
+
"The same economic exposure as owning the property. Without the friction, gatekeeping, or illiquidity.",
|
|
8755
|
+
"Securitisation of property brings a new dimension of flexibility and tradability.",
|
|
8756
|
+
// Frictionless
|
|
8757
|
+
"Settle in seconds, then sell again whenever you want. No waiting days or weeks.",
|
|
8758
|
+
"99% of the frictions in property transactions can be, and have been, reduced.",
|
|
8759
|
+
// Vision
|
|
8760
|
+
"A family office can rebalance a billion dollars in an afternoon, but couldn't sell a $50M property in under six months.",
|
|
8761
|
+
"Family offices and HNWIs prize capital flexibility. Loaf makes property flexible.",
|
|
8762
|
+
"There's no law of physics that says the world's oldest asset class must stay illiquid.",
|
|
8763
|
+
"What if property underwent an IPO?"
|
|
8402
8764
|
];
|
|
8403
8765
|
var FactCard = styled10.div`
|
|
8404
8766
|
margin-top: 1.5rem;
|
|
@@ -8506,7 +8868,7 @@ var LogoImage2 = styled10.img`
|
|
|
8506
8868
|
height: 30px;
|
|
8507
8869
|
width: auto;
|
|
8508
8870
|
`;
|
|
8509
|
-
var
|
|
8871
|
+
var LogoBeta2 = styled10.span`
|
|
8510
8872
|
font-size: 0.6rem;
|
|
8511
8873
|
font-weight: 600;
|
|
8512
8874
|
letter-spacing: 0.08em;
|
|
@@ -8664,7 +9026,7 @@ function OnboardingGuide({
|
|
|
8664
9026
|
/* @__PURE__ */ jsx(CloseButton2, { onClick: onClose, "aria-label": "Skip", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M18 6L6 18" }) }) }),
|
|
8665
9027
|
/* @__PURE__ */ jsxs(LogoRow, { children: [
|
|
8666
9028
|
/* @__PURE__ */ jsx(LogoImage2, { src: logoSrc, alt: "Loaf" }),
|
|
8667
|
-
/* @__PURE__ */ jsx(
|
|
9029
|
+
/* @__PURE__ */ jsx(LogoBeta2, { children: "Private Beta" })
|
|
8668
9030
|
] }),
|
|
8669
9031
|
/* @__PURE__ */ jsx(Title2, { children: "You're in \u{1F389}" }),
|
|
8670
9032
|
/* @__PURE__ */ jsx(Subtitle2, { children: "Here's everything you need to make your first trade." }),
|
|
@@ -12034,7 +12396,8 @@ function AssetSelectorBar({
|
|
|
12034
12396
|
onSelect,
|
|
12035
12397
|
trailing,
|
|
12036
12398
|
imageUrl,
|
|
12037
|
-
badgeLabel
|
|
12399
|
+
badgeLabel,
|
|
12400
|
+
tickerPrimary
|
|
12038
12401
|
}) {
|
|
12039
12402
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
12040
12403
|
const hasItems = selectorItems && selectorItems.length > 0;
|
|
@@ -12045,9 +12408,14 @@ function AssetSelectorBar({
|
|
|
12045
12408
|
];
|
|
12046
12409
|
return /* @__PURE__ */ jsx(AssetSelectorWrapper, { children: /* @__PURE__ */ jsxs(IPOAssetSelector, { children: [
|
|
12047
12410
|
imageUrl && /* @__PURE__ */ jsx(AssetThumbnail, { src: imageUrl, alt: propertyName }),
|
|
12048
|
-
/* @__PURE__ */ jsx(AssetSelectorDropdown, { onClick: () => hasItems && setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxs(AssetName, { children: [
|
|
12049
|
-
|
|
12050
|
-
|
|
12411
|
+
/* @__PURE__ */ jsx(AssetSelectorDropdown, { $flush: tickerPrimary, onClick: () => hasItems && setIsDropdownOpen((prev) => !prev), children: /* @__PURE__ */ jsxs(AssetName, { children: [
|
|
12412
|
+
tickerPrimary && currentTicker ? /* @__PURE__ */ jsxs(AssetIdentity, { children: [
|
|
12413
|
+
/* @__PURE__ */ jsx(AssetTicker, { children: currentTicker.toUpperCase() }),
|
|
12414
|
+
/* @__PURE__ */ jsx(AssetSubName, { children: propertyName })
|
|
12415
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12416
|
+
propertyName,
|
|
12417
|
+
currentTicker ? ` (${currentTicker.toUpperCase()})` : ""
|
|
12418
|
+
] }),
|
|
12051
12419
|
badgeLabel && /* @__PURE__ */ jsx(CompetitionBadge, { children: badgeLabel }),
|
|
12052
12420
|
hasItems && /* @__PURE__ */ jsx(
|
|
12053
12421
|
"svg",
|
|
@@ -12076,7 +12444,7 @@ function AssetSelectorBar({
|
|
|
12076
12444
|
] })
|
|
12077
12445
|
] })
|
|
12078
12446
|
] }, m.label)) }),
|
|
12079
|
-
trailing != null && /* @__PURE__ */ jsx(TrailingWrapper, { children: /* @__PURE__ */ jsx(TrailingInner, { children: trailing }) }),
|
|
12447
|
+
trailing != null && /* @__PURE__ */ jsx(TrailingWrapper, { className: "asset-bar-trailing", children: /* @__PURE__ */ jsx(TrailingInner, { children: trailing }) }),
|
|
12080
12448
|
isDropdownOpen && hasItems && /* @__PURE__ */ jsx(IPODropdown, { children: selectorItems.map((item) => {
|
|
12081
12449
|
const isCurrent = item.tokenName === currentTokenName;
|
|
12082
12450
|
const status = item.status?.toUpperCase();
|
|
@@ -12167,13 +12535,40 @@ var AssetSelectorDropdown = styled10.div`
|
|
|
12167
12535
|
display: flex;
|
|
12168
12536
|
align-items: center;
|
|
12169
12537
|
cursor: pointer;
|
|
12170
|
-
|
|
12538
|
+
/* $flush (tickerPrimary): no horizontal padding / no hover box, so opening the
|
|
12539
|
+
selector doesn't make the ticker appear shoved right by the highlight box. */
|
|
12540
|
+
padding: ${(p) => p.$flush ? "0.25rem 0" : "0.5rem"};
|
|
12171
12541
|
border-radius: 8px;
|
|
12172
|
-
transition: all 0.2s ease;
|
|
12542
|
+
transition: ${(p) => p.$flush ? "none" : "all 0.2s ease"};
|
|
12173
12543
|
flex: 0 1 auto;
|
|
12174
12544
|
min-width: 0;
|
|
12175
12545
|
overflow: hidden;
|
|
12176
|
-
&:hover { background-color: rgba(255,255,255,0.05); }
|
|
12546
|
+
&:hover { background-color: ${(p) => p.$flush ? "transparent" : "rgba(255,255,255,0.05)"}; }
|
|
12547
|
+
`;
|
|
12548
|
+
var AssetIdentity = styled10.div`
|
|
12549
|
+
display: flex;
|
|
12550
|
+
flex-direction: column;
|
|
12551
|
+
min-width: 0;
|
|
12552
|
+
line-height: 1.2;
|
|
12553
|
+
`;
|
|
12554
|
+
var AssetTicker = styled10.span`
|
|
12555
|
+
font-weight: 700;
|
|
12556
|
+
font-size: 1.35rem;
|
|
12557
|
+
color: var(--color-text);
|
|
12558
|
+
letter-spacing: -0.01em;
|
|
12559
|
+
white-space: nowrap;
|
|
12560
|
+
overflow: hidden;
|
|
12561
|
+
text-overflow: ellipsis;
|
|
12562
|
+
|
|
12563
|
+
@media (max-width: 480px) { font-size: 1.2rem; }
|
|
12564
|
+
`;
|
|
12565
|
+
var AssetSubName = styled10.span`
|
|
12566
|
+
font-size: 0.8rem;
|
|
12567
|
+
font-weight: 500;
|
|
12568
|
+
color: rgba(255, 255, 255, 0.4);
|
|
12569
|
+
white-space: nowrap;
|
|
12570
|
+
overflow: hidden;
|
|
12571
|
+
text-overflow: ellipsis;
|
|
12177
12572
|
`;
|
|
12178
12573
|
var AssetName = styled10.div`
|
|
12179
12574
|
display: flex;
|
|
@@ -14447,6 +14842,7 @@ function PortfolioActivityPanel({
|
|
|
14447
14842
|
showPositionsTab = false,
|
|
14448
14843
|
showSubscriptionsTab = true,
|
|
14449
14844
|
onPositionClick,
|
|
14845
|
+
onSharePosition,
|
|
14450
14846
|
onAssetClick,
|
|
14451
14847
|
onClosePosition,
|
|
14452
14848
|
offeringOrders = [],
|
|
@@ -14738,17 +15134,23 @@ function PortfolioActivityPanel({
|
|
|
14738
15134
|
] }),
|
|
14739
15135
|
/* @__PURE__ */ jsxs(CPnlCell, { children: [
|
|
14740
15136
|
/* @__PURE__ */ jsx(CCellLabel, { children: "PNL (%)" }),
|
|
14741
|
-
/* @__PURE__ */ jsxs(
|
|
14742
|
-
/* @__PURE__ */ jsxs(
|
|
14743
|
-
|
|
14744
|
-
|
|
15137
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.4rem" }, children: [
|
|
15138
|
+
/* @__PURE__ */ jsxs(CPnlLine, { children: [
|
|
15139
|
+
/* @__PURE__ */ jsxs(CPnlValue, { $positive: isPositive, children: [
|
|
15140
|
+
isPositive ? "+" : "-",
|
|
15141
|
+
formatCurrency4(Math.abs(pnl))
|
|
15142
|
+
] }),
|
|
15143
|
+
/* @__PURE__ */ jsxs(CPnlPct, { $positive: isPositive, children: [
|
|
15144
|
+
"(",
|
|
15145
|
+
isPositive ? "+" : "",
|
|
15146
|
+
pnlPercent.toFixed(1),
|
|
15147
|
+
"%)"
|
|
15148
|
+
] })
|
|
14745
15149
|
] }),
|
|
14746
|
-
/* @__PURE__ */
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
"%)"
|
|
14751
|
-
] })
|
|
15150
|
+
onSharePosition && !pos.settling && /* @__PURE__ */ jsx(CShareIconBtn, { role: "button", "aria-label": "Share position", onClick: (e) => {
|
|
15151
|
+
e.stopPropagation();
|
|
15152
|
+
onSharePosition(pos);
|
|
15153
|
+
}, children: /* @__PURE__ */ jsx(ShareIcon, {}) })
|
|
14752
15154
|
] })
|
|
14753
15155
|
] }),
|
|
14754
15156
|
/* @__PURE__ */ jsx(CChevronWrap, { $open: posExpanded, children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "rgba(255,255,255,0.5)", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) }) })
|
|
@@ -14768,16 +15170,16 @@ function PortfolioActivityPanel({
|
|
|
14768
15170
|
/* @__PURE__ */ jsx(CDValue, { children: formatCurrency4(pos.marketPrice) })
|
|
14769
15171
|
] })
|
|
14770
15172
|
] }),
|
|
14771
|
-
onClosePosition && !pos.settling && /* @__PURE__ */ jsxs(CActionRow, { children: [
|
|
14772
|
-
/* @__PURE__ */ jsx(CCloseBtn, { onClick: () => onClosePosition(pos.tokenName, "market", pos.quantity, pos.marketPrice), children: "Market Sell" }),
|
|
14773
|
-
/* @__PURE__ */ jsx(CCloseBtn, { onClick: () => onClosePosition(pos.tokenName, "limit", pos.quantity, pos.marketPrice), children: "Limit Sell" })
|
|
15173
|
+
(onClosePosition || onSharePosition) && !pos.settling && /* @__PURE__ */ jsxs(CActionRow, { children: [
|
|
15174
|
+
onClosePosition && /* @__PURE__ */ jsx(CCloseBtn, { onClick: () => onClosePosition(pos.tokenName, "market", pos.quantity, pos.marketPrice), children: "Market Sell" }),
|
|
15175
|
+
onClosePosition && /* @__PURE__ */ jsx(CCloseBtn, { onClick: () => onClosePosition(pos.tokenName, "limit", pos.quantity, pos.marketPrice), children: "Limit Sell" })
|
|
14774
15176
|
] })
|
|
14775
15177
|
] })
|
|
14776
15178
|
] }, pos.tokenName);
|
|
14777
15179
|
})
|
|
14778
15180
|
] }),
|
|
14779
15181
|
positions.length > 0 && !compactPositions && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14780
|
-
/* @__PURE__ */ jsxs(PositionsHeader, { $hasClose: !!onClosePosition, children: [
|
|
15182
|
+
/* @__PURE__ */ jsxs(PositionsHeader, { $hasClose: !!(onClosePosition || onSharePosition), children: [
|
|
14781
15183
|
/* @__PURE__ */ jsxs(SortableHeaderCell, { $active: posSortKey === "asset", onClick: () => handlePosSort("asset"), children: [
|
|
14782
15184
|
"Asset ",
|
|
14783
15185
|
posSortKey === "asset" && (posSortAsc ? "\u2191" : "\u2193")
|
|
@@ -14810,7 +15212,7 @@ function PortfolioActivityPanel({
|
|
|
14810
15212
|
const pnl = pos.propertyPnl ?? currentValue - costBasis;
|
|
14811
15213
|
const pnlPercent = pos.propertyPnlPercent ?? pos.percentChange ?? 0;
|
|
14812
15214
|
const isPositive = pnl >= 0;
|
|
14813
|
-
return /* @__PURE__ */ jsxs(PositionsRow, { $hasClose: !!onClosePosition, children: [
|
|
15215
|
+
return /* @__PURE__ */ jsxs(PositionsRow, { $hasClose: !!(onClosePosition || onSharePosition), children: [
|
|
14814
15216
|
/* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
14815
15217
|
/* @__PURE__ */ jsx(HoldingsPropertyLink, { onClick: () => onPositionClick?.(pos.tokenName, pos.isIpoAllocation), children: pos.tokenName }),
|
|
14816
15218
|
pos.settling && /* @__PURE__ */ jsx(SettlingTip, { children: /* @__PURE__ */ jsx(SettlingSpinner, {}) })
|
|
@@ -14827,23 +15229,29 @@ function PortfolioActivityPanel({
|
|
|
14827
15229
|
] }) }),
|
|
14828
15230
|
/* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsx("span", { style: { color: "rgba(255,255,255,0.7)", fontSize: "0.8rem" }, children: formatCurrency4(pos.averageEntryPrice) }) }),
|
|
14829
15231
|
/* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsx("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: formatCurrency4(pos.marketPrice) }) }),
|
|
14830
|
-
/* @__PURE__ */
|
|
14831
|
-
/* @__PURE__ */ jsxs(
|
|
14832
|
-
|
|
14833
|
-
|
|
15232
|
+
/* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.4rem" }, children: [
|
|
15233
|
+
/* @__PURE__ */ jsxs("span", { style: { display: "flex", flexDirection: "column" }, children: [
|
|
15234
|
+
/* @__PURE__ */ jsxs(PnLAmount, { $positive: isPositive, children: [
|
|
15235
|
+
isPositive ? "+" : "-",
|
|
15236
|
+
formatCurrency4(Math.abs(pnl))
|
|
15237
|
+
] }),
|
|
15238
|
+
/* @__PURE__ */ jsxs(PnLPercentage, { $positive: isPositive, children: [
|
|
15239
|
+
isPositive ? "+" : "",
|
|
15240
|
+
pnlPercent.toFixed(1),
|
|
15241
|
+
"%"
|
|
15242
|
+
] })
|
|
14834
15243
|
] }),
|
|
14835
|
-
/* @__PURE__ */
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
/* @__PURE__ */ jsx(CloseBtn, { onClick: (e) => {
|
|
15244
|
+
onSharePosition && !pos.settling && /* @__PURE__ */ jsx(CShareIconBtn, { role: "button", "aria-label": "Share position", onClick: (e) => {
|
|
15245
|
+
e.stopPropagation();
|
|
15246
|
+
onSharePosition(pos);
|
|
15247
|
+
}, children: /* @__PURE__ */ jsx(ShareIcon, {}) })
|
|
15248
|
+
] }) }),
|
|
15249
|
+
(onClosePosition || onSharePosition) && /* @__PURE__ */ jsx(PositionsCell, { children: !pos.settling && /* @__PURE__ */ jsxs(CloseActions, { children: [
|
|
15250
|
+
onClosePosition && /* @__PURE__ */ jsx(CloseBtn, { onClick: (e) => {
|
|
14843
15251
|
e.stopPropagation();
|
|
14844
15252
|
onClosePosition(pos.tokenName, "market", pos.quantity, pos.marketPrice);
|
|
14845
15253
|
}, children: "Market Sell" }),
|
|
14846
|
-
/* @__PURE__ */ jsx(CloseBtn, { onClick: (e) => {
|
|
15254
|
+
onClosePosition && /* @__PURE__ */ jsx(CloseBtn, { onClick: (e) => {
|
|
14847
15255
|
e.stopPropagation();
|
|
14848
15256
|
onClosePosition(pos.tokenName, "limit", pos.quantity, pos.marketPrice);
|
|
14849
15257
|
}, children: "Limit Sell" })
|
|
@@ -14851,27 +15259,30 @@ function PortfolioActivityPanel({
|
|
|
14851
15259
|
] }, pos.tokenName);
|
|
14852
15260
|
})
|
|
14853
15261
|
] }),
|
|
14854
|
-
positions.length > 0 && closeAllOpen && onClosePosition &&
|
|
14855
|
-
/* @__PURE__ */ jsx(
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
/* @__PURE__ */
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
/* @__PURE__ */
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
|
|
14867
|
-
|
|
14868
|
-
|
|
14869
|
-
|
|
14870
|
-
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
15262
|
+
positions.length > 0 && closeAllOpen && onClosePosition && typeof document !== "undefined" && createPortal(
|
|
15263
|
+
/* @__PURE__ */ jsx(CloseAllOverlay, { onClick: () => setCloseAllOpen(false), children: /* @__PURE__ */ jsxs(CloseAllModal, { onClick: (e) => e.stopPropagation(), children: [
|
|
15264
|
+
/* @__PURE__ */ jsx(CloseAllModalX, { onClick: () => setCloseAllOpen(false), children: "\xD7" }),
|
|
15265
|
+
/* @__PURE__ */ jsx(CloseAllTitle, { children: "Confirm Sell All" }),
|
|
15266
|
+
/* @__PURE__ */ jsx(CloseAllDesc, { children: "This will sell all your positions and cancel their associated TP/SL orders." }),
|
|
15267
|
+
/* @__PURE__ */ jsxs(CloseAllOption, { onClick: () => setCloseAllType("market"), children: [
|
|
15268
|
+
/* @__PURE__ */ jsx(CloseAllRadio, { $selected: closeAllType === "market" }),
|
|
15269
|
+
/* @__PURE__ */ jsx("span", { children: "Market Sell" })
|
|
15270
|
+
] }),
|
|
15271
|
+
/* @__PURE__ */ jsxs(CloseAllOption, { onClick: () => setCloseAllType("limit"), children: [
|
|
15272
|
+
/* @__PURE__ */ jsx(CloseAllRadio, { $selected: closeAllType === "limit" }),
|
|
15273
|
+
/* @__PURE__ */ jsx("span", { children: "Limit Sell at Mid Price" })
|
|
15274
|
+
] }),
|
|
15275
|
+
/* @__PURE__ */ jsxs(CloseAllConfirmBtn, { onClick: () => {
|
|
15276
|
+
positions.forEach((pos) => onClosePosition(pos.tokenName, closeAllType, pos.quantity, pos.marketPrice));
|
|
15277
|
+
setCloseAllOpen(false);
|
|
15278
|
+
}, children: [
|
|
15279
|
+
"Confirm ",
|
|
15280
|
+
closeAllType === "market" ? "Market" : "Limit",
|
|
15281
|
+
" Sell"
|
|
15282
|
+
] })
|
|
15283
|
+
] }) }),
|
|
15284
|
+
document.body
|
|
15285
|
+
)
|
|
14875
15286
|
] }),
|
|
14876
15287
|
activeTab === "subscriptions" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14877
15288
|
offeringOrders.length === 0 && /* @__PURE__ */ jsx(EmptyState, { children: "IPO allocations will appear here once you subscribe." }),
|
|
@@ -15328,57 +15739,63 @@ function PortfolioActivityPanel({
|
|
|
15328
15739
|
] }),
|
|
15329
15740
|
/* @__PURE__ */ jsx(PaginationBtn, { disabled: currentPage >= totalPages - 1, onClick: () => setCurrentPage((p) => p + 1), children: "Next \u203A" })
|
|
15330
15741
|
] }),
|
|
15331
|
-
cancelAllConfirmOpen &&
|
|
15332
|
-
/* @__PURE__ */ jsx(
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
/* @__PURE__ */
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15351
|
-
|
|
15742
|
+
cancelAllConfirmOpen && typeof document !== "undefined" && createPortal(
|
|
15743
|
+
/* @__PURE__ */ jsx(CancelConfirmOverlay, { onClick: () => setCancelAllConfirmOpen(false), children: /* @__PURE__ */ jsxs(CancelConfirmModal, { onClick: (e) => e.stopPropagation(), children: [
|
|
15744
|
+
/* @__PURE__ */ jsx(CancelConfirmTitle, { children: "Cancel All Orders" }),
|
|
15745
|
+
/* @__PURE__ */ jsxs(CancelConfirmBody, { children: [
|
|
15746
|
+
"Are you sure you want to cancel all ",
|
|
15747
|
+
openOrdersCount,
|
|
15748
|
+
" open orders? This action cannot be undone."
|
|
15749
|
+
] }),
|
|
15750
|
+
/* @__PURE__ */ jsxs(CancelConfirmActions, { children: [
|
|
15751
|
+
/* @__PURE__ */ jsx(CancelConfirmDismiss, { type: "button", onClick: () => setCancelAllConfirmOpen(false), children: "Keep Orders" }),
|
|
15752
|
+
/* @__PURE__ */ jsx(
|
|
15753
|
+
CancelConfirmProceed,
|
|
15754
|
+
{
|
|
15755
|
+
type: "button",
|
|
15756
|
+
disabled: cancellingAll,
|
|
15757
|
+
onClick: async () => {
|
|
15758
|
+
if (onCancelAllOrders) {
|
|
15759
|
+
setCancellingAll(true);
|
|
15760
|
+
try {
|
|
15761
|
+
await onCancelAllOrders();
|
|
15762
|
+
} finally {
|
|
15763
|
+
setCancellingAll(false);
|
|
15764
|
+
}
|
|
15352
15765
|
}
|
|
15353
|
-
|
|
15354
|
-
|
|
15355
|
-
|
|
15356
|
-
|
|
15357
|
-
|
|
15358
|
-
)
|
|
15359
|
-
] })
|
|
15360
|
-
|
|
15361
|
-
|
|
15362
|
-
|
|
15363
|
-
/* @__PURE__ */ jsx(
|
|
15364
|
-
|
|
15365
|
-
/* @__PURE__ */ jsx(
|
|
15366
|
-
/* @__PURE__ */
|
|
15367
|
-
|
|
15368
|
-
|
|
15369
|
-
|
|
15370
|
-
|
|
15371
|
-
|
|
15372
|
-
|
|
15373
|
-
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
|
|
15381
|
-
|
|
15766
|
+
setCancelAllConfirmOpen(false);
|
|
15767
|
+
},
|
|
15768
|
+
children: cancellingAll ? "Cancelling\u2026" : "Yes, Cancel All"
|
|
15769
|
+
}
|
|
15770
|
+
)
|
|
15771
|
+
] })
|
|
15772
|
+
] }) }),
|
|
15773
|
+
document.body
|
|
15774
|
+
),
|
|
15775
|
+
pendingCancelOrderId !== null && typeof document !== "undefined" && createPortal(
|
|
15776
|
+
/* @__PURE__ */ jsx(CancelConfirmOverlay, { onClick: () => setPendingCancelOrderId(null), children: /* @__PURE__ */ jsxs(CancelConfirmModal, { onClick: (e) => e.stopPropagation(), children: [
|
|
15777
|
+
/* @__PURE__ */ jsx(CancelConfirmTitle, { children: "Cancel Order" }),
|
|
15778
|
+
/* @__PURE__ */ jsx(CancelConfirmBody, { children: "Are you sure you want to cancel this order? This action cannot be undone." }),
|
|
15779
|
+
/* @__PURE__ */ jsxs(CancelConfirmActions, { children: [
|
|
15780
|
+
/* @__PURE__ */ jsx(CancelConfirmDismiss, { type: "button", onClick: () => setPendingCancelOrderId(null), children: "Keep Order" }),
|
|
15781
|
+
/* @__PURE__ */ jsx(
|
|
15782
|
+
CancelConfirmProceed,
|
|
15783
|
+
{
|
|
15784
|
+
type: "button",
|
|
15785
|
+
disabled: cancellingOrderId != null,
|
|
15786
|
+
onClick: async () => {
|
|
15787
|
+
if (onCancelOrder && pendingCancelOrderId !== null) {
|
|
15788
|
+
await onCancelOrder(pendingCancelOrderId);
|
|
15789
|
+
}
|
|
15790
|
+
setPendingCancelOrderId(null);
|
|
15791
|
+
},
|
|
15792
|
+
children: cancellingOrderId === pendingCancelOrderId ? "Cancelling\u2026" : "Yes, Cancel"
|
|
15793
|
+
}
|
|
15794
|
+
)
|
|
15795
|
+
] })
|
|
15796
|
+
] }) }),
|
|
15797
|
+
document.body
|
|
15798
|
+
)
|
|
15382
15799
|
] });
|
|
15383
15800
|
}
|
|
15384
15801
|
var Container2 = styled10.div`
|
|
@@ -15449,7 +15866,7 @@ var Tab = styled10.button`
|
|
|
15449
15866
|
}
|
|
15450
15867
|
`;
|
|
15451
15868
|
var TabCount = styled10.span`
|
|
15452
|
-
color: #
|
|
15869
|
+
color: var(--color-accent, #E6C87E);
|
|
15453
15870
|
font-weight: 600;
|
|
15454
15871
|
margin-left: 2px;
|
|
15455
15872
|
`;
|
|
@@ -15634,7 +16051,8 @@ var CancelConfirmOverlay = styled10.div`
|
|
|
15634
16051
|
display: flex;
|
|
15635
16052
|
align-items: center;
|
|
15636
16053
|
justify-content: center;
|
|
15637
|
-
|
|
16054
|
+
/* Above the trade page's fullscreen/sticky layers (TradePage.css uses up to 10001). */
|
|
16055
|
+
z-index: 10050;
|
|
15638
16056
|
`;
|
|
15639
16057
|
var CancelConfirmModal = styled10.div`
|
|
15640
16058
|
background: #1a1a1a;
|
|
@@ -15724,6 +16142,29 @@ var CloseBtn = styled10.button`
|
|
|
15724
16142
|
border-color: rgba(230, 200, 126, 0.5);
|
|
15725
16143
|
}
|
|
15726
16144
|
`;
|
|
16145
|
+
var CShareIconBtn = styled10.span`
|
|
16146
|
+
display: inline-flex;
|
|
16147
|
+
align-items: center;
|
|
16148
|
+
justify-content: center;
|
|
16149
|
+
width: 26px;
|
|
16150
|
+
height: 26px;
|
|
16151
|
+
border-radius: 6px;
|
|
16152
|
+
color: #E6C87E;
|
|
16153
|
+
cursor: pointer;
|
|
16154
|
+
pointer-events: auto;
|
|
16155
|
+
transition: color 0.15s ease, background 0.15s ease;
|
|
16156
|
+
&:hover {
|
|
16157
|
+
color: #F2D898;
|
|
16158
|
+
background: rgba(230, 200, 126, 0.14);
|
|
16159
|
+
}
|
|
16160
|
+
&:active { background: rgba(230, 200, 126, 0.22); }
|
|
16161
|
+
svg { width: 15px; height: 15px; }
|
|
16162
|
+
`;
|
|
16163
|
+
var ShareIcon = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
16164
|
+
/* @__PURE__ */ jsx("path", { d: "M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7" }),
|
|
16165
|
+
/* @__PURE__ */ jsx("polyline", { points: "16 6 12 2 8 6" }),
|
|
16166
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "15" })
|
|
16167
|
+
] });
|
|
15727
16168
|
var CloseAllHeaderBtn = styled10.button`
|
|
15728
16169
|
background: rgba(230, 200, 126, 0.1);
|
|
15729
16170
|
border: 1px solid rgba(230, 200, 126, 0.3);
|
|
@@ -15748,7 +16189,8 @@ var CloseAllOverlay = styled10.div`
|
|
|
15748
16189
|
display: flex;
|
|
15749
16190
|
align-items: center;
|
|
15750
16191
|
justify-content: center;
|
|
15751
|
-
|
|
16192
|
+
/* Above the trade page's fullscreen/sticky layers (TradePage.css uses up to 10001). */
|
|
16193
|
+
z-index: 10050;
|
|
15752
16194
|
`;
|
|
15753
16195
|
var CloseAllModal = styled10.div`
|
|
15754
16196
|
background: #1a1a1a;
|