@retinalabsllc/zairusjs 15.0.35 → 15.0.45

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
@@ -410,7 +410,7 @@ function AuthFormInner({
410
410
  const [authOptions, setAuthOptions] = (0, import_react6.useState)(null);
411
411
  const [otp, setOtp] = (0, import_react6.useState)(["", "", "", "", "", ""]);
412
412
  const inputRefs = (0, import_react6.useRef)([]);
413
- const cleanAlpha = (val) => val.replace(/[^a-zA-Z\s-]/g, "");
413
+ const cleanAlpha = (val) => val.replace(/[^a-zA-Z]/g, "").substring(0, 50);
414
414
  const cleanOrgName = (val) => val.replace(/[^a-zA-Z0-9\s]/g, "").substring(0, 50);
415
415
  const cleanEmailId = (val) => val.toLowerCase().replace(/[^a-z0-9@._-]/g, "");
416
416
  (0, import_react6.useEffect)(() => {
@@ -460,7 +460,7 @@ function AuthFormInner({
460
460
  firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
461
461
  lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
462
462
  organizationName: mode === "SIGNUP" && requireOrganization ? orgName : void 0,
463
- r_c: mode === "SIGNUP" ? invitationCode.trim().toUpperCase() : void 0,
463
+ r_c: mode === "SIGNUP" && invitationCode.trim() ? invitationCode.trim().toUpperCase() : void 0,
464
464
  mode,
465
465
  recaptchaToken
466
466
  });
@@ -531,7 +531,7 @@ function AuthFormInner({
531
531
  if (isSubmitting) return true;
532
532
  if (mode === "LOGIN") return emailId.length < 3;
533
533
  if (mode === "SIGNUP") {
534
- if (signupStep === "INVITATION") return invitationCode.trim().length < 3;
534
+ if (signupStep === "INVITATION") return invitationCode.trim().length > 0 && invitationCode.trim().length < 3;
535
535
  if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
536
536
  if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
537
537
  if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
@@ -547,16 +547,15 @@ function AuthFormInner({
547
547
  else if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
548
548
  else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
549
549
  else handleAuthRequestSubmit();
550
- } }, mode === "SIGNUP" && signupStep === "INVITATION" && /* @__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 " }, "Invitation Code"), /* @__PURE__ */ import_react6.default.createElement(
550
+ } }, mode === "SIGNUP" && signupStep === "INVITATION" && /* @__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 " }, "Referral Code"), /* @__PURE__ */ import_react6.default.createElement(
551
551
  "input",
552
552
  {
553
553
  type: "text",
554
554
  value: invitationCode,
555
555
  onChange: (e) => setInvitationCode(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "")),
556
- required: true,
557
556
  autoFocus: true,
558
557
  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",
559
- placeholder: "Invitation Code"
558
+ placeholder: "Referral Code (Optional)"
560
559
  }
561
560
  ))), 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) => {
562
561
  e.preventDefault();
@@ -1020,10 +1019,10 @@ var UniversalProfileSettings = ({
1020
1019
  setLastName(initialLastName || "");
1021
1020
  }, [initialFirstName, initialLastName]);
1022
1021
  const handleFirstNameChange = (val) => {
1023
- setFirstName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
1022
+ setFirstName(val.replace(/[^a-zA-Z]/g, "").substring(0, 50));
1024
1023
  };
1025
1024
  const handleLastNameChange = (val) => {
1026
- setLastName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
1025
+ setLastName(val.replace(/[^a-zA-Z]/g, "").substring(0, 50));
1027
1026
  };
1028
1027
  const handleSave = async (e) => {
1029
1028
  e.preventDefault();
@@ -2002,7 +2001,24 @@ var UniversalCardPage = ({
2002
2001
  setTimeout(() => setIsBgLoaded(true), 300);
2003
2002
  };
2004
2003
  }, [activeCard?.cardBgSrc]);
2005
- if (!activeCard) return /* @__PURE__ */ import_react31.default.createElement("div", { className: "text-center p-8 text-neutral-500" }, "No cards available");
2004
+ if (!activeCard || sortedCards.length === 0) {
2005
+ return /* @__PURE__ */ import_react31.default.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" }, onCreateCard && /* @__PURE__ */ import_react31.default.createElement(
2006
+ "button",
2007
+ {
2008
+ onClick: onCreateCard,
2009
+ 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"
2010
+ },
2011
+ /* @__PURE__ */ import_react31.default.createElement(import_react32.HugeiconsIcon, { icon: import_core_free_icons11.PlusSignIcon, size: 18 })
2012
+ ), /* @__PURE__ */ import_react31.default.createElement("div", { className: "p-6 w-full max-w-md mx-auto text-center" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "mb-8 flex justify-center" }, /* @__PURE__ */ import_react31.default.createElement(
2013
+ "svg",
2014
+ {
2015
+ xmlns: "http://www.w3.org/2000/svg",
2016
+ viewBox: "0 0 24 24",
2017
+ className: "w-12 h-12 fill-neutral-100"
2018
+ },
2019
+ /* @__PURE__ */ import_react31.default.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" })
2020
+ )), /* @__PURE__ */ import_react31.default.createElement("h1", { className: "text-xl text-black tracking-tight mb-4" }, "No cards found"), /* @__PURE__ */ import_react31.default.createElement("p", { className: "text-[13px] leading-[1.8] text-neutral-600 mb-12" }, "You do not have any virtual or physical cards generated yet. Tap the button below to issue and activate your first card.")));
2021
+ }
2006
2022
  const isActivated = activeCard.status === "ACTIVATED";
