@loafmarkets/ui 0.1.407 → 0.1.409
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 +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +348 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +348 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -712,6 +712,11 @@ type HeaderProps = {
|
|
|
712
712
|
* without DOM-level click interception. */
|
|
713
713
|
onReferClick?: () => void;
|
|
714
714
|
portfolioSummary?: HeaderPortfolioData | null;
|
|
715
|
+
/**
|
|
716
|
+
* Cumulative competition points the user has earned across all rounds up to now.
|
|
717
|
+
* When provided, the account dropdown leads with a "Total Points" summary row.
|
|
718
|
+
*/
|
|
719
|
+
totalPoints?: number | null;
|
|
715
720
|
/**
|
|
716
721
|
* True while a brand-new user's test funds (100k mock USD) are being deposited
|
|
717
722
|
* on-chain (~10s). Replaces the portfolio metrics with a "funds arriving" banner.
|
|
@@ -768,9 +773,12 @@ interface OnboardingGuideProps {
|
|
|
768
773
|
onEnterCode?: () => void;
|
|
769
774
|
/** Dismiss / skip (✕, "Skip for now", or after Browse). */
|
|
770
775
|
onClose: () => void;
|
|
776
|
+
/** Save the chosen handle (optional step). Reject to surface an error
|
|
777
|
+
* (e.g. handle taken). If omitted, the handle step is skipped entirely. */
|
|
778
|
+
onClaimHandle?: (handle: string) => Promise<void> | void;
|
|
771
779
|
logoSrc?: string;
|
|
772
780
|
}
|
|
773
|
-
declare function OnboardingGuide({ open, fundsReady, cashLabel, onBrowseProperties, onEnterCode, onClose, logoSrc, }: OnboardingGuideProps): react_jsx_runtime.JSX.Element | null;
|
|
781
|
+
declare function OnboardingGuide({ open, fundsReady, cashLabel, onBrowseProperties, onEnterCode, onClose, onClaimHandle, logoSrc, }: OnboardingGuideProps): react_jsx_runtime.JSX.Element | null;
|
|
774
782
|
|
|
775
783
|
type PropertyAddressOption = {
|
|
776
784
|
id: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -712,6 +712,11 @@ type HeaderProps = {
|
|
|
712
712
|
* without DOM-level click interception. */
|
|
713
713
|
onReferClick?: () => void;
|
|
714
714
|
portfolioSummary?: HeaderPortfolioData | null;
|
|
715
|
+
/**
|
|
716
|
+
* Cumulative competition points the user has earned across all rounds up to now.
|
|
717
|
+
* When provided, the account dropdown leads with a "Total Points" summary row.
|
|
718
|
+
*/
|
|
719
|
+
totalPoints?: number | null;
|
|
715
720
|
/**
|
|
716
721
|
* True while a brand-new user's test funds (100k mock USD) are being deposited
|
|
717
722
|
* on-chain (~10s). Replaces the portfolio metrics with a "funds arriving" banner.
|
|
@@ -768,9 +773,12 @@ interface OnboardingGuideProps {
|
|
|
768
773
|
onEnterCode?: () => void;
|
|
769
774
|
/** Dismiss / skip (✕, "Skip for now", or after Browse). */
|
|
770
775
|
onClose: () => void;
|
|
776
|
+
/** Save the chosen handle (optional step). Reject to surface an error
|
|
777
|
+
* (e.g. handle taken). If omitted, the handle step is skipped entirely. */
|
|
778
|
+
onClaimHandle?: (handle: string) => Promise<void> | void;
|
|
771
779
|
logoSrc?: string;
|
|
772
780
|
}
|
|
773
|
-
declare function OnboardingGuide({ open, fundsReady, cashLabel, onBrowseProperties, onEnterCode, onClose, logoSrc, }: OnboardingGuideProps): react_jsx_runtime.JSX.Element | null;
|
|
781
|
+
declare function OnboardingGuide({ open, fundsReady, cashLabel, onBrowseProperties, onEnterCode, onClose, onClaimHandle, logoSrc, }: OnboardingGuideProps): react_jsx_runtime.JSX.Element | null;
|
|
774
782
|
|
|
775
783
|
type PropertyAddressOption = {
|
|
776
784
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -5103,6 +5103,7 @@ var Header = ({
|
|
|
5103
5103
|
onSettingsClick,
|
|
5104
5104
|
onReferClick,
|
|
5105
5105
|
portfolioSummary,
|
|
5106
|
+
totalPoints,
|
|
5106
5107
|
fundsPending = false,
|
|
5107
5108
|
transparentOnTop = false,
|
|
5108
5109
|
headerCta = "deposit",
|
|
@@ -5566,6 +5567,11 @@ var Header = ({
|
|
|
5566
5567
|
}
|
|
5567
5568
|
),
|
|
5568
5569
|
isUserMenuOpen && /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { className: "user-menu-dropdown", children: [
|
|
5570
|
+
totalPoints != null && /* @__PURE__ */ jsxRuntime.jsxs(PointsHeader, { children: [
|
|
5571
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pts-label", children: "Total Points" }),
|
|
5572
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pts-value", children: totalPoints.toLocaleString() }),
|
|
5573
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pts-note", children: "Cumulative points earned. More soon." })
|
|
5574
|
+
] }),
|
|
5569
5575
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5570
5576
|
"button",
|
|
5571
5577
|
{
|
|
@@ -5623,7 +5629,7 @@ var Header = ({
|
|
|
5623
5629
|
}
|
|
5624
5630
|
)
|
|
5625
5631
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [
|
|
5626
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button2, { className: "signup", onClick: handleSignIn, children: "
|
|
5632
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button2, { className: "signup", onClick: handleSignIn, children: "Join Competition" }),
|
|
5627
5633
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5628
5634
|
MobileOnlyButton,
|
|
5629
5635
|
{
|
|
@@ -6151,6 +6157,33 @@ var DropdownMenu = styled10__default.default.div`
|
|
|
6151
6157
|
display: block;
|
|
6152
6158
|
}
|
|
6153
6159
|
`;
|
|
6160
|
+
var PointsHeader = styled10__default.default.div`
|
|
6161
|
+
padding: 0.7rem 1.25rem 0.8rem;
|
|
6162
|
+
margin-bottom: 0.35rem;
|
|
6163
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
6164
|
+
.pts-note {
|
|
6165
|
+
margin-top: 0.4rem;
|
|
6166
|
+
font-size: 0.6rem;
|
|
6167
|
+
line-height: 1.4;
|
|
6168
|
+
color: rgba(255, 255, 255, 0.4);
|
|
6169
|
+
}
|
|
6170
|
+
.pts-label {
|
|
6171
|
+
font-family: 'SF Mono', 'Fira Code', ui-monospace, monospace;
|
|
6172
|
+
font-size: 0.56rem;
|
|
6173
|
+
font-weight: 700;
|
|
6174
|
+
letter-spacing: 0.16em;
|
|
6175
|
+
text-transform: uppercase;
|
|
6176
|
+
color: rgba(255, 255, 255, 0.45);
|
|
6177
|
+
}
|
|
6178
|
+
.pts-value {
|
|
6179
|
+
margin-top: 0.2rem;
|
|
6180
|
+
font-size: 1.15rem;
|
|
6181
|
+
font-weight: 800;
|
|
6182
|
+
color: #E6C87E;
|
|
6183
|
+
font-variant-numeric: tabular-nums;
|
|
6184
|
+
line-height: 1;
|
|
6185
|
+
}
|
|
6186
|
+
`;
|
|
6154
6187
|
var MenuItem = styled10__default.default.div`
|
|
6155
6188
|
padding: 0.75rem 1.25rem;
|
|
6156
6189
|
cursor: pointer;
|
|
@@ -7576,7 +7609,6 @@ var LoginPopup = ({
|
|
|
7576
7609
|
] })
|
|
7577
7610
|
] });
|
|
7578
7611
|
if (gate) {
|
|
7579
|
-
const codeAccepted = codeStatus === "valid";
|
|
7580
7612
|
const showSignIn = signInMode || signInRevealed;
|
|
7581
7613
|
return /* @__PURE__ */ jsxRuntime.jsxs(GateShell, { children: [
|
|
7582
7614
|
/* @__PURE__ */ jsxRuntime.jsx(GateTint, { $reveal: showSignIn ? 1 : 0 }),
|
|
@@ -7602,35 +7634,30 @@ var LoginPopup = ({
|
|
|
7602
7634
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7603
7635
|
/* @__PURE__ */ jsxRuntime.jsxs(CodeInputWrapper, { $status: codeStatus, children: [
|
|
7604
7636
|
/* @__PURE__ */ jsxRuntime.jsx(CodePrefix, { children: CODE_PREFIX }),
|
|
7605
|
-
codeInput
|
|
7606
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7607
|
-
GateSubmit,
|
|
7608
|
-
{
|
|
7609
|
-
type: "button",
|
|
7610
|
-
"aria-label": "Submit access code",
|
|
7611
|
-
$status: codeStatus,
|
|
7612
|
-
disabled: codeStatus === "checking" || !codeComplete,
|
|
7613
|
-
onClick: () => void runCodeValidation(referralCode),
|
|
7614
|
-
children: codeAccepted ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" }) }) : codeStatus === "checking" ? /* @__PURE__ */ jsxRuntime.jsx(GateSpinner, {}) : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) })
|
|
7615
|
-
}
|
|
7616
|
-
)
|
|
7637
|
+
codeInput
|
|
7617
7638
|
] }),
|
|
7618
7639
|
(codeStatus === "invalid" || error && !signInRevealed) && /* @__PURE__ */ jsxRuntime.jsx(StatusMessage, { $error: true, children: error || "That code isn't valid. Double-check and try again." }),
|
|
7619
|
-
signInRevealed ? signInStep : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7640
|
+
signInRevealed ? signInStep : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7641
|
+
/* @__PURE__ */ jsxRuntime.jsxs(GateResendText, { children: [
|
|
7642
|
+
"Already have an account?",
|
|
7643
|
+
" ",
|
|
7644
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7645
|
+
"button",
|
|
7646
|
+
{
|
|
7647
|
+
type: "button",
|
|
7648
|
+
onClick: () => {
|
|
7649
|
+
setError("");
|
|
7650
|
+
setIsSignUp(false);
|
|
7651
|
+
setSignInMode(true);
|
|
7652
|
+
},
|
|
7653
|
+
children: "Sign in"
|
|
7654
|
+
}
|
|
7655
|
+
)
|
|
7656
|
+
] }),
|
|
7657
|
+
/* @__PURE__ */ jsxRuntime.jsxs(GateEarlyAccess, { href: "https://loafmarkets.com/?waitlist=1", children: [
|
|
7658
|
+
"Signup for early access",
|
|
7659
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14M13 6l6 6-6 6" }) })
|
|
7660
|
+
] })
|
|
7634
7661
|
] })
|
|
7635
7662
|
] })
|
|
7636
7663
|
] })
|
|
@@ -8253,6 +8280,33 @@ var GateResendText = styled10__default.default.p`
|
|
|
8253
8280
|
font-size: inherit;
|
|
8254
8281
|
}
|
|
8255
8282
|
`;
|
|
8283
|
+
var GateEarlyAccess = styled10__default.default.a`
|
|
8284
|
+
display: inline-flex;
|
|
8285
|
+
align-items: center;
|
|
8286
|
+
gap: 0.4rem;
|
|
8287
|
+
margin-top: 0.15rem;
|
|
8288
|
+
color: var(--color-text-secondary, #848e9c);
|
|
8289
|
+
font-size: 0.8rem;
|
|
8290
|
+
font-weight: 500;
|
|
8291
|
+
letter-spacing: 0.02em;
|
|
8292
|
+
text-decoration: none;
|
|
8293
|
+
cursor: pointer;
|
|
8294
|
+
transition: color 0.15s ease;
|
|
8295
|
+
|
|
8296
|
+
svg {
|
|
8297
|
+
width: 13px;
|
|
8298
|
+
height: 13px;
|
|
8299
|
+
transition: transform 0.15s ease;
|
|
8300
|
+
}
|
|
8301
|
+
|
|
8302
|
+
&:hover {
|
|
8303
|
+
color: var(--color-accent, #E6C87E);
|
|
8304
|
+
}
|
|
8305
|
+
|
|
8306
|
+
&:hover svg {
|
|
8307
|
+
transform: translateX(3px);
|
|
8308
|
+
}
|
|
8309
|
+
`;
|
|
8256
8310
|
var GateSubmit = styled10__default.default.button`
|
|
8257
8311
|
display: flex;
|
|
8258
8312
|
align-items: center;
|
|
@@ -9032,6 +9086,48 @@ var CodeLink = styled10__default.default.button`
|
|
|
9032
9086
|
text-underline-offset: 2px;
|
|
9033
9087
|
}
|
|
9034
9088
|
`;
|
|
9089
|
+
var HandleField = styled10__default.default.div`
|
|
9090
|
+
display: flex;
|
|
9091
|
+
align-items: center;
|
|
9092
|
+
gap: 0.1rem;
|
|
9093
|
+
width: 100%;
|
|
9094
|
+
margin-bottom: 0.4rem;
|
|
9095
|
+
padding: 0 0.9rem;
|
|
9096
|
+
background: rgba(255, 255, 255, 0.04);
|
|
9097
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
9098
|
+
border-radius: 10px;
|
|
9099
|
+
transition: border-color 0.15s ease;
|
|
9100
|
+
|
|
9101
|
+
&:focus-within {
|
|
9102
|
+
border-color: rgba(230, 200, 126, 0.6);
|
|
9103
|
+
}
|
|
9104
|
+
`;
|
|
9105
|
+
var HandleAt = styled10__default.default.span`
|
|
9106
|
+
color: rgba(255, 255, 255, 0.4);
|
|
9107
|
+
font-size: 1rem;
|
|
9108
|
+
font-weight: 600;
|
|
9109
|
+
`;
|
|
9110
|
+
var HandleInput = styled10__default.default.input`
|
|
9111
|
+
flex: 1;
|
|
9112
|
+
min-width: 0;
|
|
9113
|
+
padding: 0.85rem 0.4rem;
|
|
9114
|
+
border: none;
|
|
9115
|
+
background: transparent;
|
|
9116
|
+
color: #fff;
|
|
9117
|
+
font-size: 1rem;
|
|
9118
|
+
font-family: inherit;
|
|
9119
|
+
outline: none;
|
|
9120
|
+
|
|
9121
|
+
&::placeholder {
|
|
9122
|
+
color: rgba(255, 255, 255, 0.35);
|
|
9123
|
+
}
|
|
9124
|
+
`;
|
|
9125
|
+
var FieldError = styled10__default.default.div`
|
|
9126
|
+
width: 100%;
|
|
9127
|
+
margin-bottom: 0.6rem;
|
|
9128
|
+
font-size: 0.78rem;
|
|
9129
|
+
color: #ff6b6b;
|
|
9130
|
+
`;
|
|
9035
9131
|
function OnboardingGuide({
|
|
9036
9132
|
open,
|
|
9037
9133
|
fundsReady,
|
|
@@ -9039,8 +9135,21 @@ function OnboardingGuide({
|
|
|
9039
9135
|
onBrowseProperties,
|
|
9040
9136
|
onEnterCode,
|
|
9041
9137
|
onClose,
|
|
9138
|
+
onClaimHandle,
|
|
9042
9139
|
logoSrc = "/Loaf-logo-Banner.png"
|
|
9043
9140
|
}) {
|
|
9141
|
+
const [step, setStep] = React5.useState(onClaimHandle ? "handle" : "funds");
|
|
9142
|
+
const [handle, setHandle] = React5.useState("");
|
|
9143
|
+
const [claiming, setClaiming] = React5.useState(false);
|
|
9144
|
+
const [handleError, setHandleError] = React5.useState("");
|
|
9145
|
+
React5.useEffect(() => {
|
|
9146
|
+
if (open) {
|
|
9147
|
+
setStep(onClaimHandle ? "handle" : "funds");
|
|
9148
|
+
setHandle("");
|
|
9149
|
+
setClaiming(false);
|
|
9150
|
+
setHandleError("");
|
|
9151
|
+
}
|
|
9152
|
+
}, [open, onClaimHandle]);
|
|
9044
9153
|
React5.useEffect(() => {
|
|
9045
9154
|
if (!open) return;
|
|
9046
9155
|
const onKey = (e) => {
|
|
@@ -9050,6 +9159,58 @@ function OnboardingGuide({
|
|
|
9050
9159
|
return () => window.removeEventListener("keydown", onKey);
|
|
9051
9160
|
}, [open, onClose]);
|
|
9052
9161
|
if (!open) return null;
|
|
9162
|
+
const handleClaimContinue = async () => {
|
|
9163
|
+
const trimmed = handle.trim().replace(/^@+/, "");
|
|
9164
|
+
if (trimmed && onClaimHandle) {
|
|
9165
|
+
setClaiming(true);
|
|
9166
|
+
setHandleError("");
|
|
9167
|
+
try {
|
|
9168
|
+
await onClaimHandle(trimmed);
|
|
9169
|
+
} catch (err) {
|
|
9170
|
+
setHandleError(err instanceof Error ? err.message : "Couldn't claim that handle. Try another or skip.");
|
|
9171
|
+
setClaiming(false);
|
|
9172
|
+
return;
|
|
9173
|
+
}
|
|
9174
|
+
setClaiming(false);
|
|
9175
|
+
}
|
|
9176
|
+
setStep("funds");
|
|
9177
|
+
};
|
|
9178
|
+
if (step === "handle") {
|
|
9179
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Overlay3, { onClick: onClose, role: "dialog", "aria-modal": "true", "aria-label": "Claim your handle", children: /* @__PURE__ */ jsxRuntime.jsxs(Card2, { onClick: (e) => e.stopPropagation(), children: [
|
|
9180
|
+
/* @__PURE__ */ jsxRuntime.jsx(CloseButton2, { onClick: onClose, "aria-label": "Skip", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M18 6L6 18" }) }) }),
|
|
9181
|
+
/* @__PURE__ */ jsxRuntime.jsxs(LogoRow, { children: [
|
|
9182
|
+
/* @__PURE__ */ jsxRuntime.jsx(LogoImage2, { src: logoSrc, alt: "Loaf" }),
|
|
9183
|
+
/* @__PURE__ */ jsxRuntime.jsx(LogoBeta2, { children: "Private Beta" })
|
|
9184
|
+
] }),
|
|
9185
|
+
/* @__PURE__ */ jsxRuntime.jsx(Title2, { children: "Claim your handle" }),
|
|
9186
|
+
/* @__PURE__ */ jsxRuntime.jsx(Subtitle2, { children: "Pick a username for your Loaf profile. It's optional \u2014 you can set or change it later." }),
|
|
9187
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HandleField, { children: [
|
|
9188
|
+
/* @__PURE__ */ jsxRuntime.jsx(HandleAt, { children: "@" }),
|
|
9189
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9190
|
+
HandleInput,
|
|
9191
|
+
{
|
|
9192
|
+
type: "text",
|
|
9193
|
+
autoComplete: "off",
|
|
9194
|
+
autoCapitalize: "none",
|
|
9195
|
+
spellCheck: false,
|
|
9196
|
+
placeholder: "username (optional)",
|
|
9197
|
+
value: handle,
|
|
9198
|
+
onChange: (e) => {
|
|
9199
|
+
setHandle(e.target.value.replace(/[^a-zA-Z0-9_]/g, ""));
|
|
9200
|
+
setHandleError("");
|
|
9201
|
+
},
|
|
9202
|
+
onKeyDown: (e) => {
|
|
9203
|
+
if (e.key === "Enter" && !claiming) void handleClaimContinue();
|
|
9204
|
+
},
|
|
9205
|
+
autoFocus: true
|
|
9206
|
+
}
|
|
9207
|
+
)
|
|
9208
|
+
] }),
|
|
9209
|
+
handleError && /* @__PURE__ */ jsxRuntime.jsx(FieldError, { children: handleError }),
|
|
9210
|
+
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onClick: () => void handleClaimContinue(), disabled: claiming, children: claiming ? "Saving\u2026" : "Continue" }),
|
|
9211
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkipButton, { onClick: () => setStep("funds"), disabled: claiming, children: "Skip for now" })
|
|
9212
|
+
] }) });
|
|
9213
|
+
}
|
|
9053
9214
|
return /* @__PURE__ */ jsxRuntime.jsx(Overlay3, { onClick: onClose, role: "dialog", "aria-modal": "true", "aria-label": "Welcome to Loaf", children: /* @__PURE__ */ jsxRuntime.jsxs(Card2, { onClick: (e) => e.stopPropagation(), children: [
|
|
9054
9215
|
/* @__PURE__ */ jsxRuntime.jsx(CloseButton2, { onClick: onClose, "aria-label": "Skip", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M18 6L6 18" }) }) }),
|
|
9055
9216
|
/* @__PURE__ */ jsxRuntime.jsxs(LogoRow, { children: [
|
|
@@ -12113,6 +12274,11 @@ var DocIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "20", height
|
|
|
12113
12274
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
|
|
12114
12275
|
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "10 9 9 9 8 9" })
|
|
12115
12276
|
] });
|
|
12277
|
+
var DownloadIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
12278
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
12279
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "7 10 12 15 17 10" }),
|
|
12280
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
12281
|
+
] });
|
|
12116
12282
|
var LIVE_TITLE_PATTERNS = [/term\s*sheet/i, /memo/i];
|
|
12117
12283
|
var COMING_SOON_TITLES = [
|
|
12118
12284
|
"Valuation Report",
|
|
@@ -12127,11 +12293,30 @@ var COMING_SOON_TITLES = [
|
|
|
12127
12293
|
];
|
|
12128
12294
|
function PropertyDocuments({ documentsData, highlightDocument, onClearHighlight }) {
|
|
12129
12295
|
const highlightRef = React5.useRef(null);
|
|
12130
|
-
React5.
|
|
12296
|
+
const [previewUrl, setPreviewUrl] = React5.useState(null);
|
|
12297
|
+
const [previewTitle, setPreviewTitle] = React5.useState(null);
|
|
12298
|
+
const backendDocuments = Array.isArray(documentsData?.documents) ? documentsData.documents : [];
|
|
12299
|
+
const liveDocs = backendDocuments.filter(
|
|
12300
|
+
(d) => Boolean(d.documentUrl) && LIVE_TITLE_PATTERNS.some((rx) => rx.test(d.title))
|
|
12301
|
+
);
|
|
12302
|
+
const comingSoonDocs = COMING_SOON_TITLES.filter(
|
|
12303
|
+
(title) => !liveDocs.some((d) => d.title.toLowerCase().includes(title.toLowerCase()) || title.toLowerCase().includes(d.title.toLowerCase()))
|
|
12304
|
+
).map((title) => ({ title, documentUrl: "" }));
|
|
12305
|
+
const documents = [...liveDocs, ...comingSoonDocs];
|
|
12306
|
+
const activeUrl = previewUrl ?? (liveDocs[0]?.documentUrl || null);
|
|
12307
|
+
const activeTitle = previewUrl ? previewTitle : liveDocs[0]?.title || null;
|
|
12308
|
+
const selectPreview = (doc) => {
|
|
12309
|
+
setPreviewUrl(doc.documentUrl);
|
|
12310
|
+
setPreviewTitle(doc.title);
|
|
12311
|
+
};
|
|
12131
12312
|
React5.useEffect(() => {
|
|
12132
12313
|
if (highlightDocument && highlightRef.current) {
|
|
12133
12314
|
highlightRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
12134
12315
|
}
|
|
12316
|
+
if (highlightDocument) {
|
|
12317
|
+
const hit = liveDocs.find((d) => d.title.toLowerCase().includes(highlightDocument.toLowerCase()));
|
|
12318
|
+
if (hit) selectPreview(hit);
|
|
12319
|
+
}
|
|
12135
12320
|
}, [highlightDocument]);
|
|
12136
12321
|
React5.useEffect(() => {
|
|
12137
12322
|
if (!highlightDocument || !onClearHighlight) return;
|
|
@@ -12143,36 +12328,58 @@ function PropertyDocuments({ documentsData, highlightDocument, onClearHighlight
|
|
|
12143
12328
|
document.addEventListener("click", handler, true);
|
|
12144
12329
|
return () => document.removeEventListener("click", handler, true);
|
|
12145
12330
|
}, [highlightDocument, onClearHighlight]);
|
|
12146
|
-
const backendDocuments = Array.isArray(documentsData?.documents) ? documentsData.documents : [];
|
|
12147
|
-
const liveDocs = backendDocuments.filter(
|
|
12148
|
-
(d) => Boolean(d.documentUrl) && LIVE_TITLE_PATTERNS.some((rx) => rx.test(d.title))
|
|
12149
|
-
);
|
|
12150
|
-
const comingSoonDocs = COMING_SOON_TITLES.filter(
|
|
12151
|
-
(title) => !liveDocs.some((d) => d.title.toLowerCase().includes(title.toLowerCase()) || title.toLowerCase().includes(d.title.toLowerCase()))
|
|
12152
|
-
).map((title) => ({ title, documentUrl: "" }));
|
|
12153
|
-
const documents = [...liveDocs, ...comingSoonDocs];
|
|
12154
12331
|
return /* @__PURE__ */ jsxRuntime.jsxs(Section2, { children: [
|
|
12155
12332
|
/* @__PURE__ */ jsxRuntime.jsx(SectionHeading, { children: "Investment Documents" }),
|
|
12156
|
-
/* @__PURE__ */ jsxRuntime.
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12333
|
+
/* @__PURE__ */ jsxRuntime.jsxs(SplitLayout, { children: [
|
|
12334
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocList, { children: documents.map(({ documentUrl, title }) => {
|
|
12335
|
+
const isAvailable = Boolean(documentUrl);
|
|
12336
|
+
const isHighlighted = highlightDocument != null && title.toLowerCase().includes(highlightDocument.toLowerCase());
|
|
12337
|
+
const isActive = isAvailable && documentUrl === activeUrl;
|
|
12338
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12339
|
+
DocItem,
|
|
12340
|
+
{
|
|
12341
|
+
ref: isHighlighted ? highlightRef : void 0,
|
|
12342
|
+
$highlighted: isHighlighted,
|
|
12343
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
12344
|
+
DocRow,
|
|
12345
|
+
{
|
|
12346
|
+
$available: isAvailable,
|
|
12347
|
+
$active: isActive,
|
|
12348
|
+
onMouseEnter: isAvailable ? () => selectPreview({ documentUrl, title }) : void 0,
|
|
12349
|
+
onClick: isAvailable ? () => selectPreview({ documentUrl, title }) : void 0,
|
|
12350
|
+
children: [
|
|
12351
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DocName, { $available: isAvailable, children: [
|
|
12352
|
+
/* @__PURE__ */ jsxRuntime.jsx(DocIconWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(DocIcon, {}) }),
|
|
12353
|
+
title
|
|
12354
|
+
] }),
|
|
12355
|
+
isAvailable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
12356
|
+
DownloadBtn,
|
|
12357
|
+
{
|
|
12358
|
+
href: documentUrl,
|
|
12359
|
+
target: "_blank",
|
|
12360
|
+
rel: "noopener noreferrer",
|
|
12361
|
+
"aria-label": `Open ${title}`,
|
|
12362
|
+
title: "Open document",
|
|
12363
|
+
onClick: (e) => e.stopPropagation(),
|
|
12364
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {})
|
|
12365
|
+
}
|
|
12366
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(ComingSoonBadge, { children: "Coming Soon" })
|
|
12367
|
+
]
|
|
12368
|
+
}
|
|
12369
|
+
)
|
|
12370
|
+
},
|
|
12371
|
+
`${title}-${documentUrl || "pending"}`
|
|
12372
|
+
);
|
|
12373
|
+
}) }),
|
|
12374
|
+
/* @__PURE__ */ jsxRuntime.jsx(PreviewPane, { children: activeUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
12375
|
+
PreviewFrame,
|
|
12161
12376
|
{
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
children: isAvailable ? /* @__PURE__ */ jsxRuntime.jsxs(DocLink, { href: documentUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
12165
|
-
/* @__PURE__ */ jsxRuntime.jsx(DocIconWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(DocIcon, {}) }),
|
|
12166
|
-
title
|
|
12167
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(DocItemDisabled, { children: [
|
|
12168
|
-
/* @__PURE__ */ jsxRuntime.jsx(DocIconWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(DocIcon, {}) }),
|
|
12169
|
-
title,
|
|
12170
|
-
/* @__PURE__ */ jsxRuntime.jsx(ComingSoonBadge, { children: "Coming Soon" })
|
|
12171
|
-
] })
|
|
12377
|
+
src: `${activeUrl}#toolbar=0&navpanes=0&view=FitH`,
|
|
12378
|
+
title: activeTitle ?? "Document preview"
|
|
12172
12379
|
},
|
|
12173
|
-
|
|
12174
|
-
)
|
|
12175
|
-
|
|
12380
|
+
activeUrl
|
|
12381
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(PreviewEmpty, { children: "Hover a document to preview it here" }) })
|
|
12382
|
+
] })
|
|
12176
12383
|
] });
|
|
12177
12384
|
}
|
|
12178
12385
|
var Section2 = styled10__default.default.section`
|
|
@@ -12192,45 +12399,103 @@ var SectionHeading = styled10__default.default.h2`
|
|
|
12192
12399
|
align-items: center;
|
|
12193
12400
|
gap: 0.5rem;
|
|
12194
12401
|
`;
|
|
12402
|
+
var SplitLayout = styled10__default.default.div`
|
|
12403
|
+
display: flex;
|
|
12404
|
+
gap: 1.25rem;
|
|
12405
|
+
align-items: stretch;
|
|
12406
|
+
|
|
12407
|
+
@media (max-width: 768px) {
|
|
12408
|
+
flex-direction: column;
|
|
12409
|
+
}
|
|
12410
|
+
`;
|
|
12195
12411
|
var DocList = styled10__default.default.ul`
|
|
12196
12412
|
list-style: none;
|
|
12197
12413
|
padding: 0;
|
|
12198
12414
|
margin: 0;
|
|
12415
|
+
flex: 1 1 50%;
|
|
12416
|
+
min-width: 0;
|
|
12199
12417
|
`;
|
|
12200
12418
|
var DocItem = styled10__default.default.li`
|
|
12201
|
-
padding: 0.
|
|
12419
|
+
padding: 0.35rem 0;
|
|
12202
12420
|
border-bottom: 1px solid var(--color-border, rgba(255, 255, 255, 0.1));
|
|
12203
12421
|
border-radius: ${(p) => p.$highlighted ? "6px" : "0"};
|
|
12204
12422
|
background: ${(p) => p.$highlighted ? "rgba(212, 175, 55, 0.08)" : "transparent"};
|
|
12205
|
-
${(p) => p.$highlighted ? "padding: 0.75rem;" : ""}
|
|
12206
12423
|
transition: background 0.3s;
|
|
12207
12424
|
|
|
12208
12425
|
&:last-child {
|
|
12209
12426
|
border-bottom: none;
|
|
12210
12427
|
}
|
|
12211
12428
|
`;
|
|
12212
|
-
var
|
|
12429
|
+
var DocRow = styled10__default.default.div`
|
|
12213
12430
|
display: flex;
|
|
12214
12431
|
align-items: center;
|
|
12215
|
-
|
|
12216
|
-
|
|
12217
|
-
|
|
12432
|
+
gap: 0.5rem;
|
|
12433
|
+
padding: 0.4rem 0.5rem;
|
|
12434
|
+
border-radius: 6px;
|
|
12435
|
+
cursor: ${(p) => p.$available ? "pointer" : "not-allowed"};
|
|
12436
|
+
background: ${(p) => p.$active ? "rgba(230, 200, 126, 0.10)" : "transparent"};
|
|
12437
|
+
transition: background 0.2s, color 0.2s;
|
|
12218
12438
|
|
|
12219
|
-
&:hover {
|
|
12220
|
-
color: var(--color-accent);
|
|
12221
|
-
}
|
|
12439
|
+
${(p) => p.$available && !p.$active ? "&:hover { background: rgba(230, 200, 126, 0.06); }" : ""}
|
|
12222
12440
|
`;
|
|
12223
|
-
var
|
|
12441
|
+
var DocName = styled10__default.default.span`
|
|
12224
12442
|
display: flex;
|
|
12225
12443
|
align-items: center;
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12444
|
+
flex: 1;
|
|
12445
|
+
min-width: 0;
|
|
12446
|
+
color: ${(p) => p.$available ? "var(--color-text)" : "var(--color-text-secondary)"};
|
|
12447
|
+
opacity: ${(p) => p.$available ? 1 : 0.6};
|
|
12229
12448
|
`;
|
|
12230
12449
|
var DocIconWrapper = styled10__default.default.span`
|
|
12231
12450
|
margin-right: 0.75rem;
|
|
12232
12451
|
flex-shrink: 0;
|
|
12233
12452
|
color: var(--color-text-secondary);
|
|
12453
|
+
display: inline-flex;
|
|
12454
|
+
`;
|
|
12455
|
+
var DownloadBtn = styled10__default.default.a`
|
|
12456
|
+
flex-shrink: 0;
|
|
12457
|
+
display: inline-flex;
|
|
12458
|
+
align-items: center;
|
|
12459
|
+
justify-content: center;
|
|
12460
|
+
width: 30px;
|
|
12461
|
+
height: 30px;
|
|
12462
|
+
border-radius: 6px;
|
|
12463
|
+
color: var(--color-text-secondary);
|
|
12464
|
+
transition: color 0.2s, background 0.2s;
|
|
12465
|
+
|
|
12466
|
+
&:hover {
|
|
12467
|
+
color: var(--color-accent);
|
|
12468
|
+
background: rgba(230, 200, 126, 0.1);
|
|
12469
|
+
}
|
|
12470
|
+
`;
|
|
12471
|
+
var PreviewPane = styled10__default.default.div`
|
|
12472
|
+
flex: 1 1 50%;
|
|
12473
|
+
min-width: 0;
|
|
12474
|
+
min-height: 360px;
|
|
12475
|
+
display: flex;
|
|
12476
|
+
border: 1px solid var(--color-border, rgba(255, 255, 255, 0.1));
|
|
12477
|
+
border-radius: 10px;
|
|
12478
|
+
overflow: hidden;
|
|
12479
|
+
background: rgba(0, 0, 0, 0.25);
|
|
12480
|
+
|
|
12481
|
+
/* No hover on touch devices — fall back to the list + download icon. */
|
|
12482
|
+
@media (max-width: 768px) {
|
|
12483
|
+
display: none;
|
|
12484
|
+
}
|
|
12485
|
+
`;
|
|
12486
|
+
var PreviewFrame = styled10__default.default.iframe`
|
|
12487
|
+
width: 100%;
|
|
12488
|
+
height: 100%;
|
|
12489
|
+
min-height: 360px;
|
|
12490
|
+
border: 0;
|
|
12491
|
+
background: #fff;
|
|
12492
|
+
`;
|
|
12493
|
+
var PreviewEmpty = styled10__default.default.div`
|
|
12494
|
+
margin: auto;
|
|
12495
|
+
padding: 1rem;
|
|
12496
|
+
text-align: center;
|
|
12497
|
+
color: var(--color-text-secondary);
|
|
12498
|
+
font-size: 0.85rem;
|
|
12234
12499
|
`;
|
|
12235
12500
|
var ComingSoonBadge = styled10__default.default.span`
|
|
12236
12501
|
margin-left: auto;
|
|
@@ -12242,6 +12507,7 @@ var ComingSoonBadge = styled10__default.default.span`
|
|
|
12242
12507
|
font-weight: 500;
|
|
12243
12508
|
text-transform: uppercase;
|
|
12244
12509
|
letter-spacing: 0.05em;
|
|
12510
|
+
flex-shrink: 0;
|
|
12245
12511
|
`;
|
|
12246
12512
|
var formatIsoDate = (value) => {
|
|
12247
12513
|
const parsed = new Date(value);
|
|
@@ -19879,7 +20145,7 @@ var OpenMailButton = styled10__default.default.a`
|
|
|
19879
20145
|
`;
|
|
19880
20146
|
var ContactPopup = ({ onClose }) => {
|
|
19881
20147
|
const [copied, setCopied] = React5.useState(false);
|
|
19882
|
-
const email = "
|
|
20148
|
+
const email = "admin@loafmarkets.com";
|
|
19883
20149
|
const handleCopy = async () => {
|
|
19884
20150
|
try {
|
|
19885
20151
|
await navigator.clipboard.writeText(email);
|
|
@@ -20106,7 +20372,17 @@ var SiteFooter = () => {
|
|
|
20106
20372
|
/* @__PURE__ */ jsxRuntime.jsx(FooterLinkItem, { children: /* @__PURE__ */ jsxRuntime.jsx(FooterLink, { href: "/trade", children: "Trade" }) }),
|
|
20107
20373
|
/* @__PURE__ */ jsxRuntime.jsx(FooterLinkItem, { children: /* @__PURE__ */ jsxRuntime.jsx(FooterLink, { href: "/offerings", children: "Initial Offerings" }) }),
|
|
20108
20374
|
/* @__PURE__ */ jsxRuntime.jsx(FooterLinkItem, { children: /* @__PURE__ */ jsxRuntime.jsx(FooterLink, { href: "/map", children: "Property Map" }) }),
|
|
20109
|
-
/* @__PURE__ */ jsxRuntime.jsx(FooterLinkItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
20375
|
+
/* @__PURE__ */ jsxRuntime.jsx(FooterLinkItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
20376
|
+
FooterLink,
|
|
20377
|
+
{
|
|
20378
|
+
href: "/loaf-liquidity",
|
|
20379
|
+
onClick: (e) => {
|
|
20380
|
+
e.preventDefault();
|
|
20381
|
+
if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent("loaf:open-liquidity-popup"));
|
|
20382
|
+
},
|
|
20383
|
+
children: "Loaf Liquidity"
|
|
20384
|
+
}
|
|
20385
|
+
) })
|
|
20110
20386
|
] })
|
|
20111
20387
|
] }),
|
|
20112
20388
|
/* @__PURE__ */ jsxRuntime.jsxs(FooterColumn, { children: [
|
|
@@ -20142,7 +20418,7 @@ var SiteFooter = () => {
|
|
|
20142
20418
|
/* @__PURE__ */ jsxRuntime.jsx(LegalLink, { href: "/cookies", children: "Cookie Policy" })
|
|
20143
20419
|
] })
|
|
20144
20420
|
] }),
|
|
20145
|
-
/* @__PURE__ */ jsxRuntime.jsx(Disclaimer2, { children: /* @__PURE__ */ jsxRuntime.jsx(DisclaimerText, { children: "Warning: Digital asset prices can be volatile. The value of your investment can go down or up and you may not get back the amount invested. Past gains are not indicative of future returns. You are solely responsible for your investment decisions and Loaf is not liable for any losses you may incur. The information here should not be regarded as financial or investment advice. For more information, see our Terms of Use
|
|
20421
|
+
/* @__PURE__ */ jsxRuntime.jsx(Disclaimer2, { children: /* @__PURE__ */ jsxRuntime.jsx(DisclaimerText, { children: "Warning: Digital asset prices can be volatile. The value of your investment can go down or up and you may not get back the amount invested. Past gains are not indicative of future returns. You are solely responsible for your investment decisions and Loaf is not liable for any losses you may incur. The information here should not be regarded as financial or investment advice. For more information, see our Terms of Use." }) })
|
|
20146
20422
|
] }) }),
|
|
20147
20423
|
showContactPopup && /* @__PURE__ */ jsxRuntime.jsx(ContactPopup, { onClose: () => setShowContactPopup(false) })
|
|
20148
20424
|
] });
|