@insforge/nextjs 0.6.8 → 0.7.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider/InsforgeProvider.tsx","../src/hooks/useAuth.ts","../src/hooks/useUser.ts","../src/hooks/useSession.ts","../src/hooks/useOAuthProviders.ts","../src/components/SignIn.tsx","../src/components/auth/AuthBranding.tsx","../src/components/auth/AuthContainer.tsx","../src/components/auth/AuthHeader.tsx","../src/components/auth/AuthErrorBanner.tsx","../src/components/auth/AuthFormField.tsx","../src/components/auth/AuthPasswordField.tsx","../src/components/auth/AuthPasswordStrengthIndicator.tsx","../src/components/auth/AuthSubmitButton.tsx","../src/components/auth/AuthDivider.tsx","../src/components/auth/AuthLink.tsx","../src/components/auth/AuthOAuthButton.tsx","../src/config/oauth-providers.tsx","../src/components/auth/AuthOAuthProviders.tsx","../src/components/auth/AuthVerificationCodeInput.tsx","../src/components/SignUp.tsx","../src/components/UserButton.tsx","../src/components/SignedIn.tsx","../src/components/SignedOut.tsx","../src/components/Protect.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useEffect, useState, useCallback, useRef, type ReactNode } from 'react';\nimport { createClient } from '@insforge/sdk';\nimport type { InsforgeUser, InsforgeSession, OAuthProvider } from '../types';\n\ninterface InsforgeContextValue {\n // Auth state\n user: InsforgeUser | null;\n session: InsforgeSession | null;\n isLoaded: boolean;\n isSignedIn: boolean;\n \n // Auth methods\n setUser: (user: InsforgeUser | null) => void;\n signIn: (email: string, password: string) => Promise<void>;\n signUp: (email: string, password: string) => Promise<void>;\n signOut: () => Promise<void>;\n updateUser: (data: Partial<InsforgeUser>) => Promise<void>;\n \n // Email verification methods (commented out - verification disabled for now)\n // sendVerificationCode: (email: string, type: 'signup' | 'signin') => Promise<void>;\n // verifySignUpCode: (email: string, password: string, code: string) => Promise<void>;\n // verifySignInCode: (email: string, code: string) => Promise<void>;\n \n // Base config\n baseUrl: string;\n}\n\nconst InsforgeContext = createContext<InsforgeContextValue | undefined>(undefined);\n\ninterface InsforgeProviderProps {\n children: ReactNode;\n baseUrl: string;\n frontendUrl?: string;\n onAuthChange?: (user: InsforgeUser | null) => void;\n useBuiltInAuth?: boolean;\n}\n\n\n// Get token from SDK's localStorage (where SDK stores it)\nfunction getTokenFromSDK(): string | null {\n console.log('[InsforgeProvider] Getting token from SDK');\n if (typeof window === 'undefined') return null;\n\n console.log('[InsforgeProvider] Window:', window);\n try {\n // SDK stores token directly at 'insforge-auth-token' key\n const token = localStorage.getItem('insforge-auth-token');\n console.log('[InsforgeProvider] Token:', token);\n return token;\n } catch (error) {\n console.error('[InsforgeProvider] Error getting token from SDK:', error);\n return null;\n }\n}\n\n// Sync token from localStorage to server-side cookie via API\nasync function syncTokenToCookie(token: string): Promise<boolean> {\n try {\n const response = await fetch('/api/auth', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n action: 'sync-token',\n token,\n }),\n });\n\n if (!response.ok) {\n return false;\n }\n\n return true;\n } catch (error) {\n return false;\n }\n}\n\n/**\n * Unified Insforge Provider - manages authentication state and configuration\n * \n * Manages user authentication state and provides all necessary context to child components.\n * OAuth providers are loaded on-demand by SignIn/SignUp components for better performance.\n * \n * @example\n * ```tsx\n * // Production - same URL for API and frontend\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}>\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Local dev - different ports (using env var)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider \n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * >\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * // Set NEXT_PUBLIC_INSFORGE_FRONTEND_URL=http://localhost:7131 in .env.local\n * ```\n * \n * @example\n * ```tsx\n * // Local dev - different ports (using prop)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider \n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * frontendUrl={process.env.NEXT_PUBLIC_INSFORGE_FRONTEND_URL}\n * >\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Using custom SignIn/SignUp components\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider \n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * useBuiltInAuth={false}\n * >\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n */\nexport function InsforgeProvider({ \n children, \n baseUrl,\n frontendUrl,\n onAuthChange,\n useBuiltInAuth = true\n}: InsforgeProviderProps) {\n // Auth state\n const [user, setUser] = useState<InsforgeUser | null>(null);\n const [session, setSession] = useState<InsforgeSession | null>(null);\n const [isLoaded, setIsLoaded] = useState(false);\n \n const refreshIntervalRef = useRef<NodeJS.Timeout>();\n \n // Initialize SDK client with lazy initialization - only runs once\n const [insforge] = useState(() => createClient({ baseUrl }));\n\n // Load auth state\n const loadAuthState = useCallback(async () => {\n try {\n // Check if we have a token in localStorage from the SDK\n const token = getTokenFromSDK();\n\n if (!token) {\n // No token, user is not authenticated\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n setIsLoaded(true);\n return;\n }\n\n // This provides instant UI update without waiting for API call\n const cachedUserStr = localStorage.getItem('insforge-user-profile');\n if (cachedUserStr) {\n try {\n const cachedData = JSON.parse(cachedUserStr);\n if (cachedData.user) {\n console.log('[InsforgeProvider] Loading user from cache');\n const userData: InsforgeUser = {\n id: cachedData.user.id,\n email: cachedData.user.email,\n createdAt: cachedData.user.createdAt || new Date().toISOString(),\n updatedAt: cachedData.user.updatedAt || new Date().toISOString(),\n ...cachedData.profile,\n };\n\n setUser(userData);\n setSession({\n userId: cachedData.user.id,\n token: token,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n });\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n\n // Mark as loaded immediately - user info is already displayed\n setIsLoaded(true);\n }\n } catch (e) {\n console.warn('[InsforgeProvider] Failed to parse cached user data:', e);\n }\n }\n\n // Try to sync token from localStorage to HTTP-only cookie via API\n // This is optional - if API route doesn't exist, it will fail silently\n try {\n await syncTokenToCookie(token);\n } catch (error) {\n // API route doesn't exist - that's okay, middleware won't work but client-side auth will\n }\n\n // Background: Verify token is still valid and refresh user data\n // This happens after displaying cached data, so UI is already responsive\n const userResult = await insforge.auth.getCurrentUser();\n\n if (userResult.data) {\n console.log('[InsforgeProvider] User data refreshed from API');\n // Token is valid, update user state with fresh data\n const userData: InsforgeUser = {\n id: userResult.data.user.id,\n email: userResult.data.user.email,\n createdAt: userResult.data.user.createdAt || new Date().toISOString(),\n updatedAt: userResult.data.user.updatedAt || new Date().toISOString(),\n ...userResult.data.profile,\n };\n\n setUser(userData);\n setSession({\n userId: userResult.data.user.id,\n token: token,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n });\n\n // Update cache with fresh data\n localStorage.setItem('insforge-user-profile', JSON.stringify(userResult.data));\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n } else {\n // Token invalid or expired\n // Clear from both localStorage and cookie\n localStorage.removeItem('insforge-auth-token');\n localStorage.removeItem('insforge-user-profile');\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch (error) {\n // API route doesn't exist - ignore\n }\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n }\n } catch (error) {\n // Token validation failed\n console.error('[InsforgeProvider] Token validation failed:', error);\n localStorage.removeItem('insforge-auth-token');\n localStorage.removeItem('insforge-user-profile');\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch (error) {\n // API route doesn't exist - ignore\n }\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n } finally {\n setIsLoaded(true);\n }\n }, [insforge, onAuthChange]);\n\n useEffect(() => {\n // Run loadAuthState only once on mount\n loadAuthState();\n\n return () => {\n if (refreshIntervalRef.current) {\n clearInterval(refreshIntervalRef.current);\n }\n };\n }, []); // Empty deps - run only on mount\n\n const signIn = useCallback(\n async (email: string, password: string) => {\n // Use SDK to sign in (stores in localStorage)\n const sdkResult = await insforge.auth.signInWithPassword({ email, password });\n\n if (sdkResult.data) {\n const userData: InsforgeUser = {\n id: sdkResult.data.user.id,\n email: sdkResult.data.user.email,\n name: sdkResult.data.user.name || undefined,\n createdAt: sdkResult.data.user.createdAt,\n updatedAt: sdkResult.data.user.updatedAt,\n };\n\n const sessionData: InsforgeSession = {\n userId: sdkResult.data.user.id,\n token: sdkResult.data.accessToken,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n };\n\n setUser(userData);\n setSession(sessionData);\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n\n // Try to sync token to HTTP-only cookie via API route (if it exists)\n // This is optional - if API route doesn't exist, it will fail silently\n try {\n await syncTokenToCookie(sdkResult.data.accessToken);\n } catch (error) {\n console.error('Please add /api/auth route to your server to sync token to cookie:', error);\n }\n } else {\n // Authentication failed - throw error with message from SDK\n const errorMessage = sdkResult.error?.message || 'Invalid email or password';\n throw new Error(errorMessage);\n }\n },\n [insforge, onAuthChange]\n );\n\n const signUp = useCallback(\n async (email: string, password: string) => {\n // Use SDK to sign up (stores in localStorage)\n const sdkResult = await insforge.auth.signUp({ email, password });\n\n if (sdkResult.data) {\n const userData: InsforgeUser = {\n id: sdkResult.data.user.id,\n email: sdkResult.data.user.email,\n name: sdkResult.data.user.name || undefined,\n createdAt: sdkResult.data.user.createdAt,\n updatedAt: sdkResult.data.user.updatedAt,\n };\n\n const sessionData: InsforgeSession = {\n userId: sdkResult.data.user.id,\n token: sdkResult.data.accessToken,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n };\n\n setUser(userData);\n setSession(sessionData);\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n\n // Try to sync token to HTTP-only cookie via API route (if it exists)\n // This is optional - if API route doesn't exist, it will fail silently\n try {\n await syncTokenToCookie(sdkResult.data.accessToken);\n } catch (error) {\n // API route doesn't exist or failed - that's okay, middleware won't work but client-side auth will\n }\n } else {\n // Sign up failed - throw error with message from SDK\n const errorMessage = sdkResult.error?.message || 'Sign up failed';\n throw new Error(errorMessage);\n }\n },\n [insforge, onAuthChange]\n );\n\n const signOut = useCallback(async () => {\n // SDK will clear localStorage token\n await insforge.auth.signOut();\n\n // Clear cached user profile\n localStorage.removeItem('insforge-user-profile');\n\n // Clear HTTP-only cookie via API\n await fetch('/api/auth', { method: 'DELETE' }).catch(() => {});\n\n // Clear refresh interval if exists\n if (refreshIntervalRef.current) {\n clearInterval(refreshIntervalRef.current);\n }\n\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n }, [insforge, onAuthChange]);\n\n const updateUser = useCallback(\n async (data: Partial<InsforgeUser>) => {\n if (!user) throw new Error('No user signed in');\n\n // Use SDK's setProfile to update user profile\n const result = await insforge.auth.setProfile(data);\n if (result.data) {\n const updatedUser = { ...user, ...result.data };\n setUser(updatedUser);\n if (onAuthChange) {\n onAuthChange(updatedUser);\n }\n }\n },\n [user, onAuthChange, insforge]\n );\n\n // Email verification methods (commented out - verification disabled for now)\n // Will be added back in the future when backend email verification is ready\n \n // Send verification code for sign up or sign in\n // const sendVerificationCode = useCallback(\n // async (email: string, type: 'signup' | 'signin') => {\n // // TODO: Replace with actual SDK call when ready\n // // await insforge.auth.sendVerificationCode({ email, type });\n // \n // // Dummy implementation for testing\n // console.log(`[Verification] Sending ${type} code to ${email}`);\n // console.log('[Verification] Dummy code: 123456');\n // \n // // Simulate API delay\n // await new Promise(resolve => setTimeout(resolve, 500));\n // },\n // [insforge]\n // );\n\n // Verify code and complete sign up\n // const verifySignUpCode = useCallback(\n // async (email: string, password: string, code: string) => {\n // // TODO: Replace with actual SDK call when ready\n // // const sdkResult = await insforge.auth.verifySignUpCode({ email, password, code });\n // \n // // Dummy implementation - accept code \"123456\"\n // if (code !== '123456') {\n // throw new Error('Invalid verification code');\n // }\n\n // // Simulate sign up with verification\n // const sdkResult = await insforge.auth.signUp({ email, password });\n\n // if (sdkResult.data) {\n // const userData: InsforgeUser = {\n // id: sdkResult.data.user.id,\n // email: sdkResult.data.user.email,\n // name: sdkResult.data.user.name || undefined,\n // createdAt: sdkResult.data.user.createdAt,\n // updatedAt: sdkResult.data.user.updatedAt,\n // };\n\n // const sessionData: InsforgeSession = {\n // userId: sdkResult.data.user.id,\n // token: sdkResult.data.accessToken,\n // expiresAt: '',\n // createdAt: new Date().toISOString(),\n // };\n\n // setUser(userData);\n // setSession(sessionData);\n\n // if (onAuthChange) {\n // onAuthChange(userData);\n // }\n\n // // Try to sync token to HTTP-only cookie via API route (if it exists)\n // try {\n // await syncTokenToCookie(sdkResult.data.accessToken);\n // } catch (error) {\n // // API route doesn't exist or failed\n // }\n // } else {\n // const errorMessage = sdkResult.error?.message || 'Sign up failed';\n // throw new Error(errorMessage);\n // }\n // },\n // [insforge, onAuthChange]\n // );\n\n // Verify code and sign in (passwordless)\n // const verifySignInCode = useCallback(\n // async (email: string, code: string) => {\n // // TODO: Replace with actual SDK call when ready\n // // const sdkResult = await insforge.auth.verifySignInCode({ email, code });\n // \n // // Dummy implementation - accept code \"123456\"\n // if (code !== '123456') {\n // throw new Error('Invalid verification code');\n // }\n\n // // For now, we'll just simulate a successful sign in\n // // In reality, the backend should verify the code and return a session\n // throw new Error('Passwordless sign in via verification code is not yet implemented in the backend');\n // },\n // [insforge, onAuthChange]\n // );\n\n return (\n <InsforgeContext.Provider\n value={{\n // Auth\n user,\n session,\n isLoaded,\n isSignedIn: !!user,\n setUser,\n signIn,\n signUp,\n signOut,\n updateUser,\n \n // Email verification (commented out - verification disabled for now)\n // sendVerificationCode,\n // verifySignUpCode,\n // verifySignInCode,\n \n // Base\n baseUrl,\n }}\n >\n {children}\n </InsforgeContext.Provider>\n );\n}\n\n/**\n * Hook to access Insforge context\n * \n * Provides access to authentication state and methods.\n * Use `useOAuthProviders()` separately to fetch OAuth providers on-demand.\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { user, isSignedIn, signOut } = useInsforge();\n * \n * if (!isSignedIn) return <SignIn />;\n * \n * return (\n * <div>\n * <p>Welcome {user.email}</p>\n * <button onClick={signOut}>Sign Out</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useInsforge(): InsforgeContextValue {\n const context = useContext(InsforgeContext);\n if (!context) {\n throw new Error('useInsforge must be used within InsforgeProvider');\n }\n return context;\n}\n\n","import { useInsforge } from '../provider/InsforgeProvider';\r\n\r\n/**\r\n * Hook to access authentication methods\r\n * \r\n * @returns Authentication methods and loading state\r\n * \r\n * @example\r\n * ```tsx\r\n * function LoginForm() {\r\n * const { signIn, signUp, signOut, isLoaded } = useAuth();\r\n * \r\n * async function handleLogin(email: string, password: string) {\r\n * await signIn(email, password);\r\n * }\r\n * \r\n * if (!isLoaded) return <div>Loading...</div>;\r\n * \r\n * return <form onSubmit={handleLogin}>...</form>;\r\n * }\r\n * ```\r\n */\r\nexport function useAuth() {\r\n const { signIn, signUp, signOut, isLoaded, isSignedIn } = useInsforge();\r\n return { signIn, signUp, signOut, isLoaded, isSignedIn };\r\n}\r\n","import { useInsforge } from '../provider/InsforgeProvider';\r\n\r\n/**\r\n * Hook to access current user data\r\n * \r\n * @returns Current user, loading state, and update function\r\n * \r\n * @example\r\n * ```tsx\r\n * function UserProfile() {\r\n * const { user, isLoaded, updateUser, setUser } = useUser();\r\n * \r\n * if (!isLoaded) return <div>Loading...</div>;\r\n * if (!user) return <div>Not signed in</div>;\r\n * \r\n * async function handleUpdate(name: string) {\r\n * await updateUser({ name });\r\n * }\r\n * \r\n * return (\r\n * <div>\r\n * <p>Email: {user.email}</p>\r\n * <p>Name: {user.name}</p>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useUser() {\r\n const { user, isLoaded, updateUser, setUser } = useInsforge();\r\n return { user, isLoaded, updateUser, setUser };\r\n}\r\n","import { useInsforge } from '../provider/InsforgeProvider';\r\n\r\n/**\r\n * Hook to access session data\r\n * \r\n * @returns Current session and loading state\r\n * \r\n * @example\r\n * ```tsx\r\n * function SessionInfo() {\r\n * const { session, isLoaded } = useSession();\r\n * \r\n * if (!isLoaded) return <div>Loading...</div>;\r\n * if (!session) return <div>No active session</div>;\r\n * \r\n * return (\r\n * <div>\r\n * <p>User ID: {session.userId}</p>\r\n * <p>Token: {session.token.substring(0, 10)}...</p>\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport function useSession() {\r\n const { session, isLoaded } = useInsforge();\r\n return { session, isLoaded };\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport { createClient } from '@insforge/sdk';\r\nimport { useInsforge } from '../provider/InsforgeProvider';\r\nimport type { OAuthProvider } from '../types';\r\n\r\n/**\r\n * Hook to get configured OAuth providers from Insforge backend\r\n *\r\n * Lazily fetches enabled OAuth providers from the backend configuration only when needed.\r\n * This optimizes performance by avoiding unnecessary API calls on pages that don't show auth forms.\r\n * Uses the Insforge SDK for type-safe API communication.\r\n *\r\n * @returns Object containing providers array and loading state\r\n *\r\n * @example\r\n * ```tsx\r\n * function OAuthButtons() {\r\n * const { providers, isLoaded } = useOAuthProviders();\r\n * \r\n * if (!isLoaded) return <div>Loading providers...</div>;\r\n * \r\n * return (\r\n * <div>\r\n * {providers.map(provider => (\r\n * <button key={provider}>Sign in with {provider}</button>\r\n * ))}\r\n * </div>\r\n * );\r\n * }\r\n * ```\r\n *\r\n * @requires Must be used within InsforgeProvider\r\n */\r\nexport function useOAuthProviders(): { providers: OAuthProvider[], isLoaded: boolean } {\r\n const { baseUrl } = useInsforge();\r\n const [providers, setProviders] = useState<OAuthProvider[]>([]);\r\n const [isLoaded, setIsLoaded] = useState(false);\r\n\r\n useEffect(() => {\r\n let mounted = true;\r\n\r\n async function fetchProviders() {\r\n try {\r\n // Use SDK instead of raw fetch for type safety and consistent error handling\r\n const insforge = createClient({ baseUrl });\r\n const { data, error } = await insforge.auth.getOAuthProviders();\r\n\r\n if (!mounted) return;\r\n\r\n if (error) {\r\n console.warn('[useOAuthProviders] Failed to fetch OAuth providers:', error);\r\n setProviders([]);\r\n } else if (data) {\r\n setProviders(data as OAuthProvider[]);\r\n } else {\r\n setProviders([]);\r\n }\r\n \r\n setIsLoaded(true);\r\n } catch (error) {\r\n console.warn('[useOAuthProviders] Unexpected error:', error);\r\n if (mounted) {\r\n setProviders([]);\r\n setIsLoaded(true);\r\n }\r\n }\r\n }\r\n\r\n fetchProviders();\r\n\r\n return () => {\r\n mounted = false;\r\n };\r\n }, [baseUrl]);\r\n\r\n return { providers, isLoaded };\r\n}\r\n","\"use client\";\n\nimport { useState, FormEvent } from \"react\";\nimport { createClient } from \"@insforge/sdk\";\nimport { useInsforge } from \"../provider/InsforgeProvider\";\nimport { useOAuthProviders } from \"../hooks/useOAuthProviders\";\nimport type { SignInProps, OAuthProvider } from \"../types\";\nimport {\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthProviders,\n} from \"./auth\";\nimport \"../styles.css\";\n\n/**\n * Pre-built sign-in component with email/password authentication and OAuth providers.\n *\n * @component\n * @example\n * ```tsx\n * // Basic usage - OAuth providers auto-detected from backend\n * <SignIn />\n *\n * // With custom UI text\n * <SignIn\n * title=\"Welcome Back\"\n * subtitle=\"Sign in to continue\"\n * afterSignInUrl=\"/dashboard\"\n * />\n * \n * // Override OAuth providers manually (optional)\n * <SignIn providers={['google', 'github']} />\n * ```\n *\n * @param {SignInProps} props - Component props\n * @param {string} [props.afterSignInUrl='/'] - URL to redirect to after successful sign-in\n * @param {object} [props.appearance] - Custom styles for container, form, and button elements\n * @param {function} [props.onSuccess] - Callback invoked after successful sign-in with user data\n * @param {function} [props.onError] - Callback invoked when sign-in fails with error object\n *\n * @remarks\n * **OAuth Setup:**\n * - OAuth providers are automatically detected from backend configuration\n * - Alternatively, pass `providers` prop to manually specify which providers to show\n * - **IMPORTANT:** You must create an OAuth callback page at `/auth/callback` in your app\n * See example implementation in the package README\n *\n * **OAuth Flow:**\n * 1. User clicks OAuth button\n * 2. Redirects to provider (GitHub, Google, etc.)\n * 3. After authorization, provider redirects to `/auth/callback?access_token=...`\n * 4. Callback page stores token in localStorage\n * 5. User redirected to `afterSignInUrl`\n */\nexport function SignIn({\n afterSignInUrl = \"/\",\n appearance = {},\n title = \"Welcome Back\",\n subtitle = \"Login to your account\",\n emailLabel = \"Email\",\n emailPlaceholder = \"example@email.com\",\n passwordLabel = \"Password\",\n passwordPlaceholder = \"••••••\",\n forgotPasswordText = \"Forget Password?\",\n submitButtonText = \"Sign In\",\n loadingButtonText = \"Signing in...\",\n signUpText = \"Don't have an account?\",\n signUpLinkText = \"Sign Up Now\",\n signUpUrl = \"/sign-up\",\n dividerText = \"or\",\n onSuccess,\n onError,\n}: SignInProps) {\n const { signIn, baseUrl } = useInsforge();\n const { providers: oauthProviders } = useOAuthProviders();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [oauthLoading, setOauthLoading] = useState<OAuthProvider | null>(null);\n\n // Use a memoized client to prevent recreation on every render\n // This avoids SDK's OAuth detection running multiple times\n const insforge = useState(() => createClient({ baseUrl }))[0];\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setLoading(true);\n setError(\"\");\n\n try {\n await signIn(email, password);\n if (onSuccess) {\n const userResult = await insforge.auth.getCurrentUser();\n if (userResult.data) onSuccess(userResult.data as any);\n }\n window.location.href = afterSignInUrl;\n } catch (err: any) {\n const errorMessage = err.message || \"Sign in failed\";\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleOAuth(provider: OAuthProvider) {\n try {\n setOauthLoading(provider);\n // OAuth requires redirectTo parameter - backend will redirect here with token\n // We use /auth/callback as intermediate page to extract token from URL\n const redirectTo = `${window.location.origin}/auth/callback`;\n\n // Store the final destination for the callback page to use\n sessionStorage.setItem(\"oauth_final_destination\", afterSignInUrl || \"/\");\n\n const result = await insforge.auth.signInWithOAuth({\n provider,\n redirectTo,\n });\n\n console.log('handleOAuth result', result);\n\n // if (result.data?.url) {\n // window.location.href = result.data.url;\n // }\n } catch (err: any) {\n const errorMessage = err.message || `${provider} sign in failed`;\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n setOauthLoading(null);\n }\n }\n\n return (\n <AuthContainer style={appearance.container}>\n <AuthHeader title={title} subtitle={subtitle} />\n\n <AuthErrorBanner error={error} />\n\n <form onSubmit={handleSubmit} className=\"insforge-form\">\n <AuthFormField\n id=\"email\"\n type=\"email\"\n label={emailLabel}\n placeholder={emailPlaceholder}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n />\n\n <AuthPasswordField\n id=\"password\"\n label={passwordLabel}\n placeholder={passwordPlaceholder}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n autoComplete=\"current-password\"\n />\n\n <AuthSubmitButton\n isLoading={loading}\n disabled={loading || oauthLoading !== null}\n style={appearance.button}\n >\n {loading ? loadingButtonText : submitButtonText}\n </AuthSubmitButton>\n </form>\n\n <AuthLink text={signUpText} linkText={signUpLinkText} href={signUpUrl} />\n\n {oauthProviders.length > 0 && (\n <>\n <AuthDivider text={dividerText} />\n <AuthOAuthProviders\n providers={oauthProviders}\n onClick={handleOAuth}\n disabled={loading || oauthLoading !== null}\n loading={oauthLoading}\n />\n </>\n )}\n\n </AuthContainer>\n );\n}\n","'use client';\r\n\r\nimport Link from 'next/link';\r\n\r\ninterface AuthBrandingProps {\r\n text?: string;\r\n href?: string;\r\n}\r\n\r\n/**\r\n * Insforge branding component for authentication pages.\r\n * \r\n * Displays customizable branding text with the Insforge logo.\r\n * Typically placed at the bottom of authentication forms.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * // Default branding\r\n * <AuthBranding />\r\n * \r\n * // Custom text\r\n * <AuthBranding text=\"Powered by\" />\r\n * \r\n * // Custom link\r\n * <AuthBranding \r\n * text=\"Built with\" \r\n * href=\"https://insforge.app\" \r\n * />\r\n * ```\r\n * \r\n * @param {string} [text='Secured by'] - Text to display before the logo\r\n * @param {string} [href='https://insforge.dev'] - URL the logo links to\r\n */\r\nexport function AuthBranding({ text = 'Secured by', href = 'https://insforge.dev' }: AuthBrandingProps) {\r\n return (\r\n <div className=\"insforge-branding\">\r\n <p className=\"insforge-branding-text\">{text}</p>\r\n <Link href={href} target=\"_blank\" rel=\"noopener noreferrer\">\r\n <svg width=\"83\" height=\"20\" viewBox=\"0 0 83 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M2.16783 8.46797C1.9334 8.23325 1.9334 7.85269 2.16783 7.61797L8.11049 1.66797L16.6 1.66797L6.41259 11.868C6.17815 12.1027 5.79807 12.1027 5.56363 11.868L2.16783 8.46797Z\"\r\n fill=\"url(#paint0_linear_2976_9475)\"\r\n />\r\n <path\r\n d=\"M12.8858 6.44922L16.6 10.168V18.668L8.64108 10.6992L12.8858 6.44922Z\"\r\n fill=\"url(#paint1_linear_2976_9475)\"\r\n />\r\n <path\r\n d=\"M67.5439 6.48828C68.2894 6.48828 68.9145 6.67064 69.418 7.03516C69.5229 7.10943 69.6214 7.1907 69.7158 7.27637V6.70703H71.248V14.959C71.248 15.1583 71.2381 15.3485 71.2188 15.5283C71.2042 15.7129 71.1774 15.8925 71.1387 16.0674C71.0225 16.5776 70.7998 16.9957 70.4707 17.3213C70.1415 17.6518 69.7321 17.8972 69.2432 18.0576C68.7592 18.2179 68.2222 18.2988 67.6318 18.2988C67.1962 18.2988 66.7768 18.2308 66.375 18.0947C65.9782 17.9587 65.6202 17.7614 65.3008 17.5039C64.9813 17.2512 64.7199 16.9446 64.5166 16.585L66.1289 15.7832C66.2789 16.0698 66.4888 16.2819 66.7598 16.418C67.0356 16.5589 67.3289 16.6289 67.6387 16.6289C68.0016 16.6289 68.3258 16.5628 68.6113 16.4316C68.8969 16.3053 69.1176 16.116 69.2725 15.8633C69.4321 15.6155 69.5077 15.3047 69.498 14.9307V14.1797C69.4665 14.2037 69.4359 14.229 69.4033 14.252C68.8855 14.6164 68.2441 14.7988 67.4795 14.7988C66.7582 14.7988 66.1281 14.6165 65.5908 14.252C65.0537 13.8875 64.637 13.3915 64.3418 12.7646C64.0467 12.1378 63.8994 11.4307 63.8994 10.6436C63.8994 9.84651 64.0465 9.13673 64.3418 8.51465C64.6419 7.88768 65.0663 7.39481 65.6133 7.03516C66.1601 6.67077 66.8036 6.48836 67.5439 6.48828ZM37.5 6.48828C38.1099 6.48828 38.6496 6.58294 39.1191 6.77246C39.5935 6.96201 39.9762 7.2321 40.2666 7.58203C40.5569 7.93184 40.7359 8.34227 40.8037 8.81348L39.0176 9.13477C38.974 8.79951 38.8218 8.53424 38.5605 8.33984C38.304 8.14547 37.96 8.03605 37.5293 8.01172C37.1178 7.98742 36.7859 8.05051 36.5342 8.20117C36.2825 8.34698 36.1562 8.55398 36.1562 8.82129C36.1563 8.97184 36.208 9.10017 36.3096 9.20703C36.4112 9.31394 36.614 9.42141 36.9189 9.52832C37.2288 9.63524 37.6889 9.76635 38.2988 9.92188C38.9232 10.0823 39.4222 10.2666 39.7949 10.4756C40.1722 10.6796 40.4428 10.9254 40.6074 11.2119C40.7768 11.4987 40.8623 11.8466 40.8623 12.2549C40.8623 13.047 40.574 13.6691 39.998 14.1211C39.4268 14.5731 38.6348 14.7988 37.623 14.7988C36.6551 14.7988 35.8687 14.5799 35.2637 14.1426C34.6587 13.7052 34.2909 13.0908 34.1602 12.2988L35.9463 12.0215C36.0383 12.4102 36.2411 12.7169 36.5557 12.9404C36.8703 13.164 37.2678 13.2754 37.7471 13.2754C38.1681 13.2754 38.4922 13.1926 38.7197 13.0273C38.9521 12.8572 39.0684 12.6266 39.0684 12.335C39.0684 12.1552 39.0245 12.0122 38.9375 11.9053C38.8552 11.7935 38.6713 11.686 38.3857 11.584C38.1001 11.4819 37.6618 11.3528 37.0713 11.1973C36.4131 11.0223 35.8901 10.8359 35.5029 10.6367C35.1158 10.4327 34.8374 10.192 34.668 9.91504C34.4985 9.63801 34.4141 9.30188 34.4141 8.9082C34.4141 8.41746 34.5423 7.98943 34.7988 7.625C35.0553 7.26073 35.4135 6.98146 35.873 6.78711C36.3329 6.58784 36.8755 6.48828 37.5 6.48828ZM53.3047 6.48828C54.0937 6.48828 54.7815 6.66572 55.3672 7.02051C55.9527 7.37528 56.4072 7.86634 56.7314 8.49316C57.0558 9.11525 57.2187 9.83193 57.2188 10.6436C57.2188 11.46 57.0537 12.1817 56.7246 12.8086C56.4003 13.4307 55.9451 13.9196 55.3594 14.2744C54.7737 14.6242 54.0888 14.7988 53.3047 14.7988C52.5205 14.7988 51.8357 14.6214 51.25 14.2666C50.6643 13.9118 50.2091 13.4238 49.8848 12.8018C49.5653 12.1748 49.4053 11.4552 49.4053 10.6436C49.4053 9.81735 49.5703 9.09279 49.8994 8.4707C50.2286 7.8488 50.6859 7.36255 51.2715 7.0127C51.8572 6.66281 52.5351 6.48828 53.3047 6.48828ZM76.7471 6.48828C77.5603 6.48828 78.25 6.68053 78.8164 7.06445C79.3876 7.44351 79.812 7.97991 80.0879 8.6748C80.3638 9.36976 80.4672 10.189 80.3994 11.1318H74.7256C74.7843 11.6972 74.949 12.1516 75.2227 12.4951C75.5711 12.9325 76.0792 13.1513 76.7471 13.1514C77.1779 13.1514 77.5486 13.0567 77.8584 12.8672C78.173 12.6728 78.4146 12.3928 78.584 12.0283L80.3125 12.5537C80.0124 13.2633 79.5473 13.8153 78.918 14.209C78.2936 14.6025 77.6036 14.7988 76.8486 14.7988C76.0549 14.7988 75.358 14.6263 74.7578 14.2812C74.1576 13.9362 73.6875 13.458 73.3486 12.8457C73.0147 12.2334 72.8477 11.5284 72.8477 10.7314C72.8477 9.87126 73.0127 9.12495 73.3418 8.49316C73.671 7.85651 74.1282 7.36263 74.7139 7.0127C75.2995 6.6628 75.9775 6.48832 76.7471 6.48828ZM23.3301 14.5801H21.5801V4.08203H23.3301V14.5801ZM29.6152 6.48047C30.1959 6.48052 30.6753 6.5781 31.0527 6.77246C31.4301 6.96681 31.7305 7.21443 31.9531 7.51562C32.1758 7.81695 32.3398 8.13831 32.4463 8.47852C32.5528 8.81873 32.6213 9.14205 32.6504 9.44824C32.6843 9.74946 32.7012 9.99508 32.7012 10.1846V14.5801H30.9287V10.7891C30.9287 10.5413 30.9118 10.2669 30.8779 9.96582C30.844 9.66449 30.7645 9.37469 30.6387 9.09766C30.5177 8.81592 30.3337 8.58503 30.0869 8.40527C29.8449 8.22551 29.5157 8.13579 29.0996 8.13574C28.8769 8.13574 28.6563 8.17221 28.4385 8.24512C28.2206 8.31802 28.0219 8.4442 27.8428 8.62402C27.6685 8.79899 27.5284 9.04249 27.4219 9.35352C27.3154 9.65965 27.2617 10.0532 27.2617 10.5342V14.5801H25.4902V6.70703H27.0518V7.58301C27.2521 7.34675 27.486 7.14172 27.7559 6.96973C28.2593 6.64409 28.8794 6.48047 29.6152 6.48047ZM48.748 5.83887H44.2021V8.45605H47.876V10.2061H44.2021V14.5801H42.4521V4.08203H48.748V5.83887ZM62.5137 6.67773C62.7606 6.65829 63.001 6.66815 63.2334 6.70703V8.34766C63.001 8.27961 62.7317 8.25695 62.4268 8.28125C62.1267 8.30557 61.8553 8.39134 61.6133 8.53711C61.3715 8.66829 61.1733 8.83606 61.0186 9.04004C60.8686 9.24404 60.7572 9.47701 60.6846 9.73926C60.612 9.99685 60.5752 10.2768 60.5752 10.5781V14.5801H58.8184V6.70703H60.3652V7.96582C60.4243 7.85986 60.4888 7.75824 60.5605 7.66211C60.7251 7.4434 60.9219 7.26302 61.1494 7.12207C61.3429 6.99098 61.5559 6.88926 61.7881 6.81641C62.0251 6.73869 62.267 6.69235 62.5137 6.67773ZM67.8057 8.0625C67.3362 8.06252 66.9485 8.17982 66.6436 8.41309C66.3389 8.64144 66.1139 8.95232 65.9688 9.3457C65.8235 9.7345 65.751 10.1673 65.751 10.6436C65.751 11.1247 65.8215 11.5624 65.9619 11.9561C66.1071 12.3447 66.3269 12.6535 66.6221 12.8818C66.9174 13.1103 67.293 13.2246 67.748 13.2246C68.2174 13.2246 68.5953 13.1171 68.8809 12.9033C69.1711 12.6846 69.3811 12.3808 69.5117 11.9922C69.6473 11.6034 69.7158 11.1539 69.7158 10.6436C69.7158 10.1284 69.6473 9.67886 69.5117 9.29492C69.381 8.90617 69.1753 8.60445 68.8945 8.39062C68.6138 8.17213 68.2508 8.0625 67.8057 8.0625ZM53.3047 8.13574C52.8351 8.13574 52.4475 8.24222 52.1426 8.45605C51.8425 8.66504 51.6198 8.95977 51.4746 9.33887C51.3295 9.71303 51.2568 10.148 51.2568 10.6436C51.2568 11.4066 51.4288 12.0168 51.7725 12.4736C52.121 12.9256 52.6318 13.1514 53.3047 13.1514C54.0017 13.1514 54.5196 12.9177 54.8584 12.4512C55.1971 11.9846 55.3672 11.3822 55.3672 10.6436C55.3672 9.8807 55.1951 9.27324 54.8516 8.82129C54.5079 8.36444 53.9921 8.13575 53.3047 8.13574ZM76.8203 8.02637C76.1039 8.02637 75.5712 8.25013 75.2227 8.69727C74.9987 8.98144 74.8476 9.35094 74.7676 9.80566H78.6221C78.5589 9.29301 78.4236 8.89686 78.2139 8.61719C77.9186 8.22359 77.4543 8.02645 76.8203 8.02637Z\"\r\n fill=\"black\"\r\n />\r\n <defs>\r\n <linearGradient\r\n id=\"paint0_linear_2976_9475\"\r\n x1=\"1.85883\"\r\n y1=\"1.92425\"\r\n x2=\"24.3072\"\r\n y2=\"9.64016\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop />\r\n <stop offset=\"1\" stopOpacity=\"0.4\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"paint1_linear_2976_9475\"\r\n x1=\"25.6475\"\r\n y1=\"8.65468\"\r\n x2=\"10.7901\"\r\n y2=\"8.65468\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop />\r\n <stop offset=\"1\" stopOpacity=\"0.4\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n </Link>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { ReactNode, CSSProperties } from 'react';\r\nimport '../../styles.css';\r\nimport { AuthBranding } from './AuthBranding';\r\n\r\ninterface AuthContainerProps {\r\n children: ReactNode;\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * Main container component for authentication forms.\r\n * \r\n * Provides consistent styling and layout for authentication pages.\r\n * Wraps auth content in a centered card with proper spacing and shadows.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthContainer>\r\n * <AuthHeader title=\"Sign In\" />\r\n * <form>...</form>\r\n * </AuthContainer>\r\n * ```\r\n * \r\n * @param {ReactNode} children - Content to display inside the auth container\r\n * @param {CSSProperties} [style] - Optional custom CSS styles for the container\r\n */\r\nexport function AuthContainer({ children, style }: AuthContainerProps) {\r\n return (\r\n <div className=\"insforge-auth-container\" style={style}>\r\n <div className=\"insforge-auth-card\">\r\n <div className=\"insforge-auth-content\">{children}</div>\r\n <AuthBranding />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\ninterface AuthHeaderProps {\r\n title: string;\r\n subtitle?: string;\r\n}\r\n\r\n/**\r\n * Header component for authentication forms displaying title and optional subtitle.\r\n * \r\n * Provides consistent typography and spacing for auth page headers.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthHeader \r\n * title=\"Welcome Back\" \r\n * subtitle=\"Sign in to continue to your account\" \r\n * />\r\n * ```\r\n * \r\n * @param {string} title - Main heading text to display\r\n * @param {string} [subtitle] - Optional subheading text for additional context\r\n */\r\nexport function AuthHeader({ title, subtitle }: AuthHeaderProps) {\r\n return (\r\n <div className=\"insforge-auth-header\">\r\n <h1 className=\"insforge-auth-title\">{title}</h1>\r\n {subtitle && <p className=\"insforge-auth-subtitle\">{subtitle}</p>}\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { AlertTriangle } from 'lucide-react';\r\n\r\ninterface AuthErrorBannerProps {\r\n error: string;\r\n}\r\n\r\n/**\r\n * Error message banner for authentication forms.\r\n * \r\n * Displays error messages with an alert icon in a styled banner.\r\n * Automatically hides when no error is present.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthErrorBanner error={error} />\r\n * ```\r\n * \r\n * @param {string} error - Error message to display (empty string or null to hide)\r\n */\r\nexport function AuthErrorBanner({ error }: AuthErrorBannerProps) {\r\n if (!error) return null;\r\n\r\n return (\r\n <div className=\"insforge-error-banner\">\r\n <AlertTriangle className=\"insforge-error-icon\" />\r\n <span>{error}</span>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { InputHTMLAttributes } from 'react';\r\n\r\ninterface AuthFormFieldProps extends InputHTMLAttributes<HTMLInputElement> {\r\n label: string;\r\n id: string;\r\n}\r\n\r\n/**\r\n * Standard form input field with label for authentication forms.\r\n * \r\n * Provides consistent styling for text inputs, email fields, and other basic input types.\r\n * Supports all standard HTML input attributes.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthFormField\r\n * id=\"email\"\r\n * type=\"email\"\r\n * label=\"Email Address\"\r\n * placeholder=\"you@example.com\"\r\n * value={email}\r\n * onChange={(e) => setEmail(e.target.value)}\r\n * required\r\n * />\r\n * ```\r\n * \r\n * @param {string} label - Label text displayed above the input\r\n * @param {string} id - Unique identifier for the input element\r\n * @param {InputHTMLAttributes} props - All standard HTML input attributes\r\n */\r\nexport function AuthFormField({ label, id, className = '', ...props }: AuthFormFieldProps) {\r\n return (\r\n <div className=\"insforge-form-group\">\r\n <label htmlFor={id} className=\"insforge-form-label\">\r\n {label}\r\n </label>\r\n <input\r\n id={id}\r\n className={`insforge-input ${className}`}\r\n {...props}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useState, type InputHTMLAttributes } from 'react';\r\nimport { Eye, EyeOff } from 'lucide-react';\r\nimport { AuthPasswordStrengthIndicator } from './AuthPasswordStrengthIndicator';\r\n\r\ninterface AuthPasswordFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\r\n label: string;\r\n id: string;\r\n showStrengthIndicator?: boolean;\r\n forgotPasswordLink?: {\r\n href: string;\r\n text?: string;\r\n };\r\n}\r\n\r\n/**\r\n * Password input field with visibility toggle and optional strength indicator.\r\n * \r\n * Features:\r\n * - Show/hide password toggle button\r\n * - Optional password strength requirements display\r\n * - Optional \"Forgot Password?\" link\r\n * - Supports all standard input attributes\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * // Sign-in password field with forgot link\r\n * <AuthPasswordField\r\n * id=\"password\"\r\n * label=\"Password\"\r\n * value={password}\r\n * onChange={(e) => setPassword(e.target.value)}\r\n * forgotPasswordLink={{ href: '/forgot-password' }}\r\n * required\r\n * />\r\n * \r\n * // Sign-up password with strength indicator\r\n * <AuthPasswordField\r\n * id=\"password\"\r\n * label=\"Create Password\"\r\n * value={password}\r\n * onChange={(e) => setPassword(e.target.value)}\r\n * showStrengthIndicator\r\n * required\r\n * />\r\n * ```\r\n * \r\n * @param {string} label - Label text displayed above the input\r\n * @param {string} id - Unique identifier for the input element\r\n * @param {boolean} [showStrengthIndicator=false] - Whether to show password strength requirements\r\n * @param {object} [forgotPasswordLink] - Configuration for forgot password link\r\n * @param {string} forgotPasswordLink.href - URL for the forgot password page\r\n * @param {string} [forgotPasswordLink.text] - Custom text for the link (default: \"Forget Password?\")\r\n */\r\nexport function AuthPasswordField({\r\n label,\r\n id,\r\n showStrengthIndicator = false,\r\n forgotPasswordLink,\r\n value,\r\n className = '',\r\n onFocus,\r\n ...props\r\n}: AuthPasswordFieldProps) {\r\n const [showPassword, setShowPassword] = useState(false);\r\n const [showStrength, setShowStrength] = useState(false);\r\n\r\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\r\n if (showStrengthIndicator) {\r\n setShowStrength(true);\r\n }\r\n onFocus?.(e);\r\n };\r\n\r\n return (\r\n <div className=\"insforge-form-group\">\r\n {(label || forgotPasswordLink) && (\r\n <div className=\"insforge-form-label-row\">\r\n <label htmlFor={id} className=\"insforge-form-label\" style={{ margin: 0 }}>\r\n {label}\r\n </label>\r\n {forgotPasswordLink && (\r\n <a href={forgotPasswordLink.href} className=\"insforge-form-link\">\r\n {forgotPasswordLink.text || 'Forget Password?'}\r\n </a>\r\n )}\r\n </div>\r\n )}\r\n <div className=\"insforge-input-wrapper\">\r\n <input\r\n id={id}\r\n type={showPassword ? 'text' : 'password'}\r\n className={`insforge-input insforge-input-with-icon ${className}`}\r\n value={value}\r\n onFocus={handleFocus}\r\n {...props}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowPassword(!showPassword)}\r\n className=\"insforge-input-icon-btn\"\r\n aria-label={showPassword ? 'Hide password' : 'Show password'}\r\n >\r\n {showPassword ? <EyeOff size={20} /> : <Eye size={20} />}\r\n </button>\r\n </div>\r\n {showStrengthIndicator && showStrength && (\r\n <AuthPasswordStrengthIndicator password={String(value || '')} />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n","\"use client\";\r\n\r\nimport { Check } from \"lucide-react\";\r\nimport \"../../styles.css\";\r\n\r\ninterface AuthPasswordStrengthIndicatorProps {\r\n password: string;\r\n}\r\n\r\ninterface PasswordRequirement {\r\n label: string;\r\n test: (password: string) => boolean;\r\n}\r\n\r\nconst requirements: PasswordRequirement[] = [\r\n {\r\n label: \"At least 1 Uppercase letter\",\r\n test: (pwd) => /[A-Z]/.test(pwd),\r\n },\r\n {\r\n label: \"At least 1 Number\",\r\n test: (pwd) => /\\d/.test(pwd),\r\n },\r\n {\r\n label: \"Special character (e.g. !?<>@#$%)\",\r\n test: (pwd) => /[!@#$%^&*()_+\\-=[\\]{};\\\\|,.<>/?]/.test(pwd),\r\n },\r\n {\r\n label: \"8 characters or more\",\r\n test: (pwd) => pwd.length >= 8,\r\n },\r\n];\r\n\r\n/**\r\n * Validates that a password meets all strength requirements.\r\n * \r\n * Requirements:\r\n * - At least 1 uppercase letter\r\n * - At least 1 number\r\n * - At least 1 special character\r\n * - Minimum 8 characters\r\n * \r\n * @param password - The password string to validate\r\n * @returns true if all requirements are met, false otherwise\r\n */\r\nexport function validatePasswordStrength(password: string): boolean {\r\n if (!password) return false;\r\n return requirements.every((req) => req.test(password));\r\n}\r\n\r\n/**\r\n * Visual indicator component showing password strength requirements.\r\n * Displays checkmarks as each requirement is satisfied.\r\n * \r\n * @param password - The current password value to validate against requirements\r\n */\r\nexport function AuthPasswordStrengthIndicator({ password }: AuthPasswordStrengthIndicatorProps) {\r\n return (\r\n <div className=\"insforge-password-strength\">\r\n {requirements.map((requirement, index) => {\r\n const isValid = requirement.test(password);\r\n return (\r\n <div key={index} className=\"insforge-password-requirement\">\r\n <div\r\n className={`insforge-password-check ${\r\n isValid ? \"insforge-password-check-valid\" : \"\"\r\n }`}\r\n >\r\n {isValid && <Check className=\"insforge-password-check-icon\" size={12} />}\r\n </div>\r\n <span className=\"insforge-password-requirement-label\">{requirement.label}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { CircleCheck, Loader2 } from 'lucide-react';\r\nimport type { CSSProperties, ReactNode } from 'react';\r\n\r\ninterface AuthSubmitButtonProps {\r\n children: ReactNode;\r\n isLoading?: boolean;\r\n confirmed?: boolean;\r\n disabled?: boolean;\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * Primary submit button for authentication forms with loading and confirmed states.\r\n * \r\n * Features:\r\n * - Loading spinner animation\r\n * - Confirmed check icon\r\n * - Disabled state during submission\r\n * - Customizable styling\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthSubmitButton \r\n * isLoading={loading}\r\n * >\r\n * Sign In\r\n * </AuthSubmitButton>\r\n * \r\n * <AuthSubmitButton \r\n * confirmed={true}\r\n * >\r\n * Verified\r\n * </AuthSubmitButton>\r\n * ```\r\n * \r\n * @param {ReactNode} children - Button text content\r\n * @param {boolean} [isLoading=false] - Whether the button is in loading state\r\n * @param {boolean} [confirmed=false] - Whether the button is in confirmed state\r\n * @param {boolean} [disabled=false] - Whether the button is disabled\r\n * @param {CSSProperties} [style] - Optional custom CSS styles\r\n */\r\nexport function AuthSubmitButton({\r\n children,\r\n isLoading = false,\r\n confirmed = false,\r\n disabled = false,\r\n style,\r\n}: AuthSubmitButtonProps) {\r\n return (\r\n <button\r\n type=\"submit\"\r\n className=\"insforge-btn-primary\"\r\n style={style}\r\n disabled={disabled || isLoading || confirmed}\r\n data-loading={isLoading || undefined}\r\n data-confirmed={confirmed || undefined}\r\n >\r\n {isLoading && <Loader2 className=\"insforge-btn-loader\" size={20} />}\r\n {confirmed && <CircleCheck className=\"insforge-btn-check\" size={20} />}\r\n {children}\r\n </button>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\ninterface AuthDividerProps {\r\n text?: string;\r\n}\r\n\r\n/**\r\n * Visual divider with optional centered text for auth forms.\r\n * \r\n * Typically used to separate email/password login from OAuth providers.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthDivider text=\"or\" />\r\n * <AuthDivider text=\"or continue with\" />\r\n * ```\r\n * \r\n * @param {string} [text='or'] - Text to display in the center of the divider\r\n */\r\nexport function AuthDivider({ text = 'or' }: AuthDividerProps) {\r\n return (\r\n <div className=\"insforge-divider\">\r\n <span className=\"insforge-divider-text\">{text}</span>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\ninterface AuthLinkProps {\r\n text: string;\r\n linkText: string;\r\n href: string;\r\n}\r\n\r\n/**\r\n * Call-to-action link component for navigation between auth pages.\r\n * \r\n * Commonly used to link between sign-in and sign-up pages.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthLink \r\n * text=\"Don't have an account?\" \r\n * linkText=\"Sign up\" \r\n * href=\"/sign-up\" \r\n * />\r\n * \r\n * <AuthLink \r\n * text=\"Already have an account?\" \r\n * linkText=\"Sign in\" \r\n * href=\"/sign-in\" \r\n * />\r\n * ```\r\n * \r\n * @param {string} text - Regular text before the link\r\n * @param {string} linkText - Clickable link text\r\n * @param {string} href - URL to navigate to when clicked\r\n */\r\nexport function AuthLink({ text, linkText, href }: AuthLinkProps) {\r\n return (\r\n <p className=\"insforge-text-center\">\r\n {text}{' '}\r\n <a href={href} className=\"insforge-link-primary\">\r\n {linkText}\r\n </a>\r\n </p>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { Loader2 } from 'lucide-react';\r\nimport type { OAuthProvider } from '../../types';\r\nimport { getProviderConfig } from '../../config/oauth-providers';\r\n\r\ntype DisplayMode = 'full' | 'short' | 'icon';\r\n\r\ninterface AuthOAuthButtonProps {\r\n provider: OAuthProvider;\r\n onClick: (provider: OAuthProvider) => void;\r\n disabled?: boolean;\r\n loading?: boolean;\r\n displayMode?: DisplayMode;\r\n style?: React.CSSProperties;\r\n}\r\n\r\n/**\r\n * OAuth provider button with adaptive display modes.\r\n * \r\n * Automatically adjusts its display based on the specified mode:\r\n * - 'full': Full text \"Continue with [Provider]\" + icon\r\n * - 'short': Provider name only + icon\r\n * - 'icon': Icon only (compact mode)\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthOAuthButton\r\n * provider=\"google\"\r\n * onClick={(provider) => handleOAuth(provider)}\r\n * displayMode=\"full\"\r\n * />\r\n * ```\r\n * \r\n * @param {OAuthProvider} provider - OAuth provider identifier (e.g., 'google', 'github')\r\n * @param {Function} onClick - Callback function when button is clicked\r\n * @param {boolean} [disabled] - Whether the button is disabled\r\n * @param {boolean} [loading] - Whether the button is in loading state\r\n * @param {DisplayMode} [displayMode='full'] - Display mode for the button\r\n * @param {React.CSSProperties} [style] - Optional custom CSS styles\r\n */\r\nexport function AuthOAuthButton({ \r\n provider, \r\n onClick, \r\n disabled, \r\n loading, \r\n displayMode = 'full',\r\n style \r\n}: AuthOAuthButtonProps) {\r\n const config = getProviderConfig(provider);\r\n\r\n if (!config) {\r\n return null;\r\n }\r\n\r\n const getButtonText = () => {\r\n if (loading) return 'Authenticating...';\r\n if (displayMode === 'full') return `Continue with ${config.name}`;\r\n if (displayMode === 'short') return config.name;\r\n return ''; // icon only mode\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={() => onClick(provider)}\r\n className=\"insforge-oauth-btn\"\r\n disabled={disabled || loading}\r\n data-loading={loading || undefined}\r\n data-display-mode={displayMode}\r\n style={style}\r\n >\r\n <Loader2 className=\"insforge-oauth-loader\" size={18} />\r\n <span className=\"insforge-oauth-icon\">{config.svg}</span>\r\n {getButtonText() && <span className=\"insforge-oauth-text\">{getButtonText()}</span>}\r\n </button>\r\n );\r\n}\r\n\r\n","import type { OAuthProvider, OAuthProviderConfig } from '../types';\r\n\r\nexport const OAUTH_PROVIDER_CONFIG: Record<OAuthProvider, OAuthProviderConfig> = {\r\n google: {\r\n name: 'Google',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <path\r\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\r\n fill=\"#4285F4\"\r\n />\r\n <path\r\n d=\"M9 18c2.43 0 4.467-.806 5.956-2.184l-2.908-2.258c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332C2.438 15.983 5.482 18 9 18z\"\r\n fill=\"#34A853\"\r\n />\r\n <path\r\n d=\"M3.964 10.707c-.18-.54-.282-1.117-.282-1.707 0-.593.102-1.17.282-1.709V4.958H.957C.347 6.173 0 7.548 0 9c0 1.452.348 2.827.957 4.042l3.007-2.335z\"\r\n fill=\"#FBBC05\"\r\n />\r\n <path\r\n d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0 5.482 0 2.438 2.017.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z\"\r\n fill=\"#EA4335\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-google',\r\n },\r\n github: {\r\n name: 'GitHub',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-github',\r\n },\r\n discord: {\r\n name: 'Discord',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20.317 4.37a19.791 19.791 0 00-4.885-1.515.074.074 0 00-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 00-5.487 0 12.64 12.64 0 00-.617-1.25.077.077 0 00-.079-.037A19.736 19.736 0 003.677 4.37a.07.07 0 00-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 00.031.057 19.9 19.9 0 005.993 3.03.078.078 0 00.084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 00-.041-.106 13.107 13.107 0 01-1.872-.892.077.077 0 01-.008-.128 10.2 10.2 0 00.372-.292.074.074 0 01.077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 01.078.01c.12.098.246.198.373.292a.077.077 0 01-.006.127 12.299 12.299 0 01-1.873.892.077.077 0 00-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 00.084.028 19.839 19.839 0 006.002-3.03.077.077 0 00.032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 00-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z\"\r\n fill=\"#5865F2\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-discord',\r\n },\r\n facebook: {\r\n name: 'Facebook',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M24 12.073C24 5.405 18.627 0 12 0S0 5.405 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047v-2.66c0-3.025 1.792-4.697 4.533-4.697 1.312 0 2.686.236 2.686.236v2.971H15.83c-1.49 0-1.955.93-1.955 1.886v2.264h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z\"\r\n fill=\"#1877F2\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-facebook',\r\n },\r\n linkedin: {\r\n name: 'LinkedIn',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\"\r\n fill=\"#0A66C2\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-linkedin',\r\n },\r\n microsoft: {\r\n name: 'Microsoft',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 23 23\" fill=\"none\">\r\n <path d=\"M0 0h11v11H0z\" fill=\"#F25022\" />\r\n <path d=\"M12 0h11v11H12z\" fill=\"#7FBA00\" />\r\n <path d=\"M0 12h11v11H0z\" fill=\"#00A4EF\" />\r\n <path d=\"M12 12h11v11H12z\" fill=\"#FFB900\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-microsoft',\r\n },\r\n apple: {\r\n name: 'Apple',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-apple',\r\n },\r\n x: {\r\n name: 'X',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-x',\r\n },\r\n instagram: {\r\n name: 'Instagram',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"\r\n fill=\"url(#instagram-gradient)\"\r\n />\r\n <defs>\r\n <linearGradient id=\"instagram-gradient\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\r\n <stop offset=\"0%\" stopColor=\"#FD5949\" />\r\n <stop offset=\"50%\" stopColor=\"#D6249F\" />\r\n <stop offset=\"100%\" stopColor=\"#285AEB\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-instagram',\r\n },\r\n tiktok: {\r\n name: 'TikTok',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M19.589 6.686a4.793 4.793 0 01-3.77-4.245V2h-3.445v13.672a2.896 2.896 0 01-5.201 1.743l-.002-.001.002.001a2.895 2.895 0 013.183-4.51v-3.5a6.329 6.329 0 00-5.394 10.692 6.33 6.33 0 0010.857-4.424V8.687a8.182 8.182 0 004.773 1.526V6.79a4.831 4.831 0 01-1.003-.104z\"\r\n fill=\"currentColor\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-tiktok',\r\n },\r\n spotify: {\r\n name: 'Spotify',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z\"\r\n fill=\"#1DB954\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-spotify',\r\n },\r\n};\r\n\r\n/**\r\n * Get OAuth provider configuration\r\n */\r\nexport function getProviderConfig(provider: OAuthProvider): OAuthProviderConfig | null {\r\n return OAUTH_PROVIDER_CONFIG[provider] || null;\r\n}\r\n\r\n/**\r\n * Get provider display name\r\n */\r\nexport function getProviderName(provider: OAuthProvider): string {\r\n return OAUTH_PROVIDER_CONFIG[provider]?.name || provider;\r\n}\r\n\r\n/**\r\n * Check if provider is supported\r\n */\r\nexport function isProviderSupported(provider: string): provider is OAuthProvider {\r\n return provider in OAUTH_PROVIDER_CONFIG;\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { OAuthProvider } from '../../types';\r\nimport { AuthOAuthButton } from './AuthOAuthButton';\r\n\r\ninterface AuthOAuthProvidersProps {\r\n providers: OAuthProvider[];\r\n onClick: (provider: OAuthProvider) => void;\r\n disabled?: boolean;\r\n loading: OAuthProvider | null;\r\n}\r\n\r\n/**\r\n * Smart OAuth provider grid with adaptive layout.\r\n * \r\n * Automatically adjusts button display based on the number of providers:\r\n * - 1 provider: Full-width button with full text\r\n * - 2 or 4 providers: Two-column grid with short text\r\n * - 3+ providers: Three-column grid with icons only\r\n * - Automatically centers incomplete last rows (e.g., 5, 8, 11 providers)\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthOAuthProviders\r\n * providers={['google', 'github', 'discord']}\r\n * onClick={handleOAuth}\r\n * loading={currentProvider}\r\n * />\r\n * ```\r\n * \r\n * @param {OAuthProvider[]} providers - Array of OAuth provider identifiers\r\n * @param {Function} onClick - Callback function when a provider button is clicked\r\n * @param {boolean} [disabled] - Whether all buttons are disabled\r\n * @param {OAuthProvider | null} loading - Currently loading provider (or null)\r\n */\r\nexport function AuthOAuthProviders({\r\n providers,\r\n onClick,\r\n disabled,\r\n loading,\r\n}: AuthOAuthProvidersProps) {\r\n if (!providers || providers.length === 0) {\r\n return null;\r\n }\r\n\r\n const count = providers.length;\r\n\r\n // Determine display mode based on count\r\n const getDisplayMode = () => {\r\n if (count === 1) return 'full';\r\n if (count === 2 || count === 4) return 'short';\r\n return 'icon';\r\n };\r\n\r\n // Calculate grid column style for each button\r\n const getGridColumnStyle = (index: number): React.CSSProperties => {\r\n // Special cases: 1-4 providers don't use 6-column grid\r\n if (count <= 4) {\r\n return {};\r\n }\r\n\r\n // For 5+ providers, use 6-column grid\r\n const totalRows = Math.ceil(count / 3);\r\n const lastRowStartIndex = (totalRows - 1) * 3;\r\n const isInLastRow = index >= lastRowStartIndex;\r\n\r\n if (!isInLastRow) {\r\n // Not in last row, use default span 2\r\n return { gridColumn: 'span 2' };\r\n }\r\n\r\n // Calculate position in last row (0-based)\r\n const positionInLastRow = index - lastRowStartIndex;\r\n const itemsInLastRow = count - lastRowStartIndex;\r\n\r\n if (itemsInLastRow === 1) {\r\n // Last row has 1 item: center it at columns 3-4\r\n return { gridColumn: '3 / 5' };\r\n } else if (itemsInLastRow === 2) {\r\n // Last row has 2 items: center them at 2-3 and 4-5\r\n if (positionInLastRow === 0) {\r\n return { gridColumn: '2 / 4' };\r\n } else {\r\n return { gridColumn: '4 / 6' };\r\n }\r\n } else {\r\n // Last row has 3 items: normal span 2\r\n return { gridColumn: 'span 2' };\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"insforge-oauth-container\" data-provider-count={count}>\r\n {providers.map((provider, index) => (\r\n <AuthOAuthButton\r\n key={provider}\r\n provider={provider}\r\n onClick={onClick}\r\n disabled={disabled}\r\n loading={loading === provider}\r\n displayMode={getDisplayMode()}\r\n style={getGridColumnStyle(index)}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport {\r\n useRef,\r\n KeyboardEvent,\r\n ClipboardEvent,\r\n ChangeEvent,\r\n} from \"react\";\r\n\r\ninterface AuthVerificationCodeInputProps {\r\n length?: number;\r\n value: string;\r\n email: string;\r\n onChange: (value: string) => void;\r\n disabled?: boolean;\r\n}\r\n\r\n/**\r\n * 6-digit verification code input component\r\n *\r\n * Features:\r\n * - Auto-focus next input on digit entry\r\n * - Auto-focus previous input on backspace\r\n * - Paste support for full code\r\n * - Numeric input only\r\n *\r\n * @component\r\n * @example\r\n * ```tsx\r\n * const [code, setCode] = useState('');\r\n *\r\n * <AuthVerificationCodeInput\r\n * value={code}\r\n * onChange={setCode}\r\n * />\r\n * ```\r\n */\r\nexport function AuthVerificationCodeInput({\r\n length = 6,\r\n value,\r\n email,\r\n onChange,\r\n disabled = false,\r\n}: AuthVerificationCodeInputProps) {\r\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\r\n\r\n const handleChange = (index: number, digit: string) => {\r\n // Only allow single digits\r\n if (digit.length > 1) return;\r\n\r\n // Only allow numbers\r\n if (digit && !/^\\d$/.test(digit)) return;\r\n\r\n // Update the value\r\n const newValue = value.split(\"\");\r\n newValue[index] = digit;\r\n const updatedValue = newValue.join(\"\");\r\n onChange(updatedValue);\r\n\r\n // Auto-focus next input if digit was entered\r\n if (digit && index < length - 1) {\r\n inputRefs.current[index + 1]?.focus();\r\n }\r\n };\r\n\r\n const handleKeyDown = (index: number, e: KeyboardEvent<HTMLInputElement>) => {\r\n // Handle backspace\r\n if (e.key === \"Backspace\") {\r\n if (!value[index] && index > 0) {\r\n // If current input is empty, focus previous input\r\n inputRefs.current[index - 1]?.focus();\r\n } else {\r\n // Clear current input\r\n handleChange(index, \"\");\r\n }\r\n }\r\n // Handle arrow keys\r\n else if (e.key === \"ArrowLeft\" && index > 0) {\r\n inputRefs.current[index - 1]?.focus();\r\n } else if (e.key === \"ArrowRight\" && index < length - 1) {\r\n inputRefs.current[index + 1]?.focus();\r\n }\r\n };\r\n\r\n const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const pastedData = e.clipboardData.getData(\"text/plain\").trim();\r\n\r\n // Only paste if it's all digits and correct length\r\n if (/^\\d+$/.test(pastedData) && pastedData.length === length) {\r\n onChange(pastedData);\r\n // Focus last input\r\n inputRefs.current[length - 1]?.focus();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"insforge-verification-code-container\">\r\n <p className=\"insforge-verification-instructions\">\r\n We've sent a verification code to your inbox at <span>{email}</span>.\r\n Enter it below to proceed.\r\n </p>\r\n <div className=\"insforge-verification-code-inputs\">\r\n {Array.from({ length }).map((_, index) => (\r\n <input\r\n key={index}\r\n ref={(el) => {\r\n inputRefs.current[index] = el;\r\n }}\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n maxLength={1}\r\n value={value[index] || \"\"}\r\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\r\n handleChange(index, e.target.value)\r\n }\r\n onKeyDown={(e: KeyboardEvent<HTMLInputElement>) =>\r\n handleKeyDown(index, e)\r\n }\r\n onPaste={handlePaste}\r\n disabled={disabled}\r\n className=\"insforge-verification-code-input\"\r\n autoComplete=\"one-time-code\"\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\n\nimport { useState, FormEvent } from \"react\";\nimport { createClient } from \"@insforge/sdk\";\nimport { useInsforge } from \"../provider/InsforgeProvider\";\nimport { useOAuthProviders } from \"../hooks/useOAuthProviders\";\nimport type { SignUpProps, OAuthProvider } from \"../types\";\nimport {\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthProviders,\n // AuthVerificationCodeInput, // Commented out - email verification disabled for now\n validatePasswordStrength,\n} from \"./auth\";\nimport \"../styles.css\";\n\n/**\n * Pre-built sign-up component with email/password registration and OAuth providers.\n *\n * @component\n * @example\n * ```tsx\n * // Basic usage - OAuth providers auto-detected from backend\n * <SignUp />\n *\n * // With custom UI text\n * <SignUp\n * title=\"Get Started\"\n * subtitle=\"Create your account\"\n * afterSignUpUrl=\"/onboarding\"\n * />\n *\n * // Override OAuth providers manually (optional)\n * <SignUp providers={['google', 'github']} />\n * ```\n *\n * @param {SignUpProps} props - Component props\n * @param {string} [props.afterSignUpUrl='/'] - URL to redirect to after successful sign-up\n * @param {OAuthProvider[]} [props.providers] - Optional: Manually specify OAuth providers (auto-detected by default)\n * @param {object} [props.appearance] - Custom styles for container, form, and button elements\n * @param {function} [props.onSuccess] - Callback invoked after successful sign-up with user data\n * @param {function} [props.onError] - Callback invoked when sign-up fails with error object\n *\n * @remarks\n * **OAuth Setup:**\n * - OAuth providers are automatically detected from backend configuration\n * - Alternatively, pass `providers` prop to manually specify which providers to show\n * - **IMPORTANT:** You must create an OAuth callback page at `/auth/callback` in your app\n * See example implementation in the package README\n *\n * **OAuth Flow:**\n * 1. User clicks OAuth button\n * 2. Redirects to provider (GitHub, Google, etc.)\n * 3. After authorization, provider redirects to `/auth/callback?access_token=...`\n * 4. Callback page stores token in localStorage\n * 5. User redirected to `afterSignUpUrl`\n *\n * **Password Requirements:**\n * - Password must be at least 8 characters long\n */\nexport function SignUp({\n afterSignUpUrl = \"/\",\n appearance = {},\n title = \"Get Started\",\n subtitle = \"Create account\",\n emailLabel = \"Email\",\n emailPlaceholder = \"example@email.com\",\n passwordLabel = \"Password\",\n passwordPlaceholder = \"••••••\",\n submitButtonText = \"Sign Up\",\n loadingButtonText = \"Creating account...\",\n // verifyButtonText = \"Continue\", // Commented out - email verification disabled for now\n // loadingVerifyButtonText = \"Verifying...\", // Commented out - email verification disabled for now\n // verifiedButtonText = \"Verified\", // Commented out - email verification disabled for now\n signInText = \"Already have an account?\",\n signInLinkText = \"Login Now\",\n signInUrl = \"/sign-in\",\n dividerText = \"or\",\n onSuccess,\n onError,\n}: SignUpProps) {\n // const { sendVerificationCode, verifySignUpCode, oauthProviders, baseUrl } = // Commented out - email verification disabled for now\n const { signUp, baseUrl } = useInsforge(); // Direct signup without verification\n const { providers: oauthProviders } = useOAuthProviders();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n // const [verificationCode, setVerificationCode] = useState(\"\"); // Commented out - email verification disabled for now\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [oauthLoading, setOauthLoading] = useState<OAuthProvider | null>(null);\n // const [verified, setVerified] = useState(false); // Commented out - email verification disabled for now\n // const [step, setStep] = useState<\"credentials\" | \"verification\">( // Commented out - email verification disabled for now\n // \"credentials\"\n // );\n\n // Use a memoized client to prevent recreation on every render\n // This avoids SDK's OAuth detection running multiple times\n const insforge = useState(() => createClient({ baseUrl }))[0];\n\n async function handleCredentialsSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setLoading(true);\n setError(\"\");\n\n // Validate password strength before submission\n if (!validatePasswordStrength(password)) {\n setError(\"Password does not meet all requirements\");\n setLoading(false);\n return;\n }\n\n try {\n // Direct signup without email verification (verification disabled for now)\n await signUp(email, password);\n if (onSuccess) {\n const userResult = await insforge.auth.getCurrentUser();\n if (userResult.data) onSuccess(userResult.data as any);\n }\n window.location.href = afterSignUpUrl;\n \n // Email verification flow (commented out for now - will be added back in the future)\n // await sendVerificationCode(email, \"signup\");\n // setStep(\"verification\");\n } catch (err: any) {\n const errorMessage = err.message || \"Sign up failed\";\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n } finally {\n setLoading(false);\n }\n }\n\n // Email verification functions (commented out for now - will be added back in the future)\n // async function handleVerificationSubmit(e: FormEvent<HTMLFormElement>) {\n // e.preventDefault();\n // setLoading(true);\n // setError(\"\");\n\n // // Check if code is complete\n // if (verificationCode.length !== 6) {\n // setError(\"Please enter the complete verification code\");\n // setLoading(false);\n // return;\n // }\n\n // try {\n // // Verify code and complete sign up\n // await verifySignUpCode(email, password, verificationCode);\n // if (onSuccess) {\n // setVerified(true);\n // const userResult = await insforge.auth.getCurrentUser();\n // if (userResult.data) onSuccess(userResult.data as any);\n // }\n // window.location.href = afterSignUpUrl;\n // } catch (err: any) {\n // const errorMessage = err.message || \"Invalid verification code\";\n // setError(errorMessage);\n // if (onError) onError(new Error(errorMessage));\n // } finally {\n // setLoading(false);\n // }\n // }\n\n // async function handleResendCode() {\n // setLoading(true);\n // setError(\"\");\n // try {\n // await sendVerificationCode(email, \"signup\");\n // } catch (err: any) {\n // const errorMessage = err.message || \"Failed to resend code\";\n // setError(errorMessage);\n // } finally {\n // setLoading(false);\n // }\n // }\n\n async function handleOAuth(provider: OAuthProvider) {\n try {\n setOauthLoading(provider);\n // OAuth requires redirectTo parameter - backend will redirect here with token\n // We use /auth/callback as intermediate page to extract token from URL\n const redirectTo = `${window.location.origin}/auth/callback`;\n\n // Store the final destination for the callback page to use\n sessionStorage.setItem(\"oauth_final_destination\", afterSignUpUrl || \"/\");\n\n const result = await insforge.auth.signInWithOAuth({\n provider,\n redirectTo,\n });\n\n if (result.data?.url) {\n window.location.href = result.data.url;\n }\n } catch (err: any) {\n const errorMessage = err.message || `${provider} sign up failed`;\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n setOauthLoading(null);\n }\n }\n\n // Email and Password form (direct signup without verification)\n return (\n <AuthContainer style={appearance.container}>\n <AuthHeader title={title} subtitle={subtitle} />\n\n <AuthErrorBanner error={error} />\n\n <form onSubmit={handleCredentialsSubmit} className=\"insforge-form\">\n <AuthFormField\n id=\"email\"\n type=\"email\"\n label={emailLabel}\n placeholder={emailPlaceholder}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n />\n\n <AuthPasswordField\n id=\"password\"\n label={passwordLabel}\n placeholder={passwordPlaceholder}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n minLength={8}\n autoComplete=\"new-password\"\n showStrengthIndicator\n />\n\n <AuthSubmitButton\n isLoading={loading}\n disabled={loading || oauthLoading !== null}\n style={appearance.button}\n >\n {loading ? loadingButtonText : submitButtonText}\n </AuthSubmitButton>\n </form>\n\n <AuthLink\n text={signInText}\n linkText={signInLinkText}\n href={signInUrl}\n />\n\n {oauthProviders.length > 0 && (\n <>\n <AuthDivider text={dividerText} />\n <AuthOAuthProviders\n providers={oauthProviders}\n onClick={handleOAuth}\n disabled={loading || oauthLoading !== null}\n loading={oauthLoading}\n />\n </>\n )}\n </AuthContainer>\n );\n\n // Email verification step (commented out for now - will be added back in the future)\n // Step 1: Email and Password\n // if (step === \"credentials\") {\n // return (\n // <AuthContainer style={appearance.container}>\n // <AuthHeader title={title} subtitle={subtitle} />\n // <AuthErrorBanner error={error} />\n // <form onSubmit={handleCredentialsSubmit} className=\"insforge-form\">\n // <AuthFormField\n // id=\"email\"\n // type=\"email\"\n // label={emailLabel}\n // placeholder={emailPlaceholder}\n // value={email}\n // onChange={(e) => setEmail(e.target.value)}\n // required\n // autoComplete=\"email\"\n // />\n // <AuthPasswordField\n // id=\"password\"\n // label={passwordLabel}\n // placeholder={passwordPlaceholder}\n // value={password}\n // onChange={(e) => setPassword(e.target.value)}\n // required\n // minLength={8}\n // autoComplete=\"new-password\"\n // showStrengthIndicator\n // />\n // <AuthSubmitButton\n // isLoading={loading}\n // disabled={loading || oauthLoading !== null}\n // style={appearance.button}\n // >\n // {loading ? loadingButtonText : submitButtonText}\n // </AuthSubmitButton>\n // </form>\n // <AuthLink\n // text={signInText}\n // linkText={signInLinkText}\n // href={signInUrl}\n // />\n // {oauthProviders.length > 0 && (\n // <>\n // <AuthDivider text={dividerText} />\n // <AuthOAuthProviders\n // providers={oauthProviders}\n // onClick={handleOAuth}\n // disabled={loading || oauthLoading !== null}\n // loading={oauthLoading}\n // />\n // </>\n // )}\n // </AuthContainer>\n // );\n // }\n\n // Step 2: Verification Code\n // return (\n // <AuthContainer style={appearance.container}>\n // <AuthHeader title={title} subtitle={subtitle} />\n // <AuthErrorBanner error={error} />\n // <form onSubmit={handleVerificationSubmit} className=\"insforge-form\">\n // <AuthVerificationCodeInput\n // email={email}\n // value={verificationCode}\n // onChange={setVerificationCode}\n // disabled={loading}\n // />\n // <AuthSubmitButton\n // isLoading={loading}\n // disabled={loading}\n // style={appearance.button}\n // confirmed={verified}\n // >\n // {verified ? verifiedButtonText : loading ? loadingVerifyButtonText : verifyButtonText}\n // </AuthSubmitButton>\n // </form>\n // <div className=\"insforge-resend-code\">\n // Did not received the code?{\" \"}\n // <button\n // type=\"button\"\n // onClick={handleResendCode}\n // disabled={loading}\n // className=\"insforge-resend-link\"\n // >\n // Click to resend\n // </button>\n // </div>\n // </AuthContainer>\n // );\n}\n","'use client';\r\n\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport { LogOut } from 'lucide-react';\r\nimport { useInsforge } from '../provider/InsforgeProvider';\r\nimport type { UserButtonProps } from '../types';\r\n\r\n/**\r\n * User profile button with dropdown menu and sign-out functionality.\r\n * \r\n * Displays user avatar (or initials) and provides a dropdown menu with sign-out option.\r\n * Supports two display modes: 'detailed' (with email) and 'compact' (avatar only).\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * // Basic usage\r\n * <UserButton afterSignOutUrl=\"/\" />\r\n * \r\n * // Compact mode without details\r\n * <UserButton mode=\"compact\" />\r\n * \r\n * // With custom styling\r\n * <UserButton\r\n * appearance={{\r\n * button: { borderRadius: '12px' },\r\n * dropdown: { minWidth: '300px' }\r\n * }}\r\n * />\r\n * ```\r\n * \r\n * @param {UserButtonProps} props - Component props\r\n * @param {string} [props.afterSignOutUrl='/'] - URL to redirect to after sign-out\r\n * @param {'detailed'|'compact'} [props.mode='detailed'] - Display mode for the button\r\n * @param {object} [props.appearance] - Custom styles for button and dropdown elements\r\n */\r\nexport function UserButton({\r\n afterSignOutUrl = '/',\r\n mode = 'detailed',\r\n appearance = {},\r\n}: UserButtonProps) {\r\n const { user, signOut } = useInsforge();\r\n const [isOpen, setIsOpen] = useState(false);\r\n const dropdownRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n function handleClickOutside(event: MouseEvent) {\r\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\r\n setIsOpen(false);\r\n }\r\n }\r\n\r\n if (isOpen) {\r\n document.addEventListener('mousedown', handleClickOutside);\r\n }\r\n\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n };\r\n }, [isOpen]);\r\n\r\n async function handleSignOut() {\r\n await signOut();\r\n setIsOpen(false);\r\n window.location.href = afterSignOutUrl;\r\n }\r\n\r\n if (!user) return null;\r\n\r\n // Generate initials - prioritize nickname field if available, fallback to email\r\n const initials = user.nickname\r\n ? user.nickname.charAt(0).toUpperCase()\r\n : user.email.split('@')[0].slice(0, 2).toUpperCase();\r\n\r\n // Get avatar URL from user profile\r\n const avatarUrl = user.avatar_url;\r\n\r\n return (\r\n <div className=\"insforge-user-button-container\" ref={dropdownRef}>\r\n <button\r\n className={`insforge-user-button ${mode === 'detailed' ? 'insforge-user-button-detailed' : ''}`}\r\n onClick={() => setIsOpen(!isOpen)}\r\n style={appearance.button}\r\n aria-expanded={isOpen}\r\n aria-haspopup=\"true\"\r\n >\r\n {avatarUrl ? (\r\n <img src={avatarUrl} alt={user.email} className=\"insforge-user-avatar\" />\r\n ) : (\r\n <div className=\"insforge-user-avatar-placeholder\">{initials}</div>\r\n )}\r\n {mode === 'detailed' && (\r\n <div className=\"insforge-user-button-info\">\r\n {user.nickname && (\r\n <div className=\"insforge-user-button-name\">{user.nickname}</div>\r\n )}\r\n <div className=\"insforge-user-button-email\">{user.email}</div>\r\n </div>\r\n )}\r\n </button>\r\n\r\n {isOpen && (\r\n <div className=\"insforge-user-dropdown\" style={appearance.dropdown}>\r\n <button onClick={handleSignOut} className=\"insforge-sign-out-button\">\r\n <LogOut className=\"w-5 h-5\" />\r\n Sign out\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","'use client';\r\n\r\nimport { useInsforge } from '../provider/InsforgeProvider';\r\nimport type { ConditionalProps } from '../types';\r\n\r\n/**\r\n * Renders children only when user is signed in\r\n * @param children - React nodes to render when authenticated\r\n */\r\nexport function SignedIn({ children }: ConditionalProps) {\r\n const { isSignedIn, isLoaded } = useInsforge();\r\n\r\n if (!isLoaded) return null;\r\n if (!isSignedIn) return null;\r\n\r\n return <>{children}</>;\r\n}\r\n","'use client';\r\n\r\nimport { useInsforge } from '../provider/InsforgeProvider';\r\nimport type { ConditionalProps } from '../types';\r\n\r\n/**\r\n * Renders children only when user is signed out\r\n * @param children - React nodes to render when not authenticated\r\n */\r\nexport function SignedOut({ children }: ConditionalProps) {\r\n const { isSignedIn, isLoaded } = useInsforge();\r\n\r\n if (!isLoaded) return null;\r\n if (isSignedIn) return null;\r\n\r\n return <>{children}</>;\r\n}\r\n","'use client';\n\nimport { useInsforge } from '../provider/InsforgeProvider';\nimport { useEffect } from 'react';\nimport { useRouter } from 'next/navigation';\nimport type { ProtectProps } from '../types';\n\n/**\n * Protects content and redirects if not authenticated\n * Can also accept a condition function for role-based access\n * @param children - Content to protect\n * @param fallback - Optional fallback UI while loading\n * @param redirectTo - URL to redirect to if not authorized\n * @param condition - Optional function to check custom conditions (e.g., roles)\n */\nexport function Protect({\n children,\n fallback,\n redirectTo = '/sign-in',\n condition,\n}: ProtectProps) {\n const { isSignedIn, isLoaded, user } = useInsforge();\n const router = useRouter();\n\n useEffect(() => {\n if (isLoaded && !isSignedIn) {\n router.push(redirectTo);\n } else if (isLoaded && isSignedIn && condition && user) {\n // Check custom condition (e.g., role-based access)\n if (!condition(user)) {\n router.push(redirectTo);\n }\n }\n }, [isLoaded, isSignedIn, redirectTo, router, condition, user]);\n\n // Show fallback while loading\n if (!isLoaded) {\n return fallback || <div className=\"insforge-loading\">Loading...</div>;\n }\n\n // Don't render if not signed in\n if (!isSignedIn) {\n return fallback || null;\n }\n\n // Don't render if condition fails\n if (condition && user && !condition(user)) {\n return fallback || null;\n }\n\n return <>{children}</>;\n}\n"],"mappings":"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","names":["error","useState","useEffect","createClient","useState","useEffect","createClient","useState","createClient","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","jsx","jsx","jsxs","Loader2","jsx","jsxs","jsx","jsxs","Loader2","jsx","useRef","jsx","jsxs","jsx","jsxs","useState","createClient","useState","createClient","Fragment","jsx","jsxs","useState","createClient","useState","useRef","useEffect","jsx","jsxs","useState","useRef","useEffect","Fragment","jsx","Fragment","jsx","useEffect","Fragment","jsx"]}
1
+ {"version":3,"sources":["../src/provider/InsforgeProvider.tsx","../src/hooks/useAuth.ts","../src/hooks/useUser.ts","../src/hooks/useSession.ts","../src/components/SignIn.tsx","../src/hooks/useOAuthProviders.ts","../src/components/auth/AuthBranding.tsx","../src/components/auth/AuthContainer.tsx","../src/components/auth/AuthHeader.tsx","../src/components/auth/AuthErrorBanner.tsx","../src/components/auth/AuthFormField.tsx","../src/components/auth/AuthPasswordField.tsx","../src/components/auth/AuthPasswordStrengthIndicator.tsx","../src/components/auth/AuthSubmitButton.tsx","../src/components/auth/AuthDivider.tsx","../src/components/auth/AuthLink.tsx","../src/components/auth/AuthOAuthButton.tsx","../src/config/oauth-providers.tsx","../src/components/auth/AuthOAuthProviders.tsx","../src/components/auth/AuthVerificationCodeInput.tsx","../src/components/SignUp.tsx","../src/components/UserButton.tsx","../src/components/SignedIn.tsx","../src/components/SignedOut.tsx","../src/components/Protect.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useEffect, useState, useCallback, useRef, type ReactNode } from 'react';\nimport { createClient } from '@insforge/sdk';\nimport type { InsforgeUser, InsforgeSession, OAuthProvider } from '../types';\n\ninterface InsforgeContextValue {\n // Auth state\n user: InsforgeUser | null;\n session: InsforgeSession | null;\n isLoaded: boolean;\n isSignedIn: boolean;\n \n // Auth methods\n setUser: (user: InsforgeUser | null) => void;\n signIn: (email: string, password: string) => Promise<void>;\n signUp: (email: string, password: string) => Promise<void>;\n signOut: () => Promise<void>;\n updateUser: (data: Partial<InsforgeUser>) => Promise<void>;\n \n // Email verification methods (commented out - verification disabled for now)\n // sendVerificationCode: (email: string, type: 'signup' | 'signin') => Promise<void>;\n // verifySignUpCode: (email: string, password: string, code: string) => Promise<void>;\n // verifySignInCode: (email: string, code: string) => Promise<void>;\n \n // Base config\n baseUrl: string;\n}\n\nconst InsforgeContext = createContext<InsforgeContextValue | undefined>(undefined);\n\ninterface InsforgeProviderProps {\n children: ReactNode;\n baseUrl: string;\n frontendUrl?: string;\n onAuthChange?: (user: InsforgeUser | null) => void;\n useBuiltInAuth?: boolean;\n}\n\n// Sync token from localStorage to server-side cookie via API\nasync function syncTokenToCookie(token: string): Promise<boolean> {\n try {\n const response = await fetch('/api/auth', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n action: 'sync-token',\n token,\n }),\n });\n\n if (!response.ok) {\n return false;\n }\n\n return true;\n } catch (error) {\n return false;\n }\n}\n\n/**\n * Unified Insforge Provider - manages authentication state and configuration\n * \n * Manages user authentication state and provides all necessary context to child components.\n * OAuth providers are loaded on-demand by SignIn/SignUp components for better performance.\n * \n * @example\n * ```tsx\n * // Production - same URL for API and frontend\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}>\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Local dev - different ports (using env var)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider \n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * >\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * // Set NEXT_PUBLIC_INSFORGE_FRONTEND_URL=http://localhost:7131 in .env.local\n * ```\n * \n * @example\n * ```tsx\n * // Local dev - different ports (using prop)\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider \n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * frontendUrl={process.env.NEXT_PUBLIC_INSFORGE_FRONTEND_URL}\n * >\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Using custom SignIn/SignUp components\n * import { InsforgeProvider } from '@insforge/nextjs';\n * \n * export default function RootLayout({ children }) {\n * return (\n * <InsforgeProvider \n * baseUrl={process.env.NEXT_PUBLIC_INSFORGE_BASE_URL!}\n * useBuiltInAuth={false}\n * >\n * {children}\n * </InsforgeProvider>\n * );\n * }\n * ```\n */\nexport function InsforgeProvider({ \n children, \n baseUrl,\n frontendUrl,\n onAuthChange,\n useBuiltInAuth = true\n}: InsforgeProviderProps) {\n // Auth state\n const [user, setUser] = useState<InsforgeUser | null>(null);\n const [session, setSession] = useState<InsforgeSession | null>(null);\n const [isLoaded, setIsLoaded] = useState(false);\n \n const refreshIntervalRef = useRef<NodeJS.Timeout | null>(null);\n \n // Initialize SDK client with lazy initialization - only runs once\n const [insforge] = useState(() => createClient({ baseUrl }));\n\n // Load auth state\n const loadAuthState = useCallback(async () => {\n try {\n // Use SDK's getCurrentSession() to check for existing session\n // This reads from SDK's managed storage state\n const sessionResult = insforge.auth.getCurrentSession();\n const session = sessionResult.data?.session;\n const token = session?.accessToken || null;\n\n if (!token) {\n // No token, user is not authenticated\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n setIsLoaded(true);\n return;\n }\n\n // This provides instant UI update without waiting for API call\n const cachedUserStr = localStorage.getItem('insforge-user-profile');\n if (cachedUserStr) {\n try {\n const cachedData = JSON.parse(cachedUserStr);\n if (cachedData.user) {\n const userData: InsforgeUser = {\n id: cachedData.user.id,\n email: cachedData.user.email,\n createdAt: cachedData.user.createdAt || new Date().toISOString(),\n updatedAt: cachedData.user.updatedAt || new Date().toISOString(),\n ...cachedData.profile,\n };\n\n setUser(userData);\n setSession({\n userId: cachedData.user.id,\n token: token,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n });\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n\n // Mark as loaded immediately - user info is already displayed\n setIsLoaded(true);\n }\n } catch (e) {\n console.warn('[InsforgeProvider] Failed to parse cached user data:', e);\n }\n }\n\n // Try to sync token from localStorage to HTTP-only cookie via API\n // This is optional - if API route doesn't exist, it will fail silently\n try {\n await syncTokenToCookie(token);\n } catch (error) {\n // API route doesn't exist - that's okay, middleware won't work but client-side auth will\n }\n\n // Background: Verify token is still valid and refresh user data\n // This happens after displaying cached data, so UI is already responsive\n const userResult = await insforge.auth.getCurrentUser();\n\n if (userResult.data) {\n // Token is valid, update user state with fresh data\n const userData: InsforgeUser = {\n id: userResult.data.user.id,\n email: userResult.data.user.email,\n createdAt: userResult.data.user.createdAt || new Date().toISOString(),\n updatedAt: userResult.data.user.updatedAt || new Date().toISOString(),\n ...userResult.data.profile,\n };\n\n setUser(userData);\n setSession({\n userId: userResult.data.user.id,\n token: token,\n expiresAt: '',\n createdAt: new Date().toISOString(),\n });\n\n // Update cache with fresh data\n localStorage.setItem('insforge-user-profile', JSON.stringify(userResult.data));\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n } else {\n // Token invalid or expired\n // Clear from both localStorage and cookie\n localStorage.removeItem('insforge-auth-token');\n localStorage.removeItem('insforge-user-profile');\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch (error) {\n // API route doesn't exist - ignore\n }\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n }\n } catch (error) {\n // Token validation failed\n console.error('[InsforgeProvider] Token validation failed:', error);\n localStorage.removeItem('insforge-auth-token');\n localStorage.removeItem('insforge-user-profile');\n try {\n await fetch('/api/auth', { method: 'DELETE' });\n } catch (error) {\n // API route doesn't exist - ignore\n }\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n } finally {\n setIsLoaded(true);\n }\n }, [insforge, onAuthChange]);\n\n useEffect(() => {\n // Run loadAuthState only once on mount\n loadAuthState();\n\n return () => {\n if (refreshIntervalRef.current) {\n clearInterval(refreshIntervalRef.current);\n }\n };\n }, []); // Empty deps - run only on mount\n\n const signIn = useCallback(\n async (email: string, password: string) => {\n // Use SDK to sign in (SDK automatically stores token and session in localStorage)\n const sdkResult = await insforge.auth.signInWithPassword({ email, password });\n\n if (sdkResult.data) {\n // SDK has already stored the session, now fetch complete user data including profile\n const userResult = await insforge.auth.getCurrentUser();\n \n if (userResult.data) {\n // Use complete user data from SDK (includes profile fields)\n const userData: InsforgeUser = {\n id: userResult.data.user.id,\n email: userResult.data.user.email,\n name: userResult.data.user.name || undefined,\n createdAt: userResult.data.user.createdAt,\n updatedAt: userResult.data.user.updatedAt,\n ...userResult.data.profile, // Include profile fields (nickname, avatar_url, etc.)\n };\n\n const sessionData: InsforgeSession = {\n userId: userResult.data.user.id,\n token: sdkResult.data.accessToken || '',\n expiresAt: '',\n createdAt: new Date().toISOString(),\n };\n\n setUser(userData);\n setSession(sessionData);\n\n // Store complete user profile for cache\n localStorage.setItem('insforge-user-profile', JSON.stringify(userResult.data));\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n\n // Try to sync token to HTTP-only cookie via API route (if it exists)\n // This is optional - if API route doesn't exist, it will fail silently\n try {\n await syncTokenToCookie(sdkResult.data.accessToken || '');\n } catch (error) {\n console.error('Please add /api/auth route to your server to sync token to cookie:', error);\n }\n } else {\n // Fallback to basic user data if getCurrentUser fails\n const userData: InsforgeUser = {\n id: sdkResult.data.user.id,\n email: sdkResult.data.user.email,\n name: sdkResult.data.user.name || undefined,\n createdAt: sdkResult.data.user.createdAt,\n updatedAt: sdkResult.data.user.updatedAt,\n };\n\n setUser(userData);\n setSession({\n userId: sdkResult.data.user.id,\n token: sdkResult.data.accessToken || '',\n expiresAt: '',\n createdAt: new Date().toISOString(),\n });\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n }\n } else {\n // Authentication failed - throw error with message from SDK\n const errorMessage = sdkResult.error?.message || 'Invalid email or password';\n throw new Error(errorMessage);\n }\n },\n [insforge, onAuthChange]\n );\n\n const signUp = useCallback(\n async (email: string, password: string) => {\n // Use SDK to sign up (SDK automatically stores token and session in localStorage)\n const sdkResult = await insforge.auth.signUp({ email, password });\n\n if (sdkResult.data) {\n // SDK has already stored the session, now fetch complete user data including profile\n const userResult = await insforge.auth.getCurrentUser();\n \n if (userResult.data) {\n // Use complete user data from SDK (includes profile fields)\n const userData: InsforgeUser = {\n id: userResult.data.user.id,\n email: userResult.data.user.email,\n name: userResult.data.user.name || undefined,\n createdAt: userResult.data.user.createdAt,\n updatedAt: userResult.data.user.updatedAt,\n ...userResult.data.profile, // Include profile fields (nickname, avatar_url, etc.)\n };\n\n const sessionData: InsforgeSession = {\n userId: userResult.data.user.id,\n token: sdkResult.data.accessToken || '',\n expiresAt: '',\n createdAt: new Date().toISOString(),\n };\n\n setUser(userData);\n setSession(sessionData);\n\n // Store complete user profile for cache\n localStorage.setItem('insforge-user-profile', JSON.stringify(userResult.data));\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n\n // Try to sync token to HTTP-only cookie via API route (if it exists)\n // This is optional - if API route doesn't exist, it will fail silently\n try {\n await syncTokenToCookie(sdkResult.data.accessToken || '');\n } catch (error) {\n // API route doesn't exist or failed - that's okay, middleware won't work but client-side auth will\n }\n } else {\n // Fallback to basic user data if getCurrentUser fails\n const userData: InsforgeUser = {\n id: sdkResult.data.user.id,\n email: sdkResult.data.user.email,\n name: sdkResult.data.user.name || undefined,\n createdAt: sdkResult.data.user.createdAt,\n updatedAt: sdkResult.data.user.updatedAt,\n };\n\n setUser(userData);\n setSession({\n userId: sdkResult.data.user.id,\n token: sdkResult.data.accessToken || '',\n expiresAt: '',\n createdAt: new Date().toISOString(),\n });\n\n if (onAuthChange) {\n onAuthChange(userData);\n }\n }\n } else {\n // Sign up failed - throw error with message from SDK\n const errorMessage = sdkResult.error?.message || 'Sign up failed';\n throw new Error(errorMessage);\n }\n },\n [insforge, onAuthChange]\n );\n\n const signOut = useCallback(async () => {\n // SDK will clear localStorage token\n await insforge.auth.signOut();\n\n // Clear cached user profile\n localStorage.removeItem('insforge-user-profile');\n\n // Clear HTTP-only cookie via API\n await fetch('/api/auth', { method: 'DELETE' }).catch(() => {});\n\n // Clear refresh interval if exists\n if (refreshIntervalRef.current) {\n clearInterval(refreshIntervalRef.current);\n }\n\n setUser(null);\n setSession(null);\n if (onAuthChange) {\n onAuthChange(null);\n }\n }, [insforge, onAuthChange]);\n\n const updateUser = useCallback(\n async (data: Partial<InsforgeUser>) => {\n if (!user) throw new Error('No user signed in');\n\n // Use SDK's setProfile to update user profile\n const result = await insforge.auth.setProfile(data);\n if (result.data) {\n const updatedUser = { ...user, ...result.data };\n setUser(updatedUser);\n if (onAuthChange) {\n onAuthChange(updatedUser);\n }\n }\n },\n [user, onAuthChange, insforge]\n );\n\n // Email verification methods (commented out - verification disabled for now)\n // Will be added back in the future when backend email verification is ready\n \n // Send verification code for sign up or sign in\n // const sendVerificationCode = useCallback(\n // async (email: string, type: 'signup' | 'signin') => {\n // // TODO: Replace with actual SDK call when ready\n // // await insforge.auth.sendVerificationCode({ email, type });\n // \n // // Dummy implementation for testing\n // console.log(`[Verification] Sending ${type} code to ${email}`);\n // console.log('[Verification] Dummy code: 123456');\n // \n // // Simulate API delay\n // await new Promise(resolve => setTimeout(resolve, 500));\n // },\n // [insforge]\n // );\n\n // Verify code and complete sign up\n // const verifySignUpCode = useCallback(\n // async (email: string, password: string, code: string) => {\n // // TODO: Replace with actual SDK call when ready\n // // const sdkResult = await insforge.auth.verifySignUpCode({ email, password, code });\n // \n // // Dummy implementation - accept code \"123456\"\n // if (code !== '123456') {\n // throw new Error('Invalid verification code');\n // }\n\n // // Simulate sign up with verification\n // const sdkResult = await insforge.auth.signUp({ email, password });\n\n // if (sdkResult.data) {\n // const userData: InsforgeUser = {\n // id: sdkResult.data.user.id,\n // email: sdkResult.data.user.email,\n // name: sdkResult.data.user.name || undefined,\n // createdAt: sdkResult.data.user.createdAt,\n // updatedAt: sdkResult.data.user.updatedAt,\n // };\n\n // const sessionData: InsforgeSession = {\n // userId: sdkResult.data.user.id,\n // token: sdkResult.data.accessToken,\n // expiresAt: '',\n // createdAt: new Date().toISOString(),\n // };\n\n // setUser(userData);\n // setSession(sessionData);\n\n // if (onAuthChange) {\n // onAuthChange(userData);\n // }\n\n // // Try to sync token to HTTP-only cookie via API route (if it exists)\n // try {\n // await syncTokenToCookie(sdkResult.data.accessToken);\n // } catch (error) {\n // // API route doesn't exist or failed\n // }\n // } else {\n // const errorMessage = sdkResult.error?.message || 'Sign up failed';\n // throw new Error(errorMessage);\n // }\n // },\n // [insforge, onAuthChange]\n // );\n\n // Verify code and sign in (passwordless)\n // const verifySignInCode = useCallback(\n // async (email: string, code: string) => {\n // // TODO: Replace with actual SDK call when ready\n // // const sdkResult = await insforge.auth.verifySignInCode({ email, code });\n // \n // // Dummy implementation - accept code \"123456\"\n // if (code !== '123456') {\n // throw new Error('Invalid verification code');\n // }\n\n // // For now, we'll just simulate a successful sign in\n // // In reality, the backend should verify the code and return a session\n // throw new Error('Passwordless sign in via verification code is not yet implemented in the backend');\n // },\n // [insforge, onAuthChange]\n // );\n\n return (\n <InsforgeContext.Provider\n value={{\n // Auth\n user,\n session,\n isLoaded,\n isSignedIn: !!user,\n setUser,\n signIn,\n signUp,\n signOut,\n updateUser,\n \n // Email verification (commented out - verification disabled for now)\n // sendVerificationCode,\n // verifySignUpCode,\n // verifySignInCode,\n \n // Base\n baseUrl,\n }}\n >\n {children}\n </InsforgeContext.Provider>\n );\n}\n\n/**\n * Hook to access Insforge context\n * \n * Provides access to authentication state and methods.\n * Use `useOAuthProviders()` separately to fetch OAuth providers on-demand.\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { user, isSignedIn, signOut } = useInsforge();\n * \n * if (!isSignedIn) return <SignIn />;\n * \n * return (\n * <div>\n * <p>Welcome {user.email}</p>\n * <button onClick={signOut}>Sign Out</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useInsforge(): InsforgeContextValue {\n const context = useContext(InsforgeContext);\n if (!context) {\n throw new Error('useInsforge must be used within InsforgeProvider');\n }\n return context;\n}\n\n","import { useInsforge } from '../provider/InsforgeProvider';\n\n/**\n * Hook to access authentication methods\n * \n * @returns Object containing:\n * - `signIn`: Function to sign in with email and password `(email: string, password: string) => Promise<void>`\n * - `signUp`: Function to sign up with email and password `(email: string, password: string) => Promise<void>`\n * - `signOut`: Function to sign out the current user `() => Promise<void>`\n * - `isLoaded`: Boolean indicating if auth state has been loaded\n * - `isSignedIn`: Boolean indicating if user is currently signed in\n * \n * @example\n * ```tsx\n * function LoginForm() {\n * const { signIn, signUp, signOut, isLoaded, isSignedIn } = useAuth();\n * \n * async function handleLogin(email: string, password: string) {\n * try {\n * await signIn(email, password);\n * // User is now signed in\n * } catch (error) {\n * console.error('Sign in failed:', error);\n * }\n * }\n * \n * async function handleSignUp(email: string, password: string) {\n * try {\n * await signUp(email, password);\n * // User is now signed up and signed in\n * } catch (error) {\n * console.error('Sign up failed:', error);\n * }\n * }\n * \n * if (!isLoaded) return <div>Loading...</div>;\n * \n * return (\n * <form onSubmit={(e) => { e.preventDefault(); handleLogin(email, password); }}>\n * {/* form fields *\\/}\n * </form>\n * );\n * }\n * ```\n */\nexport function useAuth() {\n const { signIn, signUp, signOut, isLoaded, isSignedIn } = useInsforge();\n return { signIn, signUp, signOut, isLoaded, isSignedIn };\n}\n","import { useInsforge } from '../provider/InsforgeProvider';\n\n/**\n * Hook to access current user data\n * \n * @returns Object containing:\n * - `user`: Current user object (InsforgeUser | null)\n * - `isLoaded`: Boolean indicating if auth state has been loaded\n * - `updateUser`: Function to update user profile data `(data: Partial<InsforgeUser>) => Promise<void>`\n * - `setUser`: Internal function to manually set user state (use `updateUser` instead for normal updates)\n * \n * @example\n * ```tsx\n * function UserProfile() {\n * const { user, isLoaded, updateUser } = useUser();\n * \n * if (!isLoaded) return <div>Loading...</div>;\n * if (!user) return <div>Not signed in</div>;\n * \n * async function handleUpdate(nickname: string) {\n * await updateUser({ nickname });\n * }\n * \n * return (\n * <div>\n * <p>Email: {user.email}</p>\n * {user.nickname && <p>Nickname: {user.nickname}</p>}\n * {user.avatar_url && <img src={user.avatar_url} alt=\"Avatar\" />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useUser() {\n const { user, isLoaded, updateUser, setUser } = useInsforge();\n return { user, isLoaded, updateUser, setUser };\n}\n","import { useInsforge } from '../provider/InsforgeProvider';\n\n/**\n * Hook to access session data\n * \n * @returns Object containing:\n * - `session`: Current session object (InsforgeSession | null)\n * - `session.userId`: User ID string\n * - `session.token`: JWT access token string\n * - `session.expiresAt`: Token expiration timestamp string\n * - `session.createdAt`: Session creation timestamp string\n * - `isLoaded`: Boolean indicating if auth state has been loaded\n * \n * @example\n * ```tsx\n * function SessionInfo() {\n * const { session, isLoaded } = useSession();\n * \n * if (!isLoaded) return <div>Loading...</div>;\n * if (!session) return <div>No active session</div>;\n * \n * return (\n * <div>\n * <p>User ID: {session.userId}</p>\n * <p>Token: {session.token.substring(0, 10)}...</p>\n * <p>Created: {new Date(session.createdAt).toLocaleString()}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useSession() {\n const { session, isLoaded } = useInsforge();\n return { session, isLoaded };\n}\n","\"use client\";\n\nimport { useState, FormEvent } from \"react\";\nimport { createClient } from \"@insforge/sdk\";\nimport { useInsforge } from \"../provider/InsforgeProvider\";\nimport { useOAuthProviders } from \"../hooks/useOAuthProviders\";\nimport type { SignInProps, OAuthProvider } from \"../types\";\nimport {\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthProviders,\n} from \"./auth\";\nimport \"../styles.css\";\n\n/**\n * Pre-built sign-in component with email/password authentication and OAuth providers.\n *\n * @component\n * @example\n * ```tsx\n * // Basic usage - OAuth providers auto-detected from backend\n * <SignIn />\n *\n * // With custom UI text\n * <SignIn\n * title=\"Welcome Back\"\n * subtitle=\"Sign in to continue\"\n * afterSignInUrl=\"/dashboard\"\n * />\n * \n * // With custom callbacks\n * <SignIn\n * onSuccess={(user) => console.log('Signed in:', user)}\n * onError={(error) => console.error('Sign in failed:', error)}\n * />\n * ```\n *\n * @param {SignInProps} props - Component props\n * @param {string} [props.afterSignInUrl='/'] - URL to redirect to after successful sign-in\n * @param {object} [props.appearance] - Custom styles for container, form, and button elements\n * @param {string} [props.title='Welcome Back'] - Main heading text\n * @param {string} [props.subtitle='Login to your account'] - Subtitle text below the title\n * @param {string} [props.emailLabel='Email'] - Email field label\n * @param {string} [props.emailPlaceholder='example@email.com'] - Email field placeholder\n * @param {string} [props.passwordLabel='Password'] - Password field label\n * @param {string} [props.passwordPlaceholder='••••••'] - Password field placeholder\n * @param {string} [props.forgotPasswordText='Forget Password?'] - Forgot password link text\n * @param {string} [props.submitButtonText='Sign In'] - Submit button text\n * @param {string} [props.loadingButtonText='Signing in...'] - Loading button text\n * @param {string} [props.signUpText=\"Don't have an account?\"] - Text before sign up link\n * @param {string} [props.signUpLinkText='Sign Up Now'] - Sign up link text\n * @param {string} [props.signUpUrl='/sign-up'] - Sign up page URL\n * @param {string} [props.dividerText='or'] - Divider text between email/OAuth\n * @param {function} [props.onSuccess] - Callback invoked after successful sign-in with user data\n * @param {function} [props.onError] - Callback invoked when sign-in fails with error object\n *\n * @remarks\n * **OAuth Setup:**\n * - OAuth providers are automatically detected from backend configuration\n * - **IMPORTANT:** You must create an OAuth callback page at `/auth/callback` in your app\n * See example implementation in the package README\n *\n * **OAuth Flow:**\n * 1. User clicks OAuth button\n * 2. Redirects to provider (GitHub, Google, etc.)\n * 3. After authorization, provider redirects to `/auth/callback?access_token=...`\n * 4. Callback page stores token in localStorage\n * 5. User redirected to `afterSignInUrl`\n */\nexport function SignIn({\n afterSignInUrl = \"/\",\n appearance = {},\n title = \"Welcome Back\",\n subtitle = \"Login to your account\",\n emailLabel = \"Email\",\n emailPlaceholder = \"example@email.com\",\n passwordLabel = \"Password\",\n passwordPlaceholder = \"••••••\",\n forgotPasswordText = \"Forget Password?\",\n submitButtonText = \"Sign In\",\n loadingButtonText = \"Signing in...\",\n signUpText = \"Don't have an account?\",\n signUpLinkText = \"Sign Up Now\",\n signUpUrl = \"/sign-up\",\n dividerText = \"or\",\n onSuccess,\n onError,\n}: SignInProps) {\n const { signIn, baseUrl } = useInsforge();\n const { providers: oauthProviders } = useOAuthProviders();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [oauthLoading, setOauthLoading] = useState<OAuthProvider | null>(null);\n\n // Use a memoized client to prevent recreation on every render\n // This avoids SDK's OAuth detection running multiple times\n const insforge = useState(() => createClient({ baseUrl }))[0];\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setLoading(true);\n setError(\"\");\n\n try {\n await signIn(email, password);\n if (onSuccess) {\n const userResult = await insforge.auth.getCurrentUser();\n if (userResult.data) onSuccess(userResult.data as any);\n }\n window.location.href = afterSignInUrl;\n } catch (err: any) {\n const errorMessage = err.message || \"Sign in failed\";\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleOAuth(provider: OAuthProvider) {\n try {\n setOauthLoading(provider);\n // OAuth requires redirectTo parameter - backend will redirect here with token\n // We use /auth/callback as intermediate page to extract token from URL\n const redirectTo = `${window.location.origin}/auth/callback`;\n\n // Store the final destination for the callback page to use\n sessionStorage.setItem(\"oauth_final_destination\", afterSignInUrl || \"/\");\n\n const result = await insforge.auth.signInWithOAuth({\n provider,\n redirectTo,\n });\n\n // if (result.data?.url) {\n // window.location.href = result.data.url;\n // }\n } catch (err: any) {\n const errorMessage = err.message || `${provider} sign in failed`;\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n setOauthLoading(null);\n }\n }\n\n return (\n <AuthContainer style={appearance.container}>\n <AuthHeader title={title} subtitle={subtitle} />\n\n <AuthErrorBanner error={error} />\n\n <form onSubmit={handleSubmit} className=\"insforge-form\">\n <AuthFormField\n id=\"email\"\n type=\"email\"\n label={emailLabel}\n placeholder={emailPlaceholder}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n />\n\n <AuthPasswordField\n id=\"password\"\n label={passwordLabel}\n placeholder={passwordPlaceholder}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n autoComplete=\"current-password\"\n />\n\n <AuthSubmitButton\n isLoading={loading}\n disabled={loading || oauthLoading !== null}\n style={appearance.button}\n >\n {loading ? loadingButtonText : submitButtonText}\n </AuthSubmitButton>\n </form>\n\n <AuthLink text={signUpText} linkText={signUpLinkText} href={signUpUrl} />\n\n {oauthProviders.length > 0 && (\n <>\n <AuthDivider text={dividerText} />\n <AuthOAuthProviders\n providers={oauthProviders}\n onClick={handleOAuth}\n disabled={loading || oauthLoading !== null}\n loading={oauthLoading}\n />\n </>\n )}\n\n </AuthContainer>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { createClient } from '@insforge/sdk';\nimport type { PublicOAuthProvider } from '@insforge/shared-schemas';\nimport { useInsforge } from '../provider/InsforgeProvider';\nimport type { OAuthProvider } from '../types';\n\n/**\n * Hook to get configured OAuth providers from Insforge backend\n *\n * **IMPORTANT: This hook should ONLY be used in SignIn and SignUp components.**\n *\n * This hook lazily fetches enabled OAuth providers from the backend configuration\n * only when the component mounts. Using it in other components (like layouts or\n * other pages) will cause unnecessary API calls on every page load/refresh.\n *\n * This hook is intentionally not exported from the main package entry point to\n * prevent accidental usage. Import it directly when needed:\n * ```tsx\n * import { useOAuthProviders } from '@insforge/nextjs/src/hooks/useOAuthProviders';\n * ```\n *\n * **Usage:**\n * - ✅ Correct: Use in `<SignIn />` or `<SignUp />` components\n * - ❌ Wrong: Use in layouts, other pages, or any component that renders on every page\n *\n * @returns Object containing providers array and loading state\n *\n * @example\n * ```tsx\n * // ✅ Correct usage - only in SignIn/SignUp components\n * function SignIn() {\n * const { providers, isLoaded } = useOAuthProviders();\n * \n * if (!isLoaded) return <div>Loading providers...</div>;\n * \n * return (\n * <div>\n * {providers.map(provider => (\n * <button key={provider}>Sign in with {provider}</button>\n * ))}\n * </div>\n * );\n * }\n *\n * // ❌ Wrong usage - don't use in layouts or other components\n * function Layout() {\n * const { providers } = useOAuthProviders(); // Will fetch on every page load!\n * }\n * ```\n *\n * @requires Must be used within InsforgeProvider\n * @internal This hook is for internal use by SignIn/SignUp components only\n */\nexport function useOAuthProviders(): { providers: OAuthProvider[], isLoaded: boolean } {\n const { baseUrl } = useInsforge();\n const [providers, setProviders] = useState<OAuthProvider[]>([]);\n const [isLoaded, setIsLoaded] = useState(false);\n\n useEffect(() => {\n let mounted = true;\n\n async function fetchProviders() {\n try {\n // Use SDK instead of raw fetch for type safety and consistent error handling\n const insforge = createClient({ baseUrl });\n const { data, error } = await insforge.auth.getOAuthProviders();\n\n if (!mounted) return;\n\n if (error) {\n console.warn('[useOAuthProviders] Failed to fetch OAuth providers:', error);\n setProviders([]);\n } else if (data) {\n // Extract provider names from PublicOAuthProvider array\n // Filter to only include configured providers\n const configuredProviders = data\n .filter((p: PublicOAuthProvider) => p.isConfigured)\n .map((p: PublicOAuthProvider) => p.provider as OAuthProvider);\n setProviders(configuredProviders);\n } else {\n setProviders([]);\n }\n \n setIsLoaded(true);\n } catch (error) {\n console.warn('[useOAuthProviders] Unexpected error:', error);\n if (mounted) {\n setProviders([]);\n setIsLoaded(true);\n }\n }\n }\n\n fetchProviders();\n\n return () => {\n mounted = false;\n };\n }, [baseUrl]);\n\n return { providers, isLoaded };\n}\n","'use client';\r\n\r\nimport Link from 'next/link';\r\n\r\ninterface AuthBrandingProps {\r\n text?: string;\r\n href?: string;\r\n}\r\n\r\n/**\r\n * Insforge branding component for authentication pages.\r\n * \r\n * Displays customizable branding text with the Insforge logo.\r\n * Typically placed at the bottom of authentication forms.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * // Default branding\r\n * <AuthBranding />\r\n * \r\n * // Custom text\r\n * <AuthBranding text=\"Powered by\" />\r\n * \r\n * // Custom link\r\n * <AuthBranding \r\n * text=\"Built with\" \r\n * href=\"https://insforge.app\" \r\n * />\r\n * ```\r\n * \r\n * @param {string} [text='Secured by'] - Text to display before the logo\r\n * @param {string} [href='https://insforge.dev'] - URL the logo links to\r\n */\r\nexport function AuthBranding({ text = 'Secured by', href = 'https://insforge.dev' }: AuthBrandingProps) {\r\n return (\r\n <div className=\"insforge-branding\">\r\n <p className=\"insforge-branding-text\">{text}</p>\r\n <Link href={href} target=\"_blank\" rel=\"noopener noreferrer\">\r\n <svg width=\"83\" height=\"20\" viewBox=\"0 0 83 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M2.16783 8.46797C1.9334 8.23325 1.9334 7.85269 2.16783 7.61797L8.11049 1.66797L16.6 1.66797L6.41259 11.868C6.17815 12.1027 5.79807 12.1027 5.56363 11.868L2.16783 8.46797Z\"\r\n fill=\"url(#paint0_linear_2976_9475)\"\r\n />\r\n <path\r\n d=\"M12.8858 6.44922L16.6 10.168V18.668L8.64108 10.6992L12.8858 6.44922Z\"\r\n fill=\"url(#paint1_linear_2976_9475)\"\r\n />\r\n <path\r\n d=\"M67.5439 6.48828C68.2894 6.48828 68.9145 6.67064 69.418 7.03516C69.5229 7.10943 69.6214 7.1907 69.7158 7.27637V6.70703H71.248V14.959C71.248 15.1583 71.2381 15.3485 71.2188 15.5283C71.2042 15.7129 71.1774 15.8925 71.1387 16.0674C71.0225 16.5776 70.7998 16.9957 70.4707 17.3213C70.1415 17.6518 69.7321 17.8972 69.2432 18.0576C68.7592 18.2179 68.2222 18.2988 67.6318 18.2988C67.1962 18.2988 66.7768 18.2308 66.375 18.0947C65.9782 17.9587 65.6202 17.7614 65.3008 17.5039C64.9813 17.2512 64.7199 16.9446 64.5166 16.585L66.1289 15.7832C66.2789 16.0698 66.4888 16.2819 66.7598 16.418C67.0356 16.5589 67.3289 16.6289 67.6387 16.6289C68.0016 16.6289 68.3258 16.5628 68.6113 16.4316C68.8969 16.3053 69.1176 16.116 69.2725 15.8633C69.4321 15.6155 69.5077 15.3047 69.498 14.9307V14.1797C69.4665 14.2037 69.4359 14.229 69.4033 14.252C68.8855 14.6164 68.2441 14.7988 67.4795 14.7988C66.7582 14.7988 66.1281 14.6165 65.5908 14.252C65.0537 13.8875 64.637 13.3915 64.3418 12.7646C64.0467 12.1378 63.8994 11.4307 63.8994 10.6436C63.8994 9.84651 64.0465 9.13673 64.3418 8.51465C64.6419 7.88768 65.0663 7.39481 65.6133 7.03516C66.1601 6.67077 66.8036 6.48836 67.5439 6.48828ZM37.5 6.48828C38.1099 6.48828 38.6496 6.58294 39.1191 6.77246C39.5935 6.96201 39.9762 7.2321 40.2666 7.58203C40.5569 7.93184 40.7359 8.34227 40.8037 8.81348L39.0176 9.13477C38.974 8.79951 38.8218 8.53424 38.5605 8.33984C38.304 8.14547 37.96 8.03605 37.5293 8.01172C37.1178 7.98742 36.7859 8.05051 36.5342 8.20117C36.2825 8.34698 36.1562 8.55398 36.1562 8.82129C36.1563 8.97184 36.208 9.10017 36.3096 9.20703C36.4112 9.31394 36.614 9.42141 36.9189 9.52832C37.2288 9.63524 37.6889 9.76635 38.2988 9.92188C38.9232 10.0823 39.4222 10.2666 39.7949 10.4756C40.1722 10.6796 40.4428 10.9254 40.6074 11.2119C40.7768 11.4987 40.8623 11.8466 40.8623 12.2549C40.8623 13.047 40.574 13.6691 39.998 14.1211C39.4268 14.5731 38.6348 14.7988 37.623 14.7988C36.6551 14.7988 35.8687 14.5799 35.2637 14.1426C34.6587 13.7052 34.2909 13.0908 34.1602 12.2988L35.9463 12.0215C36.0383 12.4102 36.2411 12.7169 36.5557 12.9404C36.8703 13.164 37.2678 13.2754 37.7471 13.2754C38.1681 13.2754 38.4922 13.1926 38.7197 13.0273C38.9521 12.8572 39.0684 12.6266 39.0684 12.335C39.0684 12.1552 39.0245 12.0122 38.9375 11.9053C38.8552 11.7935 38.6713 11.686 38.3857 11.584C38.1001 11.4819 37.6618 11.3528 37.0713 11.1973C36.4131 11.0223 35.8901 10.8359 35.5029 10.6367C35.1158 10.4327 34.8374 10.192 34.668 9.91504C34.4985 9.63801 34.4141 9.30188 34.4141 8.9082C34.4141 8.41746 34.5423 7.98943 34.7988 7.625C35.0553 7.26073 35.4135 6.98146 35.873 6.78711C36.3329 6.58784 36.8755 6.48828 37.5 6.48828ZM53.3047 6.48828C54.0937 6.48828 54.7815 6.66572 55.3672 7.02051C55.9527 7.37528 56.4072 7.86634 56.7314 8.49316C57.0558 9.11525 57.2187 9.83193 57.2188 10.6436C57.2188 11.46 57.0537 12.1817 56.7246 12.8086C56.4003 13.4307 55.9451 13.9196 55.3594 14.2744C54.7737 14.6242 54.0888 14.7988 53.3047 14.7988C52.5205 14.7988 51.8357 14.6214 51.25 14.2666C50.6643 13.9118 50.2091 13.4238 49.8848 12.8018C49.5653 12.1748 49.4053 11.4552 49.4053 10.6436C49.4053 9.81735 49.5703 9.09279 49.8994 8.4707C50.2286 7.8488 50.6859 7.36255 51.2715 7.0127C51.8572 6.66281 52.5351 6.48828 53.3047 6.48828ZM76.7471 6.48828C77.5603 6.48828 78.25 6.68053 78.8164 7.06445C79.3876 7.44351 79.812 7.97991 80.0879 8.6748C80.3638 9.36976 80.4672 10.189 80.3994 11.1318H74.7256C74.7843 11.6972 74.949 12.1516 75.2227 12.4951C75.5711 12.9325 76.0792 13.1513 76.7471 13.1514C77.1779 13.1514 77.5486 13.0567 77.8584 12.8672C78.173 12.6728 78.4146 12.3928 78.584 12.0283L80.3125 12.5537C80.0124 13.2633 79.5473 13.8153 78.918 14.209C78.2936 14.6025 77.6036 14.7988 76.8486 14.7988C76.0549 14.7988 75.358 14.6263 74.7578 14.2812C74.1576 13.9362 73.6875 13.458 73.3486 12.8457C73.0147 12.2334 72.8477 11.5284 72.8477 10.7314C72.8477 9.87126 73.0127 9.12495 73.3418 8.49316C73.671 7.85651 74.1282 7.36263 74.7139 7.0127C75.2995 6.6628 75.9775 6.48832 76.7471 6.48828ZM23.3301 14.5801H21.5801V4.08203H23.3301V14.5801ZM29.6152 6.48047C30.1959 6.48052 30.6753 6.5781 31.0527 6.77246C31.4301 6.96681 31.7305 7.21443 31.9531 7.51562C32.1758 7.81695 32.3398 8.13831 32.4463 8.47852C32.5528 8.81873 32.6213 9.14205 32.6504 9.44824C32.6843 9.74946 32.7012 9.99508 32.7012 10.1846V14.5801H30.9287V10.7891C30.9287 10.5413 30.9118 10.2669 30.8779 9.96582C30.844 9.66449 30.7645 9.37469 30.6387 9.09766C30.5177 8.81592 30.3337 8.58503 30.0869 8.40527C29.8449 8.22551 29.5157 8.13579 29.0996 8.13574C28.8769 8.13574 28.6563 8.17221 28.4385 8.24512C28.2206 8.31802 28.0219 8.4442 27.8428 8.62402C27.6685 8.79899 27.5284 9.04249 27.4219 9.35352C27.3154 9.65965 27.2617 10.0532 27.2617 10.5342V14.5801H25.4902V6.70703H27.0518V7.58301C27.2521 7.34675 27.486 7.14172 27.7559 6.96973C28.2593 6.64409 28.8794 6.48047 29.6152 6.48047ZM48.748 5.83887H44.2021V8.45605H47.876V10.2061H44.2021V14.5801H42.4521V4.08203H48.748V5.83887ZM62.5137 6.67773C62.7606 6.65829 63.001 6.66815 63.2334 6.70703V8.34766C63.001 8.27961 62.7317 8.25695 62.4268 8.28125C62.1267 8.30557 61.8553 8.39134 61.6133 8.53711C61.3715 8.66829 61.1733 8.83606 61.0186 9.04004C60.8686 9.24404 60.7572 9.47701 60.6846 9.73926C60.612 9.99685 60.5752 10.2768 60.5752 10.5781V14.5801H58.8184V6.70703H60.3652V7.96582C60.4243 7.85986 60.4888 7.75824 60.5605 7.66211C60.7251 7.4434 60.9219 7.26302 61.1494 7.12207C61.3429 6.99098 61.5559 6.88926 61.7881 6.81641C62.0251 6.73869 62.267 6.69235 62.5137 6.67773ZM67.8057 8.0625C67.3362 8.06252 66.9485 8.17982 66.6436 8.41309C66.3389 8.64144 66.1139 8.95232 65.9688 9.3457C65.8235 9.7345 65.751 10.1673 65.751 10.6436C65.751 11.1247 65.8215 11.5624 65.9619 11.9561C66.1071 12.3447 66.3269 12.6535 66.6221 12.8818C66.9174 13.1103 67.293 13.2246 67.748 13.2246C68.2174 13.2246 68.5953 13.1171 68.8809 12.9033C69.1711 12.6846 69.3811 12.3808 69.5117 11.9922C69.6473 11.6034 69.7158 11.1539 69.7158 10.6436C69.7158 10.1284 69.6473 9.67886 69.5117 9.29492C69.381 8.90617 69.1753 8.60445 68.8945 8.39062C68.6138 8.17213 68.2508 8.0625 67.8057 8.0625ZM53.3047 8.13574C52.8351 8.13574 52.4475 8.24222 52.1426 8.45605C51.8425 8.66504 51.6198 8.95977 51.4746 9.33887C51.3295 9.71303 51.2568 10.148 51.2568 10.6436C51.2568 11.4066 51.4288 12.0168 51.7725 12.4736C52.121 12.9256 52.6318 13.1514 53.3047 13.1514C54.0017 13.1514 54.5196 12.9177 54.8584 12.4512C55.1971 11.9846 55.3672 11.3822 55.3672 10.6436C55.3672 9.8807 55.1951 9.27324 54.8516 8.82129C54.5079 8.36444 53.9921 8.13575 53.3047 8.13574ZM76.8203 8.02637C76.1039 8.02637 75.5712 8.25013 75.2227 8.69727C74.9987 8.98144 74.8476 9.35094 74.7676 9.80566H78.6221C78.5589 9.29301 78.4236 8.89686 78.2139 8.61719C77.9186 8.22359 77.4543 8.02645 76.8203 8.02637Z\"\r\n fill=\"black\"\r\n />\r\n <defs>\r\n <linearGradient\r\n id=\"paint0_linear_2976_9475\"\r\n x1=\"1.85883\"\r\n y1=\"1.92425\"\r\n x2=\"24.3072\"\r\n y2=\"9.64016\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop />\r\n <stop offset=\"1\" stopOpacity=\"0.4\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"paint1_linear_2976_9475\"\r\n x1=\"25.6475\"\r\n y1=\"8.65468\"\r\n x2=\"10.7901\"\r\n y2=\"8.65468\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop />\r\n <stop offset=\"1\" stopOpacity=\"0.4\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n </Link>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { ReactNode, CSSProperties } from 'react';\r\nimport '../../styles.css';\r\nimport { AuthBranding } from './AuthBranding';\r\n\r\ninterface AuthContainerProps {\r\n children: ReactNode;\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * Main container component for authentication forms.\r\n * \r\n * Provides consistent styling and layout for authentication pages.\r\n * Wraps auth content in a centered card with proper spacing and shadows.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthContainer>\r\n * <AuthHeader title=\"Sign In\" />\r\n * <form>...</form>\r\n * </AuthContainer>\r\n * ```\r\n * \r\n * @param {ReactNode} children - Content to display inside the auth container\r\n * @param {CSSProperties} [style] - Optional custom CSS styles for the container\r\n */\r\nexport function AuthContainer({ children, style }: AuthContainerProps) {\r\n return (\r\n <div className=\"insforge-auth-container\" style={style}>\r\n <div className=\"insforge-auth-card\">\r\n <div className=\"insforge-auth-content\">{children}</div>\r\n <AuthBranding />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\ninterface AuthHeaderProps {\r\n title: string;\r\n subtitle?: string;\r\n}\r\n\r\n/**\r\n * Header component for authentication forms displaying title and optional subtitle.\r\n * \r\n * Provides consistent typography and spacing for auth page headers.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthHeader \r\n * title=\"Welcome Back\" \r\n * subtitle=\"Sign in to continue to your account\" \r\n * />\r\n * ```\r\n * \r\n * @param {string} title - Main heading text to display\r\n * @param {string} [subtitle] - Optional subheading text for additional context\r\n */\r\nexport function AuthHeader({ title, subtitle }: AuthHeaderProps) {\r\n return (\r\n <div className=\"insforge-auth-header\">\r\n <h1 className=\"insforge-auth-title\">{title}</h1>\r\n {subtitle && <p className=\"insforge-auth-subtitle\">{subtitle}</p>}\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { AlertTriangle } from 'lucide-react';\r\n\r\ninterface AuthErrorBannerProps {\r\n error: string;\r\n}\r\n\r\n/**\r\n * Error message banner for authentication forms.\r\n * \r\n * Displays error messages with an alert icon in a styled banner.\r\n * Automatically hides when no error is present.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthErrorBanner error={error} />\r\n * ```\r\n * \r\n * @param {string} error - Error message to display (empty string or null to hide)\r\n */\r\nexport function AuthErrorBanner({ error }: AuthErrorBannerProps) {\r\n if (!error) return null;\r\n\r\n return (\r\n <div className=\"insforge-error-banner\">\r\n <AlertTriangle className=\"insforge-error-icon\" />\r\n <span>{error}</span>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { InputHTMLAttributes } from 'react';\r\n\r\ninterface AuthFormFieldProps extends InputHTMLAttributes<HTMLInputElement> {\r\n label: string;\r\n id: string;\r\n}\r\n\r\n/**\r\n * Standard form input field with label for authentication forms.\r\n * \r\n * Provides consistent styling for text inputs, email fields, and other basic input types.\r\n * Supports all standard HTML input attributes.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthFormField\r\n * id=\"email\"\r\n * type=\"email\"\r\n * label=\"Email Address\"\r\n * placeholder=\"you@example.com\"\r\n * value={email}\r\n * onChange={(e) => setEmail(e.target.value)}\r\n * required\r\n * />\r\n * ```\r\n * \r\n * @param {string} label - Label text displayed above the input\r\n * @param {string} id - Unique identifier for the input element\r\n * @param {InputHTMLAttributes} props - All standard HTML input attributes\r\n */\r\nexport function AuthFormField({ label, id, className = '', ...props }: AuthFormFieldProps) {\r\n return (\r\n <div className=\"insforge-form-group\">\r\n <label htmlFor={id} className=\"insforge-form-label\">\r\n {label}\r\n </label>\r\n <input\r\n id={id}\r\n className={`insforge-input ${className}`}\r\n {...props}\r\n />\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useState, type InputHTMLAttributes } from 'react';\r\nimport { Eye, EyeOff } from 'lucide-react';\r\nimport { AuthPasswordStrengthIndicator } from './AuthPasswordStrengthIndicator';\r\n\r\ninterface AuthPasswordFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\r\n label: string;\r\n id: string;\r\n showStrengthIndicator?: boolean;\r\n forgotPasswordLink?: {\r\n href: string;\r\n text?: string;\r\n };\r\n}\r\n\r\n/**\r\n * Password input field with visibility toggle and optional strength indicator.\r\n * \r\n * Features:\r\n * - Show/hide password toggle button\r\n * - Optional password strength requirements display\r\n * - Optional \"Forgot Password?\" link\r\n * - Supports all standard input attributes\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * // Sign-in password field with forgot link\r\n * <AuthPasswordField\r\n * id=\"password\"\r\n * label=\"Password\"\r\n * value={password}\r\n * onChange={(e) => setPassword(e.target.value)}\r\n * forgotPasswordLink={{ href: '/forgot-password' }}\r\n * required\r\n * />\r\n * \r\n * // Sign-up password with strength indicator\r\n * <AuthPasswordField\r\n * id=\"password\"\r\n * label=\"Create Password\"\r\n * value={password}\r\n * onChange={(e) => setPassword(e.target.value)}\r\n * showStrengthIndicator\r\n * required\r\n * />\r\n * ```\r\n * \r\n * @param {string} label - Label text displayed above the input\r\n * @param {string} id - Unique identifier for the input element\r\n * @param {boolean} [showStrengthIndicator=false] - Whether to show password strength requirements\r\n * @param {object} [forgotPasswordLink] - Configuration for forgot password link\r\n * @param {string} forgotPasswordLink.href - URL for the forgot password page\r\n * @param {string} [forgotPasswordLink.text] - Custom text for the link (default: \"Forget Password?\")\r\n */\r\nexport function AuthPasswordField({\r\n label,\r\n id,\r\n showStrengthIndicator = false,\r\n forgotPasswordLink,\r\n value,\r\n className = '',\r\n onFocus,\r\n ...props\r\n}: AuthPasswordFieldProps) {\r\n const [showPassword, setShowPassword] = useState(false);\r\n const [showStrength, setShowStrength] = useState(false);\r\n\r\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\r\n if (showStrengthIndicator) {\r\n setShowStrength(true);\r\n }\r\n onFocus?.(e);\r\n };\r\n\r\n return (\r\n <div className=\"insforge-form-group\">\r\n {(label || forgotPasswordLink) && (\r\n <div className=\"insforge-form-label-row\">\r\n <label htmlFor={id} className=\"insforge-form-label\" style={{ margin: 0 }}>\r\n {label}\r\n </label>\r\n {forgotPasswordLink && (\r\n <a href={forgotPasswordLink.href} className=\"insforge-form-link\">\r\n {forgotPasswordLink.text || 'Forget Password?'}\r\n </a>\r\n )}\r\n </div>\r\n )}\r\n <div className=\"insforge-input-wrapper\">\r\n <input\r\n id={id}\r\n type={showPassword ? 'text' : 'password'}\r\n className={`insforge-input insforge-input-with-icon ${className}`}\r\n value={value}\r\n onFocus={handleFocus}\r\n {...props}\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowPassword(!showPassword)}\r\n className=\"insforge-input-icon-btn\"\r\n aria-label={showPassword ? 'Hide password' : 'Show password'}\r\n >\r\n {showPassword ? <EyeOff size={20} /> : <Eye size={20} />}\r\n </button>\r\n </div>\r\n {showStrengthIndicator && showStrength && (\r\n <AuthPasswordStrengthIndicator password={String(value || '')} />\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n","\"use client\";\r\n\r\nimport { Check } from \"lucide-react\";\r\nimport \"../../styles.css\";\r\n\r\ninterface AuthPasswordStrengthIndicatorProps {\r\n password: string;\r\n}\r\n\r\ninterface PasswordRequirement {\r\n label: string;\r\n test: (password: string) => boolean;\r\n}\r\n\r\nconst requirements: PasswordRequirement[] = [\r\n {\r\n label: \"At least 1 Uppercase letter\",\r\n test: (pwd) => /[A-Z]/.test(pwd),\r\n },\r\n {\r\n label: \"At least 1 Number\",\r\n test: (pwd) => /\\d/.test(pwd),\r\n },\r\n {\r\n label: \"Special character (e.g. !?<>@#$%)\",\r\n test: (pwd) => /[!@#$%^&*()_+\\-=[\\]{};\\\\|,.<>/?]/.test(pwd),\r\n },\r\n {\r\n label: \"8 characters or more\",\r\n test: (pwd) => pwd.length >= 8,\r\n },\r\n];\r\n\r\n/**\r\n * Validates that a password meets all strength requirements.\r\n * \r\n * Requirements:\r\n * - At least 1 uppercase letter\r\n * - At least 1 number\r\n * - At least 1 special character\r\n * - Minimum 8 characters\r\n * \r\n * @param password - The password string to validate\r\n * @returns true if all requirements are met, false otherwise\r\n */\r\nexport function validatePasswordStrength(password: string): boolean {\r\n if (!password) return false;\r\n return requirements.every((req) => req.test(password));\r\n}\r\n\r\n/**\r\n * Visual indicator component showing password strength requirements.\r\n * Displays checkmarks as each requirement is satisfied.\r\n * \r\n * @param password - The current password value to validate against requirements\r\n */\r\nexport function AuthPasswordStrengthIndicator({ password }: AuthPasswordStrengthIndicatorProps) {\r\n return (\r\n <div className=\"insforge-password-strength\">\r\n {requirements.map((requirement, index) => {\r\n const isValid = requirement.test(password);\r\n return (\r\n <div key={index} className=\"insforge-password-requirement\">\r\n <div\r\n className={`insforge-password-check ${\r\n isValid ? \"insforge-password-check-valid\" : \"\"\r\n }`}\r\n >\r\n {isValid && <Check className=\"insforge-password-check-icon\" size={12} />}\r\n </div>\r\n <span className=\"insforge-password-requirement-label\">{requirement.label}</span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { CircleCheck, Loader2 } from 'lucide-react';\r\nimport type { CSSProperties, ReactNode } from 'react';\r\n\r\ninterface AuthSubmitButtonProps {\r\n children: ReactNode;\r\n isLoading?: boolean;\r\n confirmed?: boolean;\r\n disabled?: boolean;\r\n style?: CSSProperties;\r\n}\r\n\r\n/**\r\n * Primary submit button for authentication forms with loading and confirmed states.\r\n * \r\n * Features:\r\n * - Loading spinner animation\r\n * - Confirmed check icon\r\n * - Disabled state during submission\r\n * - Customizable styling\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthSubmitButton \r\n * isLoading={loading}\r\n * >\r\n * Sign In\r\n * </AuthSubmitButton>\r\n * \r\n * <AuthSubmitButton \r\n * confirmed={true}\r\n * >\r\n * Verified\r\n * </AuthSubmitButton>\r\n * ```\r\n * \r\n * @param {ReactNode} children - Button text content\r\n * @param {boolean} [isLoading=false] - Whether the button is in loading state\r\n * @param {boolean} [confirmed=false] - Whether the button is in confirmed state\r\n * @param {boolean} [disabled=false] - Whether the button is disabled\r\n * @param {CSSProperties} [style] - Optional custom CSS styles\r\n */\r\nexport function AuthSubmitButton({\r\n children,\r\n isLoading = false,\r\n confirmed = false,\r\n disabled = false,\r\n style,\r\n}: AuthSubmitButtonProps) {\r\n return (\r\n <button\r\n type=\"submit\"\r\n className=\"insforge-btn-primary\"\r\n style={style}\r\n disabled={disabled || isLoading || confirmed}\r\n data-loading={isLoading || undefined}\r\n data-confirmed={confirmed || undefined}\r\n >\r\n {isLoading && <Loader2 className=\"insforge-btn-loader\" size={20} />}\r\n {confirmed && <CircleCheck className=\"insforge-btn-check\" size={20} />}\r\n {children}\r\n </button>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\ninterface AuthDividerProps {\r\n text?: string;\r\n}\r\n\r\n/**\r\n * Visual divider with optional centered text for auth forms.\r\n * \r\n * Typically used to separate email/password login from OAuth providers.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthDivider text=\"or\" />\r\n * <AuthDivider text=\"or continue with\" />\r\n * ```\r\n * \r\n * @param {string} [text='or'] - Text to display in the center of the divider\r\n */\r\nexport function AuthDivider({ text = 'or' }: AuthDividerProps) {\r\n return (\r\n <div className=\"insforge-divider\">\r\n <span className=\"insforge-divider-text\">{text}</span>\r\n </div>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\ninterface AuthLinkProps {\r\n text: string;\r\n linkText: string;\r\n href: string;\r\n}\r\n\r\n/**\r\n * Call-to-action link component for navigation between auth pages.\r\n * \r\n * Commonly used to link between sign-in and sign-up pages.\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthLink \r\n * text=\"Don't have an account?\" \r\n * linkText=\"Sign up\" \r\n * href=\"/sign-up\" \r\n * />\r\n * \r\n * <AuthLink \r\n * text=\"Already have an account?\" \r\n * linkText=\"Sign in\" \r\n * href=\"/sign-in\" \r\n * />\r\n * ```\r\n * \r\n * @param {string} text - Regular text before the link\r\n * @param {string} linkText - Clickable link text\r\n * @param {string} href - URL to navigate to when clicked\r\n */\r\nexport function AuthLink({ text, linkText, href }: AuthLinkProps) {\r\n return (\r\n <p className=\"insforge-text-center\">\r\n {text}{' '}\r\n <a href={href} className=\"insforge-link-primary\">\r\n {linkText}\r\n </a>\r\n </p>\r\n );\r\n}\r\n\r\n","'use client';\r\n\r\nimport { Loader2 } from 'lucide-react';\r\nimport type { OAuthProvider } from '../../types';\r\nimport { getProviderConfig } from '../../config/oauth-providers';\r\n\r\ntype DisplayMode = 'full' | 'short' | 'icon';\r\n\r\ninterface AuthOAuthButtonProps {\r\n provider: OAuthProvider;\r\n onClick: (provider: OAuthProvider) => void;\r\n disabled?: boolean;\r\n loading?: boolean;\r\n displayMode?: DisplayMode;\r\n style?: React.CSSProperties;\r\n}\r\n\r\n/**\r\n * OAuth provider button with adaptive display modes.\r\n * \r\n * Automatically adjusts its display based on the specified mode:\r\n * - 'full': Full text \"Continue with [Provider]\" + icon\r\n * - 'short': Provider name only + icon\r\n * - 'icon': Icon only (compact mode)\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthOAuthButton\r\n * provider=\"google\"\r\n * onClick={(provider) => handleOAuth(provider)}\r\n * displayMode=\"full\"\r\n * />\r\n * ```\r\n * \r\n * @param {OAuthProvider} provider - OAuth provider identifier (e.g., 'google', 'github')\r\n * @param {Function} onClick - Callback function when button is clicked\r\n * @param {boolean} [disabled] - Whether the button is disabled\r\n * @param {boolean} [loading] - Whether the button is in loading state\r\n * @param {DisplayMode} [displayMode='full'] - Display mode for the button\r\n * @param {React.CSSProperties} [style] - Optional custom CSS styles\r\n */\r\nexport function AuthOAuthButton({ \r\n provider, \r\n onClick, \r\n disabled, \r\n loading, \r\n displayMode = 'full',\r\n style \r\n}: AuthOAuthButtonProps) {\r\n const config = getProviderConfig(provider);\r\n\r\n if (!config) {\r\n return null;\r\n }\r\n\r\n const getButtonText = () => {\r\n if (loading) return 'Authenticating...';\r\n if (displayMode === 'full') return `Continue with ${config.name}`;\r\n if (displayMode === 'short') return config.name;\r\n return ''; // icon only mode\r\n };\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={() => onClick(provider)}\r\n className=\"insforge-oauth-btn\"\r\n disabled={disabled || loading}\r\n data-loading={loading || undefined}\r\n data-display-mode={displayMode}\r\n style={style}\r\n >\r\n <Loader2 className=\"insforge-oauth-loader\" size={18} />\r\n <span className=\"insforge-oauth-icon\">{config.svg}</span>\r\n {getButtonText() && <span className=\"insforge-oauth-text\">{getButtonText()}</span>}\r\n </button>\r\n );\r\n}\r\n\r\n","import type { OAuthProvider, OAuthProviderConfig } from '../types';\r\n\r\nexport const OAUTH_PROVIDER_CONFIG: Record<OAuthProvider, OAuthProviderConfig> = {\r\n google: {\r\n name: 'Google',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <path\r\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\r\n fill=\"#4285F4\"\r\n />\r\n <path\r\n d=\"M9 18c2.43 0 4.467-.806 5.956-2.184l-2.908-2.258c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332C2.438 15.983 5.482 18 9 18z\"\r\n fill=\"#34A853\"\r\n />\r\n <path\r\n d=\"M3.964 10.707c-.18-.54-.282-1.117-.282-1.707 0-.593.102-1.17.282-1.709V4.958H.957C.347 6.173 0 7.548 0 9c0 1.452.348 2.827.957 4.042l3.007-2.335z\"\r\n fill=\"#FBBC05\"\r\n />\r\n <path\r\n d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0 5.482 0 2.438 2.017.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z\"\r\n fill=\"#EA4335\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-google',\r\n },\r\n github: {\r\n name: 'GitHub',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-github',\r\n },\r\n discord: {\r\n name: 'Discord',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20.317 4.37a19.791 19.791 0 00-4.885-1.515.074.074 0 00-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 00-5.487 0 12.64 12.64 0 00-.617-1.25.077.077 0 00-.079-.037A19.736 19.736 0 003.677 4.37a.07.07 0 00-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 00.031.057 19.9 19.9 0 005.993 3.03.078.078 0 00.084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 00-.041-.106 13.107 13.107 0 01-1.872-.892.077.077 0 01-.008-.128 10.2 10.2 0 00.372-.292.074.074 0 01.077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 01.078.01c.12.098.246.198.373.292a.077.077 0 01-.006.127 12.299 12.299 0 01-1.873.892.077.077 0 00-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 00.084.028 19.839 19.839 0 006.002-3.03.077.077 0 00.032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 00-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z\"\r\n fill=\"#5865F2\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-discord',\r\n },\r\n facebook: {\r\n name: 'Facebook',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M24 12.073C24 5.405 18.627 0 12 0S0 5.405 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047v-2.66c0-3.025 1.792-4.697 4.533-4.697 1.312 0 2.686.236 2.686.236v2.971H15.83c-1.49 0-1.955.93-1.955 1.886v2.264h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z\"\r\n fill=\"#1877F2\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-facebook',\r\n },\r\n linkedin: {\r\n name: 'LinkedIn',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\"\r\n fill=\"#0A66C2\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-linkedin',\r\n },\r\n microsoft: {\r\n name: 'Microsoft',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 23 23\" fill=\"none\">\r\n <path d=\"M0 0h11v11H0z\" fill=\"#F25022\" />\r\n <path d=\"M12 0h11v11H12z\" fill=\"#7FBA00\" />\r\n <path d=\"M0 12h11v11H0z\" fill=\"#00A4EF\" />\r\n <path d=\"M12 12h11v11H12z\" fill=\"#FFB900\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-microsoft',\r\n },\r\n apple: {\r\n name: 'Apple',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-apple',\r\n },\r\n x: {\r\n name: 'X',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-x',\r\n },\r\n instagram: {\r\n name: 'Instagram',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"\r\n fill=\"url(#instagram-gradient)\"\r\n />\r\n <defs>\r\n <linearGradient id=\"instagram-gradient\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\r\n <stop offset=\"0%\" stopColor=\"#FD5949\" />\r\n <stop offset=\"50%\" stopColor=\"#D6249F\" />\r\n <stop offset=\"100%\" stopColor=\"#285AEB\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-instagram',\r\n },\r\n tiktok: {\r\n name: 'TikTok',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M19.589 6.686a4.793 4.793 0 01-3.77-4.245V2h-3.445v13.672a2.896 2.896 0 01-5.201 1.743l-.002-.001.002.001a2.895 2.895 0 013.183-4.51v-3.5a6.329 6.329 0 00-5.394 10.692 6.33 6.33 0 0010.857-4.424V8.687a8.182 8.182 0 004.773 1.526V6.79a4.831 4.831 0 01-1.003-.104z\"\r\n fill=\"currentColor\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-tiktok',\r\n },\r\n spotify: {\r\n name: 'Spotify',\r\n svg: (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z\"\r\n fill=\"#1DB954\"\r\n />\r\n </svg>\r\n ),\r\n className: 'insforge-oauth-spotify',\r\n },\r\n};\r\n\r\n/**\r\n * Get OAuth provider configuration\r\n */\r\nexport function getProviderConfig(provider: OAuthProvider): OAuthProviderConfig | null {\r\n return OAUTH_PROVIDER_CONFIG[provider] || null;\r\n}\r\n\r\n/**\r\n * Get provider display name\r\n */\r\nexport function getProviderName(provider: OAuthProvider): string {\r\n return OAUTH_PROVIDER_CONFIG[provider]?.name || provider;\r\n}\r\n\r\n/**\r\n * Check if provider is supported\r\n */\r\nexport function isProviderSupported(provider: string): provider is OAuthProvider {\r\n return provider in OAUTH_PROVIDER_CONFIG;\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { OAuthProvider } from '../../types';\r\nimport { AuthOAuthButton } from './AuthOAuthButton';\r\n\r\ninterface AuthOAuthProvidersProps {\r\n providers: OAuthProvider[];\r\n onClick: (provider: OAuthProvider) => void;\r\n disabled?: boolean;\r\n loading: OAuthProvider | null;\r\n}\r\n\r\n/**\r\n * Smart OAuth provider grid with adaptive layout.\r\n * \r\n * Automatically adjusts button display based on the number of providers:\r\n * - 1 provider: Full-width button with full text\r\n * - 2 or 4 providers: Two-column grid with short text\r\n * - 3+ providers: Three-column grid with icons only\r\n * - Automatically centers incomplete last rows (e.g., 5, 8, 11 providers)\r\n * \r\n * @component\r\n * @example\r\n * ```tsx\r\n * <AuthOAuthProviders\r\n * providers={['google', 'github', 'discord']}\r\n * onClick={handleOAuth}\r\n * loading={currentProvider}\r\n * />\r\n * ```\r\n * \r\n * @param {OAuthProvider[]} providers - Array of OAuth provider identifiers\r\n * @param {Function} onClick - Callback function when a provider button is clicked\r\n * @param {boolean} [disabled] - Whether all buttons are disabled\r\n * @param {OAuthProvider | null} loading - Currently loading provider (or null)\r\n */\r\nexport function AuthOAuthProviders({\r\n providers,\r\n onClick,\r\n disabled,\r\n loading,\r\n}: AuthOAuthProvidersProps) {\r\n if (!providers || providers.length === 0) {\r\n return null;\r\n }\r\n\r\n const count = providers.length;\r\n\r\n // Determine display mode based on count\r\n const getDisplayMode = () => {\r\n if (count === 1) return 'full';\r\n if (count === 2 || count === 4) return 'short';\r\n return 'icon';\r\n };\r\n\r\n // Calculate grid column style for each button\r\n const getGridColumnStyle = (index: number): React.CSSProperties => {\r\n // Special cases: 1-4 providers don't use 6-column grid\r\n if (count <= 4) {\r\n return {};\r\n }\r\n\r\n // For 5+ providers, use 6-column grid\r\n const totalRows = Math.ceil(count / 3);\r\n const lastRowStartIndex = (totalRows - 1) * 3;\r\n const isInLastRow = index >= lastRowStartIndex;\r\n\r\n if (!isInLastRow) {\r\n // Not in last row, use default span 2\r\n return { gridColumn: 'span 2' };\r\n }\r\n\r\n // Calculate position in last row (0-based)\r\n const positionInLastRow = index - lastRowStartIndex;\r\n const itemsInLastRow = count - lastRowStartIndex;\r\n\r\n if (itemsInLastRow === 1) {\r\n // Last row has 1 item: center it at columns 3-4\r\n return { gridColumn: '3 / 5' };\r\n } else if (itemsInLastRow === 2) {\r\n // Last row has 2 items: center them at 2-3 and 4-5\r\n if (positionInLastRow === 0) {\r\n return { gridColumn: '2 / 4' };\r\n } else {\r\n return { gridColumn: '4 / 6' };\r\n }\r\n } else {\r\n // Last row has 3 items: normal span 2\r\n return { gridColumn: 'span 2' };\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"insforge-oauth-container\" data-provider-count={count}>\r\n {providers.map((provider, index) => (\r\n <AuthOAuthButton\r\n key={provider}\r\n provider={provider}\r\n onClick={onClick}\r\n disabled={disabled}\r\n loading={loading === provider}\r\n displayMode={getDisplayMode()}\r\n style={getGridColumnStyle(index)}\r\n />\r\n ))}\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport {\r\n useRef,\r\n KeyboardEvent,\r\n ClipboardEvent,\r\n ChangeEvent,\r\n} from \"react\";\r\n\r\ninterface AuthVerificationCodeInputProps {\r\n length?: number;\r\n value: string;\r\n email: string;\r\n onChange: (value: string) => void;\r\n disabled?: boolean;\r\n}\r\n\r\n/**\r\n * 6-digit verification code input component\r\n *\r\n * Features:\r\n * - Auto-focus next input on digit entry\r\n * - Auto-focus previous input on backspace\r\n * - Paste support for full code\r\n * - Numeric input only\r\n *\r\n * @component\r\n * @example\r\n * ```tsx\r\n * const [code, setCode] = useState('');\r\n *\r\n * <AuthVerificationCodeInput\r\n * value={code}\r\n * onChange={setCode}\r\n * />\r\n * ```\r\n */\r\nexport function AuthVerificationCodeInput({\r\n length = 6,\r\n value,\r\n email,\r\n onChange,\r\n disabled = false,\r\n}: AuthVerificationCodeInputProps) {\r\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\r\n\r\n const handleChange = (index: number, digit: string) => {\r\n // Only allow single digits\r\n if (digit.length > 1) return;\r\n\r\n // Only allow numbers\r\n if (digit && !/^\\d$/.test(digit)) return;\r\n\r\n // Update the value\r\n const newValue = value.split(\"\");\r\n newValue[index] = digit;\r\n const updatedValue = newValue.join(\"\");\r\n onChange(updatedValue);\r\n\r\n // Auto-focus next input if digit was entered\r\n if (digit && index < length - 1) {\r\n inputRefs.current[index + 1]?.focus();\r\n }\r\n };\r\n\r\n const handleKeyDown = (index: number, e: KeyboardEvent<HTMLInputElement>) => {\r\n // Handle backspace\r\n if (e.key === \"Backspace\") {\r\n if (!value[index] && index > 0) {\r\n // If current input is empty, focus previous input\r\n inputRefs.current[index - 1]?.focus();\r\n } else {\r\n // Clear current input\r\n handleChange(index, \"\");\r\n }\r\n }\r\n // Handle arrow keys\r\n else if (e.key === \"ArrowLeft\" && index > 0) {\r\n inputRefs.current[index - 1]?.focus();\r\n } else if (e.key === \"ArrowRight\" && index < length - 1) {\r\n inputRefs.current[index + 1]?.focus();\r\n }\r\n };\r\n\r\n const handlePaste = (e: ClipboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const pastedData = e.clipboardData.getData(\"text/plain\").trim();\r\n\r\n // Only paste if it's all digits and correct length\r\n if (/^\\d+$/.test(pastedData) && pastedData.length === length) {\r\n onChange(pastedData);\r\n // Focus last input\r\n inputRefs.current[length - 1]?.focus();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"insforge-verification-code-container\">\r\n <p className=\"insforge-verification-instructions\">\r\n We've sent a verification code to your inbox at <span>{email}</span>.\r\n Enter it below to proceed.\r\n </p>\r\n <div className=\"insforge-verification-code-inputs\">\r\n {Array.from({ length }).map((_, index) => (\r\n <input\r\n key={index}\r\n ref={(el) => {\r\n inputRefs.current[index] = el;\r\n }}\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n maxLength={1}\r\n value={value[index] || \"\"}\r\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\r\n handleChange(index, e.target.value)\r\n }\r\n onKeyDown={(e: KeyboardEvent<HTMLInputElement>) =>\r\n handleKeyDown(index, e)\r\n }\r\n onPaste={handlePaste}\r\n disabled={disabled}\r\n className=\"insforge-verification-code-input\"\r\n autoComplete=\"one-time-code\"\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\n\nimport { useState, FormEvent } from \"react\";\nimport { createClient } from \"@insforge/sdk\";\nimport { useInsforge } from \"../provider/InsforgeProvider\";\nimport { useOAuthProviders } from \"../hooks/useOAuthProviders\";\nimport type { SignUpProps, OAuthProvider } from \"../types\";\nimport {\n AuthContainer,\n AuthHeader,\n AuthErrorBanner,\n AuthFormField,\n AuthPasswordField,\n AuthSubmitButton,\n AuthLink,\n AuthDivider,\n AuthOAuthProviders,\n // AuthVerificationCodeInput, // Commented out - email verification disabled for now\n validatePasswordStrength,\n} from \"./auth\";\nimport \"../styles.css\";\n\n/**\n * Pre-built sign-up component with email/password registration and OAuth providers.\n *\n * @component\n * @example\n * ```tsx\n * // Basic usage - OAuth providers auto-detected from backend\n * <SignUp />\n *\n * // With custom UI text\n * <SignUp\n * title=\"Get Started\"\n * subtitle=\"Create your account\"\n * afterSignUpUrl=\"/onboarding\"\n * />\n *\n * // With custom callbacks\n * <SignUp\n * onSuccess={(user) => console.log('Signed up:', user)}\n * onError={(error) => console.error('Sign up failed:', error)}\n * />\n * ```\n *\n * @param {SignUpProps} props - Component props\n * @param {string} [props.afterSignUpUrl='/'] - URL to redirect to after successful sign-up\n * @param {object} [props.appearance] - Custom styles for container, form, and button elements\n * @param {string} [props.title='Get Started'] - Main heading text\n * @param {string} [props.subtitle='Create account'] - Subtitle text below the title\n * @param {string} [props.emailLabel='Email'] - Email field label\n * @param {string} [props.emailPlaceholder='example@email.com'] - Email field placeholder\n * @param {string} [props.passwordLabel='Password'] - Password field label\n * @param {string} [props.passwordPlaceholder='••••••'] - Password field placeholder\n * @param {string} [props.submitButtonText='Sign Up'] - Submit button text\n * @param {string} [props.loadingButtonText='Creating account...'] - Loading button text\n * @param {string} [props.signInText=\"Already have an account?\"] - Text before sign in link\n * @param {string} [props.signInLinkText='Login Now'] - Sign in link text\n * @param {string} [props.signInUrl='/sign-in'] - Sign in page URL\n * @param {string} [props.dividerText='or'] - Divider text between email/OAuth\n * @param {function} [props.onSuccess] - Callback invoked after successful sign-up with user data\n * @param {function} [props.onError] - Callback invoked when sign-up fails with error object\n *\n * @remarks\n * **OAuth Setup:**\n * - OAuth providers are automatically detected from backend configuration\n * - **IMPORTANT:** You must create an OAuth callback page at `/auth/callback` in your app\n * See example implementation in the package README\n *\n * **OAuth Flow:**\n * 1. User clicks OAuth button\n * 2. Redirects to provider (GitHub, Google, etc.)\n * 3. After authorization, provider redirects to `/auth/callback?access_token=...`\n * 4. Callback page stores token in localStorage\n * 5. User redirected to `afterSignUpUrl`\n *\n * **Password Requirements:**\n * - Password must be at least 8 characters long\n */\nexport function SignUp({\n afterSignUpUrl = \"/\",\n appearance = {},\n title = \"Get Started\",\n subtitle = \"Create account\",\n emailLabel = \"Email\",\n emailPlaceholder = \"example@email.com\",\n passwordLabel = \"Password\",\n passwordPlaceholder = \"••••••\",\n submitButtonText = \"Sign Up\",\n loadingButtonText = \"Creating account...\",\n // verifyButtonText = \"Continue\", // Commented out - email verification disabled for now\n // loadingVerifyButtonText = \"Verifying...\", // Commented out - email verification disabled for now\n // verifiedButtonText = \"Verified\", // Commented out - email verification disabled for now\n signInText = \"Already have an account?\",\n signInLinkText = \"Login Now\",\n signInUrl = \"/sign-in\",\n dividerText = \"or\",\n onSuccess,\n onError,\n}: SignUpProps) {\n // const { sendVerificationCode, verifySignUpCode, oauthProviders, baseUrl } = // Commented out - email verification disabled for now\n const { signUp, baseUrl } = useInsforge(); // Direct signup without verification\n const { providers: oauthProviders } = useOAuthProviders();\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n // const [verificationCode, setVerificationCode] = useState(\"\"); // Commented out - email verification disabled for now\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [oauthLoading, setOauthLoading] = useState<OAuthProvider | null>(null);\n // const [verified, setVerified] = useState(false); // Commented out - email verification disabled for now\n // const [step, setStep] = useState<\"credentials\" | \"verification\">( // Commented out - email verification disabled for now\n // \"credentials\"\n // );\n\n // Use a memoized client to prevent recreation on every render\n // This avoids SDK's OAuth detection running multiple times\n const insforge = useState(() => createClient({ baseUrl }))[0];\n\n async function handleCredentialsSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setLoading(true);\n setError(\"\");\n\n // Validate password strength before submission\n if (!validatePasswordStrength(password)) {\n setError(\"Password does not meet all requirements\");\n setLoading(false);\n return;\n }\n\n try {\n // Direct signup without email verification (verification disabled for now)\n await signUp(email, password);\n if (onSuccess) {\n const userResult = await insforge.auth.getCurrentUser();\n if (userResult.data) onSuccess(userResult.data as any);\n }\n window.location.href = afterSignUpUrl;\n \n // Email verification flow (commented out for now - will be added back in the future)\n // await sendVerificationCode(email, \"signup\");\n // setStep(\"verification\");\n } catch (err: any) {\n const errorMessage = err.message || \"Sign up failed\";\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n } finally {\n setLoading(false);\n }\n }\n\n // Email verification functions (commented out for now - will be added back in the future)\n // async function handleVerificationSubmit(e: FormEvent<HTMLFormElement>) {\n // e.preventDefault();\n // setLoading(true);\n // setError(\"\");\n\n // // Check if code is complete\n // if (verificationCode.length !== 6) {\n // setError(\"Please enter the complete verification code\");\n // setLoading(false);\n // return;\n // }\n\n // try {\n // // Verify code and complete sign up\n // await verifySignUpCode(email, password, verificationCode);\n // if (onSuccess) {\n // setVerified(true);\n // const userResult = await insforge.auth.getCurrentUser();\n // if (userResult.data) onSuccess(userResult.data as any);\n // }\n // window.location.href = afterSignUpUrl;\n // } catch (err: any) {\n // const errorMessage = err.message || \"Invalid verification code\";\n // setError(errorMessage);\n // if (onError) onError(new Error(errorMessage));\n // } finally {\n // setLoading(false);\n // }\n // }\n\n // async function handleResendCode() {\n // setLoading(true);\n // setError(\"\");\n // try {\n // await sendVerificationCode(email, \"signup\");\n // } catch (err: any) {\n // const errorMessage = err.message || \"Failed to resend code\";\n // setError(errorMessage);\n // } finally {\n // setLoading(false);\n // }\n // }\n\n async function handleOAuth(provider: OAuthProvider) {\n try {\n setOauthLoading(provider);\n // OAuth requires redirectTo parameter - backend will redirect here with token\n // We use /auth/callback as intermediate page to extract token from URL\n const redirectTo = `${window.location.origin}/auth/callback`;\n\n // Store the final destination for the callback page to use\n sessionStorage.setItem(\"oauth_final_destination\", afterSignUpUrl || \"/\");\n\n const result = await insforge.auth.signInWithOAuth({\n provider,\n redirectTo,\n });\n\n if (result.data?.url) {\n window.location.href = result.data.url;\n }\n } catch (err: any) {\n const errorMessage = err.message || `${provider} sign up failed`;\n setError(errorMessage);\n if (onError) onError(new Error(errorMessage));\n setOauthLoading(null);\n }\n }\n\n // Email and Password form (direct signup without verification)\n return (\n <AuthContainer style={appearance.container}>\n <AuthHeader title={title} subtitle={subtitle} />\n\n <AuthErrorBanner error={error} />\n\n <form onSubmit={handleCredentialsSubmit} className=\"insforge-form\">\n <AuthFormField\n id=\"email\"\n type=\"email\"\n label={emailLabel}\n placeholder={emailPlaceholder}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n />\n\n <AuthPasswordField\n id=\"password\"\n label={passwordLabel}\n placeholder={passwordPlaceholder}\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n minLength={8}\n autoComplete=\"new-password\"\n showStrengthIndicator\n />\n\n <AuthSubmitButton\n isLoading={loading}\n disabled={loading || oauthLoading !== null}\n style={appearance.button}\n >\n {loading ? loadingButtonText : submitButtonText}\n </AuthSubmitButton>\n </form>\n\n <AuthLink\n text={signInText}\n linkText={signInLinkText}\n href={signInUrl}\n />\n\n {oauthProviders.length > 0 && (\n <>\n <AuthDivider text={dividerText} />\n <AuthOAuthProviders\n providers={oauthProviders}\n onClick={handleOAuth}\n disabled={loading || oauthLoading !== null}\n loading={oauthLoading}\n />\n </>\n )}\n </AuthContainer>\n );\n\n // Email verification step (commented out for now - will be added back in the future)\n // Step 1: Email and Password\n // if (step === \"credentials\") {\n // return (\n // <AuthContainer style={appearance.container}>\n // <AuthHeader title={title} subtitle={subtitle} />\n // <AuthErrorBanner error={error} />\n // <form onSubmit={handleCredentialsSubmit} className=\"insforge-form\">\n // <AuthFormField\n // id=\"email\"\n // type=\"email\"\n // label={emailLabel}\n // placeholder={emailPlaceholder}\n // value={email}\n // onChange={(e) => setEmail(e.target.value)}\n // required\n // autoComplete=\"email\"\n // />\n // <AuthPasswordField\n // id=\"password\"\n // label={passwordLabel}\n // placeholder={passwordPlaceholder}\n // value={password}\n // onChange={(e) => setPassword(e.target.value)}\n // required\n // minLength={8}\n // autoComplete=\"new-password\"\n // showStrengthIndicator\n // />\n // <AuthSubmitButton\n // isLoading={loading}\n // disabled={loading || oauthLoading !== null}\n // style={appearance.button}\n // >\n // {loading ? loadingButtonText : submitButtonText}\n // </AuthSubmitButton>\n // </form>\n // <AuthLink\n // text={signInText}\n // linkText={signInLinkText}\n // href={signInUrl}\n // />\n // {oauthProviders.length > 0 && (\n // <>\n // <AuthDivider text={dividerText} />\n // <AuthOAuthProviders\n // providers={oauthProviders}\n // onClick={handleOAuth}\n // disabled={loading || oauthLoading !== null}\n // loading={oauthLoading}\n // />\n // </>\n // )}\n // </AuthContainer>\n // );\n // }\n\n // Step 2: Verification Code\n // return (\n // <AuthContainer style={appearance.container}>\n // <AuthHeader title={title} subtitle={subtitle} />\n // <AuthErrorBanner error={error} />\n // <form onSubmit={handleVerificationSubmit} className=\"insforge-form\">\n // <AuthVerificationCodeInput\n // email={email}\n // value={verificationCode}\n // onChange={setVerificationCode}\n // disabled={loading}\n // />\n // <AuthSubmitButton\n // isLoading={loading}\n // disabled={loading}\n // style={appearance.button}\n // confirmed={verified}\n // >\n // {verified ? verifiedButtonText : loading ? loadingVerifyButtonText : verifyButtonText}\n // </AuthSubmitButton>\n // </form>\n // <div className=\"insforge-resend-code\">\n // Did not received the code?{\" \"}\n // <button\n // type=\"button\"\n // onClick={handleResendCode}\n // disabled={loading}\n // className=\"insforge-resend-link\"\n // >\n // Click to resend\n // </button>\n // </div>\n // </AuthContainer>\n // );\n}\n","'use client';\n\nimport { useState, useRef, useEffect } from 'react';\nimport { LogOut } from 'lucide-react';\nimport { useInsforge } from '../provider/InsforgeProvider';\nimport type { UserButtonProps } from '../types';\n\n/**\n * User profile button with dropdown menu and sign-out functionality.\n * \n * Displays user avatar (or initials) and provides a dropdown menu with sign-out option.\n * Supports two display modes: 'detailed' (with nickname/email) and 'simple' (avatar only).\n * \n * @component\n * @example\n * ```tsx\n * // Basic usage\n * <UserButton afterSignOutUrl=\"/\" />\n * \n * // Simple mode without details (avatar only)\n * <UserButton mode=\"simple\" />\n * \n * // With custom styling\n * <UserButton\n * appearance={{\n * button: { borderRadius: '12px' },\n * dropdown: { minWidth: '300px' }\n * }}\n * />\n * ```\n * \n * @param {UserButtonProps} props - Component props\n * @param {string} [props.afterSignOutUrl='/'] - URL to redirect to after sign-out\n * @param {'detailed'|'simple'} [props.mode='detailed'] - Display mode for the button\n * - 'detailed': Shows avatar + nickname (if available) + email in an expanded button\n * - 'simple': Shows only the avatar in a compact circular button\n * @param {object} [props.appearance] - Custom styles for button and dropdown elements\n * - `appearance.button`: Styles for the trigger button\n * - `appearance.dropdown`: Styles for the dropdown menu\n */\nexport function UserButton({\n afterSignOutUrl = '/',\n mode = 'detailed',\n appearance = {},\n}: UserButtonProps) {\n const { user, signOut } = useInsforge();\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [isOpen]);\n\n async function handleSignOut() {\n await signOut();\n setIsOpen(false);\n window.location.href = afterSignOutUrl;\n }\n\n if (!user) return null;\n\n // Generate initials - prioritize nickname field if available, fallback to email\n const initials = user.nickname\n ? user.nickname.charAt(0).toUpperCase()\n : user.email.split('@')[0].slice(0, 2).toUpperCase();\n\n // Get avatar URL from user profile\n const avatarUrl = user.avatar_url;\n\n return (\n <div className=\"insforge-user-button-container\" ref={dropdownRef}>\n <button\n className={`insforge-user-button ${mode === 'detailed' ? 'insforge-user-button-detailed' : ''}`}\n onClick={() => setIsOpen(!isOpen)}\n style={appearance.button}\n aria-expanded={isOpen}\n aria-haspopup=\"true\"\n >\n {avatarUrl ? (\n <img src={avatarUrl} alt={user.email} className=\"insforge-user-avatar\" />\n ) : (\n <div className=\"insforge-user-avatar-placeholder\">{initials}</div>\n )}\n {mode === 'detailed' && (\n <div className=\"insforge-user-button-info\">\n {user.nickname && (\n <div className=\"insforge-user-button-name\">{user.nickname}</div>\n )}\n <div className=\"insforge-user-button-email\">{user.email}</div>\n </div>\n )}\n </button>\n\n {isOpen && (\n <div className=\"insforge-user-dropdown\" style={appearance.dropdown}>\n <button onClick={handleSignOut} className=\"insforge-sign-out-button\">\n <LogOut className=\"w-5 h-5\" />\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport { useInsforge } from '../provider/InsforgeProvider';\nimport type { ConditionalProps } from '../types';\n\n/**\n * Conditional component that renders children only when user is signed in.\n * \n * This component is useful for conditionally rendering content based on authentication state.\n * It returns null (renders nothing) when user is not signed in or while auth state is loading.\n * \n * @component\n * @example\n * ```tsx\n * // Basic usage\n * <SignedIn>\n * <Dashboard />\n * </SignedIn>\n * \n * // With loading state handling\n * <SignedIn>\n * <UserProfile />\n * </SignedIn>\n * ```\n * \n * @param {ConditionalProps} props - Component props\n * @param {ReactNode} props.children - React nodes to render when user is authenticated\n * \n * @returns {JSX.Element | null} Renders children when signed in, null otherwise\n */\nexport function SignedIn({ children }: ConditionalProps) {\n const { isSignedIn, isLoaded } = useInsforge();\n\n if (!isLoaded) return null;\n if (!isSignedIn) return null;\n\n return <>{children}</>;\n}\n","'use client';\n\nimport { useInsforge } from '../provider/InsforgeProvider';\nimport type { ConditionalProps } from '../types';\n\n/**\n * Conditional component that renders children only when user is signed out (not authenticated).\n * \n * This component is useful for conditionally rendering content based on authentication state.\n * It returns null (renders nothing) when user is signed in or while auth state is loading.\n * \n * @component\n * @example\n * ```tsx\n * // Basic usage - show sign-in form only when not authenticated\n * <SignedOut>\n * <SignIn />\n * </SignedOut>\n * \n * // With multiple children\n * <SignedOut>\n * <SignIn />\n * <SignUp />\n * </SignedOut>\n * ```\n * \n * @param {ConditionalProps} props - Component props\n * @param {ReactNode} props.children - React nodes to render when user is not authenticated\n * \n * @returns {JSX.Element | null} Renders children when signed out, null otherwise\n */\nexport function SignedOut({ children }: ConditionalProps) {\n const { isSignedIn, isLoaded } = useInsforge();\n\n if (!isLoaded) return null;\n if (isSignedIn) return null;\n\n return <>{children}</>;\n}\n","'use client';\n\nimport { useInsforge } from '../provider/InsforgeProvider';\nimport { useEffect } from 'react';\nimport { useRouter } from 'next/navigation';\nimport type { ProtectProps } from '../types';\n\n/**\n * Protected route component that redirects unauthenticated users and optionally checks custom conditions.\n * \n * This component protects content by:\n * 1. Redirecting to sign-in page if user is not authenticated\n * 2. Optionally checking custom conditions (e.g., role-based access control)\n * 3. Showing fallback UI while loading or when access is denied\n * \n * @component\n * @example\n * ```tsx\n * // Basic usage - protect route\n * <Protect redirectTo=\"/sign-in\">\n * <Dashboard />\n * </Protect>\n * \n * // With custom fallback\n * <Protect \n * redirectTo=\"/sign-in\"\n * fallback={<div>Checking access...</div>}\n * >\n * <AdminPanel />\n * </Protect>\n * \n * // With custom condition (role-based access)\n * <Protect\n * redirectTo=\"/unauthorized\"\n * condition={(user) => user.role === 'admin'}\n * >\n * <AdminOnlyContent />\n * </Protect>\n * ```\n * \n * @param {ProtectProps} props - Component props\n * @param {ReactNode} props.children - Content to protect (rendered when access is granted)\n * @param {ReactNode} [props.fallback] - Optional fallback UI to show while loading or when access is denied\n * @param {string} [props.redirectTo='/sign-in'] - URL to redirect to if not authenticated or condition fails\n * @param {function} [props.condition] - Optional function to check custom conditions\n * - Receives user object as parameter\n * - Returns true to grant access, false to deny\n * - Example: `(user) => user.role === 'admin'`\n * \n * @returns {JSX.Element} Renders children when access is granted, fallback or null otherwise\n * \n * @remarks\n * - This component uses Next.js router for redirects, so it must be used within a Next.js app\n * - The condition function is called after authentication is confirmed\n * - If condition fails, user is redirected to `redirectTo` URL\n */\nexport function Protect({\n children,\n fallback,\n redirectTo = '/sign-in',\n condition,\n}: ProtectProps) {\n const { isSignedIn, isLoaded, user } = useInsforge();\n const router = useRouter();\n\n useEffect(() => {\n if (isLoaded && !isSignedIn) {\n router.push(redirectTo);\n } else if (isLoaded && isSignedIn && condition && user) {\n // Check custom condition (e.g., role-based access)\n if (!condition(user)) {\n router.push(redirectTo);\n }\n }\n }, [isLoaded, isSignedIn, redirectTo, router, condition, user]);\n\n // Show fallback while loading\n if (!isLoaded) {\n return fallback || <div className=\"insforge-loading\">Loading...</div>;\n }\n\n // Don't render if not signed in\n if (!isSignedIn) {\n return fallback || null;\n }\n\n // Don't render if condition fails\n if (condition && user && !condition(user)) {\n return fallback || null;\n }\n\n return <>{children}</>;\n}\n"],"mappings":"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","names":["session","error","useState","createClient","useState","useEffect","createClient","useState","useEffect","createClient","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","jsx","jsx","jsxs","Loader2","jsx","jsxs","jsx","jsxs","Loader2","jsx","useRef","jsx","jsxs","jsx","jsxs","useState","createClient","useState","createClient","Fragment","jsx","jsxs","useState","createClient","useState","useRef","useEffect","jsx","jsxs","useState","useRef","useEffect","Fragment","jsx","Fragment","jsx","useEffect","Fragment","jsx"]}