@retinalabsllc/zairusjs 16.0.80 → 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 CHANGED
@@ -411,6 +411,7 @@ function AuthFormInner({
411
411
  const [firstName, setFirstName] = (0, import_react6.useState)("");
412
412
  const [lastName, setLastName] = (0, import_react6.useState)("");
413
413
  const [orgName, setOrgName] = (0, import_react6.useState)("");
414
+ const [accountType, setAccountType] = (0, import_react6.useState)("ORGANIZATION");
414
415
  const [agreedToTerms, setAgreedToTerms] = (0, import_react6.useState)(false);
415
416
  const [userHas2FA, setUserHas2FA] = (0, import_react6.useState)(false);
416
417
  const [userHasPasskey, setUserHasPasskey] = (0, import_react6.useState)(false);
@@ -462,13 +463,12 @@ function AuthFormInner({
462
463
  if (useRecaptcha && captchaContext?.executeRecaptcha) {
463
464
  recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
464
465
  }
465
- const hasOrg = mode === "SIGNUP" && requireOrganization && orgName.trim().length > 0;
466
466
  const res = await onAuthRequest({
467
467
  email: emailId,
468
468
  firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
469
469
  lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
470
- organizationName: hasOrg ? orgName.trim() : void 0,
471
- accountType: hasOrg ? "ORGANIZATION" : "INDIVIDUAL",
470
+ organizationName: mode === "SIGNUP" && accountType === "ORGANIZATION" ? orgName.trim() : void 0,
471
+ accountType: mode === "SIGNUP" ? accountType : void 0,
472
472
  mode,
473
473
  recaptchaToken
474
474
  });
@@ -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);
@@ -536,7 +563,7 @@ function AuthFormInner({
536
563
  if (mode === "LOGIN") return emailId.length < 3;
537
564
  if (mode === "SIGNUP") {
538
565
  if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
539
- if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
566
+ if (signupStep === "ORGANIZATION") return accountType === "ORGANIZATION" ? orgName.trim().length < 3 : false;
540
567
  if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
541
568
  }
542
569
  return false;
@@ -549,7 +576,23 @@ 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: "space-y-1.5 relative" }, /* @__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" }))), (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) => {
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(
580
+ "button",
581
+ {
582
+ type: "button",
583
+ onClick: () => setAccountType("INDIVIDUAL"),
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"}`
585
+ },
586
+ "Personal"
587
+ ), /* @__PURE__ */ import_react6.default.createElement(
588
+ "button",
589
+ {
590
+ type: "button",
591
+ onClick: () => setAccountType("ORGANIZATION"),
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"}`
593
+ },
594
+ "Organization"
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) => {
553
596
  e.preventDefault();
554
597
  verifyOtpCode(otp.join(""));
555
598
  } }, /* @__PURE__ */ import_react6.default.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ import_react6.default.createElement(
@@ -569,14 +612,23 @@ function AuthFormInner({
569
612
  },
570
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"
571
614
  }
572
- ))), /* @__PURE__ */ import_react6.default.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")), userHasPasskey && /* @__PURE__ */ import_react6.default.createElement("div", { className: "pt-6 " }, /* @__PURE__ */ import_react6.default.createElement(
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(
573
625
  "button",
574
626
  {
575
627
  onClick: triggerPasskeyLogin,
576
628
  disabled: isSubmitting,
577
- 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"
629
+ 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"
578
630
  },
579
- "Use Passkey / Biometrics"
631
+ "Use Passkey Biometrics"
580
632
  ))))));
581
633
  }
582
634
  var PipleAuth = (props) => {
package/dist/index.mjs CHANGED
@@ -328,6 +328,7 @@ function AuthFormInner({
328
328
  const [firstName, setFirstName] = useState3("");
329
329
  const [lastName, setLastName] = useState3("");
330
330
  const [orgName, setOrgName] = useState3("");
331
+ const [accountType, setAccountType] = useState3("ORGANIZATION");
331
332
  const [agreedToTerms, setAgreedToTerms] = useState3(false);
332
333
  const [userHas2FA, setUserHas2FA] = useState3(false);
333
334
  const [userHasPasskey, setUserHasPasskey] = useState3(false);
@@ -379,13 +380,12 @@ function AuthFormInner({
379
380
  if (useRecaptcha && captchaContext?.executeRecaptcha) {
380
381
  recaptchaToken = await captchaContext.executeRecaptcha("auth_request");
381
382
  }
382
- const hasOrg = mode === "SIGNUP" && requireOrganization && orgName.trim().length > 0;
383
383
  const res = await onAuthRequest({
384
384
  email: emailId,
385
385
  firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
386
386
  lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
387
- organizationName: hasOrg ? orgName.trim() : void 0,
388
- accountType: hasOrg ? "ORGANIZATION" : "INDIVIDUAL",
387
+ organizationName: mode === "SIGNUP" && accountType === "ORGANIZATION" ? orgName.trim() : void 0,
388
+ accountType: mode === "SIGNUP" ? accountType : void 0,
389
389
  mode,
390
390
  recaptchaToken
391
391
  });
@@ -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);
@@ -453,7 +480,7 @@ function AuthFormInner({
453
480
  if (mode === "LOGIN") return emailId.length < 3;
454
481
  if (mode === "SIGNUP") {
455
482
  if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
456
- if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
483
+ if (signupStep === "ORGANIZATION") return accountType === "ORGANIZATION" ? orgName.trim().length < 3 : false;
457
484
  if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
458
485
  }
459
486
  return false;
@@ -466,7 +493,23 @@ 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: "space-y-1.5 relative" }, /* @__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" }))), (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) => {
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(
497
+ "button",
498
+ {
499
+ type: "button",
500
+ onClick: () => setAccountType("INDIVIDUAL"),
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"}`
502
+ },
503
+ "Personal"
504
+ ), /* @__PURE__ */ React5.createElement(
505
+ "button",
506
+ {
507
+ type: "button",
508
+ onClick: () => setAccountType("ORGANIZATION"),
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"}`
510
+ },
511
+ "Organization"
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) => {
470
513
  e.preventDefault();
471
514
  verifyOtpCode(otp.join(""));
472
515
  } }, /* @__PURE__ */ React5.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React5.createElement(
@@ -486,14 +529,23 @@ function AuthFormInner({
486
529
  },
487
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"
488
531
  }
489
- ))), /* @__PURE__ */ React5.createElement(ThreeDActionButton, { type: "submit", disabled: otp.join("").length < 6, isLoading: isSubmitting, className: "w-full" }, "Verify Code")), userHasPasskey && /* @__PURE__ */ React5.createElement("div", { className: "pt-6 " }, /* @__PURE__ */ React5.createElement(
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(
490
542
  "button",
491
543
  {
492
544
  onClick: triggerPasskeyLogin,
493
545
  disabled: isSubmitting,
494
- 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"
546
+ 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"
495
547
  },
496
- "Use Passkey / Biometrics"
548
+ "Use Passkey Biometrics"
497
549
  ))))));
498
550
  }
499
551
  var PipleAuth = (props) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retinalabsllc/zairusjs",
3
- "version": "16.0.80",
3
+ "version": "16.0.95",
4
4
  "description": "A perceptive, Ai data driven Next.js UI component library.",
5
5
  "author": "Retina Labs Company",
6
6
  "license": "MIT",