@retinalabsllc/zairusjs 15.0.85 → 15.0.95
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 +30 -37
- package/dist/index.d.ts +30 -37
- package/dist/index.js +458 -589
- package/dist/index.mjs +572 -702
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -293,12 +293,143 @@ var Header = ({
|
|
|
293
293
|
};
|
|
294
294
|
|
|
295
295
|
// src/components/PipleAuth.tsx
|
|
296
|
-
import
|
|
296
|
+
import React6, { useState as useState4, useRef as useRef2, useEffect as useEffect3, Suspense } from "react";
|
|
297
297
|
import { useSearchParams } from "next/navigation";
|
|
298
298
|
import toast from "react-hot-toast";
|
|
299
299
|
import { useGoogleReCaptcha, GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
|
|
300
300
|
import { startAuthentication } from "@simplewebauthn/browser";
|
|
301
|
-
|
|
301
|
+
|
|
302
|
+
// src/components/TextInput.tsx
|
|
303
|
+
import React5, { useState as useState3 } from "react";
|
|
304
|
+
var InputSpinner = () => /* @__PURE__ */ React5.createElement("svg", { className: "animate-spin h-3 w-3 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React5.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React5.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
305
|
+
var FlagImage = ({ countryCode }) => {
|
|
306
|
+
const [loaded, setLoaded] = useState3(false);
|
|
307
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "relative w-6 h-6 rounded-full overflow-hidden flex items-center justify-center bg-neutral-100 shrink-0 border border-neutral-200" }, !loaded && /* @__PURE__ */ React5.createElement("div", { className: "absolute inset-0 flex items-center justify-center" }, /* @__PURE__ */ React5.createElement(InputSpinner, null)), /* @__PURE__ */ React5.createElement(
|
|
308
|
+
"img",
|
|
309
|
+
{
|
|
310
|
+
src: `https://flagcdn.com/w40/${countryCode.toLowerCase()}.png`,
|
|
311
|
+
alt: countryCode,
|
|
312
|
+
className: `object-cover w-full h-full transition-opacity duration-300 ${loaded ? "opacity-100" : "opacity-0"}`,
|
|
313
|
+
onLoad: () => setLoaded(true)
|
|
314
|
+
}
|
|
315
|
+
));
|
|
316
|
+
};
|
|
317
|
+
var TextInput = ({
|
|
318
|
+
label,
|
|
319
|
+
value,
|
|
320
|
+
onChange,
|
|
321
|
+
placeholder,
|
|
322
|
+
maxLength,
|
|
323
|
+
disabled,
|
|
324
|
+
readOnly,
|
|
325
|
+
type = "text",
|
|
326
|
+
onClick
|
|
327
|
+
}) => /* @__PURE__ */ React5.createElement("div", { className: "space-y-2 flex-1 w-full", onClick }, label && /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block" }, label), /* @__PURE__ */ React5.createElement(
|
|
328
|
+
"input",
|
|
329
|
+
{
|
|
330
|
+
type,
|
|
331
|
+
value,
|
|
332
|
+
onChange: (e) => onChange(e.target.value.substring(0, maxLength || 100)),
|
|
333
|
+
placeholder,
|
|
334
|
+
disabled,
|
|
335
|
+
readOnly,
|
|
336
|
+
autoComplete: "off",
|
|
337
|
+
spellCheck: "false",
|
|
338
|
+
className: `w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black transition-all outline-none focus:border-black disabled:opacity-50 ${readOnly ? "cursor-pointer" : ""}`
|
|
339
|
+
}
|
|
340
|
+
));
|
|
341
|
+
var NumberInput = ({
|
|
342
|
+
label,
|
|
343
|
+
value,
|
|
344
|
+
onChange,
|
|
345
|
+
placeholder,
|
|
346
|
+
maxLength,
|
|
347
|
+
disabled
|
|
348
|
+
}) => /* @__PURE__ */ React5.createElement("div", { className: "space-y-2 flex-1 w-full" }, label && /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block" }, label), /* @__PURE__ */ React5.createElement(
|
|
349
|
+
"input",
|
|
350
|
+
{
|
|
351
|
+
type: "text",
|
|
352
|
+
value,
|
|
353
|
+
onChange: (e) => {
|
|
354
|
+
const numOnly = e.target.value.replace(/[^0-9]/g, "");
|
|
355
|
+
onChange(numOnly.substring(0, maxLength || 20));
|
|
356
|
+
},
|
|
357
|
+
placeholder,
|
|
358
|
+
disabled,
|
|
359
|
+
autoComplete: "off",
|
|
360
|
+
spellCheck: "false",
|
|
361
|
+
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black transition-all outline-none focus:border-black disabled:opacity-50"
|
|
362
|
+
}
|
|
363
|
+
));
|
|
364
|
+
var PhoneInput = ({
|
|
365
|
+
label,
|
|
366
|
+
value,
|
|
367
|
+
onChange,
|
|
368
|
+
selectedCountry,
|
|
369
|
+
onCountryClick,
|
|
370
|
+
placeholder,
|
|
371
|
+
disabled
|
|
372
|
+
}) => /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5 flex-1 w-full" }, label && /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block" }, label), /* @__PURE__ */ React5.createElement("div", { className: `flex items-center gap-3 border-b border-neutral-200 focus-within:border-black transition-all duration-300 pb-2 ${disabled ? "opacity-50" : ""}` }, /* @__PURE__ */ React5.createElement(
|
|
373
|
+
"button",
|
|
374
|
+
{
|
|
375
|
+
type: "button",
|
|
376
|
+
disabled,
|
|
377
|
+
onClick: onCountryClick,
|
|
378
|
+
className: "flex items-center gap-1.5 outline-none hover:opacity-80 transition-opacity"
|
|
379
|
+
},
|
|
380
|
+
/* @__PURE__ */ React5.createElement(FlagImage, { countryCode: selectedCountry.code }),
|
|
381
|
+
/* @__PURE__ */ React5.createElement("span", { className: "text-sm text-black font-medium pl-1" }, selectedCountry.dialCode),
|
|
382
|
+
/* @__PURE__ */ React5.createElement("svg", { className: "w-3 h-3 text-neutral-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" }, /* @__PURE__ */ React5.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }))
|
|
383
|
+
), /* @__PURE__ */ React5.createElement(
|
|
384
|
+
"input",
|
|
385
|
+
{
|
|
386
|
+
type: "tel",
|
|
387
|
+
value,
|
|
388
|
+
onChange: (e) => {
|
|
389
|
+
const numOnly = e.target.value.replace(/[^0-9]/g, "");
|
|
390
|
+
onChange(numOnly.substring(0, 15));
|
|
391
|
+
},
|
|
392
|
+
disabled,
|
|
393
|
+
required: true,
|
|
394
|
+
autoFocus: true,
|
|
395
|
+
autoComplete: "off",
|
|
396
|
+
spellCheck: "false",
|
|
397
|
+
className: "w-full text-sm bg-transparent text-black outline-none pt-1",
|
|
398
|
+
placeholder: placeholder || "0801 234 5678"
|
|
399
|
+
}
|
|
400
|
+
)));
|
|
401
|
+
|
|
402
|
+
// src/components/PipleAuth.tsx
|
|
403
|
+
var SUPPORTED_COUNTRIES = [
|
|
404
|
+
{ code: "NG", dialCode: "+234", name: "Nigeria" },
|
|
405
|
+
{ code: "GH", dialCode: "+233", name: "Ghana" },
|
|
406
|
+
{ code: "KE", dialCode: "+254", name: "Kenya" }
|
|
407
|
+
];
|
|
408
|
+
var InputSpinner2 = () => /* @__PURE__ */ React6.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React6.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React6.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
409
|
+
var CountrySelectorDialog = ({ isOpen, onClose, onSelect }) => {
|
|
410
|
+
if (!isOpen) return null;
|
|
411
|
+
return /* @__PURE__ */ React6.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40" }, /* @__PURE__ */ React6.createElement("div", { className: "absolute inset-0", onClick: onClose }), /* @__PURE__ */ React6.createElement("div", { className: "w-full max-w-sm bg-white rounded-2xl shadow-2xl overflow-hidden relative z-10 animate-in fade-in zoom-in-95 duration-200" }, /* @__PURE__ */ React6.createElement(
|
|
412
|
+
"button",
|
|
413
|
+
{
|
|
414
|
+
onClick: onClose,
|
|
415
|
+
className: "absolute top-4 right-4 p-2 text-neutral-700 hover:text-neutral-400 transition-colors outline-none"
|
|
416
|
+
},
|
|
417
|
+
/* @__PURE__ */ React6.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React6.createElement("path", { d: "M18 6 6 18" }), /* @__PURE__ */ React6.createElement("path", { d: "m6 6 12 12" }))
|
|
418
|
+
), /* @__PURE__ */ React6.createElement("div", { className: "p-6 sm:p-8" }, /* @__PURE__ */ React6.createElement("div", { className: "mb-6 mt-2" }, /* @__PURE__ */ React6.createElement("h2", { className: "text-xl text-black tracking-tight mb-2" }, "Select Country"), /* @__PURE__ */ React6.createElement("p", { className: "text-[13px] text-neutral-500 leading-relaxed" }, "Choose your region to continue.")), /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-2" }, SUPPORTED_COUNTRIES.map((c) => /* @__PURE__ */ React6.createElement(
|
|
419
|
+
"button",
|
|
420
|
+
{
|
|
421
|
+
key: c.code,
|
|
422
|
+
onClick: () => {
|
|
423
|
+
onSelect(c);
|
|
424
|
+
onClose();
|
|
425
|
+
},
|
|
426
|
+
className: "flex items-center gap-4 p-3 rounded-xl hover:bg-neutral-50 transition-colors text-left outline-none"
|
|
427
|
+
},
|
|
428
|
+
/* @__PURE__ */ React6.createElement(FlagImage, { countryCode: c.code }),
|
|
429
|
+
/* @__PURE__ */ React6.createElement("span", { className: "text-sm text-black flex-1 font-medium" }, c.name),
|
|
430
|
+
/* @__PURE__ */ React6.createElement("span", { className: "text-sm text-neutral-500 font-mono" }, c.dialCode)
|
|
431
|
+
))))));
|
|
432
|
+
};
|
|
302
433
|
function AuthFormInner({
|
|
303
434
|
companyName,
|
|
304
435
|
workspaceLabel = "Workspace",
|
|
@@ -314,28 +445,26 @@ function AuthFormInner({
|
|
|
314
445
|
const searchParams = useSearchParams();
|
|
315
446
|
const redirectUrl = searchParams.get("redirect") || defaultRedirectPath;
|
|
316
447
|
const captchaContext = useRecaptcha ? useGoogleReCaptcha() : null;
|
|
317
|
-
const [mode, setMode] =
|
|
318
|
-
const [step, setStep] =
|
|
319
|
-
const getInitialSignupStep = () =>
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const [
|
|
323
|
-
const [
|
|
324
|
-
const [
|
|
325
|
-
const [
|
|
326
|
-
const [
|
|
327
|
-
const [firstName, setFirstName] =
|
|
328
|
-
const [lastName, setLastName] =
|
|
329
|
-
const [orgName, setOrgName] =
|
|
330
|
-
const [agreedToTerms, setAgreedToTerms] =
|
|
331
|
-
const [
|
|
332
|
-
const [
|
|
333
|
-
const [
|
|
334
|
-
const [otp, setOtp] = useState3(["", "", "", "", "", ""]);
|
|
448
|
+
const [mode, setMode] = useState4("LOGIN");
|
|
449
|
+
const [step, setStep] = useState4("INPUT");
|
|
450
|
+
const getInitialSignupStep = () => "INVITATION";
|
|
451
|
+
const [signupStep, setSignupStep] = useState4(getInitialSignupStep());
|
|
452
|
+
const [isSubmitting, setIsSubmitting] = useState4(false);
|
|
453
|
+
const [countdown, setCountdown] = useState4(0);
|
|
454
|
+
const [invitationCode, setInvitationCode] = useState4("");
|
|
455
|
+
const [phoneNumber, setPhoneNumber] = useState4("");
|
|
456
|
+
const [selectedCountry, setSelectedCountry] = useState4(SUPPORTED_COUNTRIES[0]);
|
|
457
|
+
const [isCountryDialogOpen, setIsCountryDialogOpen] = useState4(false);
|
|
458
|
+
const [firstName, setFirstName] = useState4("");
|
|
459
|
+
const [lastName, setLastName] = useState4("");
|
|
460
|
+
const [orgName, setOrgName] = useState4("");
|
|
461
|
+
const [agreedToTerms, setAgreedToTerms] = useState4(false);
|
|
462
|
+
const [userHasPasskey, setUserHasPasskey] = useState4(false);
|
|
463
|
+
const [authOptions, setAuthOptions] = useState4(null);
|
|
464
|
+
const [otp, setOtp] = useState4(["", "", "", "", "", ""]);
|
|
335
465
|
const inputRefs = useRef2([]);
|
|
336
466
|
const cleanAlpha = (val) => val.replace(/[^a-zA-Z]/g, "").substring(0, 50);
|
|
337
467
|
const cleanOrgName = (val) => val.replace(/[^a-zA-Z0-9\s]/g, "").substring(0, 50);
|
|
338
|
-
const cleanEmailId = (val) => val.toLowerCase().replace(/[^a-z0-9@._-]/g, "");
|
|
339
468
|
useEffect3(() => {
|
|
340
469
|
if (countdown > 0) {
|
|
341
470
|
const timer = setTimeout(() => setCountdown(countdown - 1), 1e3);
|
|
@@ -365,6 +494,10 @@ function AuthFormInner({
|
|
|
365
494
|
verifyOtpCode(newOtp.join(""));
|
|
366
495
|
}
|
|
367
496
|
};
|
|
497
|
+
const getFormattedPhoneNumber = () => {
|
|
498
|
+
const cleanNumber = phoneNumber.replace(/^0+/, "");
|
|
499
|
+
return `${selectedCountry.dialCode}${cleanNumber}`;
|
|
500
|
+
};
|
|
368
501
|
const handleAuthRequestSubmit = async (e) => {
|
|
369
502
|
if (e) e.preventDefault();
|
|
370
503
|
if (mode === "SIGNUP" && !agreedToTerms) {
|
|
@@ -379,7 +512,8 @@ function AuthFormInner({
|
|
|
379
512
|
recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
|
|
380
513
|
}
|
|
381
514
|
const res = await onAuthRequest({
|
|
382
|
-
|
|
515
|
+
phoneNumber: getFormattedPhoneNumber(),
|
|
516
|
+
country: selectedCountry.code,
|
|
383
517
|
firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
|
|
384
518
|
lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
|
|
385
519
|
organizationName: mode === "SIGNUP" && requireOrganization ? orgName : void 0,
|
|
@@ -388,10 +522,9 @@ function AuthFormInner({
|
|
|
388
522
|
recaptchaToken
|
|
389
523
|
});
|
|
390
524
|
if (res.success) {
|
|
391
|
-
setUserHas2FA(!!res.has2FA);
|
|
392
525
|
setUserHasPasskey(!!res.hasPasskey);
|
|
393
526
|
if (res.passkeyOptions) setAuthOptions(res.passkeyOptions);
|
|
394
|
-
toast.success(res.
|
|
527
|
+
toast.success(res.needsPukSetup ? "Verification code sent" : "Security check required");
|
|
395
528
|
setStep("OTP");
|
|
396
529
|
setCountdown(60);
|
|
397
530
|
} else {
|
|
@@ -407,7 +540,10 @@ function AuthFormInner({
|
|
|
407
540
|
if (codeToVerify.length !== 6 || isSubmitting) return;
|
|
408
541
|
setIsSubmitting(true);
|
|
409
542
|
try {
|
|
410
|
-
const res = await onVerifyOtp({
|
|
543
|
+
const res = await onVerifyOtp({
|
|
544
|
+
phoneNumber: getFormattedPhoneNumber(),
|
|
545
|
+
code: codeToVerify
|
|
546
|
+
});
|
|
411
547
|
if (res.success) {
|
|
412
548
|
window.location.href = res.redirect || redirectUrl;
|
|
413
549
|
} else {
|
|
@@ -426,7 +562,11 @@ function AuthFormInner({
|
|
|
426
562
|
setIsSubmitting(true);
|
|
427
563
|
try {
|
|
428
564
|
const credentialResponse = await startAuthentication({ optionsJSON: authOptions });
|
|
429
|
-
const res = await onVerifyOtp({
|
|
565
|
+
const res = await onVerifyOtp({
|
|
566
|
+
phoneNumber: getFormattedPhoneNumber(),
|
|
567
|
+
isPasskey: true,
|
|
568
|
+
passkeyCredential: credentialResponse
|
|
569
|
+
});
|
|
430
570
|
if (res.success) {
|
|
431
571
|
window.location.href = res.redirect || redirectUrl;
|
|
432
572
|
} else {
|
|
@@ -442,35 +582,42 @@ function AuthFormInner({
|
|
|
442
582
|
if (signupStep === "INVITATION") {
|
|
443
583
|
if (requireNames) setSignupStep("NAME");
|
|
444
584
|
else if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
445
|
-
else setSignupStep("
|
|
585
|
+
else setSignupStep("PHONE_ID");
|
|
446
586
|
} else if (signupStep === "NAME") {
|
|
447
587
|
if (requireOrganization) setSignupStep("ORGANIZATION");
|
|
448
|
-
else setSignupStep("
|
|
588
|
+
else setSignupStep("PHONE_ID");
|
|
449
589
|
} else if (signupStep === "ORGANIZATION") {
|
|
450
|
-
setSignupStep("
|
|
590
|
+
setSignupStep("PHONE_ID");
|
|
451
591
|
}
|
|
452
592
|
};
|
|
453
593
|
const isContinueDisabled = () => {
|
|
454
594
|
if (isSubmitting) return true;
|
|
455
|
-
if (mode === "LOGIN") return
|
|
595
|
+
if (mode === "LOGIN") return phoneNumber.length < 5;
|
|
456
596
|
if (mode === "SIGNUP") {
|
|
457
597
|
if (signupStep === "INVITATION") return invitationCode.trim().length > 0 && invitationCode.trim().length < 3;
|
|
458
598
|
if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
|
|
459
599
|
if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
|
|
460
|
-
if (signupStep === "
|
|
600
|
+
if (signupStep === "PHONE_ID") return phoneNumber.length < 5 || !agreedToTerms;
|
|
461
601
|
}
|
|
462
602
|
return false;
|
|
463
603
|
};
|
|
464
|
-
return /* @__PURE__ */
|
|
604
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
|
|
605
|
+
CountrySelectorDialog,
|
|
606
|
+
{
|
|
607
|
+
isOpen: isCountryDialogOpen,
|
|
608
|
+
onClose: () => setIsCountryDialogOpen(false),
|
|
609
|
+
onSelect: setSelectedCountry
|
|
610
|
+
}
|
|
611
|
+
), /* @__PURE__ */ React6.createElement("div", { className: "w-full max-w-md mx-auto flex flex-col items-center gap-4 relative z-10 animate-in fade-in duration-300" }, /* @__PURE__ */ React6.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React6.createElement("div", { className: "p-8 md:p-12" }, step === "INPUT" && /* @__PURE__ */ React6.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React6.createElement("div", { className: "mb-12 text-center mt-2" }, /* @__PURE__ */ React6.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, mode === "LOGIN" ? `${companyName} ${workspaceLabel}` : "Create Account"), /* @__PURE__ */ React6.createElement("div", { className: "text-[13px] text-neutral-500" }, mode === "LOGIN" ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, "Don't have an account? ", /* @__PURE__ */ React6.createElement("button", { type: "button", onClick: () => {
|
|
465
612
|
setMode("SIGNUP");
|
|
466
613
|
setSignupStep(getInitialSignupStep());
|
|
467
|
-
}, className: "text-black transition-colors ml-1" }, "Sign up")) : /* @__PURE__ */
|
|
614
|
+
}, className: "text-black transition-colors ml-1" }, "Sign up")) : /* @__PURE__ */ React6.createElement(React6.Fragment, null, "Already have an account? ", /* @__PURE__ */ React6.createElement("button", { type: "button", onClick: () => setMode("LOGIN"), className: "text-black transition-colors ml-1" }, "Log in")))), /* @__PURE__ */ React6.createElement("form", { className: "space-y-6", autoComplete: "off", onSubmit: (e) => {
|
|
468
615
|
e.preventDefault();
|
|
469
616
|
if (mode === "SIGNUP" && signupStep === "INVITATION") handleNextSignupStep();
|
|
470
617
|
else if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
471
618
|
else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
|
|
472
619
|
else handleAuthRequestSubmit();
|
|
473
|
-
} }, mode === "SIGNUP" && signupStep === "INVITATION" && /* @__PURE__ */
|
|
620
|
+
} }, mode === "SIGNUP" && signupStep === "INVITATION" && /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React6.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Referral Code"), /* @__PURE__ */ React6.createElement(
|
|
474
621
|
"input",
|
|
475
622
|
{
|
|
476
623
|
type: "text",
|
|
@@ -480,10 +627,20 @@ function AuthFormInner({
|
|
|
480
627
|
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300 tracking-widest",
|
|
481
628
|
placeholder: "Referral Code (Optional)"
|
|
482
629
|
}
|
|
483
|
-
))), mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */
|
|
630
|
+
))), mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React6.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ React6.createElement("input", { type: "text", value: firstName, onChange: (e) => setFirstName(cleanAlpha(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "First name" })), /* @__PURE__ */ React6.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React6.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ React6.createElement("input", { type: "text", value: lastName, onChange: (e) => setLastName(cleanAlpha(e.target.value)), required: true, className: "w-full px-2 py-3 bg-transparent text-sm border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Last name" }))), mode === "SIGNUP" && signupStep === "ORGANIZATION" && requireOrganization && /* @__PURE__ */ React6.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React6.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React6.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ React6.createElement("input", { type: "text", value: orgName, onChange: (e) => setOrgName(cleanOrgName(e.target.value)), required: true, autoFocus: true, className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black outline-none focus:border-black transition-all duration-300", placeholder: "Acme Corporation" }))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "PHONE_ID") && /* @__PURE__ */ React6.createElement("div", { className: "space-y-6 animate-in fade-in duration-300" }, /* @__PURE__ */ React6.createElement(
|
|
631
|
+
PhoneInput,
|
|
632
|
+
{
|
|
633
|
+
label: "Phone Number",
|
|
634
|
+
value: phoneNumber,
|
|
635
|
+
onChange: setPhoneNumber,
|
|
636
|
+
selectedCountry,
|
|
637
|
+
onCountryClick: () => setIsCountryDialogOpen(true),
|
|
638
|
+
disabled: isSubmitting
|
|
639
|
+
}
|
|
640
|
+
), mode === "SIGNUP" && /* @__PURE__ */ React6.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React6.createElement("input", { type: "checkbox", id: "zairus-terms", checked: agreedToTerms, onChange: (e) => setAgreedToTerms(e.target.checked), className: "mt-0.5 w-4 h-4 bg-white border-neutral-300 rounded text-black focus:ring-black cursor-pointer", required: true }), /* @__PURE__ */ React6.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ React6.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ React6.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ React6.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ React6.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React6.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ React6.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React6.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter your 6-digit security passcode or OTP.")), /* @__PURE__ */ React6.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
484
641
|
e.preventDefault();
|
|
485
642
|
verifyOtpCode(otp.join(""));
|
|
486
|
-
} }, /* @__PURE__ */
|
|
643
|
+
} }, /* @__PURE__ */ React6.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React6.createElement(
|
|
487
644
|
"input",
|
|
488
645
|
{
|
|
489
646
|
key: index,
|
|
@@ -500,25 +657,25 @@ function AuthFormInner({
|
|
|
500
657
|
},
|
|
501
658
|
className: "w-10 h-12 text-center text-lg bg-transparent border-b-2 border-neutral-200 text-black outline-none focus:border-black transition-all duration-300"
|
|
502
659
|
}
|
|
503
|
-
))), /* @__PURE__ */
|
|
660
|
+
))), /* @__PURE__ */ React6.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")), userHasPasskey && /* @__PURE__ */ React6.createElement("div", { className: "pt-6" }, /* @__PURE__ */ React6.createElement(
|
|
504
661
|
"button",
|
|
505
662
|
{
|
|
506
663
|
onClick: triggerPasskeyLogin,
|
|
507
664
|
disabled: isSubmitting,
|
|
508
|
-
className: "w-full py-2.5 rounded-full text-black border border-neutral-200
|
|
665
|
+
className: "w-full py-2.5 rounded-full text-black border border-neutral-200 hover:bg-neutral-50 text-xs tracking-wide transition-colors outline-none disabled:opacity-50"
|
|
509
666
|
},
|
|
510
667
|
"Use Passkey / Biometrics"
|
|
511
|
-
))))));
|
|
668
|
+
)))))));
|
|
512
669
|
}
|
|
513
670
|
var PipleAuth = (props) => {
|
|
514
671
|
if (props.useRecaptcha && props.recaptchaSiteKey) {
|
|
515
|
-
return /* @__PURE__ */
|
|
672
|
+
return /* @__PURE__ */ React6.createElement(GoogleReCaptchaProvider, { reCaptchaKey: props.recaptchaSiteKey }, /* @__PURE__ */ React6.createElement(Suspense, { fallback: /* @__PURE__ */ React6.createElement("div", { className: "h-64 flex items-center justify-center" }, /* @__PURE__ */ React6.createElement(InputSpinner2, null)) }, /* @__PURE__ */ React6.createElement(AuthFormInner, { ...props })));
|
|
516
673
|
}
|
|
517
|
-
return /* @__PURE__ */
|
|
674
|
+
return /* @__PURE__ */ React6.createElement(Suspense, { fallback: /* @__PURE__ */ React6.createElement("div", { className: "h-64 flex items-center justify-center" }, /* @__PURE__ */ React6.createElement(InputSpinner2, null)) }, /* @__PURE__ */ React6.createElement(AuthFormInner, { ...props }));
|
|
518
675
|
};
|
|
519
676
|
|
|
520
677
|
// src/components/Footer.tsx
|
|
521
|
-
import
|
|
678
|
+
import React7, { useState as useState5 } from "react";
|
|
522
679
|
import Link3 from "next/link";
|
|
523
680
|
import { HugeiconsIcon as HugeiconsIcon2 } from "@hugeicons/react";
|
|
524
681
|
var Footer = ({
|
|
@@ -528,20 +685,20 @@ var Footer = ({
|
|
|
528
685
|
copyrightText,
|
|
529
686
|
topSection
|
|
530
687
|
}) => {
|
|
531
|
-
const [openCol, setOpenCol] =
|
|
688
|
+
const [openCol, setOpenCol] = useState5(null);
|
|
532
689
|
const toggleColumn = (idx) => {
|
|
533
690
|
setOpenCol(openCol === idx ? null : idx);
|
|
534
691
|
};
|
|
535
|
-
return /* @__PURE__ */
|
|
692
|
+
return /* @__PURE__ */ React7.createElement("div", { className: "" }, topSection && topSection, /* @__PURE__ */ React7.createElement("footer", { className: "relative px-6 overflow-hidden flex flex-col" }, /* @__PURE__ */ React7.createElement("div", { className: "relative w-full max-w-7xl mx-auto z-20 flex flex-col" }, /* @__PURE__ */ React7.createElement("div", { className: "relative py-12 md:py-16" }, /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col lg:flex-row justify-between items-start gap-12 lg:gap-16 mb-12 text-left" }, /* @__PURE__ */ React7.createElement("div", { className: "w-full lg:max-w-sm flex flex-col items-start justify-between shrink-0" }, /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-4 mb-4" }, /* @__PURE__ */ React7.createElement("img", { src: "https://retinalabs.company/assets/images/ndpr.avif", alt: "NDPR", className: "w-28 h-auto object-contain filter grayscale opacity-80" }), /* @__PURE__ */ React7.createElement("img", { src: "https://retinalabs.company/assets/images/gdpr.avif", alt: "GDPR", className: "w-12 h-12 object-contain filter grayscale opacity-80" })), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement("p", { className: "text-[11px] text-neutral-600 leading-relaxed pr-4" }, description))), /* @__PURE__ */ React7.createElement("div", { className: "w-full lg:flex-1 lg:max-w-2xl" }, /* @__PURE__ */ React7.createElement("div", { className: "hidden md:grid grid-cols-2 gap-x-16 lg:gap-x-24 gap-y-12" }, columns.map((col, idx) => /* @__PURE__ */ React7.createElement("div", { key: idx, className: "flex flex-col" }, /* @__PURE__ */ React7.createElement("h4", { className: "text-[11px] tracking-[0.2em] text-black mb-6 " }, col.title), /* @__PURE__ */ React7.createElement("ul", { className: "space-y-4 text-[13px] text-neutral-500" }, col.links.map((link, lIdx) => /* @__PURE__ */ React7.createElement("li", { key: lIdx }, link.isExternal ? /* @__PURE__ */ React7.createElement("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", className: "hover:text-black transition-colors block truncate" }, link.label) : /* @__PURE__ */ React7.createElement(Link3, { href: link.href, className: "hover:text-black transition-colors block truncate" }, link.label))))))), /* @__PURE__ */ React7.createElement("div", { className: "flex flex-col md:hidden w-full border-t border-neutral-200 mt-4" }, columns.map((col, idx) => {
|
|
536
693
|
const isOpen = openCol === idx;
|
|
537
|
-
return /* @__PURE__ */
|
|
694
|
+
return /* @__PURE__ */ React7.createElement("div", { key: idx, className: "border-b border-neutral-200" }, /* @__PURE__ */ React7.createElement(
|
|
538
695
|
"button",
|
|
539
696
|
{
|
|
540
697
|
onClick: () => toggleColumn(idx),
|
|
541
698
|
className: "w-full flex items-center justify-between py-5 text-left outline-none"
|
|
542
699
|
},
|
|
543
|
-
/* @__PURE__ */
|
|
544
|
-
/* @__PURE__ */
|
|
700
|
+
/* @__PURE__ */ React7.createElement("span", { className: "text-[11px] tracking-[0.2em] text-black " }, col.title),
|
|
701
|
+
/* @__PURE__ */ React7.createElement(
|
|
545
702
|
"svg",
|
|
546
703
|
{
|
|
547
704
|
className: `w-4 h-4 text-neutral-400 transition-transform duration-300 ${isOpen ? "rotate-180" : ""}`,
|
|
@@ -549,10 +706,10 @@ var Footer = ({
|
|
|
549
706
|
viewBox: "0 0 24 24",
|
|
550
707
|
stroke: "currentColor"
|
|
551
708
|
},
|
|
552
|
-
/* @__PURE__ */
|
|
709
|
+
/* @__PURE__ */ React7.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M19 9l-7 7-7-7" })
|
|
553
710
|
)
|
|
554
|
-
), /* @__PURE__ */
|
|
555
|
-
})))), /* @__PURE__ */
|
|
711
|
+
), /* @__PURE__ */ React7.createElement("div", { className: `grid transition-all duration-300 ease-in-out ${isOpen ? "grid-rows-[1fr] pb-6 opacity-100" : "grid-rows-[0fr] opacity-0"}` }, /* @__PURE__ */ React7.createElement("div", { className: "overflow-hidden" }, /* @__PURE__ */ React7.createElement("ul", { className: "space-y-4 text-[13px] text-neutral-500 pt-2" }, col.links.map((link, lIdx) => /* @__PURE__ */ React7.createElement("li", { key: lIdx }, link.isExternal ? /* @__PURE__ */ React7.createElement("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", className: "hover:text-black transition-colors" }, link.label) : /* @__PURE__ */ React7.createElement(Link3, { href: link.href, className: "hover:text-black transition-colors" }, link.label)))))));
|
|
712
|
+
})))), /* @__PURE__ */ React7.createElement("div", { className: "pt-8 mt-4 flex flex-col-reverse md:flex-row justify-between items-start md:items-center gap-6 relative z-20" }, /* @__PURE__ */ React7.createElement("p", { className: "text-[11px] text-neutral-400 tracking-widest text-left" }, copyrightText), socialLinks && socialLinks.length > 0 && /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-6" }, socialLinks.map((social, idx) => /* @__PURE__ */ React7.createElement(
|
|
556
713
|
"a",
|
|
557
714
|
{
|
|
558
715
|
key: idx,
|
|
@@ -561,12 +718,12 @@ var Footer = ({
|
|
|
561
718
|
rel: "noopener noreferrer",
|
|
562
719
|
className: "text-neutral-400 hover:text-black transition-colors"
|
|
563
720
|
},
|
|
564
|
-
/* @__PURE__ */
|
|
721
|
+
/* @__PURE__ */ React7.createElement(HugeiconsIcon2, { icon: social.icon, size: 20 })
|
|
565
722
|
))))))));
|
|
566
723
|
};
|
|
567
724
|
|
|
568
725
|
// src/components/MobileNav.tsx
|
|
569
|
-
import
|
|
726
|
+
import React8 from "react";
|
|
570
727
|
import Link4 from "next/link";
|
|
571
728
|
import { usePathname as usePathname2 } from "next/navigation";
|
|
572
729
|
import { HugeiconsIcon as HugeiconsIcon3 } from "@hugeicons/react";
|
|
@@ -576,23 +733,23 @@ var MobileNav = ({ items }) => {
|
|
|
576
733
|
const pathMatches = items.some((item) => {
|
|
577
734
|
return item.href === "/" || item.href === "/app" ? pathname === "/" || pathname === "/app" : pathname === item.href || pathname?.startsWith(`${item.href}/`);
|
|
578
735
|
});
|
|
579
|
-
return /* @__PURE__ */
|
|
736
|
+
return /* @__PURE__ */ React8.createElement("div", { className: "fixed bottom-6 inset-x-0 z-100 flex justify-center pointer-events-none px-3 animate-in slide-in-from-bottom-8 fade-in duration-500 md:hidden" }, /* @__PURE__ */ React8.createElement("nav", { className: "pointer-events-auto w-full max-w-sm bg-white/50 backdrop-blur-xl shadow-[0_8px_30px_rgb(0,0,0,0.08)] rounded-full px-6 py-2.5 flex items-center justify-between" }, items.map((item, index) => {
|
|
580
737
|
const isActive = !pathMatches && index === 0 ? true : item.href === "/" || item.href === "/app" ? pathname === "/" || pathname === "/app" : pathname === item.href || pathname?.startsWith(`${item.href}/`);
|
|
581
|
-
return /* @__PURE__ */
|
|
738
|
+
return /* @__PURE__ */ React8.createElement(
|
|
582
739
|
Link4,
|
|
583
740
|
{
|
|
584
741
|
key: item.label,
|
|
585
742
|
href: item.href,
|
|
586
743
|
className: "flex flex-col items-center justify-center gap-1 min-w-14 transition-transform active:scale-95 outline-none"
|
|
587
744
|
},
|
|
588
|
-
/* @__PURE__ */
|
|
745
|
+
/* @__PURE__ */ React8.createElement("div", { className: `transition-colors duration-300 ${isActive ? "text-black" : "text-neutral-400 hover:text-neutral-600"}` }, /* @__PURE__ */ React8.createElement(
|
|
589
746
|
HugeiconsIcon3,
|
|
590
747
|
{
|
|
591
748
|
icon: item.icon,
|
|
592
749
|
size: 20
|
|
593
750
|
}
|
|
594
751
|
)),
|
|
595
|
-
/* @__PURE__ */
|
|
752
|
+
/* @__PURE__ */ React8.createElement(
|
|
596
753
|
"span",
|
|
597
754
|
{
|
|
598
755
|
className: `text-[9px] tracking-wide transition-colors duration-300 ${isActive ? "text-black" : "text-neutral-400"}`
|
|
@@ -604,14 +761,14 @@ var MobileNav = ({ items }) => {
|
|
|
604
761
|
};
|
|
605
762
|
|
|
606
763
|
// src/components/UniversalOrganizationPage.tsx
|
|
607
|
-
import React11, { useState as
|
|
764
|
+
import React11, { useState as useState7, useEffect as useEffect4 } from "react";
|
|
608
765
|
import toast2 from "react-hot-toast";
|
|
609
766
|
|
|
610
767
|
// src/components/ManagedToaster.tsx
|
|
611
|
-
import
|
|
768
|
+
import React9 from "react";
|
|
612
769
|
import { Toaster } from "react-hot-toast";
|
|
613
770
|
var ManagedToaster = () => {
|
|
614
|
-
return /* @__PURE__ */
|
|
771
|
+
return /* @__PURE__ */ React9.createElement(
|
|
615
772
|
Toaster,
|
|
616
773
|
{
|
|
617
774
|
position: "top-right",
|
|
@@ -642,58 +799,8 @@ var ManagedToaster = () => {
|
|
|
642
799
|
);
|
|
643
800
|
};
|
|
644
801
|
|
|
645
|
-
// src/components/TextInput.tsx
|
|
646
|
-
import React9 from "react";
|
|
647
|
-
var TextInput = ({
|
|
648
|
-
label,
|
|
649
|
-
value,
|
|
650
|
-
onChange,
|
|
651
|
-
placeholder,
|
|
652
|
-
maxLength,
|
|
653
|
-
disabled,
|
|
654
|
-
readOnly,
|
|
655
|
-
type = "text",
|
|
656
|
-
onClick
|
|
657
|
-
}) => /* @__PURE__ */ React9.createElement("div", { className: "space-y-2 flex-1 w-full", onClick }, label && /* @__PURE__ */ React9.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, label), /* @__PURE__ */ React9.createElement(
|
|
658
|
-
"input",
|
|
659
|
-
{
|
|
660
|
-
type,
|
|
661
|
-
value,
|
|
662
|
-
onChange: (e) => onChange(e.target.value.substring(0, maxLength || 100)),
|
|
663
|
-
placeholder,
|
|
664
|
-
disabled,
|
|
665
|
-
readOnly,
|
|
666
|
-
autoComplete: "off",
|
|
667
|
-
spellCheck: "false",
|
|
668
|
-
className: `w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black transition-all outline-none focus:border-black disabled:opacity-50 ${readOnly ? "cursor-pointer" : ""}`
|
|
669
|
-
}
|
|
670
|
-
));
|
|
671
|
-
var NumberInput = ({
|
|
672
|
-
label,
|
|
673
|
-
value,
|
|
674
|
-
onChange,
|
|
675
|
-
placeholder,
|
|
676
|
-
maxLength,
|
|
677
|
-
disabled
|
|
678
|
-
}) => /* @__PURE__ */ React9.createElement("div", { className: "space-y-2 flex-1 w-full" }, label && /* @__PURE__ */ React9.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, label), /* @__PURE__ */ React9.createElement(
|
|
679
|
-
"input",
|
|
680
|
-
{
|
|
681
|
-
type: "text",
|
|
682
|
-
value,
|
|
683
|
-
onChange: (e) => {
|
|
684
|
-
const numOnly = e.target.value.replace(/[^0-9]/g, "");
|
|
685
|
-
onChange(numOnly.substring(0, maxLength || 20));
|
|
686
|
-
},
|
|
687
|
-
placeholder,
|
|
688
|
-
disabled,
|
|
689
|
-
autoComplete: "off",
|
|
690
|
-
spellCheck: "false",
|
|
691
|
-
className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black transition-all outline-none focus:border-black disabled:opacity-50"
|
|
692
|
-
}
|
|
693
|
-
));
|
|
694
|
-
|
|
695
802
|
// src/components/Banner.tsx
|
|
696
|
-
import React10, { useState as
|
|
803
|
+
import React10, { useState as useState6 } from "react";
|
|
697
804
|
import { HugeiconsIcon as HugeiconsIcon4 } from "@hugeicons/react";
|
|
698
805
|
import {
|
|
699
806
|
Alert02Icon,
|
|
@@ -710,7 +817,7 @@ var Banner = ({
|
|
|
710
817
|
onDismiss,
|
|
711
818
|
action
|
|
712
819
|
}) => {
|
|
713
|
-
const [isVisible, setIsVisible] =
|
|
820
|
+
const [isVisible, setIsVisible] = useState6(true);
|
|
714
821
|
if (!isVisible) return null;
|
|
715
822
|
const handleDismiss = () => {
|
|
716
823
|
setIsVisible(false);
|
|
@@ -759,7 +866,7 @@ import {
|
|
|
759
866
|
ArrowLeft01Icon,
|
|
760
867
|
CircleLock02Icon
|
|
761
868
|
} from "@hugeicons/core-free-icons";
|
|
762
|
-
var
|
|
869
|
+
var InputSpinner3 = () => /* @__PURE__ */ React11.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React11.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ React11.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
|
|
763
870
|
var UniversalOrganizationPage = ({
|
|
764
871
|
initialOrgName,
|
|
765
872
|
initialSlug,
|
|
@@ -776,12 +883,12 @@ var UniversalOrganizationPage = ({
|
|
|
776
883
|
if (typeof window !== "undefined") window.history.back();
|
|
777
884
|
});
|
|
778
885
|
const resolvedInitialUsername = initialUsername || initialSlug;
|
|
779
|
-
const [web3Name, setWeb3Name] =
|
|
780
|
-
const [username, setUsername] =
|
|
781
|
-
const [slug, setSlug] =
|
|
782
|
-
const [isCheckingSlug, setIsCheckingSlug] =
|
|
783
|
-
const [slugAvailable, setSlugAvailable] =
|
|
784
|
-
const [isSubmitting, setIsSubmitting] =
|
|
886
|
+
const [web3Name, setWeb3Name] = useState7(initialOrgName);
|
|
887
|
+
const [username, setUsername] = useState7(resolvedInitialUsername);
|
|
888
|
+
const [slug, setSlug] = useState7(initialSlug);
|
|
889
|
+
const [isCheckingSlug, setIsCheckingSlug] = useState7(false);
|
|
890
|
+
const [slugAvailable, setSlugAvailable] = useState7(null);
|
|
891
|
+
const [isSubmitting, setIsSubmitting] = useState7(false);
|
|
785
892
|
useEffect4(() => {
|
|
786
893
|
setWeb3Name(initialOrgName || "");
|
|
787
894
|
setSlug(initialSlug || "");
|
|
@@ -891,7 +998,7 @@ var UniversalOrganizationPage = ({
|
|
|
891
998
|
className: "w-full px-2 py-3 text-sm bg-transparent text-black outline-none disabled:opacity-50 disabled:cursor-not-allowed",
|
|
892
999
|
placeholder: "sovereign-user-handle"
|
|
893
1000
|
}
|
|
894
|
-
), /* @__PURE__ */ React11.createElement("span", { className: "text-neutral-400 text-sm py-3 pr-8 shrink-0 whitespace-nowrap" }, slugPrefixUrl), /* @__PURE__ */ React11.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ React11.createElement(
|
|
1001
|
+
), /* @__PURE__ */ React11.createElement("span", { className: "text-neutral-400 text-sm py-3 pr-8 shrink-0 whitespace-nowrap" }, slugPrefixUrl), /* @__PURE__ */ React11.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ React11.createElement(InputSpinner3, null), !isCheckingSlug && !isReadOnly && slug !== initialSlug && slug.length >= 3 && slugAvailable === false && /* @__PURE__ */ React11.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-red-100" }, /* @__PURE__ */ React11.createElement("svg", { className: "w-2 h-2 text-red-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React11.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && !isReadOnly && slug !== initialSlug && slug.length >= 3 && slugAvailable === true && /* @__PURE__ */ React11.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ React11.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ React11.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ React11.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ React11.createElement(
|
|
895
1002
|
ThreeDActionButton,
|
|
896
1003
|
{
|
|
897
1004
|
type: "submit",
|
|
@@ -916,7 +1023,7 @@ var UniversalOrganizationPage = ({
|
|
|
916
1023
|
};
|
|
917
1024
|
|
|
918
1025
|
// src/components/UniversalProfileSettings.tsx
|
|
919
|
-
import React12, { useState as
|
|
1026
|
+
import React12, { useState as useState8, useEffect as useEffect5 } from "react";
|
|
920
1027
|
import toast3 from "react-hot-toast";
|
|
921
1028
|
import { HugeiconsIcon as HugeiconsIcon6 } from "@hugeicons/react";
|
|
922
1029
|
import {
|
|
@@ -929,28 +1036,28 @@ import {
|
|
|
929
1036
|
var UniversalProfileSettings = ({
|
|
930
1037
|
initialFirstName,
|
|
931
1038
|
initialLastName,
|
|
932
|
-
|
|
1039
|
+
phoneNumber,
|
|
933
1040
|
accountStatus = "GOOD",
|
|
934
1041
|
memberSince,
|
|
935
1042
|
isReadOnly = false,
|
|
936
1043
|
bannerProps,
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1044
|
+
hasPasscode = false,
|
|
1045
|
+
isPasscodeLoading = false,
|
|
1046
|
+
onSavePasscode,
|
|
940
1047
|
onSaveProfile,
|
|
941
1048
|
onBack
|
|
942
1049
|
}) => {
|
|
943
1050
|
const onBackHandler = onBack ?? (() => {
|
|
944
1051
|
if (typeof window !== "undefined") window.history.back();
|
|
945
1052
|
});
|
|
946
|
-
const [firstName, setFirstName] =
|
|
947
|
-
const [lastName, setLastName] =
|
|
948
|
-
const [isSubmitting, setIsSubmitting] =
|
|
949
|
-
const [
|
|
950
|
-
const [
|
|
951
|
-
const [
|
|
952
|
-
const [
|
|
953
|
-
const [
|
|
1053
|
+
const [firstName, setFirstName] = useState8(initialFirstName);
|
|
1054
|
+
const [lastName, setLastName] = useState8(initialLastName);
|
|
1055
|
+
const [isSubmitting, setIsSubmitting] = useState8(false);
|
|
1056
|
+
const [isPasscodeModalOpen, setIsPasscodeModalOpen] = useState8(false);
|
|
1057
|
+
const [oldPasscode, setOldPasscode] = useState8("");
|
|
1058
|
+
const [newPasscode, setNewPasscode] = useState8("");
|
|
1059
|
+
const [confirmPasscode, setConfirmPasscode] = useState8("");
|
|
1060
|
+
const [isPasscodeSubmitting, setIsPasscodeSubmitting] = useState8(false);
|
|
954
1061
|
useEffect5(() => {
|
|
955
1062
|
setFirstName(initialFirstName || "");
|
|
956
1063
|
setLastName(initialLastName || "");
|
|
@@ -979,40 +1086,40 @@ var UniversalProfileSettings = ({
|
|
|
979
1086
|
setIsSubmitting(false);
|
|
980
1087
|
}
|
|
981
1088
|
};
|
|
982
|
-
const
|
|
983
|
-
if (
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1089
|
+
const closePasscodeModal = () => {
|
|
1090
|
+
if (isPasscodeSubmitting) return;
|
|
1091
|
+
setIsPasscodeModalOpen(false);
|
|
1092
|
+
setOldPasscode("");
|
|
1093
|
+
setNewPasscode("");
|
|
1094
|
+
setConfirmPasscode("");
|
|
988
1095
|
};
|
|
989
|
-
const
|
|
990
|
-
setter(val.replace(/\D/g, "").substring(0,
|
|
1096
|
+
const handlePasscodeInput = (val, setter) => {
|
|
1097
|
+
setter(val.replace(/\D/g, "").substring(0, 6));
|
|
991
1098
|
};
|
|
992
|
-
const
|
|
1099
|
+
const handlePasscodeSubmit = async (e) => {
|
|
993
1100
|
e.preventDefault();
|
|
994
|
-
if (!
|
|
995
|
-
if (
|
|
996
|
-
if (
|
|
997
|
-
if (
|
|
998
|
-
|
|
1101
|
+
if (!onSavePasscode) return;
|
|
1102
|
+
if (hasPasscode && oldPasscode.length !== 6) return toast3.error("Old Passcode must be exactly 6-digits.");
|
|
1103
|
+
if (newPasscode.length !== 6) return toast3.error("New Passcode must be exactly 6-digits.");
|
|
1104
|
+
if (newPasscode !== confirmPasscode) return toast3.error("New Passcodes do not match.");
|
|
1105
|
+
setIsPasscodeSubmitting(true);
|
|
999
1106
|
try {
|
|
1000
|
-
const action =
|
|
1001
|
-
const res = await
|
|
1107
|
+
const action = hasPasscode ? "change_passcode" : "create_passcode";
|
|
1108
|
+
const res = await onSavePasscode({
|
|
1002
1109
|
action,
|
|
1003
|
-
|
|
1004
|
-
|
|
1110
|
+
oldPasscode: hasPasscode ? oldPasscode : void 0,
|
|
1111
|
+
newPasscode
|
|
1005
1112
|
});
|
|
1006
1113
|
if (res.success) {
|
|
1007
|
-
toast3.success(res.message || "
|
|
1008
|
-
|
|
1114
|
+
toast3.success(res.message || "Passcode updated successfully.");
|
|
1115
|
+
closePasscodeModal();
|
|
1009
1116
|
} else {
|
|
1010
|
-
toast3.error(res.error || "Failed to update
|
|
1117
|
+
toast3.error(res.error || "Failed to update Passcode.");
|
|
1011
1118
|
}
|
|
1012
1119
|
} catch (error) {
|
|
1013
1120
|
toast3.error("Uh oh! Something went wrong.");
|
|
1014
1121
|
} finally {
|
|
1015
|
-
|
|
1122
|
+
setIsPasscodeSubmitting(false);
|
|
1016
1123
|
}
|
|
1017
1124
|
};
|
|
1018
1125
|
const hasChanges = firstName !== initialFirstName || lastName !== initialLastName;
|
|
@@ -1025,7 +1132,7 @@ var UniversalProfileSettings = ({
|
|
|
1025
1132
|
},
|
|
1026
1133
|
/* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: ArrowLeft01Icon2, size: 16 }),
|
|
1027
1134
|
" Back"
|
|
1028
|
-
)), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col max-w-3xl w-full mx-auto rounded-2xl p-6 bg-white
|
|
1135
|
+
)), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col max-w-3xl w-full mx-auto rounded-2xl p-6 bg-white gap-8 animate-in fade-in duration-300" }, /* @__PURE__ */ React12.createElement(ManagedToaster, null), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-3 sm:gap-4" }, /* @__PURE__ */ React12.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React12.createElement("h1", { className: "text-black text-xl mb-1 truncate tracking-tight" }, "Personal Settings"), /* @__PURE__ */ React12.createElement("p", { className: "text-xs text-neutral-500 truncate" }, "Manage your personal account profile.")), isReadOnly && /* @__PURE__ */ React12.createElement("span", { className: "p-2 w-9 h-9 bg-neutral-100 text-neutral-400 rounded-full shrink-0" }, /* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: CircleLock02Icon2, size: 18, className: "text-current" }))), bannerProps && /* @__PURE__ */ React12.createElement(Banner, { ...bannerProps }), /* @__PURE__ */ React12.createElement("div", { className: "w-full max-w-5xl" }, /* @__PURE__ */ React12.createElement("form", { className: "flex flex-col gap-8", onSubmit: handleSave, autoComplete: "off" }, /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col sm:flex-row gap-6" }, /* @__PURE__ */ React12.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1029
1136
|
TextInput,
|
|
1030
1137
|
{
|
|
1031
1138
|
label: "First Name",
|
|
@@ -1046,17 +1153,17 @@ var UniversalProfileSettings = ({
|
|
|
1046
1153
|
))), /* @__PURE__ */ React12.createElement("div", { className: "space-y-2 min-w-0" }, /* @__PURE__ */ React12.createElement(
|
|
1047
1154
|
TextInput,
|
|
1048
1155
|
{
|
|
1049
|
-
label: "
|
|
1050
|
-
value:
|
|
1156
|
+
label: "Registered Phone Number",
|
|
1157
|
+
value: phoneNumber,
|
|
1051
1158
|
onChange: () => {
|
|
1052
1159
|
},
|
|
1053
1160
|
disabled: true
|
|
1054
1161
|
}
|
|
1055
|
-
), /* @__PURE__ */ React12.createElement("p", { className: "text-[11px] text-neutral-500 mt-1 truncate" }, "To change your
|
|
1162
|
+
), /* @__PURE__ */ React12.createElement("p", { className: "text-[11px] text-neutral-500 mt-1 truncate" }, "To change your primary number, please contact support.")), /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between pt-8 mt-2 gap-6 sm:gap-4" }, /* @__PURE__ */ React12.createElement("div", { className: "flex items-center gap-6 min-w-0" }, /* @__PURE__ */ React12.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React12.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block truncate" }, "Account Status"), /* @__PURE__ */ React12.createElement("span", { className: "text-xs text-black block truncate" }, accountStatus)), /* @__PURE__ */ React12.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React12.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block truncate" }, "Member Since"), /* @__PURE__ */ React12.createElement("span", { className: "text-xs text-black block truncate" }, memberSince ? new Date(memberSince).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" }) : "N/A")), /* @__PURE__ */ React12.createElement("div", { className: "min-w-0 pl-4" }, /* @__PURE__ */ React12.createElement(
|
|
1056
1163
|
"button",
|
|
1057
1164
|
{
|
|
1058
1165
|
type: "button",
|
|
1059
|
-
onClick: () =>
|
|
1166
|
+
onClick: () => setIsPasscodeModalOpen(true),
|
|
1060
1167
|
className: "w-9 h-9 flex items-center justify-center border border-neutral-200 rounded-full text-black hover:bg-neutral-50 transition-colors outline-none"
|
|
1061
1168
|
},
|
|
1062
1169
|
/* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: LockKeyIcon, size: 17, className: "text-black" })
|
|
@@ -1080,48 +1187,48 @@ var UniversalProfileSettings = ({
|
|
|
1080
1187
|
className: "min-w-32 w-full sm:w-auto"
|
|
1081
1188
|
},
|
|
1082
1189
|
"Save Changes"
|
|
1083
|
-
))))),
|
|
1190
|
+
))))), isPasscodeModalOpen && /* @__PURE__ */ React12.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React12.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: closePasscodeModal }), /* @__PURE__ */ React12.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React12.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React12.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, hasPasscode ? "Change Passcode" : "Create Security Passcode"), /* @__PURE__ */ React12.createElement("button", { onClick: closePasscodeModal, disabled: isPasscodeSubmitting, className: "text-neutral-400 hover:text-black transition-colors outline-none disabled:opacity-50" }, /* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: CancelCircleIcon, size: 18 }))), /* @__PURE__ */ React12.createElement("div", { className: "p-6" }, isPasscodeLoading ? /* @__PURE__ */ React12.createElement("div", { className: "flex flex-col items-center justify-center py-10" }, /* @__PURE__ */ React12.createElement(HugeiconsIcon6, { icon: Loading03Icon2, size: 28, className: "animate-spin text-neutral-400 mb-4" })) : /* @__PURE__ */ React12.createElement("form", { onSubmit: handlePasscodeSubmit, className: "flex flex-col gap-6" }, hasPasscode && /* @__PURE__ */ React12.createElement(
|
|
1084
1191
|
TextInput,
|
|
1085
1192
|
{
|
|
1086
1193
|
type: "password",
|
|
1087
|
-
label: "Old
|
|
1088
|
-
maxLength:
|
|
1089
|
-
disabled:
|
|
1090
|
-
value:
|
|
1091
|
-
onChange: (val) =>
|
|
1092
|
-
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1194
|
+
label: "Old 6-Digit Passcode",
|
|
1195
|
+
maxLength: 6,
|
|
1196
|
+
disabled: isPasscodeSubmitting,
|
|
1197
|
+
value: oldPasscode,
|
|
1198
|
+
onChange: (val) => handlePasscodeInput(val, setOldPasscode),
|
|
1199
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
1093
1200
|
}
|
|
1094
1201
|
), /* @__PURE__ */ React12.createElement(
|
|
1095
1202
|
TextInput,
|
|
1096
1203
|
{
|
|
1097
1204
|
type: "password",
|
|
1098
|
-
label:
|
|
1099
|
-
maxLength:
|
|
1100
|
-
disabled:
|
|
1101
|
-
value:
|
|
1102
|
-
onChange: (val) =>
|
|
1103
|
-
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1205
|
+
label: hasPasscode ? "New 6-Digit Passcode" : "Enter 6-Digit Passcode",
|
|
1206
|
+
maxLength: 6,
|
|
1207
|
+
disabled: isPasscodeSubmitting,
|
|
1208
|
+
value: newPasscode,
|
|
1209
|
+
onChange: (val) => handlePasscodeInput(val, setNewPasscode),
|
|
1210
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
1104
1211
|
}
|
|
1105
1212
|
), /* @__PURE__ */ React12.createElement(
|
|
1106
1213
|
TextInput,
|
|
1107
1214
|
{
|
|
1108
1215
|
type: "password",
|
|
1109
|
-
label: "Retype New
|
|
1110
|
-
maxLength:
|
|
1111
|
-
disabled:
|
|
1112
|
-
value:
|
|
1113
|
-
onChange: (val) =>
|
|
1114
|
-
placeholder: "\u2022\u2022\u2022\u2022"
|
|
1216
|
+
label: "Retype New Passcode",
|
|
1217
|
+
maxLength: 6,
|
|
1218
|
+
disabled: isPasscodeSubmitting,
|
|
1219
|
+
value: confirmPasscode,
|
|
1220
|
+
onChange: (val) => handlePasscodeInput(val, setConfirmPasscode),
|
|
1221
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
1115
1222
|
}
|
|
1116
1223
|
), /* @__PURE__ */ React12.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React12.createElement(
|
|
1117
1224
|
ThreeDActionButton,
|
|
1118
1225
|
{
|
|
1119
1226
|
type: "submit",
|
|
1120
|
-
disabled:
|
|
1121
|
-
isLoading:
|
|
1227
|
+
disabled: isPasscodeSubmitting || newPasscode.length !== 6 || confirmPasscode.length !== 6 || hasPasscode && oldPasscode.length !== 6,
|
|
1228
|
+
isLoading: isPasscodeSubmitting,
|
|
1122
1229
|
className: "w-full"
|
|
1123
1230
|
},
|
|
1124
|
-
|
|
1231
|
+
hasPasscode ? "Update Passcode" : "Set Passcode"
|
|
1125
1232
|
))))))));
|
|
1126
1233
|
};
|
|
1127
1234
|
|
|
@@ -1214,7 +1321,7 @@ var UniversalErrorView = ({
|
|
|
1214
1321
|
};
|
|
1215
1322
|
|
|
1216
1323
|
// src/components/UniversalTransactionPage.tsx
|
|
1217
|
-
import React15, { useState as
|
|
1324
|
+
import React15, { useState as useState9, useEffect as useEffect6, useRef as useRef3 } from "react";
|
|
1218
1325
|
import { HugeiconsIcon as HugeiconsIcon9 } from "@hugeicons/react";
|
|
1219
1326
|
import toast4 from "react-hot-toast";
|
|
1220
1327
|
import {
|
|
@@ -1276,12 +1383,12 @@ var UniversalTransactionPage = ({
|
|
|
1276
1383
|
onReportTransaction,
|
|
1277
1384
|
onGenerateReceipt
|
|
1278
1385
|
}) => {
|
|
1279
|
-
const [selectedTransaction, setSelectedTransaction] =
|
|
1280
|
-
const [isGeneratingReceipt, setIsGeneratingReceipt] =
|
|
1281
|
-
const [localSearchQuery, setLocalSearchQuery] =
|
|
1282
|
-
const [isTyping, setIsTyping] =
|
|
1283
|
-
const [isDirectionModalOpen, setIsDirectionModalOpen] =
|
|
1284
|
-
const [isTypeModalOpen, setIsTypeModalOpen] =
|
|
1386
|
+
const [selectedTransaction, setSelectedTransaction] = useState9(null);
|
|
1387
|
+
const [isGeneratingReceipt, setIsGeneratingReceipt] = useState9(false);
|
|
1388
|
+
const [localSearchQuery, setLocalSearchQuery] = useState9(searchQuery);
|
|
1389
|
+
const [isTyping, setIsTyping] = useState9(false);
|
|
1390
|
+
const [isDirectionModalOpen, setIsDirectionModalOpen] = useState9(false);
|
|
1391
|
+
const [isTypeModalOpen, setIsTypeModalOpen] = useState9(false);
|
|
1285
1392
|
const directionDropdownRef = useRef3(null);
|
|
1286
1393
|
const typeDropdownRef = useRef3(null);
|
|
1287
1394
|
useEffect6(() => {
|
|
@@ -1448,7 +1555,7 @@ var UniversalTransactionPage = ({
|
|
|
1448
1555
|
};
|
|
1449
1556
|
|
|
1450
1557
|
// src/components/UniversalHomeView.tsx
|
|
1451
|
-
import React16, { useState as
|
|
1558
|
+
import React16, { useState as useState10, useEffect as useEffect7 } from "react";
|
|
1452
1559
|
import { HugeiconsIcon as HugeiconsIcon10 } from "@hugeicons/react";
|
|
1453
1560
|
import {
|
|
1454
1561
|
ViewOffSlashIcon,
|
|
@@ -1457,50 +1564,18 @@ import {
|
|
|
1457
1564
|
Notification01Icon,
|
|
1458
1565
|
ArrowLeft01Icon as ArrowLeft01Icon4,
|
|
1459
1566
|
ArrowRight01Icon as ArrowRight01Icon2,
|
|
1460
|
-
CancelCircleIcon as CancelCircleIcon3
|
|
1567
|
+
CancelCircleIcon as CancelCircleIcon3,
|
|
1568
|
+
ArrowUpRight01Icon as ArrowUpRight01Icon2
|
|
1461
1569
|
} from "@hugeicons/core-free-icons";
|
|
1462
|
-
var renderKMT = (val, currencySymbol) => {
|
|
1463
|
-
let formatted = val;
|
|
1464
|
-
let suffix = "";
|
|
1465
|
-
if (val >= 1e12) {
|
|
1466
|
-
formatted = val / 1e12;
|
|
1467
|
-
suffix = "T";
|
|
1468
|
-
} else if (val >= 1e6) {
|
|
1469
|
-
formatted = val / 1e6;
|
|
1470
|
-
suffix = "M";
|
|
1471
|
-
} else if (val >= 1e3) {
|
|
1472
|
-
formatted = val / 1e3;
|
|
1473
|
-
suffix = "k";
|
|
1474
|
-
}
|
|
1475
|
-
const displayStr = parseFloat(formatted.toFixed(2)).toString();
|
|
1476
|
-
return /* @__PURE__ */ React16.createElement("span", { className: "flex items-baseline mt-1" }, /* @__PURE__ */ React16.createElement("span", { className: "text-[13px] text-neutral-800 mr-0.5 " }, currencySymbol), /* @__PURE__ */ React16.createElement("span", { className: "text-xl text-neutral-800 tracking-tight " }, displayStr), /* @__PURE__ */ React16.createElement("span", { className: "text-[14px] text-neutral-600 ml-0.5 " }, suffix));
|
|
1477
|
-
};
|
|
1478
|
-
var renderKMT2 = (val, currencySymbol) => {
|
|
1479
|
-
let formatted = val;
|
|
1480
|
-
let suffix = "";
|
|
1481
|
-
if (val >= 1e12) {
|
|
1482
|
-
formatted = val / 1e12;
|
|
1483
|
-
suffix = "T";
|
|
1484
|
-
} else if (val >= 1e6) {
|
|
1485
|
-
formatted = val / 1e6;
|
|
1486
|
-
suffix = "M";
|
|
1487
|
-
} else if (val >= 1e3) {
|
|
1488
|
-
formatted = val / 1e3;
|
|
1489
|
-
suffix = "k";
|
|
1490
|
-
}
|
|
1491
|
-
const displayStr = parseFloat(formatted.toFixed(2)).toString();
|
|
1492
|
-
return /* @__PURE__ */ React16.createElement("span", { className: "flex items-baseline mt-1" }, /* @__PURE__ */ React16.createElement("span", { className: "text-[13px] text-white mr-0.5 " }, currencySymbol), /* @__PURE__ */ React16.createElement("span", { className: "text-xl text-white tracking-tight " }, displayStr), /* @__PURE__ */ React16.createElement("span", { className: "text-[14px] text-white/50 ml-0.5 " }, suffix));
|
|
1493
|
-
};
|
|
1494
1570
|
var UniversalHomeView = ({
|
|
1495
1571
|
fullName = "",
|
|
1496
1572
|
avatarSrc,
|
|
1497
|
-
balanceLabel = "
|
|
1573
|
+
balanceLabel = "Pending Balance",
|
|
1498
1574
|
balanceAmount,
|
|
1499
1575
|
balanceCurrency = "$",
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
secondaryAction,
|
|
1576
|
+
calculatorAction,
|
|
1577
|
+
buyCryptoAction,
|
|
1578
|
+
referralAction,
|
|
1504
1579
|
notifications = [],
|
|
1505
1580
|
notificationPage = 1,
|
|
1506
1581
|
notificationTotalPages = 1,
|
|
@@ -1511,11 +1586,11 @@ var UniversalHomeView = ({
|
|
|
1511
1586
|
customContent,
|
|
1512
1587
|
transactionsProps
|
|
1513
1588
|
}) => {
|
|
1514
|
-
const [displayAmount, setDisplayAmount] =
|
|
1515
|
-
const [isBalanceHidden, setIsBalanceHidden] =
|
|
1516
|
-
const [isAvatarLoaded, setIsAvatarLoaded] =
|
|
1517
|
-
const [showNotifDialog, setShowNotifDialog] =
|
|
1518
|
-
const [selectedNotif, setSelectedNotif] =
|
|
1589
|
+
const [displayAmount, setDisplayAmount] = useState10("0.00");
|
|
1590
|
+
const [isBalanceHidden, setIsBalanceHidden] = useState10(false);
|
|
1591
|
+
const [isAvatarLoaded, setIsAvatarLoaded] = useState10(false);
|
|
1592
|
+
const [showNotifDialog, setShowNotifDialog] = useState10(false);
|
|
1593
|
+
const [selectedNotif, setSelectedNotif] = useState10(null);
|
|
1519
1594
|
const fallbackAvatarUrl = `/api/avatar/?name=${encodeURIComponent(fullName || " ")}&background=ffffff&color=000000&size=200&font-size=0.33`;
|
|
1520
1595
|
const finalAvatarSrc = avatarSrc || fallbackAvatarUrl;
|
|
1521
1596
|
const hasUnreadNotifs = notifications.some((n) => !n.isRead);
|
|
@@ -1564,7 +1639,7 @@ var UniversalHomeView = ({
|
|
|
1564
1639
|
setShowNotifDialog(true);
|
|
1565
1640
|
setSelectedNotif(null);
|
|
1566
1641
|
},
|
|
1567
|
-
className: "relative w-10 h-10 flex items-center justify-center rounded-full bg-white
|
|
1642
|
+
className: "relative w-10 h-10 flex items-center justify-center rounded-full bg-white outline-none hover:bg-neutral-50 transition-colors"
|
|
1568
1643
|
},
|
|
1569
1644
|
/* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: Notification01Icon, size: 20, className: "text-black" }),
|
|
1570
1645
|
hasUnreadNotifs && /* @__PURE__ */ React16.createElement("span", { className: "absolute top-2.5 right-2.5 w-2 h-2 bg-red-500 rounded-full border border-white" })
|
|
@@ -1575,35 +1650,44 @@ var UniversalHomeView = ({
|
|
|
1575
1650
|
className: "text-neutral-400 hover:text-white transition-colors outline-none"
|
|
1576
1651
|
},
|
|
1577
1652
|
/* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: isBalanceHidden ? ViewIcon : ViewOffSlashIcon, size: 16 })
|
|
1578
|
-
)), /* @__PURE__ */ React16.createElement("p", { className: `text-2xl text-white tracking-tight mb-6 tabular-nums flex items-baseline transition-all duration-300 ${isBalanceHidden ? "blur-sm opacity-40 select-none" : ""}` }, /* @__PURE__ */ React16.createElement("span", { className: "text-lg text-neutral-400 mr-1" }, balanceCurrency), intPart, decPart && /* @__PURE__ */ React16.createElement("span", { className: "text-lg text-neutral-400" }, ".", decPart)), /* @__PURE__ */ React16.createElement("div", { className: "flex items-center
|
|
1653
|
+
)), /* @__PURE__ */ React16.createElement("p", { className: `text-2xl text-white tracking-tight mb-6 tabular-nums flex items-baseline transition-all duration-300 ${isBalanceHidden ? "blur-sm opacity-40 select-none" : ""}` }, /* @__PURE__ */ React16.createElement("span", { className: "text-lg text-neutral-400 mr-1" }, balanceCurrency), intPart, decPart && /* @__PURE__ */ React16.createElement("span", { className: "text-lg text-neutral-400" }, ".", decPart)), /* @__PURE__ */ React16.createElement("div", { className: "flex items-center w-full" }, calculatorAction && /* @__PURE__ */ React16.createElement(
|
|
1579
1654
|
"button",
|
|
1580
1655
|
{
|
|
1581
|
-
onClick:
|
|
1582
|
-
className: "px-6 py-2 bg-white text-
|
|
1656
|
+
onClick: calculatorAction.onClick,
|
|
1657
|
+
className: "px-6 py-2 bg-transparent border border-white/20 text-white truncate text-[12px] rounded-full transition-colors hover:bg-white/10 outline-none text-center"
|
|
1583
1658
|
},
|
|
1584
|
-
"
|
|
1585
|
-
),
|
|
1586
|
-
"
|
|
1659
|
+
calculatorAction.label || "Rate Calculator"
|
|
1660
|
+
)))), /* @__PURE__ */ React16.createElement("div", { className: "grid grid-cols-2 gap-2" }, /* @__PURE__ */ React16.createElement(
|
|
1661
|
+
"div",
|
|
1587
1662
|
{
|
|
1588
|
-
onClick:
|
|
1589
|
-
className: "
|
|
1663
|
+
onClick: buyCryptoAction?.onClick,
|
|
1664
|
+
className: "bg-[#143731] rounded-2xl p-5 relative overflow-hidden flex flex-col h-32 sm:h-36 cursor-pointer hover:opacity-90 transition-opacity"
|
|
1590
1665
|
},
|
|
1591
|
-
"
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1666
|
+
/* @__PURE__ */ React16.createElement("div", { className: "relative z-10 flex flex-col h-full justify-between" }, /* @__PURE__ */ React16.createElement("p", { className: "text-[15px] sm:text-[15px] text-white font-medium" }, "Buy Crypto"), /* @__PURE__ */ React16.createElement("div", { className: "w-8 h-8 rounded-full bg-white/10 border border-white/10 flex items-center justify-center" }, /* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: ArrowUpRight01Icon2, size: 16, className: "text-white" }))),
|
|
1667
|
+
/* @__PURE__ */ React16.createElement(
|
|
1668
|
+
"img",
|
|
1669
|
+
{
|
|
1670
|
+
src: "https://retinalabs.company/assets/images/save_box.avif",
|
|
1671
|
+
alt: "Buy Crypto",
|
|
1672
|
+
className: "absolute bottom-4 right-2 translate-x-1/4 translate-y-1/2 w-32 h-auto object-contain z-0 pointer-events-none drop-shadow-md"
|
|
1673
|
+
}
|
|
1674
|
+
)
|
|
1675
|
+
), /* @__PURE__ */ React16.createElement(
|
|
1676
|
+
"div",
|
|
1601
1677
|
{
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1678
|
+
onClick: referralAction?.onClick,
|
|
1679
|
+
className: "bg-[#ceff8a] rounded-2xl p-5 relative overflow-hidden flex flex-col h-32 sm:h-36 cursor-pointer hover:opacity-90 transition-opacity"
|
|
1680
|
+
},
|
|
1681
|
+
/* @__PURE__ */ React16.createElement("div", { className: "relative z-10 flex flex-col h-full justify-between" }, /* @__PURE__ */ React16.createElement("p", { className: "text-[15px] sm:text-[15px] text-black font-medium" }, "Referral"), /* @__PURE__ */ React16.createElement("div", { className: "w-8 h-8 rounded-full bg-black/5 border border-black/5 flex items-center justify-center" }, /* @__PURE__ */ React16.createElement(HugeiconsIcon10, { icon: ArrowRight01Icon2, size: 16, className: "text-black" }))),
|
|
1682
|
+
/* @__PURE__ */ React16.createElement(
|
|
1683
|
+
"img",
|
|
1684
|
+
{
|
|
1685
|
+
src: "https://retinalabs.company/assets/images/gift_box.avif",
|
|
1686
|
+
alt: "Referral",
|
|
1687
|
+
className: "absolute bottom-4 right-2 translate-x-1/4 translate-y-1/2 w-32 h-auto object-contain z-0 pointer-events-none drop-shadow-md"
|
|
1688
|
+
}
|
|
1689
|
+
)
|
|
1690
|
+
))), customContent && /* @__PURE__ */ React16.createElement("div", { className: "w-full" }, customContent), /* @__PURE__ */ React16.createElement("div", { className: "w-full mt-2" }, /* @__PURE__ */ React16.createElement(
|
|
1607
1691
|
UniversalTransactionPage,
|
|
1608
1692
|
{
|
|
1609
1693
|
...transactionsProps,
|
|
@@ -1643,7 +1727,7 @@ var UniversalHomeView = ({
|
|
|
1643
1727
|
};
|
|
1644
1728
|
|
|
1645
1729
|
// src/components/UniversalWalletPage.tsx
|
|
1646
|
-
import React18, { useState as
|
|
1730
|
+
import React18, { useState as useState11 } from "react";
|
|
1647
1731
|
import toast5 from "react-hot-toast";
|
|
1648
1732
|
import { HugeiconsIcon as HugeiconsIcon12 } from "@hugeicons/react";
|
|
1649
1733
|
import {
|
|
@@ -1706,7 +1790,7 @@ var truncateAddress2 = (ref) => {
|
|
|
1706
1790
|
return `${ref.substring(0, 11)}.....${ref.substring(ref.length - 11)}`;
|
|
1707
1791
|
};
|
|
1708
1792
|
var WalletLogo = ({ src, alt, sizeClass = "w-10 h-10" }) => {
|
|
1709
|
-
const [isLoaded, setIsLoaded] =
|
|
1793
|
+
const [isLoaded, setIsLoaded] = useState11(false);
|
|
1710
1794
|
return /* @__PURE__ */ React18.createElement("div", { className: `relative shrink-0 rounded-full bg-neutral-100 flex items-center justify-center overflow-hidden ${sizeClass}` }, !isLoaded && /* @__PURE__ */ React18.createElement(HugeiconsIcon12, { icon: Loading03Icon7, size: 16, className: "animate-spin text-neutral-400 absolute" }), /* @__PURE__ */ React18.createElement("img", { src, alt, onLoad: () => setIsLoaded(true), className: `w-full h-full object-cover transition-opacity duration-300 ${isLoaded ? "opacity-100" : "opacity-0"}` }));
|
|
1711
1795
|
};
|
|
1712
1796
|
var UniversalWalletPage = ({
|
|
@@ -1729,18 +1813,18 @@ var UniversalWalletPage = ({
|
|
|
1729
1813
|
const onBackHandler = onBack ?? (() => {
|
|
1730
1814
|
if (typeof window !== "undefined") window.history.back();
|
|
1731
1815
|
});
|
|
1732
|
-
const [selectedWallet, setSelectedWallet] =
|
|
1733
|
-
const [localSearchQuery, setLocalSearchQuery] =
|
|
1734
|
-
const [addModalOpen, setAddModalOpen] =
|
|
1735
|
-
const [importModalOpen, setImportModalOpen] =
|
|
1736
|
-
const [flowStep, setFlowStep] =
|
|
1737
|
-
const [generatedPhrase, setGeneratedPhrase] =
|
|
1738
|
-
const [hasBackedUp, setHasBackedUp] =
|
|
1739
|
-
const [verifyWords, setVerifyWords] =
|
|
1740
|
-
const [walletPassword, setWalletPassword] =
|
|
1741
|
-
const [importWords, setImportWords] =
|
|
1742
|
-
const [isProcessing, setIsProcessing] =
|
|
1743
|
-
const [showCopyWarning, setShowCopyWarning] =
|
|
1816
|
+
const [selectedWallet, setSelectedWallet] = useState11(null);
|
|
1817
|
+
const [localSearchQuery, setLocalSearchQuery] = useState11("");
|
|
1818
|
+
const [addModalOpen, setAddModalOpen] = useState11(false);
|
|
1819
|
+
const [importModalOpen, setImportModalOpen] = useState11(false);
|
|
1820
|
+
const [flowStep, setFlowStep] = useState11(1);
|
|
1821
|
+
const [generatedPhrase, setGeneratedPhrase] = useState11("");
|
|
1822
|
+
const [hasBackedUp, setHasBackedUp] = useState11(false);
|
|
1823
|
+
const [verifyWords, setVerifyWords] = useState11([]);
|
|
1824
|
+
const [walletPassword, setWalletPassword] = useState11("");
|
|
1825
|
+
const [importWords, setImportWords] = useState11(Array(24).fill(""));
|
|
1826
|
+
const [isProcessing, setIsProcessing] = useState11(false);
|
|
1827
|
+
const [showCopyWarning, setShowCopyWarning] = useState11(false);
|
|
1744
1828
|
const filteredWallets = wallets.filter((wallet) => {
|
|
1745
1829
|
const q = localSearchQuery.toLowerCase();
|
|
1746
1830
|
return wallet.name.toLowerCase().includes(q) || wallet.currency.toLowerCase().includes(q) || wallet.network.toLowerCase().includes(q);
|
|
@@ -1929,16 +2013,18 @@ var UniversalWalletPage = ({
|
|
|
1929
2013
|
};
|
|
1930
2014
|
|
|
1931
2015
|
// src/components/UniversalCardPage.tsx
|
|
1932
|
-
import React19, { useState as
|
|
2016
|
+
import React19, { useState as useState12, useEffect as useEffect8 } from "react";
|
|
1933
2017
|
import { useRouter } from "next/navigation";
|
|
2018
|
+
import toast6 from "react-hot-toast";
|
|
1934
2019
|
import { HugeiconsIcon as HugeiconsIcon13 } from "@hugeicons/react";
|
|
1935
2020
|
import {
|
|
1936
2021
|
SnowIcon,
|
|
1937
2022
|
Delete02Icon,
|
|
1938
2023
|
ArrowRight01Icon as ArrowRight01Icon3,
|
|
1939
|
-
SlidersHorizontalIcon,
|
|
1940
2024
|
ViewOffSlashIcon as ViewOffSlashIcon2,
|
|
1941
2025
|
Loading03Icon as Loading03Icon8,
|
|
2026
|
+
CancelCircleIcon as CancelCircleIcon5,
|
|
2027
|
+
Copy01Icon as Copy01Icon3,
|
|
1942
2028
|
PlusSignIcon as PlusSignIcon2
|
|
1943
2029
|
} from "@hugeicons/core-free-icons";
|
|
1944
2030
|
var UniversalCardPage = ({
|
|
@@ -1946,10 +2032,8 @@ var UniversalCardPage = ({
|
|
|
1946
2032
|
actionPath = "/app/cards/action/",
|
|
1947
2033
|
onReveal,
|
|
1948
2034
|
onFreeze,
|
|
1949
|
-
onSetLimits,
|
|
1950
2035
|
onDelete,
|
|
1951
|
-
onFundCard
|
|
1952
|
-
onCreateCard
|
|
2036
|
+
onFundCard
|
|
1953
2037
|
}) => {
|
|
1954
2038
|
const router = useRouter();
|
|
1955
2039
|
const sortedCards = React19.useMemo(() => {
|
|
@@ -1959,146 +2043,78 @@ var UniversalCardPage = ({
|
|
|
1959
2043
|
return 0;
|
|
1960
2044
|
});
|
|
1961
2045
|
}, [cards]);
|
|
1962
|
-
const [activeTabIndex, setActiveTabIndex] =
|
|
2046
|
+
const [activeTabIndex, setActiveTabIndex] = useState12(0);
|
|
1963
2047
|
const activeCard = sortedCards[activeTabIndex];
|
|
1964
|
-
const [isBgLoaded, setIsBgLoaded] =
|
|
1965
|
-
const [isFreezing, setIsFreezing] =
|
|
1966
|
-
const [
|
|
1967
|
-
const [
|
|
1968
|
-
const [isDeleting, setIsDeleting] = useState11(false);
|
|
2048
|
+
const [isBgLoaded, setIsBgLoaded] = useState12(false);
|
|
2049
|
+
const [isFreezing, setIsFreezing] = useState12(false);
|
|
2050
|
+
const [showDeleteDialog, setShowDeleteDialog] = useState12(false);
|
|
2051
|
+
const [isDeleting, setIsDeleting] = useState12(false);
|
|
1969
2052
|
useEffect8(() => {
|
|
1970
2053
|
setIsBgLoaded(false);
|
|
1971
2054
|
if (!activeCard?.cardBgSrc) return;
|
|
1972
2055
|
const img = new Image();
|
|
1973
2056
|
img.src = activeCard.cardBgSrc;
|
|
1974
|
-
img.onload = () =>
|
|
1975
|
-
setTimeout(() => setIsBgLoaded(true), 300);
|
|
1976
|
-
};
|
|
2057
|
+
img.onload = () => setIsBgLoaded(true);
|
|
1977
2058
|
}, [activeCard?.cardBgSrc]);
|
|
1978
2059
|
if (!activeCard || sortedCards.length === 0) {
|
|
1979
|
-
return /* @__PURE__ */ React19.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300 relative min-h-100 justify-center" },
|
|
1980
|
-
"button",
|
|
1981
|
-
{
|
|
1982
|
-
onClick: onCreateCard,
|
|
1983
|
-
className: "fixed bottom-24 right-6 sm:right-50 z-50 w-11 h-11 rounded-full bg-white shadow-xl flex items-center justify-center text-black transition-all outline-none"
|
|
1984
|
-
},
|
|
1985
|
-
/* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: PlusSignIcon2, size: 18 })
|
|
1986
|
-
), /* @__PURE__ */ React19.createElement("div", { className: "p-6 w-full max-w-md mx-auto text-center" }, /* @__PURE__ */ React19.createElement("div", { className: "mb-8 flex justify-center" }, /* @__PURE__ */ React19.createElement(
|
|
1987
|
-
"svg",
|
|
1988
|
-
{
|
|
1989
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1990
|
-
viewBox: "0 0 24 24",
|
|
1991
|
-
className: "w-12 h-12 fill-neutral-100"
|
|
1992
|
-
},
|
|
1993
|
-
/* @__PURE__ */ React19.createElement("path", { fillRule: "evenodd", d: "M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z", clipRule: "evenodd" })
|
|
1994
|
-
)), /* @__PURE__ */ React19.createElement("h1", { className: "text-xl text-black tracking-tight mb-4" }, "No cards available"), /* @__PURE__ */ React19.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 mb-12" }, "You do not have any virtual or physical cards generated yet.")));
|
|
2060
|
+
return /* @__PURE__ */ React19.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300 relative min-h-100 justify-center" }, /* @__PURE__ */ React19.createElement("div", { className: "p-6 w-full max-w-md mx-auto text-center" }, /* @__PURE__ */ React19.createElement("div", { className: "mb-8 flex justify-center" }, /* @__PURE__ */ React19.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", className: "w-12 h-12 fill-neutral-100" }, /* @__PURE__ */ React19.createElement("path", { fillRule: "evenodd", d: "M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z", clipRule: "evenodd" }))), /* @__PURE__ */ React19.createElement("h1", { className: "text-xl text-black tracking-tight mb-4" }, "No cards available"), /* @__PURE__ */ React19.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 mb-12" }, "You do not have any active cards on your account.")));
|
|
1995
2061
|
}
|
|
1996
2062
|
const isActivated = activeCard.status === "ACTIVATED";
|
|
1997
2063
|
const isFrozen = activeCard.status === "FROZEN";
|
|
1998
2064
|
const isUnactivated = activeCard.status === "UNACTIVATED";
|
|
1999
2065
|
const isDead = ["BLOCKED", "EXPIRED", "DELETED"].includes(activeCard.status);
|
|
2000
|
-
const
|
|
2001
|
-
const
|
|
2002
|
-
const
|
|
2003
|
-
const
|
|
2004
|
-
const
|
|
2005
|
-
|
|
2006
|
-
const buttonClasses = activeCard.contentDark ? "bg-black/10 text-black hover:bg-black/20 font-medium" : "bg-white/25 text-white hover:bg-white/35";
|
|
2007
|
-
const handleToggleFreeze = () => {
|
|
2008
|
-
if (freezeDisabled || isFreezing) return;
|
|
2066
|
+
const actionsDisabled = !isActivated && !isFrozen || isDead;
|
|
2067
|
+
const showActionOverlay = !isActivated && isBgLoaded || isFrozen;
|
|
2068
|
+
const overlayClasses = activeCard.contentDark ? "bg-white/30 backdrop-blur-[3px]" : "bg-black/30 backdrop-blur-[3px]";
|
|
2069
|
+
const buttonClasses = activeCard.contentDark ? "bg-black text-white hover:bg-black/80 font-medium" : "bg-white text-black hover:bg-neutral-100 font-medium";
|
|
2070
|
+
const handleToggleFreeze = async () => {
|
|
2071
|
+
if (actionsDisabled || isFreezing || !onFreeze) return;
|
|
2009
2072
|
setIsFreezing(true);
|
|
2010
|
-
|
|
2011
|
-
|
|
2073
|
+
try {
|
|
2074
|
+
await onFreeze(activeCard.id);
|
|
2075
|
+
} finally {
|
|
2012
2076
|
setIsFreezing(false);
|
|
2013
|
-
}
|
|
2077
|
+
}
|
|
2014
2078
|
};
|
|
2015
2079
|
const confirmDelete = async () => {
|
|
2016
2080
|
setIsDeleting(true);
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
setShowDeleteDialog(false);
|
|
2021
|
-
}, 1200);
|
|
2081
|
+
if (onDelete) onDelete(activeCard.id);
|
|
2082
|
+
setIsDeleting(false);
|
|
2083
|
+
setShowDeleteDialog(false);
|
|
2022
2084
|
};
|
|
2023
|
-
const formatTabLabel = (
|
|
2024
|
-
|
|
2025
|
-
const capitalizedTier = card.tier.charAt(0).toUpperCase() + card.tier.slice(1).toLowerCase();
|
|
2026
|
-
return `${capitalizedTier}`;
|
|
2027
|
-
}
|
|
2028
|
-
const capitalizedType = card.type.charAt(0).toUpperCase() + card.type.slice(1).toLowerCase();
|
|
2029
|
-
return `${capitalizedType}`;
|
|
2085
|
+
const formatTabLabel = (type) => {
|
|
2086
|
+
return type.charAt(0).toUpperCase() + type.slice(1).toLowerCase();
|
|
2030
2087
|
};
|
|
2031
|
-
return /* @__PURE__ */ React19.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300 relative" }, /* @__PURE__ */ React19.createElement("h1", { className: "text-2xl mt-2 text-black tracking-tight mb-2 text-center" }, "My Cards"),
|
|
2088
|
+
return /* @__PURE__ */ React19.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300 relative" }, /* @__PURE__ */ React19.createElement("h1", { className: "text-2xl mt-2 text-black tracking-tight mb-2 text-center" }, "My Cards"), sortedCards.length > 1 && /* @__PURE__ */ React19.createElement("div", { className: "flex items-center justify-center mb-6 w-full px-2 gap-3" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-center bg-white rounded-full p-1 max-w-full overflow-x-auto custom-scrollbar" }, sortedCards.map((tab, idx) => /* @__PURE__ */ React19.createElement(
|
|
2032
2089
|
"button",
|
|
2033
2090
|
{
|
|
2034
|
-
|
|
2035
|
-
|
|
2091
|
+
key: tab.id,
|
|
2092
|
+
onClick: () => setActiveTabIndex(idx),
|
|
2093
|
+
className: `px-4 py-1.5 rounded-full text-[11px] transition-all duration-200 outline-none whitespace-nowrap shrink-0 ${activeTabIndex === idx ? "bg-neutral-100 text-black" : "text-neutral-500 hover:text-black hover:bg-neutral-50/50"}`
|
|
2036
2094
|
},
|
|
2037
|
-
|
|
2038
|
-
),
|
|
2039
|
-
|
|
2040
|
-
return /* @__PURE__ */ React19.createElement(
|
|
2041
|
-
"button",
|
|
2042
|
-
{
|
|
2043
|
-
key: tab.id,
|
|
2044
|
-
onClick: () => setActiveTabIndex(idx),
|
|
2045
|
-
className: `px-4 py-1.5 rounded-full text-[11px] transition-all duration-200 outline-none whitespace-nowrap shrink-0 ${isActive ? "bg-neutral-100 text-black" : "text-neutral-500 hover:text-black hover:bg-neutral-50/50"}`
|
|
2046
|
-
},
|
|
2047
|
-
formatTabLabel(tab)
|
|
2048
|
-
);
|
|
2049
|
-
}))), /* @__PURE__ */ React19.createElement("div", { className: "w-full pt-2 pb-2 flex justify-center" }, /* @__PURE__ */ React19.createElement(
|
|
2050
|
-
"div",
|
|
2095
|
+
formatTabLabel(tab.type)
|
|
2096
|
+
)))), /* @__PURE__ */ React19.createElement("div", { className: "w-full pt-2 pb-6 flex justify-center" }, /* @__PURE__ */ React19.createElement("div", { className: "relative w-full max-w-85", style: { height: 179 } }, !isBgLoaded && /* @__PURE__ */ React19.createElement("div", { className: "absolute inset-0 w-full h-full bg-white rounded-2xl flex items-center justify-center z-50" }, /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: Loading03Icon8, size: 28, className: "animate-spin text-black" })), showActionOverlay && /* @__PURE__ */ React19.createElement("div", { className: `absolute inset-0 z-40 w-full h-full rounded-2xl flex flex-col items-center justify-center transition-all ${overlayClasses}` }, isUnactivated && /* @__PURE__ */ React19.createElement(
|
|
2097
|
+
"button",
|
|
2051
2098
|
{
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
!isBgLoaded && /* @__PURE__ */ React19.createElement("div", { className: "absolute inset-0 w-full h-full bg-white rounded-2xl flex items-center justify-center z-50" }, /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: Loading03Icon8, size: 28, className: "animate-spin text-black" })),
|
|
2056
|
-
showActionOverlay && /* @__PURE__ */ React19.createElement("div", { className: `absolute inset-0 z-40 w-full h-full rounded-2xl flex flex-col items-center justify-center transition-all ${overlayClasses}` }, isUnactivated && /* @__PURE__ */ React19.createElement(
|
|
2057
|
-
"button",
|
|
2058
|
-
{
|
|
2059
|
-
onClick: (e) => {
|
|
2060
|
-
e.stopPropagation();
|
|
2061
|
-
router.push(`${actionPath}${activeCard.id}`);
|
|
2062
|
-
},
|
|
2063
|
-
className: `px-6 py-2 text-[11px] rounded-full transition-all outline-none active:scale-95 ${buttonClasses}`
|
|
2099
|
+
onClick: (e) => {
|
|
2100
|
+
e.stopPropagation();
|
|
2101
|
+
router.push(`${actionPath}${activeCard.id}`);
|
|
2064
2102
|
},
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
className: `px-6 py-2.5 text-[12px] rounded-full transition-all outline-none active:scale-95 flex items-center gap-2 disabled:opacity-80 ${buttonClasses}`
|
|
2071
|
-
},
|
|
2072
|
-
isOverlayActionLoading ? /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: Loading03Icon8, size: 16, className: `animate-spin ${activeCard.contentDark ? "text-black" : "text-white"}` }) : "Card Frozen"
|
|
2073
|
-
)),
|
|
2074
|
-
/* @__PURE__ */ React19.createElement("div", { className: `absolute inset-0 w-full h-full rounded-2xl overflow-hidden transition-all duration-700 ${isBgLoaded ? "opacity-100 scale-100" : "opacity-0 scale-105"}` }, /* @__PURE__ */ React19.createElement(
|
|
2075
|
-
"div",
|
|
2076
|
-
{
|
|
2077
|
-
className: "absolute inset-0 bg-cover bg-center",
|
|
2078
|
-
style: { backgroundImage: `url(${activeCard.cardBgSrc})` }
|
|
2079
|
-
}
|
|
2080
|
-
), /* @__PURE__ */ React19.createElement("div", { className: "relative z-10 w-full h-full p-5 flex flex-col justify-between" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-start justify-end w-full gap-4" }, activeCard.prepaid && /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col items-end gap-1 text-right" }, /* @__PURE__ */ React19.createElement("span", { className: `text-[9px] tracking-widest ${activeCard.contentDark ? "text-black/60" : "text-white/60"}` }, "Card Tier"), /* @__PURE__ */ React19.createElement("span", { className: `text-[11px] tracking-widest font-medium ${activeCard.contentDark ? "text-black" : "text-white"}` }, activeCard.tier))), /* @__PURE__ */ React19.createElement("div", { className: "flex justify-between items-end w-full" }, /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React19.createElement("span", { className: `text-[9px] tracking-widest ${activeCard.contentDark ? "text-black/60" : "text-white/60"}` }, activeCard.prepaid ? "Card Balance" : "Card Tier"), /* @__PURE__ */ React19.createElement("span", { className: `text-[12px] tracking-widest font-medium ${activeCard.contentDark ? "text-black" : "text-white"}` }, activeCard.prepaid ? activeCard.balance || "$0.00" : activeCard.tier)), activeCard.networkLogoSrc && /* @__PURE__ */ React19.createElement(
|
|
2081
|
-
"img",
|
|
2082
|
-
{
|
|
2083
|
-
src: activeCard.networkLogoSrc,
|
|
2084
|
-
alt: "Network Logo",
|
|
2085
|
-
className: "h-7 w-auto max-w-20 object-contain opacity-90"
|
|
2086
|
-
}
|
|
2087
|
-
))))
|
|
2088
|
-
)), activeCard.bannerProps ? /* @__PURE__ */ React19.createElement("div", { className: "mb-6 w-full mt-2" }, /* @__PURE__ */ React19.createElement(Banner, { ...activeCard.bannerProps })) : isPreordered ? /* @__PURE__ */ React19.createElement("div", { className: "mb-6 w-full mt-2" }, /* @__PURE__ */ React19.createElement(
|
|
2089
|
-
Banner,
|
|
2103
|
+
className: `px-6 py-2 text-[11px] rounded-full transition-all outline-none ${buttonClasses}`
|
|
2104
|
+
},
|
|
2105
|
+
"Activate Card"
|
|
2106
|
+
), isFrozen && /* @__PURE__ */ React19.createElement("div", { className: `px-6 py-2.5 text-[12px] rounded-full flex items-center gap-2 ${buttonClasses}` }, "Card Frozen")), /* @__PURE__ */ React19.createElement("div", { className: `absolute inset-0 w-full h-full rounded-2xl overflow-hidden transition-all duration-700 ${isBgLoaded ? "opacity-100 scale-100" : "opacity-0 scale-105"}` }, /* @__PURE__ */ React19.createElement(
|
|
2107
|
+
"div",
|
|
2090
2108
|
{
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
message: `Your ${activeCard.tier} ${activeCard.type.toLowerCase()} card has been pre-ordered successfully and is pending batch processing.`,
|
|
2094
|
-
isDismissible: false
|
|
2109
|
+
className: "absolute inset-0 bg-cover bg-center",
|
|
2110
|
+
style: { backgroundImage: `url(${activeCard.cardBgSrc})` }
|
|
2095
2111
|
}
|
|
2096
|
-
)) :
|
|
2112
|
+
), /* @__PURE__ */ React19.createElement("div", { className: "relative z-10 w-full h-full p-5 flex flex-col justify-between" }, /* @__PURE__ */ React19.createElement("div", { className: "flex items-start justify-end w-full gap-4" }, activeCard.networkLogoSrc && /* @__PURE__ */ React19.createElement("img", { src: activeCard.networkLogoSrc, alt: "Network Logo", className: "h-7 w-auto max-w-20 object-contain opacity-90" })), /* @__PURE__ */ React19.createElement("div", { className: "flex justify-between items-end w-full" }, /* @__PURE__ */ React19.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React19.createElement("span", { className: `text-[10px] tracking-widest ${activeCard.contentDark ? "text-black/60" : "text-white/70"} drop-shadow-sm` }, "Balance"), /* @__PURE__ */ React19.createElement("span", { className: `text-[16px] tracking-widest font-medium ${activeCard.contentDark ? "text-black" : "text-white"} drop-shadow-sm` }, activeCard.balance))))))), /* @__PURE__ */ React19.createElement("div", { className: "w-full flex flex-col gap-4 mt-1" }, /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React19.createElement(
|
|
2097
2113
|
MenuRow,
|
|
2098
2114
|
{
|
|
2099
2115
|
icon: PlusSignIcon2,
|
|
2100
2116
|
title: "Fund Card",
|
|
2101
|
-
subtitle: "Add money to card",
|
|
2117
|
+
subtitle: "Add money to card balance",
|
|
2102
2118
|
onClick: () => {
|
|
2103
2119
|
if (!actionsDisabled && onFundCard) onFundCard(activeCard.id);
|
|
2104
2120
|
},
|
|
@@ -2111,9 +2127,9 @@ var UniversalCardPage = ({
|
|
|
2111
2127
|
title: "Reveal Information",
|
|
2112
2128
|
subtitle: "Show secure card details",
|
|
2113
2129
|
onClick: () => {
|
|
2114
|
-
if (!
|
|
2130
|
+
if (!actionsDisabled && onReveal) onReveal(activeCard.id);
|
|
2115
2131
|
},
|
|
2116
|
-
disabled:
|
|
2132
|
+
disabled: actionsDisabled
|
|
2117
2133
|
}
|
|
2118
2134
|
), /* @__PURE__ */ React19.createElement(
|
|
2119
2135
|
MenuRow,
|
|
@@ -2125,19 +2141,7 @@ var UniversalCardPage = ({
|
|
|
2125
2141
|
isToggle: true,
|
|
2126
2142
|
toggleState: isFrozen,
|
|
2127
2143
|
toggleLoading: isFreezing,
|
|
2128
|
-
disabled:
|
|
2129
|
-
isLast: activeCard.prepaid
|
|
2130
|
-
}
|
|
2131
|
-
), !activeCard.prepaid && /* @__PURE__ */ React19.createElement(
|
|
2132
|
-
MenuRow,
|
|
2133
|
-
{
|
|
2134
|
-
icon: SlidersHorizontalIcon,
|
|
2135
|
-
title: "Set Limits",
|
|
2136
|
-
subtitle: "Set card limits",
|
|
2137
|
-
onClick: () => {
|
|
2138
|
-
if (!actionsDisabled && onSetLimits) onSetLimits(activeCard.id);
|
|
2139
|
-
},
|
|
2140
|
-
disabled: actionsDisabled,
|
|
2144
|
+
disabled: isUnactivated || isDead,
|
|
2141
2145
|
isLast: true
|
|
2142
2146
|
}
|
|
2143
2147
|
)), /* @__PURE__ */ React19.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React19.createElement(
|
|
@@ -2157,7 +2161,7 @@ var UniversalCardPage = ({
|
|
|
2157
2161
|
{
|
|
2158
2162
|
isOpen: showDeleteDialog,
|
|
2159
2163
|
title: "Delete Card",
|
|
2160
|
-
message: "
|
|
2164
|
+
message: "Are you sure you want to delete this card? This action is permanent and cannot be undone.",
|
|
2161
2165
|
confirmText: "Delete",
|
|
2162
2166
|
isDestructive: true,
|
|
2163
2167
|
isProcessing: isDeleting,
|
|
@@ -2166,31 +2170,10 @@ var UniversalCardPage = ({
|
|
|
2166
2170
|
}
|
|
2167
2171
|
));
|
|
2168
2172
|
};
|
|
2169
|
-
var MenuRow = ({
|
|
2170
|
-
icon,
|
|
2171
|
-
title,
|
|
2172
|
-
subtitle,
|
|
2173
|
-
onClick,
|
|
2174
|
-
iconColor = "text-black",
|
|
2175
|
-
titleColor = "text-black",
|
|
2176
|
-
isLast = false,
|
|
2177
|
-
isToggle = false,
|
|
2178
|
-
toggleState = false,
|
|
2179
|
-
toggleLoading = false,
|
|
2180
|
-
disabled = false
|
|
2181
|
-
}) => /* @__PURE__ */ React19.createElement(
|
|
2182
|
-
"div",
|
|
2183
|
-
{
|
|
2184
|
-
onClick: disabled ? void 0 : onClick,
|
|
2185
|
-
className: `flex items-center p-3 transition-colors ${!isLast ? "" : ""} ${disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer hover:bg-neutral-50"}`
|
|
2186
|
-
},
|
|
2187
|
-
/* @__PURE__ */ React19.createElement("div", { className: "w-9 h-9 rounded-full border border-neutral-200 flex items-center justify-center shrink-0 mr-4" }, /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon, size: 16, className: iconColor })),
|
|
2188
|
-
/* @__PURE__ */ React19.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React19.createElement("p", { className: `text-[13px] truncate ${titleColor}` }, title), /* @__PURE__ */ React19.createElement("p", { className: "text-[11px] text-neutral-500 truncate" }, subtitle)),
|
|
2189
|
-
isToggle ? /* @__PURE__ */ React19.createElement("div", { className: `relative w-11 h-6 rounded-full transition-colors duration-300 ml-2 shrink-0 ${toggleState ? "bg-black" : "bg-neutral-100"} ${disabled ? "opacity-50" : ""}` }, /* @__PURE__ */ React19.createElement("div", { className: `absolute top-1 left-1 w-4 h-4 rounded-full bg-white shadow-sm transition-transform duration-300 flex items-center justify-center ${toggleState ? "translate-x-5" : "translate-x-0"}` }, toggleLoading && /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: Loading03Icon8, size: 10, className: "animate-spin text-black" }))) : /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: ArrowRight01Icon3, size: 18, className: "text-neutral-400 shrink-0 ml-2" })
|
|
2190
|
-
);
|
|
2173
|
+
var MenuRow = ({ icon, title, subtitle, onClick, isLast = false, isToggle = false, toggleState = false, toggleLoading = false, disabled = false }) => /* @__PURE__ */ React19.createElement("div", { onClick: disabled ? void 0 : onClick, className: `flex items-center p-3 transition-colors ${disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer hover:bg-neutral-50"}` }, /* @__PURE__ */ React19.createElement("div", { className: "w-9 h-9 rounded-full border border-neutral-200 flex items-center justify-center shrink-0 mr-4" }, /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon, size: 16, className: "text-black" })), /* @__PURE__ */ React19.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React19.createElement("p", { className: "text-[13px] truncate text-black" }, title), /* @__PURE__ */ React19.createElement("p", { className: "text-[11px] text-neutral-500 truncate" }, subtitle)), isToggle ? /* @__PURE__ */ React19.createElement("div", { className: `relative w-11 h-6 rounded-full transition-colors duration-300 ml-2 shrink-0 ${toggleState ? "bg-black" : "bg-neutral-100"} ${disabled ? "opacity-50" : ""}` }, /* @__PURE__ */ React19.createElement("div", { className: `absolute top-1 left-1 w-4 h-4 rounded-full bg-white shadow-sm transition-transform duration-300 flex items-center justify-center ${toggleState ? "translate-x-5" : "translate-x-0"}` }, toggleLoading && /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: Loading03Icon8, size: 10, className: "animate-spin text-black" }))) : /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: ArrowRight01Icon3, size: 18, className: "text-neutral-400 shrink-0 ml-2" }));
|
|
2191
2174
|
|
|
2192
2175
|
// src/components/UniversalProfilePage.tsx
|
|
2193
|
-
import React20, { useState as
|
|
2176
|
+
import React20, { useState as useState13 } from "react";
|
|
2194
2177
|
import { HugeiconsIcon as HugeiconsIcon14 } from "@hugeicons/react";
|
|
2195
2178
|
import {
|
|
2196
2179
|
UserIcon,
|
|
@@ -2219,11 +2202,11 @@ var UniversalProfilePage = ({
|
|
|
2219
2202
|
onLogoutTap,
|
|
2220
2203
|
onDeleteTap
|
|
2221
2204
|
}) => {
|
|
2222
|
-
const [isAvatarLoaded, setIsAvatarLoaded] =
|
|
2223
|
-
const [showLogoutDialog, setShowLogoutDialog] =
|
|
2224
|
-
const [isLoggingOut, setIsLoggingOut] =
|
|
2225
|
-
const [showDeleteDialog, setShowDeleteDialog] =
|
|
2226
|
-
const [isDeleting, setIsDeleting] =
|
|
2205
|
+
const [isAvatarLoaded, setIsAvatarLoaded] = useState13(false);
|
|
2206
|
+
const [showLogoutDialog, setShowLogoutDialog] = useState13(false);
|
|
2207
|
+
const [isLoggingOut, setIsLoggingOut] = useState13(false);
|
|
2208
|
+
const [showDeleteDialog, setShowDeleteDialog] = useState13(false);
|
|
2209
|
+
const [isDeleting, setIsDeleting] = useState13(false);
|
|
2227
2210
|
const handleConfirmLogout = async () => {
|
|
2228
2211
|
setIsLoggingOut(true);
|
|
2229
2212
|
try {
|
|
@@ -2374,7 +2357,7 @@ var MenuRow2 = ({ icon, title, subtitle, onClick, iconColor = "text-black", titl
|
|
|
2374
2357
|
);
|
|
2375
2358
|
|
|
2376
2359
|
// src/components/UniversalSidebar.tsx
|
|
2377
|
-
import React21, { useState as
|
|
2360
|
+
import React21, { useState as useState14 } from "react";
|
|
2378
2361
|
import Link5 from "next/link";
|
|
2379
2362
|
import { HugeiconsIcon as HugeiconsIcon15 } from "@hugeicons/react";
|
|
2380
2363
|
import {
|
|
@@ -2387,8 +2370,8 @@ var UniversalSidebar = ({
|
|
|
2387
2370
|
showLogoutAction = false,
|
|
2388
2371
|
onLogout
|
|
2389
2372
|
}) => {
|
|
2390
|
-
const [showLogoutDialog, setShowLogoutDialog] =
|
|
2391
|
-
const [isLoggingOut, setIsLoggingOut] =
|
|
2373
|
+
const [showLogoutDialog, setShowLogoutDialog] = useState14(false);
|
|
2374
|
+
const [isLoggingOut, setIsLoggingOut] = useState14(false);
|
|
2392
2375
|
const hasActiveMatch = navItems.some(
|
|
2393
2376
|
(item) => item.path === "/" || item.path === "/app" ? currentPath === "/" || currentPath === "/app" : currentPath === item.path || currentPath?.startsWith(`${item.path}/`)
|
|
2394
2377
|
);
|
|
@@ -2446,21 +2429,21 @@ var UniversalSidebar = ({
|
|
|
2446
2429
|
};
|
|
2447
2430
|
|
|
2448
2431
|
// src/components/HeroSection.tsx
|
|
2449
|
-
import React23, { useState as
|
|
2432
|
+
import React23, { useState as useState16, useEffect as useEffect9, useRef as useRef4 } from "react";
|
|
2450
2433
|
import Link6 from "next/link";
|
|
2451
2434
|
import Image3 from "next/image";
|
|
2452
2435
|
|
|
2453
2436
|
// src/components/WaitlistDialog.tsx
|
|
2454
|
-
import React22, { useState as
|
|
2455
|
-
import { toast as
|
|
2437
|
+
import React22, { useState as useState15 } from "react";
|
|
2438
|
+
import { toast as toast7 } from "react-hot-toast";
|
|
2456
2439
|
var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
2457
|
-
const [email, setEmail] =
|
|
2458
|
-
const [isLoading, setIsLoading] =
|
|
2440
|
+
const [email, setEmail] = useState15("");
|
|
2441
|
+
const [isLoading, setIsLoading] = useState15(false);
|
|
2459
2442
|
if (!isOpen) return null;
|
|
2460
2443
|
const handleSubmit = async (e) => {
|
|
2461
2444
|
e.preventDefault();
|
|
2462
2445
|
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
2463
|
-
|
|
2446
|
+
toast7.error("Please enter a valid email address.");
|
|
2464
2447
|
return;
|
|
2465
2448
|
}
|
|
2466
2449
|
setIsLoading(true);
|
|
@@ -2474,14 +2457,14 @@ var WaitlistDialog = ({ isOpen, onClose }) => {
|
|
|
2474
2457
|
});
|
|
2475
2458
|
const data = await response.json();
|
|
2476
2459
|
if (response.ok && data.success) {
|
|
2477
|
-
|
|
2460
|
+
toast7.success(data.message || "You've been added to the waitlist!");
|
|
2478
2461
|
setEmail("");
|
|
2479
2462
|
onClose();
|
|
2480
2463
|
} else {
|
|
2481
|
-
|
|
2464
|
+
toast7.error(data.error || "Something went wrong. Please try again.");
|
|
2482
2465
|
}
|
|
2483
2466
|
} catch (error) {
|
|
2484
|
-
|
|
2467
|
+
toast7.error("Network error. Please check your connection.");
|
|
2485
2468
|
} finally {
|
|
2486
2469
|
setIsLoading(false);
|
|
2487
2470
|
}
|
|
@@ -2558,8 +2541,8 @@ var HeroSection = ({
|
|
|
2558
2541
|
bgImageSrc,
|
|
2559
2542
|
isWaitlist = false
|
|
2560
2543
|
}) => {
|
|
2561
|
-
const [isAnimating, setIsAnimating] =
|
|
2562
|
-
const [isWaitlistOpen, setIsWaitlistOpen] =
|
|
2544
|
+
const [isAnimating, setIsAnimating] = useState16(false);
|
|
2545
|
+
const [isWaitlistOpen, setIsWaitlistOpen] = useState16(false);
|
|
2563
2546
|
const titleRef = useRef4(null);
|
|
2564
2547
|
useEffect9(() => {
|
|
2565
2548
|
const observer = new IntersectionObserver(
|
|
@@ -2654,10 +2637,10 @@ var HeroSection = ({
|
|
|
2654
2637
|
};
|
|
2655
2638
|
|
|
2656
2639
|
// src/components/AppBento2.tsx
|
|
2657
|
-
import React24, { useState as
|
|
2640
|
+
import React24, { useState as useState17, useEffect as useEffect10, useRef as useRef5 } from "react";
|
|
2658
2641
|
import { HugeiconsIcon as HugeiconsIcon16 } from "@hugeicons/react";
|
|
2659
2642
|
var AppBento2 = ({ tagline, headline, features }) => {
|
|
2660
|
-
const [isAnimating, setIsAnimating] =
|
|
2643
|
+
const [isAnimating, setIsAnimating] = useState17(false);
|
|
2661
2644
|
const titleRef = useRef5(null);
|
|
2662
2645
|
useEffect10(() => {
|
|
2663
2646
|
const observer = new IntersectionObserver(
|
|
@@ -2729,114 +2712,36 @@ var AppBento2 = ({ tagline, headline, features }) => {
|
|
|
2729
2712
|
};
|
|
2730
2713
|
|
|
2731
2714
|
// src/components/UniversalSecurityPage.tsx
|
|
2732
|
-
import React25, { useState as
|
|
2733
|
-
import
|
|
2715
|
+
import React25, { useState as useState18 } from "react";
|
|
2716
|
+
import toast8 from "react-hot-toast";
|
|
2734
2717
|
import { HugeiconsIcon as HugeiconsIcon17 } from "@hugeicons/react";
|
|
2735
2718
|
import {
|
|
2736
|
-
CancelCircleIcon as
|
|
2719
|
+
CancelCircleIcon as CancelCircleIcon6,
|
|
2737
2720
|
Loading03Icon as Loading03Icon10,
|
|
2738
|
-
Copy01Icon as Copy01Icon3,
|
|
2739
2721
|
ArrowLeft01Icon as ArrowLeft01Icon6,
|
|
2740
|
-
CircleLockCheck02Icon,
|
|
2741
2722
|
Key01Icon,
|
|
2723
|
+
LockKeyIcon as LockKeyIcon3,
|
|
2742
2724
|
ArrowRight01Icon as ArrowRight01Icon5
|
|
2743
2725
|
} from "@hugeicons/core-free-icons";
|
|
2744
2726
|
import { startRegistration } from "@simplewebauthn/browser";
|
|
2745
2727
|
var UniversalSecurityPage = ({
|
|
2746
|
-
|
|
2728
|
+
hasPasscode,
|
|
2747
2729
|
hasPasskey,
|
|
2748
|
-
|
|
2749
|
-
is2FALoading = false,
|
|
2730
|
+
isPasscodeLoading = false,
|
|
2750
2731
|
isPasskeyLoading = false,
|
|
2751
2732
|
onBack,
|
|
2752
|
-
|
|
2753
|
-
onVerifyAndEnable2FA,
|
|
2754
|
-
onVerifyAndDisable2FA,
|
|
2733
|
+
onSavePasscode,
|
|
2755
2734
|
onRequestPasskeySetup,
|
|
2756
2735
|
onVerifyAndEnablePasskey,
|
|
2757
2736
|
onDisablePasskey
|
|
2758
2737
|
}) => {
|
|
2759
|
-
const [
|
|
2760
|
-
const [
|
|
2761
|
-
const [
|
|
2762
|
-
const [
|
|
2763
|
-
const [
|
|
2764
|
-
const [
|
|
2765
|
-
const [
|
|
2766
|
-
const [isSubmitting, setIsSubmitting] = useState17(false);
|
|
2767
|
-
const inputRefs = useRef6([]);
|
|
2768
|
-
const resetOtp = () => {
|
|
2769
|
-
setOtp(Array(6).fill(""));
|
|
2770
|
-
setIsSubmitting(false);
|
|
2771
|
-
};
|
|
2772
|
-
const handleOtpChange = (index, value) => {
|
|
2773
|
-
const sanitizedValue = value.replace(/\D/g, "").slice(-1);
|
|
2774
|
-
const newOtp = [...otp];
|
|
2775
|
-
newOtp[index] = sanitizedValue;
|
|
2776
|
-
setOtp(newOtp);
|
|
2777
|
-
if (sanitizedValue && index < 5) {
|
|
2778
|
-
inputRefs.current[index + 1]?.focus();
|
|
2779
|
-
}
|
|
2780
|
-
};
|
|
2781
|
-
const handlePaste = (e) => {
|
|
2782
|
-
e.preventDefault();
|
|
2783
|
-
const pastedData = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, 6);
|
|
2784
|
-
if (!pastedData) return;
|
|
2785
|
-
const newOtp = [...otp];
|
|
2786
|
-
for (let i = 0; i < pastedData.length; i++) {
|
|
2787
|
-
newOtp[i] = pastedData[i];
|
|
2788
|
-
}
|
|
2789
|
-
setOtp(newOtp);
|
|
2790
|
-
const focusIndex = Math.min(pastedData.length, 5);
|
|
2791
|
-
inputRefs.current[focusIndex]?.focus();
|
|
2792
|
-
};
|
|
2793
|
-
const handleCopySecret = async (secret) => {
|
|
2794
|
-
try {
|
|
2795
|
-
if (navigator?.clipboard?.writeText && window.isSecureContext) {
|
|
2796
|
-
await navigator.clipboard.writeText(secret);
|
|
2797
|
-
toast7.success("Secret copied to clipboard");
|
|
2798
|
-
} else {
|
|
2799
|
-
throw new Error("Clipboard API not available");
|
|
2800
|
-
}
|
|
2801
|
-
} catch (e) {
|
|
2802
|
-
try {
|
|
2803
|
-
const textArea = document.createElement("textarea");
|
|
2804
|
-
textArea.value = secret;
|
|
2805
|
-
textArea.style.position = "fixed";
|
|
2806
|
-
textArea.style.left = "-999999px";
|
|
2807
|
-
textArea.style.top = "-999999px";
|
|
2808
|
-
document.body.appendChild(textArea);
|
|
2809
|
-
textArea.focus();
|
|
2810
|
-
textArea.select();
|
|
2811
|
-
document.execCommand("copy");
|
|
2812
|
-
textArea.remove();
|
|
2813
|
-
toast7.success("Secret copied to clipboard");
|
|
2814
|
-
} catch (err) {
|
|
2815
|
-
toast7.error("Unable to copy. Please manually copy the key.");
|
|
2816
|
-
}
|
|
2817
|
-
}
|
|
2818
|
-
};
|
|
2819
|
-
const handleToggle2FA = async () => {
|
|
2820
|
-
if (is2FALoading) return;
|
|
2821
|
-
if (has2FA) {
|
|
2822
|
-
resetOtp();
|
|
2823
|
-
setShow2FADisableModal(true);
|
|
2824
|
-
} else {
|
|
2825
|
-
if (!onRequest2FASetup) return;
|
|
2826
|
-
setIsFetchingSetup(true);
|
|
2827
|
-
try {
|
|
2828
|
-
const data = await onRequest2FASetup();
|
|
2829
|
-
setTwoFaSecret(data.secret);
|
|
2830
|
-
setTwoFaQr(data.qrCodeUrl);
|
|
2831
|
-
resetOtp();
|
|
2832
|
-
setShow2FASetupModal(true);
|
|
2833
|
-
} catch (error) {
|
|
2834
|
-
toast7.error("Failed to initialize 2FA setup");
|
|
2835
|
-
} finally {
|
|
2836
|
-
setIsFetchingSetup(false);
|
|
2837
|
-
}
|
|
2838
|
-
}
|
|
2839
|
-
};
|
|
2738
|
+
const [showPasskeyModal, setShowPasskeyModal] = useState18(false);
|
|
2739
|
+
const [isSubmitting, setIsSubmitting] = useState18(false);
|
|
2740
|
+
const [isPasscodeModalOpen, setIsPasscodeModalOpen] = useState18(false);
|
|
2741
|
+
const [oldPasscode, setOldPasscode] = useState18("");
|
|
2742
|
+
const [newPasscode, setNewPasscode] = useState18("");
|
|
2743
|
+
const [confirmPasscode, setConfirmPasscode] = useState18("");
|
|
2744
|
+
const [isPasscodeSubmitting, setIsPasscodeSubmitting] = useState18(false);
|
|
2840
2745
|
const handleTogglePasskey = () => {
|
|
2841
2746
|
if (isPasskeyLoading) return;
|
|
2842
2747
|
if (hasPasskey) {
|
|
@@ -2845,38 +2750,40 @@ var UniversalSecurityPage = ({
|
|
|
2845
2750
|
setShowPasskeyModal(true);
|
|
2846
2751
|
}
|
|
2847
2752
|
};
|
|
2848
|
-
const
|
|
2849
|
-
if (
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
toast7.success("2FA Enabled Successfully");
|
|
2855
|
-
setShow2FASetupModal(false);
|
|
2856
|
-
} else {
|
|
2857
|
-
toast7.error("Invalid verification code");
|
|
2858
|
-
}
|
|
2859
|
-
} catch (error) {
|
|
2860
|
-
toast7.error("Verification failed");
|
|
2861
|
-
} finally {
|
|
2862
|
-
setIsSubmitting(false);
|
|
2863
|
-
}
|
|
2753
|
+
const closePasscodeModal = () => {
|
|
2754
|
+
if (isPasscodeSubmitting) return;
|
|
2755
|
+
setIsPasscodeModalOpen(false);
|
|
2756
|
+
setOldPasscode("");
|
|
2757
|
+
setNewPasscode("");
|
|
2758
|
+
setConfirmPasscode("");
|
|
2864
2759
|
};
|
|
2865
|
-
const
|
|
2866
|
-
|
|
2867
|
-
|
|
2760
|
+
const handlePasscodeInput = (val, setter) => {
|
|
2761
|
+
setter(val.replace(/\D/g, "").substring(0, 6));
|
|
2762
|
+
};
|
|
2763
|
+
const handlePasscodeSubmit = async (e) => {
|
|
2764
|
+
e.preventDefault();
|
|
2765
|
+
if (!onSavePasscode) return;
|
|
2766
|
+
if (hasPasscode && oldPasscode.length !== 6) return toast8.error("Old Passcode must be exactly 6-digits.");
|
|
2767
|
+
if (newPasscode.length !== 6) return toast8.error("New Passcode must be exactly 6-digits.");
|
|
2768
|
+
if (newPasscode !== confirmPasscode) return toast8.error("New Passcodes do not match.");
|
|
2769
|
+
setIsPasscodeSubmitting(true);
|
|
2868
2770
|
try {
|
|
2869
|
-
const
|
|
2771
|
+
const action = hasPasscode ? "change_passcode" : "create_passcode";
|
|
2772
|
+
const res = await onSavePasscode({
|
|
2773
|
+
action,
|
|
2774
|
+
oldPasscode: hasPasscode ? oldPasscode : void 0,
|
|
2775
|
+
newPasscode
|
|
2776
|
+
});
|
|
2870
2777
|
if (res.success) {
|
|
2871
|
-
|
|
2872
|
-
|
|
2778
|
+
toast8.success(res.message || "Passcode updated successfully.");
|
|
2779
|
+
closePasscodeModal();
|
|
2873
2780
|
} else {
|
|
2874
|
-
|
|
2781
|
+
toast8.error(res.error || "Failed to update Passcode.");
|
|
2875
2782
|
}
|
|
2876
2783
|
} catch (error) {
|
|
2877
|
-
|
|
2784
|
+
toast8.error("Uh oh! Something went wrong.");
|
|
2878
2785
|
} finally {
|
|
2879
|
-
|
|
2786
|
+
setIsPasscodeSubmitting(false);
|
|
2880
2787
|
}
|
|
2881
2788
|
};
|
|
2882
2789
|
const submitEnablePasskey = async () => {
|
|
@@ -2895,13 +2802,13 @@ var UniversalSecurityPage = ({
|
|
|
2895
2802
|
}
|
|
2896
2803
|
const res = await onVerifyAndEnablePasskey(credentialResponse);
|
|
2897
2804
|
if (res.success) {
|
|
2898
|
-
|
|
2805
|
+
toast8.success("Passkey Created Successfully");
|
|
2899
2806
|
setShowPasskeyModal(false);
|
|
2900
2807
|
} else {
|
|
2901
|
-
|
|
2808
|
+
toast8.error("Failed to verify device passkey.");
|
|
2902
2809
|
}
|
|
2903
2810
|
} catch (error) {
|
|
2904
|
-
|
|
2811
|
+
toast8.error(error.message || "Passkey setup interrupted.");
|
|
2905
2812
|
} finally {
|
|
2906
2813
|
setIsSubmitting(false);
|
|
2907
2814
|
}
|
|
@@ -2910,20 +2817,18 @@ var UniversalSecurityPage = ({
|
|
|
2910
2817
|
"button",
|
|
2911
2818
|
{
|
|
2912
2819
|
onClick: onBack,
|
|
2913
|
-
className: "flex items-center gap-2 text-neutral-500 hover:text-black transition-colors text-[13px]
|
|
2820
|
+
className: "flex items-center gap-2 text-neutral-500 hover:text-black transition-colors text-[13px] outline-none"
|
|
2914
2821
|
},
|
|
2915
2822
|
/* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: ArrowLeft01Icon6, size: 16 }),
|
|
2916
2823
|
" Back"
|
|
2917
2824
|
)), /* @__PURE__ */ React25.createElement("div", { className: "w-full flex flex-col gap-4" }, /* @__PURE__ */ React25.createElement("div", { className: "w-full bg-white rounded-2xl overflow-hidden" }, /* @__PURE__ */ React25.createElement(
|
|
2918
2825
|
MenuRow3,
|
|
2919
2826
|
{
|
|
2920
|
-
icon:
|
|
2921
|
-
title: "
|
|
2922
|
-
subtitle: "
|
|
2923
|
-
onClick:
|
|
2924
|
-
isToggle:
|
|
2925
|
-
toggleState: has2FA,
|
|
2926
|
-
toggleLoading: is2FALoading || isFetchingSetup
|
|
2827
|
+
icon: LockKeyIcon3,
|
|
2828
|
+
title: "Security Passcode",
|
|
2829
|
+
subtitle: hasPasscode ? "Change your 6-digit passcode" : "Create a 6-digit passcode",
|
|
2830
|
+
onClick: () => setIsPasscodeModalOpen(true),
|
|
2831
|
+
isToggle: false
|
|
2927
2832
|
}
|
|
2928
2833
|
), /* @__PURE__ */ React25.createElement(
|
|
2929
2834
|
MenuRow3,
|
|
@@ -2937,86 +2842,49 @@ var UniversalSecurityPage = ({
|
|
|
2937
2842
|
toggleLoading: isPasskeyLoading,
|
|
2938
2843
|
isLast: true
|
|
2939
2844
|
}
|
|
2940
|
-
))),
|
|
2941
|
-
|
|
2942
|
-
{
|
|
2943
|
-
type: "button",
|
|
2944
|
-
onClick: () => handleCopySecret(twoFaSecret),
|
|
2945
|
-
className: "text-neutral-400 hover:text-black transition-colors outline-none shrink-0 ml-2"
|
|
2946
|
-
},
|
|
2947
|
-
/* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: Copy01Icon3, size: 16 })
|
|
2948
|
-
)))), /* @__PURE__ */ React25.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React25.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React25.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ React25.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
|
|
2949
|
-
e.preventDefault();
|
|
2950
|
-
submitEnable2FA(otp.join(""));
|
|
2951
|
-
} }, /* @__PURE__ */ React25.createElement("div", { className: "flex justify-between gap-2 pb-6", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React25.createElement(
|
|
2952
|
-
"input",
|
|
2845
|
+
))), isPasscodeModalOpen && /* @__PURE__ */ React25.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React25.createElement("div", { className: "absolute inset-0 bg-black/40", onClick: closePasscodeModal }), /* @__PURE__ */ React25.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React25.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React25.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, hasPasscode ? "Change Passcode" : "Create Security Passcode"), /* @__PURE__ */ React25.createElement("button", { onClick: closePasscodeModal, disabled: isPasscodeSubmitting, className: "text-neutral-400 hover:text-black transition-colors outline-none disabled:opacity-50" }, /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React25.createElement("div", { className: "p-6" }, isPasscodeLoading ? /* @__PURE__ */ React25.createElement("div", { className: "flex flex-col items-center justify-center py-10" }, /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: Loading03Icon10, size: 28, className: "animate-spin text-neutral-400 mb-4" })) : /* @__PURE__ */ React25.createElement("form", { onSubmit: handlePasscodeSubmit, className: "flex flex-col gap-6" }, hasPasscode && /* @__PURE__ */ React25.createElement(
|
|
2846
|
+
TextInput,
|
|
2953
2847
|
{
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
value: digit,
|
|
2962
|
-
onChange: (e) => handleOtpChange(index, e.target.value),
|
|
2963
|
-
onKeyDown: (e) => {
|
|
2964
|
-
if (e.key === "Backspace" && !otp[index] && index > 0) {
|
|
2965
|
-
inputRefs.current[index - 1]?.focus();
|
|
2966
|
-
}
|
|
2967
|
-
},
|
|
2968
|
-
className: "w-8 h-12 text-center text-lg bg-transparent border-b-2 border-neutral-200 text-black outline-none focus:border-black transition-all duration-300"
|
|
2848
|
+
type: "password",
|
|
2849
|
+
label: "Old 6-Digit Passcode",
|
|
2850
|
+
maxLength: 6,
|
|
2851
|
+
disabled: isPasscodeSubmitting,
|
|
2852
|
+
value: oldPasscode,
|
|
2853
|
+
onChange: (val) => handlePasscodeInput(val, setOldPasscode),
|
|
2854
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
2969
2855
|
}
|
|
2970
|
-
))), /* @__PURE__ */ React25.createElement(
|
|
2971
|
-
ThreeDActionButton,
|
|
2972
|
-
{
|
|
2973
|
-
type: "submit",
|
|
2974
|
-
disabled: otp.join("").length < 6,
|
|
2975
|
-
isLoading: isSubmitting,
|
|
2976
|
-
className: "w-full py-3.5"
|
|
2977
|
-
},
|
|
2978
|
-
"Verify & Enable"
|
|
2979
2856
|
), /* @__PURE__ */ React25.createElement(
|
|
2980
|
-
|
|
2981
|
-
{
|
|
2982
|
-
type: "button",
|
|
2983
|
-
onClick: () => handleCopySecret(twoFaSecret),
|
|
2984
|
-
className: "w-full flex items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-xs tracking-wide transition-colors mt-2"
|
|
2985
|
-
},
|
|
2986
|
-
/* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: Copy01Icon3, size: 16, className: "mr-2" }),
|
|
2987
|
-
"Copy Secret Key"
|
|
2988
|
-
))))), show2FADisableModal && /* @__PURE__ */ React25.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React25.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FADisableModal(false) }), /* @__PURE__ */ React25.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React25.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React25.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Disable 2FA"), /* @__PURE__ */ React25.createElement("button", { onClick: () => !isSubmitting && setShow2FADisableModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: CancelCircleIcon5, size: 18 }))), /* @__PURE__ */ React25.createElement("div", { className: "p-6" }, /* @__PURE__ */ React25.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React25.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React25.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the code from your authenticator app to disable 2FA.")), /* @__PURE__ */ React25.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
2989
|
-
e.preventDefault();
|
|
2990
|
-
submitDisable2FA(otp.join(""));
|
|
2991
|
-
} }, /* @__PURE__ */ React25.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React25.createElement(
|
|
2992
|
-
"input",
|
|
2857
|
+
TextInput,
|
|
2993
2858
|
{
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
value: digit,
|
|
3002
|
-
onChange: (e) => handleOtpChange(index, e.target.value),
|
|
3003
|
-
onKeyDown: (e) => {
|
|
3004
|
-
if (e.key === "Backspace" && !otp[index] && index > 0) {
|
|
3005
|
-
inputRefs.current[index - 1]?.focus();
|
|
3006
|
-
}
|
|
3007
|
-
},
|
|
3008
|
-
className: "w-10 h-12 text-center text-lg bg-transparent border-b-2 border-neutral-200 text-black outline-none focus:border-black transition-all duration-300"
|
|
2859
|
+
type: "password",
|
|
2860
|
+
label: hasPasscode ? "New 6-Digit Passcode" : "Enter 6-Digit Passcode",
|
|
2861
|
+
maxLength: 6,
|
|
2862
|
+
disabled: isPasscodeSubmitting,
|
|
2863
|
+
value: newPasscode,
|
|
2864
|
+
onChange: (val) => handlePasscodeInput(val, setNewPasscode),
|
|
2865
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
3009
2866
|
}
|
|
3010
|
-
)
|
|
2867
|
+
), /* @__PURE__ */ React25.createElement(
|
|
2868
|
+
TextInput,
|
|
2869
|
+
{
|
|
2870
|
+
type: "password",
|
|
2871
|
+
label: "Retype New Passcode",
|
|
2872
|
+
maxLength: 6,
|
|
2873
|
+
disabled: isPasscodeSubmitting,
|
|
2874
|
+
value: confirmPasscode,
|
|
2875
|
+
onChange: (val) => handlePasscodeInput(val, setConfirmPasscode),
|
|
2876
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
2877
|
+
}
|
|
2878
|
+
), /* @__PURE__ */ React25.createElement("div", { className: "pt-2" }, /* @__PURE__ */ React25.createElement(
|
|
3011
2879
|
ThreeDActionButton,
|
|
3012
2880
|
{
|
|
3013
2881
|
type: "submit",
|
|
3014
|
-
disabled:
|
|
3015
|
-
isLoading:
|
|
3016
|
-
className: "w-full
|
|
2882
|
+
disabled: isPasscodeSubmitting || newPasscode.length !== 6 || confirmPasscode.length !== 6 || hasPasscode && oldPasscode.length !== 6,
|
|
2883
|
+
isLoading: isPasscodeSubmitting,
|
|
2884
|
+
className: "w-full"
|
|
3017
2885
|
},
|
|
3018
|
-
"
|
|
3019
|
-
))))), showPasskeyModal && /* @__PURE__ */ React25.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React25.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ React25.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React25.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, /* @__PURE__ */ React25.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ React25.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon:
|
|
2886
|
+
hasPasscode ? "Update Passcode" : "Set Passcode"
|
|
2887
|
+
)))))), showPasskeyModal && /* @__PURE__ */ React25.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React25.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ React25.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React25.createElement("div", { className: "flex items-center justify-between p-5 shrink-0" }, /* @__PURE__ */ React25.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ React25.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React25.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ React25.createElement("h2", { className: "text-lg text-black mb-2 tracking-tight" }, "Simplify your Sign In"), /* @__PURE__ */ React25.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ React25.createElement(
|
|
3020
2888
|
ThreeDActionButton,
|
|
3021
2889
|
{
|
|
3022
2890
|
onClick: submitEnablePasskey,
|
|
@@ -3044,19 +2912,19 @@ var MenuRow3 = ({
|
|
|
3044
2912
|
onClick: disabled ? void 0 : onClick,
|
|
3045
2913
|
className: `flex items-center p-4 transition-colors ${!isLast ? "" : ""} ${disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer hover:bg-neutral-50"}`
|
|
3046
2914
|
},
|
|
3047
|
-
/* @__PURE__ */ React25.createElement("div", { className: "w-9 h-9 rounded-full
|
|
3048
|
-
/* @__PURE__ */ React25.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React25.createElement("p", { className: `text-[14px]
|
|
2915
|
+
/* @__PURE__ */ React25.createElement("div", { className: "w-9 h-9 rounded-full border border-neutral-200 flex items-center justify-center shrink-0 mr-4" }, /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon, size: 16, className: iconColor })),
|
|
2916
|
+
/* @__PURE__ */ React25.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React25.createElement("p", { className: `text-[14px] truncate ${titleColor}` }, title), /* @__PURE__ */ React25.createElement("p", { className: "text-[12px] text-neutral-500 truncate" }, subtitle)),
|
|
3049
2917
|
isToggle ? /* @__PURE__ */ React25.createElement("div", { className: `relative w-11 h-6 rounded-full transition-colors duration-300 ml-2 shrink-0 ${toggleState ? "bg-black" : "bg-neutral-100"} ${disabled ? "opacity-50" : ""}` }, /* @__PURE__ */ React25.createElement("div", { className: `absolute top-1 left-1 w-4 h-4 rounded-full bg-white shadow-sm transition-transform duration-300 flex items-center justify-center ${toggleState ? "translate-x-5" : "translate-x-0"}` }, toggleLoading && /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: Loading03Icon10, size: 10, className: "animate-spin text-black" }))) : /* @__PURE__ */ React25.createElement(HugeiconsIcon17, { icon: ArrowRight01Icon5, size: 18, className: "text-neutral-400 shrink-0 ml-2" })
|
|
3050
2918
|
);
|
|
3051
2919
|
|
|
3052
2920
|
// src/components/FeatureScroll.tsx
|
|
3053
|
-
import React26, { useRef as
|
|
2921
|
+
import React26, { useRef as useRef6, useState as useState19, useEffect as useEffect11 } from "react";
|
|
3054
2922
|
import Image4 from "next/image";
|
|
3055
2923
|
import { HugeiconsIcon as HugeiconsIcon18 } from "@hugeicons/react";
|
|
3056
2924
|
import { ArrowLeft01Icon as ArrowLeft01Icon7, ArrowRight01Icon as ArrowRight01Icon6, Loading03Icon as Loading03Icon11 } from "@hugeicons/core-free-icons";
|
|
3057
2925
|
var FeatureCard = ({ feature, bgImage }) => {
|
|
3058
|
-
const [isBgLoading, setIsBgLoading] =
|
|
3059
|
-
const [isFgLoading, setIsFgLoading] =
|
|
2926
|
+
const [isBgLoading, setIsBgLoading] = useState19(true);
|
|
2927
|
+
const [isFgLoading, setIsFgLoading] = useState19(!!feature.image);
|
|
3060
2928
|
return /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col shrink-0 w-[90vw] sm:w-150 snap-center md:snap-start group cursor-grab active:cursor-grabbing" }, /* @__PURE__ */ React26.createElement("div", { className: "relative w-full aspect-16/10 bg-neutral-100 rounded-2xl overflow-hidden mb-6 flex items-center justify-center" }, /* @__PURE__ */ React26.createElement(
|
|
3061
2929
|
Image4,
|
|
3062
2930
|
{
|
|
@@ -3094,9 +2962,9 @@ var FeatureCard = ({ feature, bgImage }) => {
|
|
|
3094
2962
|
))), /* @__PURE__ */ React26.createElement("div", { className: "flex flex-col text-left pr-4" }, /* @__PURE__ */ React26.createElement("h3", { className: " text-xl tracking-tight text-black mb-2" }, feature.title), /* @__PURE__ */ React26.createElement("p", { className: "text-[13px] leading-relaxed text-neutral-600 max-w-[90%]" }, feature.desc)));
|
|
3095
2963
|
};
|
|
3096
2964
|
var FeatureScroll = ({ tagline, headline, features }) => {
|
|
3097
|
-
const scrollRef =
|
|
3098
|
-
const [canScrollLeft, setCanScrollLeft] =
|
|
3099
|
-
const [canScrollRight, setCanScrollRight] =
|
|
2965
|
+
const scrollRef = useRef6(null);
|
|
2966
|
+
const [canScrollLeft, setCanScrollLeft] = useState19(false);
|
|
2967
|
+
const [canScrollRight, setCanScrollRight] = useState19(true);
|
|
3100
2968
|
const checkScroll = () => {
|
|
3101
2969
|
if (scrollRef.current) {
|
|
3102
2970
|
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
|
|
@@ -3185,7 +3053,7 @@ var PlatformFeatures = ({
|
|
|
3185
3053
|
};
|
|
3186
3054
|
|
|
3187
3055
|
// src/components/ManagedDocument.tsx
|
|
3188
|
-
import React28, { useState as
|
|
3056
|
+
import React28, { useState as useState20, useEffect as useEffect12, useRef as useRef7 } from "react";
|
|
3189
3057
|
var ManagedDocument = ({
|
|
3190
3058
|
tagline,
|
|
3191
3059
|
title,
|
|
@@ -3193,8 +3061,8 @@ var ManagedDocument = ({
|
|
|
3193
3061
|
contactText,
|
|
3194
3062
|
contactEmail
|
|
3195
3063
|
}) => {
|
|
3196
|
-
const [isAnimating, setIsAnimating] =
|
|
3197
|
-
const titleRef =
|
|
3064
|
+
const [isAnimating, setIsAnimating] = useState20(false);
|
|
3065
|
+
const titleRef = useRef7(null);
|
|
3198
3066
|
useEffect12(() => {
|
|
3199
3067
|
const observer = new IntersectionObserver(
|
|
3200
3068
|
([entry]) => {
|
|
@@ -3235,10 +3103,10 @@ var ManagedDocument = ({
|
|
|
3235
3103
|
};
|
|
3236
3104
|
|
|
3237
3105
|
// src/components/ManagedContactBlock.tsx
|
|
3238
|
-
import React29, { useState as
|
|
3106
|
+
import React29, { useState as useState21, useEffect as useEffect13 } from "react";
|
|
3239
3107
|
import { HugeiconsIcon as HugeiconsIcon20 } from "@hugeicons/react";
|
|
3240
3108
|
var SecureEmail = ({ user, domain, className }) => {
|
|
3241
|
-
const [isMounted, setIsMounted] =
|
|
3109
|
+
const [isMounted, setIsMounted] = useState21(false);
|
|
3242
3110
|
useEffect13(() => {
|
|
3243
3111
|
setIsMounted(true);
|
|
3244
3112
|
}, []);
|
|
@@ -3300,7 +3168,7 @@ var ManagedContactBlock = ({
|
|
|
3300
3168
|
};
|
|
3301
3169
|
|
|
3302
3170
|
// src/components/ManagedPricingBlock.tsx
|
|
3303
|
-
import React30, { useState as
|
|
3171
|
+
import React30, { useState as useState22, useEffect as useEffect14, useRef as useRef8 } from "react";
|
|
3304
3172
|
import Link7 from "next/link";
|
|
3305
3173
|
import Image5 from "next/image";
|
|
3306
3174
|
var CheckIcon = ({ className = "" }) => /* @__PURE__ */ React30.createElement("svg", { viewBox: "0 0 24 24", fill: "none", className: `w-4 h-4 shrink-0 ${className}`, xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React30.createElement("circle", { cx: "12", cy: "12", r: "10", fill: "black" }), /* @__PURE__ */ React30.createElement("path", { d: "M8 12L11 15L16 9", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
@@ -3311,9 +3179,9 @@ var ManagedPricingBlock = ({
|
|
|
3311
3179
|
plans = [],
|
|
3312
3180
|
tabs
|
|
3313
3181
|
}) => {
|
|
3314
|
-
const [isAnimating, setIsAnimating] =
|
|
3315
|
-
const [activeTabIndex, setActiveTabIndex] =
|
|
3316
|
-
const titleRef =
|
|
3182
|
+
const [isAnimating, setIsAnimating] = useState22(false);
|
|
3183
|
+
const [activeTabIndex, setActiveTabIndex] = useState22(0);
|
|
3184
|
+
const titleRef = useRef8(null);
|
|
3317
3185
|
useEffect14(() => {
|
|
3318
3186
|
const observer = new IntersectionObserver(
|
|
3319
3187
|
([entry]) => {
|
|
@@ -3529,13 +3397,13 @@ var ManagedNewsletterSplitBlock = ({
|
|
|
3529
3397
|
};
|
|
3530
3398
|
|
|
3531
3399
|
// src/components/PortfolioHero.tsx
|
|
3532
|
-
import React34, { useEffect as useEffect15, useRef as
|
|
3400
|
+
import React34, { useEffect as useEffect15, useRef as useRef9 } from "react";
|
|
3533
3401
|
import Link8 from "next/link";
|
|
3534
3402
|
import Image8 from "next/image";
|
|
3535
3403
|
import { HugeiconsIcon as HugeiconsIcon22 } from "@hugeicons/react";
|
|
3536
3404
|
import { ArrowRight01Icon as ArrowRight01Icon7 } from "@hugeicons/core-free-icons";
|
|
3537
3405
|
var useScrollAnimation = () => {
|
|
3538
|
-
const elementRef =
|
|
3406
|
+
const elementRef = useRef9(null);
|
|
3539
3407
|
useEffect15(() => {
|
|
3540
3408
|
const el = elementRef.current;
|
|
3541
3409
|
if (!el) return;
|
|
@@ -3620,7 +3488,7 @@ var PortfolioHero = ({
|
|
|
3620
3488
|
};
|
|
3621
3489
|
|
|
3622
3490
|
// src/components/GifFeatureCard.tsx
|
|
3623
|
-
import React35, { useState as
|
|
3491
|
+
import React35, { useState as useState23 } from "react";
|
|
3624
3492
|
import Image9 from "next/image";
|
|
3625
3493
|
import { HugeiconsIcon as HugeiconsIcon23 } from "@hugeicons/react";
|
|
3626
3494
|
import { Loading03Icon as Loading03Icon12 } from "@hugeicons/core-free-icons";
|
|
@@ -3631,7 +3499,7 @@ var GifFeatureCard = ({
|
|
|
3631
3499
|
alt = "Feature animation",
|
|
3632
3500
|
className = "aspect-video"
|
|
3633
3501
|
}) => {
|
|
3634
|
-
const [isLoading, setIsLoading] =
|
|
3502
|
+
const [isLoading, setIsLoading] = useState23(true);
|
|
3635
3503
|
return /* @__PURE__ */ React35.createElement("div", { className: `relative w-full bg-black overflow-hidden shadow-2xl ${className}` }, isLoading && /* @__PURE__ */ React35.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-20 bg-black" }, /* @__PURE__ */ React35.createElement(
|
|
3636
3504
|
HugeiconsIcon23,
|
|
3637
3505
|
{
|
|
@@ -3664,7 +3532,7 @@ var GifFeatureCard = ({
|
|
|
3664
3532
|
};
|
|
3665
3533
|
|
|
3666
3534
|
// src/components/MedicalFeatureStatsBlock.tsx
|
|
3667
|
-
import React36, { useState as
|
|
3535
|
+
import React36, { useState as useState24, useEffect as useEffect16, useRef as useRef10 } from "react";
|
|
3668
3536
|
import Image10 from "next/image";
|
|
3669
3537
|
var MedicalFeatureStatsBlock = ({
|
|
3670
3538
|
bottomHeadline,
|
|
@@ -3673,8 +3541,8 @@ var MedicalFeatureStatsBlock = ({
|
|
|
3673
3541
|
trustText,
|
|
3674
3542
|
stats
|
|
3675
3543
|
}) => {
|
|
3676
|
-
const [isAnimating, setIsAnimating] =
|
|
3677
|
-
const titleRef =
|
|
3544
|
+
const [isAnimating, setIsAnimating] = useState24(false);
|
|
3545
|
+
const titleRef = useRef10(null);
|
|
3678
3546
|
useEffect16(() => {
|
|
3679
3547
|
const observer = new IntersectionObserver(
|
|
3680
3548
|
([entry]) => {
|
|
@@ -3714,12 +3582,12 @@ var MedicalFeatureStatsBlock = ({
|
|
|
3714
3582
|
};
|
|
3715
3583
|
|
|
3716
3584
|
// src/components/ConsultantShowcase.tsx
|
|
3717
|
-
import React37, { useState as
|
|
3585
|
+
import React37, { useState as useState25 } from "react";
|
|
3718
3586
|
import Image11 from "next/image";
|
|
3719
3587
|
import { HugeiconsIcon as HugeiconsIcon24 } from "@hugeicons/react";
|
|
3720
3588
|
import { Loading03Icon as Loading03Icon13 } from "@hugeicons/core-free-icons";
|
|
3721
3589
|
var ImageWithLoader = ({ src, alt, className, sizes, priority = false }) => {
|
|
3722
|
-
const [isLoading, setIsLoading] =
|
|
3590
|
+
const [isLoading, setIsLoading] = useState25(true);
|
|
3723
3591
|
return /* @__PURE__ */ React37.createElement("div", { className: `absolute inset-0 bg-neutral-800 ${className}` }, isLoading && /* @__PURE__ */ React37.createElement("div", { className: "absolute inset-0 flex items-center justify-center z-20 bg-neutral-800/50 backdrop-blur-md transition-opacity duration-300" }, /* @__PURE__ */ React37.createElement(HugeiconsIcon24, { icon: Loading03Icon13, size: 24, className: "animate-spin text-white/50" })), /* @__PURE__ */ React37.createElement(
|
|
3724
3592
|
Image11,
|
|
3725
3593
|
{
|
|
@@ -3739,9 +3607,9 @@ var ImageWithLoader = ({ src, alt, className, sizes, priority = false }) => {
|
|
|
3739
3607
|
var ConsultantShowcase = ({
|
|
3740
3608
|
profiles
|
|
3741
3609
|
}) => {
|
|
3742
|
-
const [currentIndex, setCurrentIndex] =
|
|
3743
|
-
const [touchStart, setTouchStart] =
|
|
3744
|
-
const [touchEnd, setTouchEnd] =
|
|
3610
|
+
const [currentIndex, setCurrentIndex] = useState25(0);
|
|
3611
|
+
const [touchStart, setTouchStart] = useState25(null);
|
|
3612
|
+
const [touchEnd, setTouchEnd] = useState25(null);
|
|
3745
3613
|
const nextSlide = () => {
|
|
3746
3614
|
setCurrentIndex((prev) => prev === profiles.length - 1 ? 0 : prev + 1);
|
|
3747
3615
|
};
|
|
@@ -3809,7 +3677,7 @@ var ConsultantShowcase = ({
|
|
|
3809
3677
|
};
|
|
3810
3678
|
|
|
3811
3679
|
// src/components/ContentGridBlock.tsx
|
|
3812
|
-
import React38, { useState as
|
|
3680
|
+
import React38, { useState as useState26 } from "react";
|
|
3813
3681
|
import Image12 from "next/image";
|
|
3814
3682
|
import { HugeiconsIcon as HugeiconsIcon25 } from "@hugeicons/react";
|
|
3815
3683
|
import { Loading03Icon as Loading03Icon14 } from "@hugeicons/core-free-icons";
|
|
@@ -3982,9 +3850,9 @@ var UniversalVerificationPage = ({
|
|
|
3982
3850
|
};
|
|
3983
3851
|
|
|
3984
3852
|
// src/components/UniversalRewardPage.tsx
|
|
3985
|
-
import React41, { useState as
|
|
3853
|
+
import React41, { useState as useState27 } from "react";
|
|
3986
3854
|
import axios from "axios";
|
|
3987
|
-
import
|
|
3855
|
+
import toast9 from "react-hot-toast";
|
|
3988
3856
|
import Confetti from "react-confetti";
|
|
3989
3857
|
import { useWindowSize } from "react-use";
|
|
3990
3858
|
import { HugeiconsIcon as HugeiconsIcon27 } from "@hugeicons/react";
|
|
@@ -3999,7 +3867,7 @@ var formatWeb3Name = (name) => {
|
|
|
3999
3867
|
};
|
|
4000
3868
|
var PageSpinner4 = () => /* @__PURE__ */ React41.createElement("div", { className: "flex justify-center items-center py-12 w-full" }, /* @__PURE__ */ React41.createElement(HugeiconsIcon27, { icon: Loading03Icon16, size: 32, className: "animate-spin mb-4 text-black" }));
|
|
4001
3869
|
var AvatarLogo = ({ src, alt, name, sizeClass = "w-12 h-12" }) => {
|
|
4002
|
-
const [isLoaded, setIsLoaded] =
|
|
3870
|
+
const [isLoaded, setIsLoaded] = useState27(false);
|
|
4003
3871
|
const fallbackUrl = `/api/avatar/?name=${encodeURIComponent(name || " ")}&background=ffffff&color=000000&size=200&font-size=0.33`;
|
|
4004
3872
|
const finalSrc = src || fallbackUrl;
|
|
4005
3873
|
return /* @__PURE__ */ React41.createElement("div", { className: `relative shrink-0 rounded-full bg-neutral-100 flex items-center justify-center overflow-hidden border-[3px] border-white ${sizeClass}` }, !isLoaded && /* @__PURE__ */ React41.createElement(HugeiconsIcon27, { icon: Loading03Icon16, size: 16, className: "animate-spin text-neutral-400 absolute" }), /* @__PURE__ */ React41.createElement("img", { src: finalSrc, alt, onLoad: () => setIsLoaded(true), className: `w-full h-full object-cover transition-opacity duration-300 ${isLoaded ? "opacity-100" : "opacity-0"}` }));
|
|
@@ -4017,11 +3885,11 @@ var UniversalRewardPage = ({
|
|
|
4017
3885
|
const onBackHandler = onBack ?? (() => {
|
|
4018
3886
|
if (typeof window !== "undefined") window.history.back();
|
|
4019
3887
|
});
|
|
4020
|
-
const [activeTabIndex, setActiveTabIndex] =
|
|
3888
|
+
const [activeTabIndex, setActiveTabIndex] = useState27(1);
|
|
4021
3889
|
const tabs = [{ label: "Today" }, { label: "Week" }, { label: "Month" }];
|
|
4022
|
-
const [selectedReward, setSelectedReward] =
|
|
4023
|
-
const [isClaiming, setIsClaiming] =
|
|
4024
|
-
const [showConfetti, setShowConfetti] =
|
|
3890
|
+
const [selectedReward, setSelectedReward] = useState27(null);
|
|
3891
|
+
const [isClaiming, setIsClaiming] = useState27(false);
|
|
3892
|
+
const [showConfetti, setShowConfetti] = useState27(false);
|
|
4025
3893
|
const getActiveLeaderboard = () => {
|
|
4026
3894
|
if (activeTabIndex === 0) return leaderboardToday || [];
|
|
4027
3895
|
if (activeTabIndex === 1) return leaderboardWeek || [];
|
|
@@ -4039,7 +3907,7 @@ var UniversalRewardPage = ({
|
|
|
4039
3907
|
const res = await axios.post(selectedReward.endpoint, selectedReward.config);
|
|
4040
3908
|
if (res.data.success) {
|
|
4041
3909
|
setShowConfetti(true);
|
|
4042
|
-
|
|
3910
|
+
toast9.success(res.data.message || "Reward claimed successfully!");
|
|
4043
3911
|
setSelectedReward(null);
|
|
4044
3912
|
onRefresh();
|
|
4045
3913
|
setTimeout(() => {
|
|
@@ -4047,7 +3915,7 @@ var UniversalRewardPage = ({
|
|
|
4047
3915
|
}, 6e3);
|
|
4048
3916
|
}
|
|
4049
3917
|
} catch (error) {
|
|
4050
|
-
|
|
3918
|
+
toast9.error(error.response?.data?.error || "Failed to claim reward. Please try again.");
|
|
4051
3919
|
} finally {
|
|
4052
3920
|
setIsClaiming(false);
|
|
4053
3921
|
}
|
|
@@ -4096,8 +3964,8 @@ var UniversalRewardPage = ({
|
|
|
4096
3964
|
};
|
|
4097
3965
|
|
|
4098
3966
|
// src/components/UniversalReferralPage.tsx
|
|
4099
|
-
import React42, { useState as
|
|
4100
|
-
import
|
|
3967
|
+
import React42, { useState as useState28 } from "react";
|
|
3968
|
+
import toast10 from "react-hot-toast";
|
|
4101
3969
|
import { HugeiconsIcon as HugeiconsIcon28 } from "@hugeicons/react";
|
|
4102
3970
|
import {
|
|
4103
3971
|
ArrowLeft01Icon as ArrowLeft01Icon10,
|
|
@@ -4116,6 +3984,8 @@ var formatDate = (dateInput) => {
|
|
|
4116
3984
|
var UniversalReferralPage = ({
|
|
4117
3985
|
referralCode,
|
|
4118
3986
|
totalCount,
|
|
3987
|
+
referralCoins = 0,
|
|
3988
|
+
// Default to 0
|
|
4119
3989
|
referrals,
|
|
4120
3990
|
isLoading,
|
|
4121
3991
|
currentPage,
|
|
@@ -4130,18 +4000,18 @@ var UniversalReferralPage = ({
|
|
|
4130
4000
|
if (!referralCode) return;
|
|
4131
4001
|
try {
|
|
4132
4002
|
await navigator.clipboard.writeText(referralCode);
|
|
4133
|
-
|
|
4003
|
+
toast10.success("Referral code copied!");
|
|
4134
4004
|
} catch {
|
|
4135
|
-
|
|
4005
|
+
toast10.error("Failed to copy code.");
|
|
4136
4006
|
}
|
|
4137
4007
|
};
|
|
4138
4008
|
const AvatarLogo2 = ({ src, alt, name, sizeClass = "w-10 h-10" }) => {
|
|
4139
|
-
const [isLoaded, setIsLoaded] =
|
|
4009
|
+
const [isLoaded, setIsLoaded] = useState28(false);
|
|
4140
4010
|
const fallbackUrl = `/api/avatar/?name=${encodeURIComponent(name || " ")}&background=e0e0e0&color=000000&size=200&font-size=0.33`;
|
|
4141
4011
|
const finalSrc = src || fallbackUrl;
|
|
4142
4012
|
return /* @__PURE__ */ React42.createElement("div", { className: `relative shrink-0 rounded-full bg-neutral-100 flex items-center justify-center overflow-hidden border-2 border-white ${sizeClass}` }, !isLoaded && /* @__PURE__ */ React42.createElement(HugeiconsIcon28, { icon: Loading03Icon17, size: 16, className: "animate-spin text-neutral-400 absolute" }), /* @__PURE__ */ React42.createElement("img", { src: finalSrc, alt, onLoad: () => setIsLoaded(true), className: `w-full h-full object-cover transition-opacity duration-300 ${isLoaded ? "opacity-100" : "opacity-0"}` }));
|
|
4143
4013
|
};
|
|
4144
|
-
return /* @__PURE__ */ React42.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ React42.createElement(ManagedToaster, null), /* @__PURE__ */ React42.createElement("div", { className: "mb-6 flex w-full items-center px-1" }, /* @__PURE__ */ React42.createElement("button", { onClick: onBackHandler, className: "flex items-center gap-2 text-neutral-500 hover:text-black transition-colors text-[13px] outline-none" }, /* @__PURE__ */ React42.createElement(HugeiconsIcon28, { icon: ArrowLeft01Icon10, size: 16 }), " Back")), /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-3xl bg-white w-full" }, /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col gap-4 mb-2" }, /* @__PURE__ */ React42.createElement("div", null, /* @__PURE__ */ React42.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, "Your Referrals"), /* @__PURE__ */ React42.createElement("p", { className: "text-xs text-neutral-500" }, "Invite friends and earn rewards when they verify and activate cards.")), /* @__PURE__ */ React42.createElement("div", { className: "border border-neutral-200 rounded-xl p-4 flex items-center justify-between mt-2" }, /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React42.createElement("span", { className: "text-[11px] tracking-widest text-neutral-400 " }, "Invitation Code"), isLoading && !referralCode ? /* @__PURE__ */ React42.createElement("div", { className: "h-6 w-24 bg-neutral-50 animate-pulse rounded mt-1" }) : /* @__PURE__ */ React42.createElement("span", { className: "text-lg
|
|
4014
|
+
return /* @__PURE__ */ React42.createElement("div", { className: "w-full max-w-3xl mx-auto flex flex-col animate-in fade-in duration-300" }, /* @__PURE__ */ React42.createElement(ManagedToaster, null), /* @__PURE__ */ React42.createElement("div", { className: "mb-6 flex w-full items-center px-1" }, /* @__PURE__ */ React42.createElement("button", { onClick: onBackHandler, className: "flex items-center gap-2 text-neutral-500 hover:text-black transition-colors text-[13px] outline-none" }, /* @__PURE__ */ React42.createElement(HugeiconsIcon28, { icon: ArrowLeft01Icon10, size: 16 }), " Back")), /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col gap-8 p-6 rounded-3xl bg-white w-full" }, /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col gap-4 mb-2" }, /* @__PURE__ */ React42.createElement("div", null, /* @__PURE__ */ React42.createElement("h1", { className: "text-black text-xl mb-1 tracking-tight" }, "Your Referrals"), /* @__PURE__ */ React42.createElement("p", { className: "text-xs text-neutral-500" }, "Invite friends and earn rewards when they verify and activate cards.")), /* @__PURE__ */ React42.createElement("div", { className: "border border-neutral-200 rounded-xl p-4 flex items-center justify-between mt-2" }, /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React42.createElement("span", { className: "text-[11px] tracking-widest text-neutral-400 " }, "Invitation Code"), isLoading && !referralCode ? /* @__PURE__ */ React42.createElement("div", { className: "h-6 w-24 bg-neutral-50 animate-pulse rounded mt-1" }) : /* @__PURE__ */ React42.createElement("span", { className: "text-lg text-black tracking-widest" }, referralCode)), /* @__PURE__ */ React42.createElement(
|
|
4145
4015
|
"button",
|
|
4146
4016
|
{
|
|
4147
4017
|
onClick: handleCopyCode,
|
|
@@ -4149,7 +4019,7 @@ var UniversalReferralPage = ({
|
|
|
4149
4019
|
className: "w-10 h-10 rounded-full bg-white flex items-center justify-center text-neutral-500 hover:text-black transition-colors outline-none disabled:opacity-50"
|
|
4150
4020
|
},
|
|
4151
4021
|
/* @__PURE__ */ React42.createElement(HugeiconsIcon28, { icon: Copy01Icon4, size: 18 })
|
|
4152
|
-
)), /* @__PURE__ */ React42.createElement("div", { className: "text-[13px]
|
|
4022
|
+
)), /* @__PURE__ */ React42.createElement("div", { className: "flex items-center justify-between text-[13px] text-black px-1 mt-2" }, /* @__PURE__ */ React42.createElement("span", null, "Total Invited: ", isLoading && !totalCount ? "-" : totalCount), /* @__PURE__ */ React42.createElement("span", null, "Points: ", isLoading && !referralCoins && referralCoins !== 0 ? "-" : referralCoins))), /* @__PURE__ */ React42.createElement("div", { className: "w-full overflow-hidden" }, isLoading ? /* @__PURE__ */ React42.createElement(PageSpinner5, null) : /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ React42.createElement("div", null, referrals.length === 0 ? /* @__PURE__ */ React42.createElement("div", { className: "flex flex-col items-center justify-center py-12 opacity-50" }, /* @__PURE__ */ React42.createElement("p", { className: "text-xs text-neutral-500 text-center" }, "You haven't referred anyone yet.")) : referrals.map((ref, idx) => /* @__PURE__ */ React42.createElement(
|
|
4153
4023
|
"div",
|
|
4154
4024
|
{
|
|
4155
4025
|
key: `${ref.profile.username}-${idx}`,
|
|
@@ -4162,8 +4032,8 @@ var UniversalReferralPage = ({
|
|
|
4162
4032
|
alt: ref.profile.username,
|
|
4163
4033
|
name: formatWeb3Name2(ref.profile.web3Name)
|
|
4164
4034
|
}
|
|
4165
|
-
), /* @__PURE__ */ React42.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5 pr-4" }, /* @__PURE__ */ React42.createElement("p", { className: "text-[14px]
|
|
4166
|
-
/* @__PURE__ */ React42.createElement("div", { className: "shrink-0 flex flex-col items-end gap-1 text-right" }, /* @__PURE__ */ React42.createElement("span", { className: "text-[11px] text-neutral-400" }, "Joined"), /* @__PURE__ */ React42.createElement("span", { className: "text-[12px]
|
|
4035
|
+
), /* @__PURE__ */ React42.createElement("div", { className: "min-w-0 flex-1 flex flex-col gap-0.5 pr-4" }, /* @__PURE__ */ React42.createElement("p", { className: "text-[14px] text-black truncate" }, formatWeb3Name2(ref.profile.web3Name)), /* @__PURE__ */ React42.createElement("p", { className: "text-[12px] text-neutral-500 truncate" }, "@", ref.profile.username))),
|
|
4036
|
+
/* @__PURE__ */ React42.createElement("div", { className: "shrink-0 flex flex-col items-end gap-1 text-right" }, /* @__PURE__ */ React42.createElement("span", { className: "text-[11px] text-neutral-400" }, "Joined"), /* @__PURE__ */ React42.createElement("span", { className: "text-[12px] text-black" }, formatDate(ref.joinedAt)))
|
|
4167
4037
|
))), /* @__PURE__ */ React42.createElement("div", { className: "flex items-center justify-between pt-6 mt-2 " }, /* @__PURE__ */ React42.createElement("span", { className: "text-[11px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages === 0 ? 1 : totalPages), /* @__PURE__ */ React42.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React42.createElement(
|
|
4168
4038
|
"button",
|
|
4169
4039
|
{
|
|
@@ -4184,13 +4054,13 @@ var UniversalReferralPage = ({
|
|
|
4184
4054
|
};
|
|
4185
4055
|
|
|
4186
4056
|
// src/components/UniversalCardActionPage.tsx
|
|
4187
|
-
import React43, { useState as
|
|
4057
|
+
import React43, { useState as useState29 } from "react";
|
|
4188
4058
|
import Confetti2 from "react-confetti";
|
|
4189
4059
|
import { useWindowSize as useWindowSize2 } from "react-use";
|
|
4190
4060
|
import { HugeiconsIcon as HugeiconsIcon29 } from "@hugeicons/react";
|
|
4191
4061
|
import {
|
|
4192
4062
|
ArrowLeft01Icon as ArrowLeft01Icon11,
|
|
4193
|
-
CancelCircleIcon as
|
|
4063
|
+
CancelCircleIcon as CancelCircleIcon7,
|
|
4194
4064
|
Loading03Icon as Loading03Icon18
|
|
4195
4065
|
} from "@hugeicons/core-free-icons";
|
|
4196
4066
|
var CheckIcon2 = ({ className = "" }) => /* @__PURE__ */ React43.createElement("svg", { viewBox: "0 0 24 24", fill: "none", className: `w-4 h-4 shrink-0 ${className}`, xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React43.createElement("circle", { cx: "12", cy: "12", r: "10", fill: "black" }), /* @__PURE__ */ React43.createElement("path", { d: "M8 12L11 15L16 9", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
@@ -4235,10 +4105,10 @@ var UniversalCardActionPage = ({
|
|
|
4235
4105
|
if (typeof window !== "undefined") window.history.back();
|
|
4236
4106
|
});
|
|
4237
4107
|
const { width, height } = useWindowSize2();
|
|
4238
|
-
const [selectedTier, setSelectedTier] =
|
|
4239
|
-
const [intendedAction, setIntendedAction] =
|
|
4240
|
-
const [isProcessing, setIsProcessing] =
|
|
4241
|
-
const [showConfetti, setShowConfetti] =
|
|
4108
|
+
const [selectedTier, setSelectedTier] = useState29(null);
|
|
4109
|
+
const [intendedAction, setIntendedAction] = useState29(null);
|
|
4110
|
+
const [isProcessing, setIsProcessing] = useState29(false);
|
|
4111
|
+
const [showConfetti, setShowConfetti] = useState29(false);
|
|
4242
4112
|
const availableTiers = tiers.filter((t) => t.isAvailable || t.acceptPreorder || t.acceptWaitlist);
|
|
4243
4113
|
const handleTierClick = (tier, explicitAction) => {
|
|
4244
4114
|
setSelectedTier(tier);
|
|
@@ -4345,7 +4215,7 @@ var UniversalCardActionPage = ({
|
|
|
4345
4215
|
onClick: () => setSelectedTier(null),
|
|
4346
4216
|
className: "text-neutral-400 hover:text-black transition-colors outline-none disabled:opacity-50"
|
|
4347
4217
|
},
|
|
4348
|
-
/* @__PURE__ */ React43.createElement(HugeiconsIcon29, { icon:
|
|
4218
|
+
/* @__PURE__ */ React43.createElement(HugeiconsIcon29, { icon: CancelCircleIcon7, size: 18 })
|
|
4349
4219
|
)), /* @__PURE__ */ React43.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 relative z-10" }, /* @__PURE__ */ React43.createElement("div", { className: "flex flex-col items-center justify-center mb-6" }, /* @__PURE__ */ React43.createElement("p", { className: "text-2xl text-black mb-1" }, selectedTier.priceUSD === 0 ? "Free" : `$${selectedTier.priceUSD.toFixed(2)}`), /* @__PURE__ */ React43.createElement("span", { className: `text-[10px] tracking-widest px-4 py-1.5 rounded-full bg-neutral-100 text-black mt-1` }, formatTierName(selectedTier.tierName), " ", formatTierName(cardType))), /* @__PURE__ */ React43.createElement("div", { className: "grid grid-cols-1 gap-y-6 mb-8 mt-4" }, /* @__PURE__ */ React43.createElement("div", null, /* @__PURE__ */ React43.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1" }, "Action"), /* @__PURE__ */ React43.createElement("span", { className: "text-[13px] text-black " }, intendedAction === "upgrade" ? `Upgrade to ${formatTierName(selectedTier.tierName)}` : `Pre-order Card`)), intendedAction === "pre_order" && selectedTier.priceUSD > 0 && /* @__PURE__ */ React43.createElement("div", null, /* @__PURE__ */ React43.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-1" }, "Payment Notice"), /* @__PURE__ */ React43.createElement("span", { className: "text-[12px] text-neutral-600 leading-relaxed block" }, "By confirming, $", selectedTier.priceUSD.toFixed(2), " will be securely deducted from your USD asset balance to guarantee your order."))), /* @__PURE__ */ React43.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React43.createElement(
|
|
4350
4220
|
ThreeDActionButton,
|
|
4351
4221
|
{
|
|
@@ -4378,9 +4248,9 @@ var UniversalCardActionPage = ({
|
|
|
4378
4248
|
};
|
|
4379
4249
|
|
|
4380
4250
|
// src/components/PinDialerBottomSheet.tsx
|
|
4381
|
-
import React44, { useState as
|
|
4251
|
+
import React44, { useState as useState30, useEffect as useEffect17 } from "react";
|
|
4382
4252
|
import { HugeiconsIcon as HugeiconsIcon30 } from "@hugeicons/react";
|
|
4383
|
-
import { CancelCircleIcon as
|
|
4253
|
+
import { CancelCircleIcon as CancelCircleIcon8 } from "@hugeicons/core-free-icons";
|
|
4384
4254
|
var PinDialerBottomSheet = ({
|
|
4385
4255
|
isOpen,
|
|
4386
4256
|
title = "Action Required",
|
|
@@ -4388,7 +4258,7 @@ var PinDialerBottomSheet = ({
|
|
|
4388
4258
|
onClose,
|
|
4389
4259
|
onComplete
|
|
4390
4260
|
}) => {
|
|
4391
|
-
const [pin, setPin] =
|
|
4261
|
+
const [pin, setPin] = useState30("");
|
|
4392
4262
|
useEffect17(() => {
|
|
4393
4263
|
setPin("");
|
|
4394
4264
|
}, [isOpen]);
|
|
@@ -4415,7 +4285,7 @@ var PinDialerBottomSheet = ({
|
|
|
4415
4285
|
disabled: isVerifying,
|
|
4416
4286
|
className: "text-neutral-400 hover:text-black transition-colors outline-none disabled:opacity-50"
|
|
4417
4287
|
},
|
|
4418
|
-
/* @__PURE__ */ React44.createElement(HugeiconsIcon30, { icon:
|
|
4288
|
+
/* @__PURE__ */ React44.createElement(HugeiconsIcon30, { icon: CancelCircleIcon8, size: 20 })
|
|
4419
4289
|
)), /* @__PURE__ */ React44.createElement("div", { className: "flex flex-col px-6 pb-6 pt-2 relative" }, /* @__PURE__ */ React44.createElement("form", { onSubmit: handleSubmit, className: "flex flex-col gap-6" }, /* @__PURE__ */ React44.createElement(
|
|
4420
4290
|
TextInput,
|
|
4421
4291
|
{
|