UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

4 lines (3 loc) 11.7 kB
'use client'; "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime");require("@emotion/styled");const b=require("../../ui/button/button.cjs"),y=require("../../ui/input/input.cjs"),j=require("../../ui/card/card.cjs"),A=require("../../ui/divider/divider.cjs"),P=require("../../ui/badge/badge.cjs"),B=require("../../ui/avatar/avatar.cjs"),f=require("@heroicons/react/24/outline"),p=require("react"),k=require("../../../hooks/use-auth.cjs"),z=require("../../../hooks/use-config.cjs"),C=require("../common/error-boundary.cjs");function F({token:x,onAcceptSuccess:a,onDeclineSuccess:d,onError:s}){const{client:n,user:v}=k.useAuth(),[t,N]=p.useState(null),[l,o]=p.useState("idle"),[u,m]=p.useState(null),g=p.useCallback(async c=>{try{o("validating"),m(null);const r=await n.invitations.validateInvitation({invitationValidationRequest:{token:c}});r.valid&&r.invitation?(N(r.invitation),new Date(r.invitation.expiresAt)<new Date?(o("expired"),m("This invitation has expired")):o("valid")):(o("invalid"),m(r.message||"Invalid invitation token"))}catch(r){const h=r instanceof Error?r:new Error("Failed to validate invitation");o("error"),m(h.message),s?.(h)}},[n,s]),i=p.useCallback(async c=>{if(!t){m("No invitation data available");return}try{o("accepting"),m(null);const r={token:t.token};c&&(r.userData=c);const h=await n.invitations.acceptInvitation({acceptInvitationRequest:r});if(h.success)o("accepted"),a?.({organizationId:t.organizationId,userId:h.userId||v?.id||""}),t.redirectUrl&&setTimeout(()=>{window.location.href=t.redirectUrl},2e3);else throw new Error(h.message||"Failed to accept invitation")}catch(r){const h=r instanceof Error?r:new Error("Failed to accept invitation");o("error"),m(h.message),s?.(h)}},[t,n,v,a,s]),w=p.useCallback(async()=>{if(!t){m("No invitation data available");return}try{o("declining"),m(null);const c=await n.invitations.declineInvitation({declineInvitationRequest:{token:t.token}});if(c.success)o("declined"),d?.();else throw new Error(c.message||"Failed to decline invitation")}catch(c){const r=c instanceof Error?c:new Error("Failed to decline invitation");o("error"),m(r.message),s?.(r)}},[t,n,d,s]);return p.useEffect(()=>{x&&l==="idle"&&g(x)},[x,l,g]),p.useEffect(()=>{if(!x&&typeof window<"u"){const c=new URLSearchParams(window.location.search),r=c.get("invitation_token")||c.get("invite");r&&l==="idle"&&g(r)}},[x,l,g]),{invitation:t,status:l,error:u,validateInvitation:g,acceptInvitation:i,declineInvitation:w,isLoading:l==="validating"||l==="accepting"||l==="declining"}}function T(x){const a=new Date(x),d=new Date,s=a.getTime()-d.getTime(),n=Math.ceil(s/(1e3*60*60)),v=Math.ceil(s/(1e3*60*60*24));return s<=0?"Expired":n<=24?`Expires in ${n} hour${n!==1?"s":""}`:`Expires in ${v} day${v!==1?"s":""}`}function R(x){const a=new Date(x),d=new Date,s=a.getTime()-d.getTime(),n=s/(1e3*60*60);return s<=0?"expired":n<=24?"expiring":"active"}const S=C.withErrorBoundary(function({token:a,onAcceptSuccess:d,onDeclineSuccess:s,onError:n,className:v,style:t}){const{user:N}=k.useAuth(),{config:l}=z.useConfig(),{invitation:o,status:u,error:m,acceptInvitation:g,declineInvitation:i,isLoading:w}=F({token:a,onAcceptSuccess:d,onDeclineSuccess:s,onError:n}),c=async D=>{await g(D)},r=async()=>{await i()},h=()=>u==="validating"?e.jsx(I,{status:"validating"}):u==="invalid"||u==="error"?e.jsx(I,{status:u==="invalid"?"invalid":"error",error:m||void 0}):u==="expired"?e.jsx(I,{status:"expired",invitation:o||void 0}):u==="accepted"?e.jsx(I,{status:"accepted",invitation:o||void 0}):u==="declined"?e.jsx(I,{status:"declined",invitation:o||void 0}):o&&u==="valid"?e.jsxs("div",{className:"space-y-6",children:[e.jsx(q,{invitation:o,onAccept:()=>c(),onDecline:r,isLoading:w}),!N&&e.jsx(E,{invitation:o,onSubmit:c,isLoading:w,requiresSignUp:!0})]}):null;return e.jsx("div",{className:v,style:t,children:h()})}),q=C.withErrorBoundary(function({invitation:a,onAccept:d,onDecline:s,isLoading:n=!1,className:v}){const t=R(a.expiresAt),N=T(a.expiresAt);return e.jsxs(j.Card,{className:`max-w-md mx-auto ${v||""}`,variant:"shadow",children:[e.jsxs(j.CardHeader,{className:"flex flex-col items-center pb-2",children:[e.jsx("div",{className:"flex items-center justify-center w-16 h-16 bg-primary-100 rounded-full mb-4",children:e.jsx(f.BuildingOfficeIcon,{className:"h-8 w-8 text-primary"})}),e.jsx("h2",{className:"text-xl font-bold text-center",children:"Organization Invitation"}),e.jsx(P.Badge,{color:t==="expired"?"danger":t==="expiring"?"warning":"success",variant:"flat",className:"mt-2",children:N})]}),e.jsxs(j.CardBody,{className:"space-y-6",children:[e.jsx("div",{className:"text-center",children:e.jsxs("div",{className:"flex items-center justify-center mb-3",children:[a.organizationLogo?e.jsx(B.Avatar,{src:a.organizationLogo,alt:a.organizationName,size:"lg",className:"mr-3"}):e.jsx("div",{className:"w-12 h-12 bg-default-200 rounded-full flex items-center justify-center mr-3",children:e.jsx(f.BuildingOfficeIcon,{className:"h-6 w-6 text-default-500"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold",children:a.organizationName}),e.jsx("p",{className:"text-sm text-default-500",children:"wants you to join their organization"})]})]})}),e.jsx(A.Divider,{}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm text-default-600",children:"Email:"}),e.jsx("span",{className:"text-sm font-medium",children:a.email})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm text-default-600",children:"Role:"}),e.jsx(P.Badge,{color:"primary",variant:"flat",startContent:e.jsx(f.ShieldCheckIcon,{className:"h-3 w-3"}),children:a.roleName})]}),a.invitedByName&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm text-default-600",children:"Invited by:"}),e.jsxs("div",{className:"flex items-center gap-2",children:[a.invitedByAvatar&&e.jsx(B.Avatar,{src:a.invitedByAvatar,size:"sm"}),e.jsx("span",{className:"text-sm font-medium",children:a.invitedByName})]})]})]}),a.message&&e.jsxs(e.Fragment,{children:[e.jsx(A.Divider,{}),e.jsx("div",{className:"bg-default-50 p-4 rounded-lg",children:e.jsxs("p",{className:"text-sm text-default-700 italic",children:['"',a.message,'"']})})]}),e.jsxs("div",{className:"flex gap-3 pt-4",children:[e.jsx(b.Button,{color:"success",variant:"solid",className:"flex-1",onClick:d,isLoading:n,disabled:t==="expired",startContent:e.jsx(f.CheckCircleIcon,{className:"h-4 w-4"}),children:"Accept Invitation"}),e.jsx(b.Button,{color:"danger",variant:"flat",className:"flex-1",onClick:s,isLoading:n,disabled:t==="expired",startContent:e.jsx(f.XCircleIcon,{className:"h-4 w-4"}),children:"Decline"})]})]})]})}),E=C.withErrorBoundary(function({invitation:a,onSubmit:d,isLoading:s=!1,requiresSignUp:n=!1,className:v}){const[t,N]=p.useState({firstName:"",lastName:"",password:"",confirmPassword:""}),[l,o]=p.useState({}),u=(i,w)=>{N(c=>({...c,[i]:w})),l[i]&&o(c=>({...c,[i]:""}))},m=()=>{const i={};return n&&(t.firstName.trim()||(i.firstName="First name is required"),t.lastName.trim()||(i.lastName="Last name is required"),t.password?t.password.length<8&&(i.password="Password must be at least 8 characters"):i.password="Password is required",t.password!==t.confirmPassword&&(i.confirmPassword="Passwords do not match")),o(i),Object.keys(i).length===0},g=i=>{if(i.preventDefault(),!m())return;const w=n?{firstName:t.firstName,lastName:t.lastName,password:t.password}:void 0;d(w)};return n?e.jsxs(j.Card,{className:`max-w-md mx-auto ${v||""}`,variant:"flat",children:[e.jsxs(j.CardHeader,{children:[e.jsx("h3",{className:"text-lg font-semibold",children:"Complete Your Profile"}),e.jsxs("p",{className:"text-sm text-default-500",children:["Create your account to join ",a.organizationName]})]}),e.jsx(j.CardBody,{children:e.jsxs("form",{onSubmit:g,className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(y.Input,{label:"First Name",placeholder:"Enter your first name",value:t.firstName,onChange:i=>u("firstName",i.target.value),isInvalid:!!l.firstName,errorMessage:l.firstName,disabled:s,required:!0}),e.jsx(y.Input,{label:"Last Name",placeholder:"Enter your last name",value:t.lastName,onChange:i=>u("lastName",i.target.value),isInvalid:!!l.lastName,errorMessage:l.lastName,disabled:s,required:!0})]}),e.jsx(y.Input,{type:"password",label:"Password",placeholder:"Create a strong password",value:t.password,onChange:i=>u("password",i.target.value),isInvalid:!!l.password,errorMessage:l.password,disabled:s,required:!0}),e.jsx(y.Input,{type:"password",label:"Confirm Password",placeholder:"Confirm your password",value:t.confirmPassword,onChange:i=>u("confirmPassword",i.target.value),isInvalid:!!l.confirmPassword,errorMessage:l.confirmPassword,disabled:s,required:!0}),e.jsx(b.Button,{type:"submit",color:"primary",className:"w-full",isLoading:s,disabled:s,children:"Join Organization"})]})})]}):null}),I=C.withErrorBoundary(function({status:a,invitation:d,error:s,className:n}){const t=(()=>{switch(a){case"validating":return{icon:e.jsx(f.ClockIcon,{className:"h-16 w-16 text-primary animate-spin"}),title:"Validating Invitation",message:"Please wait while we verify your invitation...",color:"primary"};case"valid":return{icon:e.jsx(f.CheckCircleIcon,{className:"h-16 w-16 text-success"}),title:"Valid Invitation",message:"Your invitation is valid and ready to accept.",color:"success"};case"accepted":return{icon:e.jsx(f.CheckCircleIcon,{className:"h-16 w-16 text-success"}),title:"Invitation Accepted!",message:d?`Welcome to ${d.organizationName}! You've been added as ${d.roleName}.`:"Your invitation has been accepted successfully.",color:"success"};case"declined":return{icon:e.jsx(f.XCircleIcon,{className:"h-16 w-16 text-default-500"}),title:"Invitation Declined",message:"You have declined this organization invitation.",color:"default"};case"expired":return{icon:e.jsx(f.ExclamationTriangleIcon,{className:"h-16 w-16 text-warning"}),title:"Invitation Expired",message:"This invitation has expired. Please request a new invitation from the organization.",color:"warning"};case"invalid":return{icon:e.jsx(f.XCircleIcon,{className:"h-16 w-16 text-danger"}),title:"Invalid Invitation",message:"This invitation link is invalid or has already been used.",color:"danger"};case"error":return{icon:e.jsx(f.ExclamationTriangleIcon,{className:"h-16 w-16 text-danger"}),title:"Error",message:s||"An error occurred while processing your invitation.",color:"danger"};default:return{icon:e.jsx(f.ClockIcon,{className:"h-16 w-16 text-default-500"}),title:"Unknown Status",message:"Unable to determine invitation status.",color:"default"}}})();return e.jsx(j.Card,{className:`max-w-md mx-auto ${n||""}`,variant:"flat",children:e.jsxs(j.CardBody,{className:"text-center py-8",children:[e.jsx("div",{className:"flex justify-center mb-6",children:t.icon}),e.jsx("h2",{className:"text-xl font-semibold mb-3",children:t.title}),e.jsx("p",{className:"text-default-600 mb-6",children:t.message}),a==="accepted"&&d?.redirectUrl&&e.jsx("p",{className:"text-sm text-default-500",children:"Redirecting you to the organization dashboard..."}),(a==="expired"||a==="invalid"||a==="error")&&e.jsx(b.Button,{color:"primary",variant:"flat",onClick:()=>window.location.href="/",children:"Return to Home"})]})})}),M={InviteAcceptance:S,InvitePreview:q,InviteAcceptForm:E,InviteStatus:I};exports.InvitationComponents=M;exports.InviteAcceptForm=E;exports.InviteAcceptance=S;exports.InvitePreview=q;exports.InviteStatus=I; //# sourceMappingURL=invitations.cjs.map