# `AuthBoundary`

A component that simplifies protecting routes and content based on authentication state. It handles four distinct scenarios: loading, error, unauthenticated, and authenticated.

## Usage

```tsx
import { AuthBoundary } from '@openfort/react-native';
import { Text, ActivityIndicator } from 'react-native';

function App() {
  return (
    <AuthBoundary
      loading={<ActivityIndicator size="large" />}
      unauthenticated={<LoginScreen />}
      error={(error) => <Text>Error: {error.message}</Text>}
    >
      <AuthenticatedApp />
    </AuthBoundary>
  );
}
```

## Props

```ts
type AuthBoundaryProps = {
  /** Component to render while the SDK is initializing */
  loading: React.ReactNode
  /** Component to render when the user is not authenticated */
  unauthenticated: React.ReactNode
  /** Optional component to render when there's an error during SDK initialization */
  error?: React.ReactNode | ((error: Error) => React.ReactNode)
  /** Children to render when the user is authenticated and the SDK is ready */
  children: React.ReactNode
}
```

## States

The component handles four states:

| State | Condition | Renders |
|-------|-----------|---------|
| Loading | SDK is initializing | `loading` prop |
| Error | SDK encountered initialization error | `error` prop (if provided) |
| Unauthenticated | User is not logged in | `unauthenticated` prop |
| Authenticated | User is logged in, SDK is ready | `children` |

## With React Navigation

A common pattern is to use `AuthBoundary` with React Navigation to show different navigation stacks based on authentication state:

```tsx
import { AuthBoundary } from '@openfort/react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <AuthBoundary
        loading={<SplashScreen />}
        unauthenticated={
          <Stack.Navigator>
            <Stack.Screen name="Login" component={LoginScreen} />
            <Stack.Screen name="Signup" component={SignupScreen} />
          </Stack.Navigator>
        }
      >
        <Stack.Navigator>
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Profile" component={ProfileScreen} />
        </Stack.Navigator>
      </AuthBoundary>
    </NavigationContainer>
  );
}
```

## With Expo Router

When using Expo Router, place the `AuthBoundary` in your root layout:

```tsx
// app/_layout.tsx
import { AuthBoundary, OpenfortProvider } from '@openfort/react-native';
import { Slot } from 'expo-router';
import { ActivityIndicator, View } from 'react-native';

export default function RootLayout() {
  return (
    <OpenfortProvider
      publishableKey="YOUR_PUBLISHABLE_KEY"
      walletConfig={{
        shieldPublishableKey: "YOUR_SHIELD_KEY",
        createEncryptedSessionEndpoint: "https://your-backend.com/api/encryption-session"
      }}
    >
      <AuthBoundary
        loading={
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <ActivityIndicator size="large" />
          </View>
        }
        unauthenticated={<LoginScreen />}
      >
        <Slot />
      </AuthBoundary>
    </OpenfortProvider>
  );
}
```

## Error Handling

The `error` prop can be either a static component or a function that receives the error:

```tsx
// Static error component
<AuthBoundary
  loading={<LoadingScreen />}
  unauthenticated={<LoginScreen />}
  error={<Text>Something went wrong</Text>}
>
  <App />
</AuthBoundary>

// Dynamic error component
<AuthBoundary
  loading={<LoadingScreen />}
  unauthenticated={<LoginScreen />}
  error={(error) => (
    <View>
      <Text>Error: {error.message}</Text>
      <Button title="Retry" onPress={() => { /* retry logic */ }} />
    </View>
  )}
>
  <App />
</AuthBoundary>
```