2007
2023
  const isFrozen = activeCard.status === "FROZEN";
2008
2024
  const isUnactivated = activeCard.status === "UNACTIVATED";
@@ -2022,14 +2038,6 @@ var UniversalCardPage = ({
2022
2038
  setIsFreezing(false);
2023
2039
  }, 800);
2024
2040
  };
2025
- const handleOverlayUnfreeze = () => {
2026
- if (isOverlayActionLoading) return;
2027
- setIsOverlayActionLoading(true);
2028
- setTimeout(() => {
2029
- if (onFreeze) onFreeze(activeCard.id);
2030
- setIsOverlayActionLoading(false);
2031
- }, 800);
2032
- };
2033
2041
  const confirmDelete = async () => {
2034
2042
  setIsDeleting(true);
2035
2043
  setTimeout(() => {
@@ -2053,7 +2061,7 @@ var UniversalCardPage = ({
2053
2061
  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"
2054
2062
  },
2055
2063
  /* @__PURE__ */ import_react31.default.createElement(import_react32.HugeiconsIcon, { icon: import_core_free_icons11.PlusSignIcon, size: 18 })
2056
- ), /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center justify-center mb-6 w-full px-2 gap-3" }, sortedCards.length > 0 && /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center bg-white rounded-full p-1 sm:p-1.5 max-w-full overflow-x-auto custom-scrollbar" }, sortedCards.map((tab, idx) => {
2064
+ ), sortedCards.length > 1 && /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center justify-center mb-6 w-full px-2 gap-3" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center bg-white rounded-full p-1 sm:p-1.5 max-w-full overflow-x-auto custom-scrollbar" }, sortedCards.map((tab, idx) => {
2057
2065
  const isActive = activeTabIndex === idx;
2058
2066
  return /* @__PURE__ */ import_react31.default.createElement(
2059
2067
  "button",
@@ -2081,16 +2089,6 @@ var UniversalCardPage = ({
2081
2089
  className: `px-6 py-2 text-[11px] rounded-full transition-all outline-none active:scale-95 ${buttonClasses}`
2082
2090
  },
2083
2091
  "Activate Card"
2084
- ), isDead && /* @__PURE__ */ import_react31.default.createElement(
2085
- "button",
2086
- {
2087
- onClick: (e) => {
2088
- e.stopPropagation();
2089
- router.push(`${actionPath}${activeCard.id}`);
2090
- },
2091
- className: `px-6 py-2 text-[11px] rounded-full transition-all outline-none active:scale-95 ${buttonClasses}`
2092
- },
2093
- "Create Card"
2094
2092
  ), isFrozen && /* @__PURE__ */ import_react31.default.createElement(
2095
2093
  "button",
2096
2094
  {
package/dist/index.mjs CHANGED
@@ -332,7 +332,7 @@ function AuthFormInner({
332
332
  const [authOptions, setAuthOptions] = useState3(null);
333
333
  const [otp, setOtp] = useState3(["", "", "", "", "", ""]);
334
334
  const inputRefs = useRef2([]);
335
- const cleanAlpha = (val) => val.replace(/[^a-zA-Z\s-]/g, "");
335
+ const cleanAlpha = (val) => val.replace(/[^a-zA-Z]/g, "").substring(0, 50);
336
336
  const cleanOrgName = (val) => val.replace(/[^a-zA-Z0-9\s]/g, "").substring(0, 50);
337
337
  const cleanEmailId = (val) => val.toLowerCase().replace(/[^a-z0-9@._-]/g, "");
338
338
  useEffect3(() => {
@@ -382,7 +382,7 @@ function AuthFormInner({
382
382
  firstName: mode === "SIGNUP" && requireNames ? firstName : void 0,
383
383
  lastName: mode === "SIGNUP" && requireNames ? lastName : void 0,
384
384
  organizationName: mode === "SIGNUP" && requireOrganization ? orgName : void 0,
385
- r_c: mode === "SIGNUP" ? invitationCode.trim().toUpperCase() : void 0,
385
+ r_c: mode === "SIGNUP" && invitationCode.trim() ? invitationCode.trim().toUpperCase() : void 0,
386
386
  mode,
387
387
  recaptchaToken
388
388
  });
@@ -453,7 +453,7 @@ function AuthFormInner({
453
453
  if (isSubmitting) return true;
454
454
  if (mode === "LOGIN") return emailId.length < 3;
455
455
  if (mode === "SIGNUP") {
456
- if (signupStep === "INVITATION") return invitationCode.trim().length < 3;
456
+ if (signupStep === "INVITATION") return invitationCode.trim().length > 0 && invitationCode.trim().length < 3;
457
457
  if (signupStep === "NAME") return firstName.trim() === "" || lastName.trim() === "";
458
458
  if (signupStep === "ORGANIZATION") return orgName.trim().length < 3;
459
459
  if (signupStep === "EMAIL_ID") return emailId.length < 3 || !agreedToTerms;
@@ -469,16 +469,15 @@ function AuthFormInner({
469
469
  else if (mode === "SIGNUP" && signupStep === "NAME") handleNextSignupStep();
470
470
  else if (mode === "SIGNUP" && signupStep === "ORGANIZATION") handleNextSignupStep();
471
471
  else handleAuthRequestSubmit();
472
- } }, mode === "SIGNUP" && signupStep === "INVITATION" && /* @__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 " }, "Invitation Code"), /* @__PURE__ */ React5.createElement(
472
+ } }, mode === "SIGNUP" && signupStep === "INVITATION" && /* @__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 " }, "Referral Code"), /* @__PURE__ */ React5.createElement(
473
473
  "input",
474
474
  {
475
475
  type: "text",
476
476
  value: invitationCode,
477
477
  onChange: (e) => setInvitationCode(e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, "")),
478
- required: true,
479
478
  autoFocus: true,
480
479
  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
- placeholder: "Invitation Code"
480
+ placeholder: "Referral Code (Optional)"
482
481
  }
483
482
  ))), 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) => {
484
483
  e.preventDefault();
@@ -956,10 +955,10 @@ var UniversalProfileSettings = ({
956
955
  setLastName(initialLastName || "");
957
956
  }, [initialFirstName, initialLastName]);
958
957
  const handleFirstNameChange = (val) => {
959
- setFirstName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
958
+ setFirstName(val.replace(/[^a-zA-Z]/g, "").substring(0, 50));
960
959
  };
961
960
  const handleLastNameChange = (val) => {
962
- setLastName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
961
+ setLastName(val.replace(/[^a-zA-Z]/g, "").substring(0, 50));
963
962
  };
964
963
  const handleSave = async (e) => {
965
964
  e.preventDefault();
@@ -1975,7 +1974,24 @@ var UniversalCardPage = ({
1975
1974
  setTimeout(() => setIsBgLoaded(true), 300);
1976
1975
  };
1977
1976
  }, [activeCard?.cardBgSrc]);
1978
- if (!activeCard) return /* @__PURE__ */ React19.createElement("div", { className: "text-center p-8 text-neutral-500" }, "No cards available");
1977
+ if (!activeCard || sortedCards.length === 0) {
1978
+ 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" }, onCreateCard && /* @__PURE__ */ React19.createElement(
1979
+ "button",
1980
+ {
1981
+ onClick: onCreateCard,
1982
+ 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"
1983
+ },
1984
+ /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: PlusSignIcon2, size: 18 })
1985
+ ), /* @__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(
1986
+ "svg",
1987
+ {
1988
+ xmlns: "http://www.w3.org/2000/svg",
1989
+ viewBox: "0 0 24 24",
1990
+ className: "w-12 h-12 fill-neutral-100"
1991
+ },
1992
+ /* @__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" })
1993
+ )), /* @__PURE__ */ React19.createElement("h1", { className: "text-xl text-black tracking-tight mb-4" }, "No cards found"), /* @__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. Tap the button below to issue and activate your first card.")));
1994
+ }
1979
1995
  const isActivated = activeCard.status === "ACTIVATED";
1980
1996
  const isFrozen = activeCard.status === "FROZEN";
1981
1997
  const isUnactivated = activeCard.status === "UNACTIVATED";
@@ -1995,14 +2011,6 @@ var UniversalCardPage = ({
1995
2011
  setIsFreezing(false);
1996
2012
  }, 800);
1997
2013
  };
1998
- const handleOverlayUnfreeze = () => {
1999
- if (isOverlayActionLoading) return;
2000
- setIsOverlayActionLoading(true);
2001
- setTimeout(() => {
2002
- if (onFreeze) onFreeze(activeCard.id);
2003
- setIsOverlayActionLoading(false);
2004
- }, 800);
2005
- };
2006
2014
  const confirmDelete = async () => {
2007
2015
  setIsDeleting(true);
2008
2016
  setTimeout(() => {
@@ -2026,7 +2034,7 @@ var UniversalCardPage = ({
2026
2034
  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"
2027
2035
  },
2028
2036
  /* @__PURE__ */ React19.createElement(HugeiconsIcon13, { icon: PlusSignIcon2, size: 18 })
2029
- ), /* @__PURE__ */ React19.createElement("div", { className: "flex items-center justify-center mb-6 w-full px-2 gap-3" }, sortedCards.length > 0 && /* @__PURE__ */ React19.createElement("div", { className: "flex items-center bg-white rounded-full p-1 sm:p-1.5 max-w-full overflow-x-auto custom-scrollbar" }, sortedCards.map((tab, idx) => {
2037
+ ), 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 sm:p-1.5 max-w-full overflow-x-auto custom-scrollbar" }, sortedCards.map((tab, idx) => {
2030
2038
  const isActive = activeTabIndex === idx;
2031
2039
  return /* @__PURE__ */ React19.createElement(
2032
2040
  "button",
@@ -2054,16 +2062,6 @@ var UniversalCardPage = ({
2054
2062
  className: `px-6 py-2 text-[11px] rounded-full transition-all outline-none active:scale-95 ${buttonClasses}`
2055
2063
  },
2056
2064
  "Activate Card"
2057
- ), isDead && /* @__PURE__ */ React19.createElement(
2058
- "button",
2059
- {
2060
- onClick: (e) => {
2061
- e.stopPropagation();
2062
- router.push(`${actionPath}${activeCard.id}`);
2063
- },
2064
- className: `px-6 py-2 text-[11px] rounded-full transition-all outline-none active:scale-95 ${buttonClasses}`
2065
- },
2066
- "Create Card"
2067
2065
  ), isFrozen && /* @__PURE__ */ React19.createElement(
2068
2066
  "button",
2069
2067
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retinalabsllc/zairusjs",
3
- "version": "15.0.35",
3
+ "version": "15.0.45",
4
4
  "description": "A perceptive, Ai data driven Next.js UI component library.",
5
5
  "author": "Retina Labs Company",
6
6
  "license": "MIT",