UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

4 lines (3 loc) 10.7 kB
'use client'; "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime");require("@emotion/styled");const Y=require("../../ui/button/button.cjs"),ee=require("../../ui/spinner/spinner.cjs"),A=require("../../ui/link/link.cjs"),_=require("../../ui/divider/divider.cjs"),h=require("@heroicons/react/24/outline"),W=require("framer-motion"),r=require("react"),O=require("../../../hooks/use-auth.cjs"),G=require("../../../hooks/use-config.cjs"),H=require("../../../hooks/use-magic-link.cjs"),se=require("../../forms/email-field.cjs"),T=require("../../forms/form-wrapper.cjs"),Z=require("../../forms/password-field.cjs"),te=t=>t&&t.__esModule?t:{default:t},re=te(r),J=re.default.memo(({password:t,requirements:i={minLength:8,requireUppercase:!0,requireLowercase:!0,requireNumbers:!0,requireSymbols:!1}})=>{const d=r.useMemo(()=>{const s=[];return i.minLength&&s.push({label:`At least ${i.minLength} characters`,passed:t.length>=i.minLength}),i.requireUppercase&&s.push({label:"One uppercase letter",passed:/[A-Z]/.test(t)}),i.requireLowercase&&s.push({label:"One lowercase letter",passed:/[a-z]/.test(t)}),i.requireNumbers&&s.push({label:"One number",passed:/\d/.test(t)}),i.requireSymbols&&s.push({label:"One special character",passed:/[!@#$%^&*(),.?":{}|<>]/.test(t)}),s},[t,i]),v=d.filter(s=>s.passed).length,o=Math.round(v/d.length*100),p=()=>o<40?"bg-danger-500":o<70?"bg-warning-500":"bg-success-500",y=()=>o<40?"Weak":o<70?"Medium":"Strong";return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-default-600",children:"Password strength"}),e.jsx("span",{className:`font-medium ${o<40?"text-danger-600":o<70?"text-warning-600":"text-success-600"}`,children:y()})]}),e.jsx("div",{className:"w-full bg-default-200 rounded-full h-2",children:e.jsx(W.motion.div,{className:`h-2 rounded-full ${p()}`,initial:{width:0},animate:{width:`${o}%`},transition:{duration:.3}})})]}),e.jsx("div",{className:"space-y-1",children:d.map((s,w)=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx(h.CheckCircleIcon,{className:`w-4 h-4 ${s.passed?"text-success-600":"text-default-300"}`}),e.jsx("span",{className:s.passed?"text-success-700 dark:text-success-400":"text-default-500",children:s.label})]},w))})]})});J.displayName="PasswordStrengthIndicator";function K({email:t="",onSuccess:i,onError:d,title:v="Forgot Password",subtitle:o="Enter your email address and we'll send you a link to reset your password.",redirectUrl:p,variant:y="default",size:s="md",radius:w="md",className:S="",showBackLink:L=!0,organizationId:f}){const{isValidEmail:B}=H.useMagicLink(),{requestPasswordReset:C,isLoading:N}=O.useAuth(),{components:I,linksPath:q}=G.useConfig(),[m,a]=r.useState(t),[E,j]=r.useState(!1),[$,u]=r.useState(null),F=I.Button??Y.Button,M=r.useCallback(async b=>{if(b.preventDefault(),u(null),!m){u("Please enter your email address");return}if(!B(m)){u("Please enter a valid email address");return}try{const k=p||(typeof window<"u"?`${window.location.origin}/auth/reset-password`:"/auth/reset-password"),P=await C({email:m,redirectUrl:k});P.success?(j(!0),i?.(m)):(u(P.error||"Failed to send reset link"),d?.(new Error(P.error||"Failed to send reset link")))}catch(g){const k=g instanceof Error?g.message:"Failed to send reset link";u(k),d?.(g instanceof Error?g:new Error(k))}},[m,B,C,p,f,i,d]),c=r.useCallback(async()=>{j(!1),u(null)},[]),x=r.useMemo(()=>({size:s,variant:"flat",className:`space-y-6 ${S}`,title:v,subtitle:E?void 0:o,showCard:y==="card"}),[s,S,v,o,y,E]);return E?e.jsx(T.default,{...x,children:e.jsxs("div",{className:"text-center space-y-4",children:[e.jsx(W.motion.div,{initial:{scale:0},animate:{scale:1},className:"mx-auto w-16 h-16 rounded-full bg-success-100 dark:bg-success-900/30 flex items-center justify-center",children:e.jsx(h.EnvelopeIcon,{className:"w-8 h-8 text-success-600"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold text-foreground mb-2",children:"Check Your Email"}),e.jsxs("p",{className:"text-default-500 text-sm",children:["We've sent a password reset link to ",e.jsx("strong",{children:m})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-default-400",children:"Didn't receive the email? Check your spam folder."}),e.jsx(F,{variant:"light",size:"sm",onPress:c,children:"Send Another Email"})]}),L&&e.jsxs(e.Fragment,{children:[e.jsx(_.Divider,{className:"my-4"}),e.jsxs(A.Link,{href:q?.signIn||"/auth/sign-in",className:"flex items-center justify-center gap-2 text-sm",children:[e.jsx(h.ArrowLeftIcon,{className:"w-4 h-4"}),"Back to Sign In"]})]})]})}):e.jsx(T.default,{...x,onSubmit:M,children:e.jsxs("div",{className:"space-y-4",children:[e.jsx(se.default,{label:"Email Address",name:"email",placeholder:"Enter your email address",value:m,onChange:a,startContent:e.jsx(h.EnvelopeIcon,{className:"w-4 h-4 text-default-400"}),size:s,radius:w,required:!0,disabled:N,variant:"bordered",autoFocus:!0}),$&&e.jsx("div",{className:"text-danger-600 text-sm bg-danger-50 dark:bg-danger-900/20 rounded-lg p-3",children:$}),e.jsx(F,{type:"submit",color:"primary",size:s,radius:w,className:"w-full",isLoading:N,isDisabled:!m||N,children:N?"Sending...":"Send Reset Link"}),L&&e.jsxs(e.Fragment,{children:[e.jsx(_.Divider,{className:"my-4"}),e.jsx("div",{className:"text-center",children:e.jsxs(A.Link,{href:q?.signIn||"/auth/sign-in",className:"flex items-center justify-center gap-2 text-sm",children:[e.jsx(h.ArrowLeftIcon,{className:"w-4 h-4"}),"Back to Sign In"]})})]})]})})}function Q({token:t,onSuccess:i,onError:d,title:v="Reset Password",subtitle:o="Enter your new password below.",redirectUrl:p="/auth/sign-in",variant:y="default",size:s="md",radius:w="md",className:S="",autoVerify:L=!0,passwordRequirements:f={minLength:8,requireUppercase:!0,requireLowercase:!0,requireNumbers:!0,requireSymbols:!1}}){const{signIn:B,validateToken:C}=O.useAuth(),{components:N,linksPath:I}=G.useConfig(),{extractTokenFromUrl:q}=H.useMagicLink(),{resetPassword:m}=O.useAuth(),[a,E]=r.useState(""),[j,$]=r.useState(""),[u,F]=r.useState(!1),[M,c]=r.useState(null),[x,b]=r.useState("idle"),[g,k]=r.useState(null),P=N.Button??Y.Button,R=r.useMemo(()=>t||q(),[t,q]);r.useEffect(()=>{L&&x==="idle"&&X()},[L,R,x]);const X=r.useCallback(async()=>{if(!R){b("invalid"),c("No reset token found in URL");return}try{b("verifying"),c(null);const n=await C({token:R,type:"password"});n.success?(b("valid"),k(R)):(b("invalid"),c(n.error||"Invalid or expired reset link"))}catch(n){b("invalid");const l=n instanceof Error?n.message:"Failed to verify reset token";c(l),d?.(n instanceof Error?n:new Error(l))}},[R,C,d]),D=r.useMemo(()=>{const n=[];return f.minLength&&n.push(a.length>=f.minLength),f.requireUppercase&&n.push(/[A-Z]/.test(a)),f.requireLowercase&&n.push(/[a-z]/.test(a)),f.requireNumbers&&n.push(/\d/.test(a)),f.requireSymbols&&n.push(/[!@#$%^&*(),.?":{}|<>]/.test(a)),n.every(l=>l)},[a,f]),z=r.useCallback(async n=>{if(n.preventDefault(),c(null),!a||!j){c("Please fill in all fields");return}if(a!==j){c("Passwords do not match");return}if(!D){c("Password does not meet requirements");return}if(!g){c("Invalid reset token");return}try{F(!0);const l=await m({token:g,newPassword:a});l.status==="complete"&&l.user?(i?.(l),setTimeout(()=>{typeof window<"u"&&(window.location.href=p)},2e3)):c(l.error?.message||"Failed to reset password")}catch(l){const V=l instanceof Error?l.message:"Failed to reset password";c(V),d?.(l instanceof Error?l:new Error(V))}finally{F(!1)}},[a,j,D,g,m,i,d,p]),U=r.useMemo(()=>({size:s,variant:"flat",className:`space-y-6 ${S}`,title:v,subtitle:x==="valid"?o:void 0,showCard:y==="card"}),[s,S,v,o,y,x]);return x==="verifying"?e.jsx(T.default,{...U,children:e.jsxs("div",{className:"text-center space-y-4",children:[e.jsx(ee.Spinner,{size:"lg"}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold text-foreground mb-2",children:"Verifying Reset Link"}),e.jsx("p",{className:"text-default-500 text-sm",children:"Please wait while we verify your reset link..."})]})]})}):x==="invalid"?e.jsx(T.default,{...U,children:e.jsxs("div",{className:"text-center space-y-4",children:[e.jsx(W.motion.div,{initial:{scale:0},animate:{scale:1},className:"mx-auto w-16 h-16 rounded-full bg-danger-100 dark:bg-danger-900/30 flex items-center justify-center",children:e.jsx(h.ExclamationTriangleIcon,{className:"w-8 h-8 text-danger-600"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-xl font-semibold text-foreground mb-2",children:"Invalid Reset Link"}),e.jsx("p",{className:"text-default-500 text-sm",children:M||"This password reset link is invalid or has expired."})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(P,{as:A.Link,href:I?.forgotPassword||"/auth/forgot-password",color:"primary",children:"Request New Reset Link"}),e.jsx("div",{className:"text-center",children:e.jsxs(A.Link,{href:I?.signIn||"/auth/sign-in",className:"text-sm flex items-center justify-center gap-2",children:[e.jsx(h.ArrowLeftIcon,{className:"w-4 h-4"}),"Back to Sign In"]})})]})]})}):e.jsx(T.default,{...U,onSubmit:z,children:e.jsxs("div",{className:"space-y-4",children:[e.jsx(Z.default,{label:"New Password",name:"password",placeholder:"Enter your new password",value:a,onChange:E,startContent:e.jsx(h.KeyIcon,{className:"w-4 h-4 text-default-400"}),size:s,radius:w,required:!0,disabled:u,variant:"bordered",autoFocus:!0}),a&&e.jsx(J,{password:a,requirements:f}),e.jsx(Z.default,{label:"Confirm Password",name:"confirmPassword",placeholder:"Confirm your new password",value:j,onChange:$,startContent:e.jsx(h.KeyIcon,{className:"w-4 h-4 text-default-400"}),size:s,radius:w,required:!0,disabled:u,variant:"bordered"}),M&&e.jsx("div",{className:"text-danger-600 text-sm bg-danger-50 dark:bg-danger-900/20 rounded-lg p-3",children:M}),e.jsx(P,{type:"submit",color:"primary",size:s,radius:w,className:"w-full",isLoading:u,isDisabled:!a||!j||!D||u,children:u?"Resetting...":"Reset Password"}),e.jsx(_.Divider,{className:"my-4"}),e.jsx("div",{className:"text-center",children:e.jsxs(A.Link,{href:I?.signIn||"/auth/sign-in",className:"text-sm flex items-center justify-center gap-2",children:[e.jsx(h.ArrowLeftIcon,{className:"w-4 h-4"}),"Back to Sign In"]})})]})})}function ae(t){return e.jsx(K,{...t,variant:"card"})}function ne(t){return e.jsx(Q,{...t,variant:"card"})}exports.ForgotPassword=K;exports.ForgotPasswordCard=ae;exports.ResetPassword=Q;exports.ResetPasswordCard=ne;exports.default=K; //# sourceMappingURL=forgot-password.cjs.map