@retinalabsllc/zairusjs 16.0.90 → 16.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.js +40 -4
- package/dist/index.mjs +40 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -488,6 +488,33 @@ function AuthFormInner({
|
|
|
488
488
|
setIsSubmitting(false);
|
|
489
489
|
}
|
|
490
490
|
};
|
|
491
|
+
const handleResendCode = async () => {
|
|
492
|
+
if (countdown > 0 || isSubmitting) return;
|
|
493
|
+
setIsSubmitting(true);
|
|
494
|
+
try {
|
|
495
|
+
let recaptchaToken = void 0;
|
|
496
|
+
if (useRecaptcha && captchaContext?.executeRecaptcha) {
|
|
497
|
+
recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
|
|
498
|
+
}
|
|
499
|
+
const res = await onAuthRequest({
|
|
500
|
+
email: emailId,
|
|
501
|
+
mode: "LOGIN",
|
|
502
|
+
recaptchaToken
|
|
503
|
+
});
|
|
504
|
+
if (res.success) {
|
|
505
|
+
import_react_hot_toast.default.success("Verification code resent");
|
|
506
|
+
setOtp(["", "", "", "", "", ""]);
|
|
507
|
+
inputRefs.current[0]?.focus();
|
|
508
|
+
setCountdown(60);
|
|
509
|
+
} else {
|
|
510
|
+
import_react_hot_toast.default.error(res.error || "Failed to resend code.");
|
|
511
|
+
}
|
|
512
|
+
} catch {
|
|
513
|
+
import_react_hot_toast.default.error("Service unavailable. Try again later.");
|
|
514
|
+
} finally {
|
|
515
|
+
setIsSubmitting(false);
|
|
516
|
+
}
|
|
517
|
+
};
|
|
491
518
|
const verifyOtpCode = async (codeToVerify) => {
|
|
492
519
|
if (codeToVerify.length !== 6 || isSubmitting) return;
|
|
493
520
|
setIsSubmitting(true);
|
|
@@ -549,12 +576,12 @@ function AuthFormInner({
|
|
|
549
576
|
if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
550
577
|
else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
|
|
551
578
|
else handleAuthRequestSubmit();
|
|
552
|
-
} }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex bg-neutral-100 p-1 rounded-
|
|
579
|
+
} }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex bg-neutral-100 p-1 rounded-full" }, /* @__PURE__ */ import_react6.default.createElement(
|
|
553
580
|
"button",
|
|
554
581
|
{
|
|
555
582
|
type: "button",
|
|
556
583
|
onClick: () => setAccountType("INDIVIDUAL"),
|
|
557
|
-
className: `flex-1 py-2 text-xs rounded-
|
|
584
|
+
className: `flex-1 py-2 text-xs rounded-full transition-colors outline-none ${accountType === "INDIVIDUAL" ? "bg-white text-black" : "text-neutral-500 hover:text-black"}`
|
|
558
585
|
},
|
|
559
586
|
"Personal"
|
|
560
587
|
), /* @__PURE__ */ import_react6.default.createElement(
|
|
@@ -562,7 +589,7 @@ function AuthFormInner({
|
|
|
562
589
|
{
|
|
563
590
|
type: "button",
|
|
564
591
|
onClick: () => setAccountType("ORGANIZATION"),
|
|
565
|
-
className: `flex-1 py-2 text-xs rounded-
|
|
592
|
+
className: `flex-1 py-2 text-xs rounded-full transition-colors outline-none ${accountType === "ORGANIZATION" ? "bg-white text-black" : "text-neutral-500 hover:text-black"}`
|
|
566
593
|
},
|
|
567
594
|
"Organization"
|
|
568
595
|
)), accountType === "ORGANIZATION" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5 relative animate-in fade-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ import_react6.default.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" })), accountType === "INDIVIDUAL" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "py-4 text-center animate-in fade-in duration-200" }, /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "You are creating a personal account. You can join organizations later."))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react6.default.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ import_react6.default.createElement("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: 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: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ import_react6.default.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__ */ import_react6.default.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ import_react6.default.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ import_react6.default.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ import_react6.default.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ import_react6.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react6.default.createElement("p", { className: "text-[13px] text-neutral-500" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ import_react6.default.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
@@ -585,7 +612,16 @@ function AuthFormInner({
|
|
|
585
612
|
},
|
|
586
613
|
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"
|
|
587
614
|
}
|
|
588
|
-
))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")
|
|
615
|
+
))), /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex flex-col gap-4" }, /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code"), !userHas2FA && /* @__PURE__ */ import_react6.default.createElement(
|
|
616
|
+
"button",
|
|
617
|
+
{
|
|
618
|
+
type: "button",
|
|
619
|
+
onClick: handleResendCode,
|
|
620
|
+
disabled: countdown > 0 || isSubmitting,
|
|
621
|
+
className: "text-[12px] text-neutral-500 hover:text-black transition-colors outline-none disabled:opacity-50"
|
|
622
|
+
},
|
|
623
|
+
countdown > 0 ? `Resend code in ${countdown}s` : "Resend verification code"
|
|
624
|
+
))), userHasPasskey && /* @__PURE__ */ import_react6.default.createElement("div", { className: "pt-6 " }, /* @__PURE__ */ import_react6.default.createElement(
|
|
589
625
|
"button",
|
|
590
626
|
{
|
|
591
627
|
onClick: triggerPasskeyLogin,
|
package/dist/index.mjs
CHANGED
|
@@ -405,6 +405,33 @@ function AuthFormInner({
|
|
|
405
405
|
setIsSubmitting(false);
|
|
406
406
|
}
|
|
407
407
|
};
|
|
408
|
+
const handleResendCode = async () => {
|
|
409
|
+
if (countdown > 0 || isSubmitting) return;
|
|
410
|
+
setIsSubmitting(true);
|
|
411
|
+
try {
|
|
412
|
+
let recaptchaToken = void 0;
|
|
413
|
+
if (useRecaptcha && captchaContext?.executeRecaptcha) {
|
|
414
|
+
recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
|
|
415
|
+
}
|
|
416
|
+
const res = await onAuthRequest({
|
|
417
|
+
email: emailId,
|
|
418
|
+
mode: "LOGIN",
|
|
419
|
+
recaptchaToken
|
|
420
|
+
});
|
|
421
|
+
if (res.success) {
|
|
422
|
+
toast.success("Verification code resent");
|
|
423
|
+
setOtp(["", "", "", "", "", ""]);
|
|
424
|
+
inputRefs.current[0]?.focus();
|
|
425
|
+
setCountdown(60);
|
|
426
|
+
} else {
|
|
427
|
+
toast.error(res.error || "Failed to resend code.");
|
|
428
|
+
}
|
|
429
|
+
} catch {
|
|
430
|
+
toast.error("Service unavailable. Try again later.");
|
|
431
|
+
} finally {
|
|
432
|
+
setIsSubmitting(false);
|
|
433
|
+
}
|
|
434
|
+
};
|
|
408
435
|
const verifyOtpCode = async (codeToVerify) => {
|
|
409
436
|
if (codeToVerify.length !== 6 || isSubmitting) return;
|
|
410
437
|
setIsSubmitting(true);
|
|
@@ -466,12 +493,12 @@ function AuthFormInner({
|
|
|
466
493
|
if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
|
|
467
494
|
else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
|
|
468
495
|
else handleAuthRequestSubmit();
|
|
469
|
-
} }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ React5.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__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ React5.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__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "flex bg-neutral-100 p-1 rounded-
|
|
496
|
+
} }, mode === "SIGNUP" && signupStep === "NAME" && requireNames && /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "First Name"), /* @__PURE__ */ React5.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__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Last Name"), /* @__PURE__ */ React5.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__ */ React5.createElement("div", { className: "flex flex-col gap-6" }, /* @__PURE__ */ React5.createElement("div", { className: "flex bg-neutral-100 p-1 rounded-full" }, /* @__PURE__ */ React5.createElement(
|
|
470
497
|
"button",
|
|
471
498
|
{
|
|
472
499
|
type: "button",
|
|
473
500
|
onClick: () => setAccountType("INDIVIDUAL"),
|
|
474
|
-
className: `flex-1 py-2 text-xs rounded-
|
|
501
|
+
className: `flex-1 py-2 text-xs rounded-full transition-colors outline-none ${accountType === "INDIVIDUAL" ? "bg-white text-black" : "text-neutral-500 hover:text-black"}`
|
|
475
502
|
},
|
|
476
503
|
"Personal"
|
|
477
504
|
), /* @__PURE__ */ React5.createElement(
|
|
@@ -479,7 +506,7 @@ function AuthFormInner({
|
|
|
479
506
|
{
|
|
480
507
|
type: "button",
|
|
481
508
|
onClick: () => setAccountType("ORGANIZATION"),
|
|
482
|
-
className: `flex-1 py-2 text-xs rounded-
|
|
509
|
+
className: `flex-1 py-2 text-xs rounded-full transition-colors outline-none ${accountType === "ORGANIZATION" ? "bg-white text-black" : "text-neutral-500 hover:text-black"}`
|
|
483
510
|
},
|
|
484
511
|
"Organization"
|
|
485
512
|
)), accountType === "ORGANIZATION" && /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5 relative animate-in fade-in zoom-in-95 duration-200" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Organization Name"), /* @__PURE__ */ React5.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" })), accountType === "INDIVIDUAL" && /* @__PURE__ */ React5.createElement("div", { className: "py-4 text-center animate-in fade-in duration-200" }, /* @__PURE__ */ React5.createElement("p", { className: "text-[13px] text-neutral-500" }, "You are creating a personal account. You can join organizations later."))), (mode === "LOGIN" || mode === "SIGNUP" && signupStep === "EMAIL_ID") && /* @__PURE__ */ React5.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React5.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React5.createElement("label", { className: "text-[11px] text-neutral-400 tracking-[0.2em] block " }, "Email ID"), /* @__PURE__ */ React5.createElement("input", { type: "email", value: emailId, onChange: (e) => setEmailId(cleanEmailId(e.target.value)), required: true, autoFocus: 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: "name@company.com" })), mode === "SIGNUP" && /* @__PURE__ */ React5.createElement("div", { className: "flex items-start gap-3 mt-4" }, /* @__PURE__ */ React5.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__ */ React5.createElement("label", { htmlFor: "zairus-terms", className: "text-[11px] text-neutral-500 cursor-pointer leading-snug" }, "I agree to ", companyName, "'s ", /* @__PURE__ */ React5.createElement("a", { href: termsUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Terms of Service"), " and ", /* @__PURE__ */ React5.createElement("a", { href: privacyUrl, target: "_blank", rel: "noreferrer", className: "text-black underline " }, "Privacy Policy"), "."))), /* @__PURE__ */ React5.createElement(ThreeDActionButton, { type: "submit", disabled: isContinueDisabled(), isLoading: isSubmitting, className: "w-full mt-10" }, "Continue"))), step === "OTP" && /* @__PURE__ */ React5.createElement("div", { className: "animate-in fade-in duration-300" }, /* @__PURE__ */ React5.createElement("div", { className: "text-center mb-10 mt-2" }, /* @__PURE__ */ React5.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React5.createElement("p", { className: "text-[13px] text-neutral-500" }, userHas2FA ? "Enter the code from your authenticator app." : `Enter the code sent to ${emailId}`)), /* @__PURE__ */ React5.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
@@ -502,7 +529,16 @@ function AuthFormInner({
|
|
|
502
529
|
},
|
|
503
530
|
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"
|
|
504
531
|
}
|
|
505
|
-
))), /* @__PURE__ */ React5.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")
|
|
532
|
+
))), /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col gap-4" }, /* @__PURE__ */ React5.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code"), !userHas2FA && /* @__PURE__ */ React5.createElement(
|
|
533
|
+
"button",
|
|
534
|
+
{
|
|
535
|
+
type: "button",
|
|
536
|
+
onClick: handleResendCode,
|
|
537
|
+
disabled: countdown > 0 || isSubmitting,
|
|
538
|
+
className: "text-[12px] text-neutral-500 hover:text-black transition-colors outline-none disabled:opacity-50"
|
|
539
|
+
},
|
|
540
|
+
countdown > 0 ? `Resend code in ${countdown}s` : "Resend verification code"
|
|
541
|
+
))), userHasPasskey && /* @__PURE__ */ React5.createElement("div", { className: "pt-6 " }, /* @__PURE__ */ React5.createElement(
|
|
506
542
|
"button",
|
|
507
543
|
{
|
|
508
544
|
onClick: triggerPasskeyLogin,
|