@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 15.6 kB
Source Map (JSON)
{"version":3,"file":"sign-up.cjs","sources":["../../../../../src/components/auth/sign-up/sign-up.tsx"],"sourcesContent":["/**\n * @frank-auth/react - Main Sign Up Component\n *\n * Comprehensive sign-up component that can render as form, modal, or card\n * based on props. This is the main entry point for sign-up functionality.\n */\n\n'use client';\n\nimport React from 'react';\n\nimport {SignUpForm} from './sign-up-form';\nimport {SignUpModal} from './sign-up-modal';\nimport {SignUpCard} from './sign-up-card';\n\nimport type {BaseSignUpProps, SignUpCardProps, SignUpFormProps, SignUpModalProps} from './index';\n\n// ============================================================================\n// Sign Up Component Types\n// ============================================================================\n\nexport interface SignUpProps extends BaseSignUpProps {\n /**\n * Render mode\n */\n mode?: 'form' | 'modal' | 'card';\n\n /**\n * Modal-specific props (when mode is 'modal')\n */\n modalProps?: Partial<SignUpModalProps>;\n\n /**\n * Card-specific props (when mode is 'card')\n */\n cardProps?: Partial<SignUpCardProps>;\n\n /**\n * Form-specific props (when mode is 'form' or not specified)\n */\n formProps?: Partial<SignUpFormProps>;\n\n /**\n * Auto-detect mode based on context\n */\n autoMode?: boolean;\n}\n\n// ============================================================================\n// Main Sign Up Component\n// ============================================================================\n\n/**\n * Universal Sign Up component that can render in different modes\n *\n * @example Form mode (default)\n * ```tsx\n * <SignUp\n * methods={['password', 'oauth']}\n * onSuccess={(result) => console.log('Signed up:', result)}\n * />\n * ```\n *\n * @example Modal mode\n * ```tsx\n * <SignUp\n * mode=\"modal\"\n * isOpen={isModalOpen}\n * onClose={() => setIsModalOpen(false)}\n * onSuccess={(result) => console.log('Signed up:', result)}\n * />\n * ```\n *\n * @example Card mode\n * ```tsx\n * <SignUp\n * mode=\"card\"\n * centered\n * maxWidth={400}\n * onSuccess={(result) => console.log('Signed up:', result)}\n * />\n * ```\n *\n * @example Auto-mode (detects context)\n * ```tsx\n * <SignUp\n * autoMode\n * onSuccess={(result) => console.log('Signed up:', result)}\n * />\n * ```\n */\nexport function SignUp({\n mode = 'form',\n modalProps = {},\n cardProps = {},\n formProps = {},\n autoMode = false,\n ...baseProps\n }: SignUpProps) {\n // Auto-detect mode based on context\n const detectedMode = React.useMemo(() => {\n if (!autoMode) return mode;\n\n // Check if we're in a modal context (has backdrop)\n const hasBackdrop = typeof window !== 'undefined' &&\n document.querySelector('[data-modal-backdrop]');\n\n if (hasBackdrop) return 'modal';\n\n // Check if we're in a card context (has card container)\n const hasCardContainer = typeof window !== 'undefined' &&\n document.querySelector('[data-card-container]');\n\n if (hasCardContainer) return 'card';\n\n // Default to form\n return 'form';\n }, [autoMode, mode]);\n\n const finalMode = autoMode ? detectedMode : mode;\n\n // Render based on mode\n switch (finalMode) {\n case 'modal':\n return (\n <SignUpModal\n {...baseProps}\n {...modalProps}\n />\n );\n\n case 'card':\n return (\n <SignUpCard\n {...baseProps}\n {...cardProps}\n />\n );\n\n case 'form':\n default:\n return (\n <SignUpForm\n {...baseProps}\n {...formProps}\n />\n );\n }\n}\n\n// ============================================================================\n// Sign Up Component Variants\n// ============================================================================\n\n/**\n * Sign Up Form (explicit form mode)\n */\nexport function SignUpFormComponent(props: SignUpProps) {\n return <SignUp {...props} mode=\"form\" />;\n}\n\n/**\n * Sign Up Modal (explicit modal mode)\n */\nexport function SignUpModalComponent(props: SignUpProps) {\n return <SignUp {...props} mode=\"modal\" />;\n}\n\n/**\n * Sign Up Card (explicit card mode)\n */\nexport function SignUpCardComponent(props: SignUpProps) {\n return <SignUp {...props} mode=\"card\" />;\n}\n\n// ============================================================================\n// Specialized Sign Up Components\n// ============================================================================\n\n/**\n * Organization Invitation Sign Up\n */\nexport interface OrganizationInviteSignUpProps extends Omit<SignUpProps, 'invitationToken' | 'organizationId'> {\n /**\n * Invitation token\n */\n invitationToken: string;\n\n /**\n * Organization name for display\n */\n organizationName?: string;\n\n /**\n * Inviter information\n */\n inviterInfo?: {\n name?: string;\n email?: string;\n };\n}\n\nexport function OrganizationInviteSignUp({\n invitationToken,\n organizationName,\n inviterInfo,\n title,\n subtitle,\n ...props\n }: OrganizationInviteSignUpProps) {\n // Parse invitation token to get organization info\n const invitationData = React.useMemo(() => {\n try {\n const decoded = atob(invitationToken);\n return JSON.parse(decoded);\n } catch {\n return null;\n }\n }, [invitationToken]);\n\n const orgName = organizationName || invitationData?.orgName || 'the organization';\n const inviterName = inviterInfo?.name || invitationData?.inviterName;\n\n const finalTitle = title || `Join ${orgName}`;\n const finalSubtitle = subtitle || (\n inviterName\n ? `${inviterName} has invited you to join ${orgName}`\n : `You've been invited to join ${orgName}`\n );\n\n return (\n <SignUp\n {...props}\n invitationToken={invitationToken}\n organizationId={invitationData?.orgId}\n title={finalTitle}\n subtitle={finalSubtitle}\n showBranding={true}\n />\n );\n}\n\n/**\n * Quick Sign Up (minimal fields)\n */\nexport function QuickSignUp(props: SignUpProps) {\n return (\n <SignUp\n {...props}\n formProps={{\n variant: 'compact',\n collectFields: ['firstName', 'lastName'],\n ...props.formProps,\n }}\n />\n );\n}\n\n/**\n * Comprehensive Sign Up (all fields)\n */\nexport function ComprehensiveSignUp(props: SignUpProps) {\n return (\n <SignUp\n {...props}\n formProps={{\n variant: 'default',\n collectFields: ['firstName', 'lastName', 'username', 'phoneNumber'],\n passwordRequirements: {\n minLength: 12,\n requireUppercase: true,\n requireLowercase: true,\n requireNumbers: true,\n requireSymbols: true,\n },\n ...props.formProps,\n }}\n />\n );\n}\n\n/**\n * Social Sign Up (OAuth only)\n */\nexport function SocialSignUp(props: SignUpProps) {\n return (\n <SignUp\n {...props}\n methods={['oauth']}\n title=\"Create your account\"\n subtitle=\"Sign up with your social account\"\n />\n );\n}\n\n/**\n * Passwordless Sign Up (magic link + passkey)\n */\nexport function PasswordlessSignUp(props: SignUpProps) {\n return (\n <SignUp\n {...props}\n methods={['magic-link', 'passkey', 'oauth']}\n title=\"Create your account\"\n subtitle=\"Sign up without a password\"\n />\n );\n}\n\n// ============================================================================\n// Sign Up with Progressive Enhancement\n// ============================================================================\n\n/**\n * Progressive Sign Up - starts simple, adds complexity as needed\n */\nexport function ProgressiveSignUp({\n onSuccess,\n ...props\n }: SignUpProps) {\n const [step, setStep] = React.useState<'basic' | 'detailed' | 'verification'>('basic');\n const [userData, setUserData] = React.useState<any>(null);\n\n const handleBasicSuccess = React.useCallback((result: any) => {\n if (result.status === 'complete') {\n onSuccess?.(result);\n } else if (result.status === 'needs_verification') {\n setUserData(result);\n setStep('verification');\n } else {\n setUserData(result);\n setStep('detailed');\n }\n }, [onSuccess]);\n\n const handleDetailedSuccess = React.useCallback((result: any) => {\n if (result.status === 'complete') {\n onSuccess?.(result);\n } else {\n setUserData(result);\n setStep('verification');\n }\n }, [onSuccess]);\n\n const handleVerificationSuccess = React.useCallback((result: any) => {\n onSuccess?.(result);\n }, [onSuccess]);\n\n // Render based on step\n switch (step) {\n case 'detailed':\n return (\n <SignUp\n {...props}\n title=\"Complete your profile\"\n subtitle=\"Tell us a bit more about yourself\"\n formProps={{\n collectFields: ['firstName', 'lastName', 'username'],\n autoFocus: true,\n ...props.formProps,\n }}\n onSuccess={handleDetailedSuccess}\n />\n );\n\n case 'verification':\n return (\n <div className=\"text-center space-y-4\">\n <h2 className=\"text-xl font-semibold\">Check your email</h2>\n <p className=\"text-default-500\">\n We've sent a verification link to your email address\n </p>\n <button\n onClick={() => setStep('basic')}\n className=\"text-primary hover:underline\"\n >\n Use a different email\n </button>\n </div>\n );\n\n case 'basic':\n default:\n return (\n <SignUp\n {...props}\n formProps={{\n variant: 'minimal',\n collectFields: [],\n ...props.formProps,\n }}\n onSuccess={handleBasicSuccess}\n />\n );\n }\n}\n\n// ============================================================================\n// Export\n// ============================================================================\n\nexport default SignUp;"],"names":["SignUp","mode","modalProps","cardProps","formProps","autoMode","baseProps","detectedMode","React","jsx","SignUpModal","SignUpCard","SignUpForm","SignUpFormComponent","props","SignUpModalComponent","SignUpCardComponent","OrganizationInviteSignUp","invitationToken","organizationName","inviterInfo","title","subtitle","invitationData","decoded","orgName","inviterName","finalTitle","finalSubtitle","QuickSignUp","ComprehensiveSignUp","SocialSignUp","PasswordlessSignUp","ProgressiveSignUp","onSuccess","step","setStep","userData","setUserData","handleBasicSuccess","result","handleDetailedSuccess","jsxs"],"mappings":"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"}