import React, { useState, useMemo, FormEvent } from 'react'; import { Card, Stack, Text, Button, Divider, Icon, Spinner } from '../../components'; import { useTheme } from '../../core'; import { GoogleIcon, GithubIcon } from '../../icons'; import { AuthResponse } from './AuthResponse'; import { AuthAlert } from './Alerts'; import { CredentialsForm } from './CredentialsForm'; import { MagicLinkForm } from './MagicLinkForm'; // A more generic provider type for the UI export interface AuthProviderConfig { id: string; name: string; type: 'oauth' | 'credentials' | 'magiclink' | 'passkey'; // Add other provider-specific properties if needed for UI [key: string]: any; } interface SignInPageProps { providers: AuthProviderConfig[]; signIn: (providerId: string, formData?: Record) => Promise; title?: string; subtitle?: string; className?: string; } const providerIcons: Record = { google: GoogleIcon, github: GithubIcon, }; export const SignInPage: React.FC = ({ providers, signIn, title = 'Sign In', subtitle, className, }) => { const { theme } = useTheme(); const [alert, setAlert] = useState<{ type: 'error' | 'success'; message: string } | null>(null); const [loadingProvider, setLoadingProvider] = useState(null); const oauthProviders = useMemo(() => providers.filter(p => p.type === 'oauth'), [providers]); const credentialsProvider = useMemo(() => providers.find(p => p.type === 'credentials'), [providers]); const magicLinkProvider = useMemo(() => providers.find(p => p.type === 'magiclink'), [providers]); const handleSignIn = async (providerId: string, formData?: Record) => { setLoadingProvider(providerId); setAlert(null); try { const response = await signIn(providerId, formData); if (response) { if (response.error) setAlert({ type: 'error', message: response.error }); else if (response.success) setAlert({ type: 'success', message: response.success }); } } catch (e: any) { setAlert({ type: 'error', message: e.message || 'An unknown error occurred.' }); } finally { setLoadingProvider(null); } }; return ( {title} {subtitle && {subtitle}} {oauthProviders.length > 0 && ( {oauthProviders.map(provider => { const ProviderIcon = providerIcons[provider.id]; return ( ); })} )} {(oauthProviders.length > 0 && (credentialsProvider || magicLinkProvider)) && ( OR )} {credentialsProvider && ( handleSignIn(credentialsProvider.id, formData)} /> )} {magicLinkProvider && ( handleSignIn(magicLinkProvider.id, formData)} /> )} ); };