# @iblai/web-utils

A collection of React hooks, utilities, and providers for IBL AI web applications.

## Installation

```bash
pnpm add @iblai/web-utils
```

## Overview

The web-utils package provides:
- **Authentication utilities** for cross-SPA auth flows
- **React hooks** for chat, subscriptions, and time tracking
- **Context providers** for auth, tenant, and mentor management
- **Utility functions** for common operations
- **TypeScript types** for type-safe development

## Authentication Utilities

### Redirect to Auth SPA

Redirect users to the authentication SPA for login:

```tsx
import { redirectToAuthSpa, isLoggedIn } from '@iblai/web-utils';

function LoginButton() {
  const handleLogin = () => {
    redirectToAuthSpa({
      authUrl: 'https://auth.example.com',
      appName: 'mentor',
      platformKey: 'my-tenant',
      redirectTo: window.location.href,
    });
  };

  if (isLoggedIn()) {
    return <div>Already logged in</div>;
  }

  return <button onClick={handleLogin}>Log In</button>;
}
```

### Handle Logout

Complete logout with cookie cleanup and cross-SPA synchronization:

```tsx
import { handleLogout } from '@iblai/web-utils';

function LogoutButton() {
  const handleClick = () => {
    handleLogout({
      authUrl: 'https://auth.example.com',
      appName: 'mentor',
      callback: () => {
        console.log('Logged out successfully');
      },
    });
  };

  return <button onClick={handleClick}>Log Out</button>;
}
```

### Join Tenant Flow

Redirect users to signup/join a specific tenant:

```tsx
import { redirectToAuthSpaJoinTenant } from '@iblai/web-utils';

function SignupButton() {
  const handleSignup = () => {
    redirectToAuthSpaJoinTenant(
      'https://auth.example.com',
      'my-tenant',
      'https://app.example.com/welcome'
    );
  };

  return <button onClick={handleSignup}>Sign Up</button>;
}
```

### Get Join URL

Get the signup URL without redirecting:

```tsx
import { getAuthSpaJoinUrl } from '@iblai/web-utils';

function ShareInviteLink() {
  const inviteUrl = getAuthSpaJoinUrl(
    'https://auth.example.com',
    'my-tenant',
    'https://app.example.com/welcome'
  );

  return (
    <div>
      <p>Share this link:</p>
      <input value={inviteUrl} readOnly />
    </div>
  );
}
```

### Check Login Status

```tsx
import { isLoggedIn, getPlatformKey } from '@iblai/web-utils';

function Header() {
  const loggedIn = isLoggedIn();
  const tenantKey = getPlatformKey(window.location.href);

  return (
    <header>
      {loggedIn ? `Logged in to ${tenantKey}` : 'Please log in'}
    </header>
  );
}
```

## Context Providers

### Auth Provider

Manage authentication state across your app:

```tsx
import { AuthProvider, useAuthContext } from '@iblai/web-utils';

function App() {
  return (
    <AuthProvider>
      <YourApp />
    </AuthProvider>
  );
}

function UserInfo() {
  const { isAuthenticated, user, logout } = useAuthContext();

  if (!isAuthenticated) {
    return <div>Not logged in</div>;
  }

  return (
    <div>
      <p>Welcome, {user.name}</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}
```

### Tenant Provider

Manage tenant/platform context:

```tsx
import { TenantProvider, useTenantContext } from '@iblai/web-utils';

function App() {
  return (
    <TenantProvider>
      <YourApp />
    </TenantProvider>
  );
}

function TenantInfo() {
  const { tenant, setTenant } = useTenantContext();

  return (
    <div>
      <h2>Current Tenant: {tenant?.name}</h2>
      <p>Key: {tenant?.key}</p>
    </div>
  );
}
```

### Mentor Provider

Manage mentor context for AI chat applications:

```tsx
import { MentorProvider, useMentorContext } from '@iblai/web-utils';

function App() {
  return (
    <MentorProvider>
      <YourApp />
    </MentorProvider>
  );
}

function MentorInfo() {
  const { mentor, setMentor } = useMentorContext();

  return (
    <div>
      <h2>Active Mentor: {mentor?.name}</h2>
      <p>ID: {mentor?.id}</p>
    </div>
  );
}
```

## React Hooks

### Advanced Chat Hook

Manage AI chat conversations with advanced features:

```tsx
import { useAdvancedChat } from '@iblai/web-utils';

function ChatInterface() {
  const {
    messages,
    sendMessage,
    isStreaming,
    stopGeneration,
    sessionId,
  } = useAdvancedChat({
    wsUrl: 'wss://api.example.com/chat',
    wsToken: 'your-token',
    mentorId: 'mentor-123',
  });

  const handleSend = (text: string) => {
    sendMessage({
      content: text,
      sessionId,
    });
  };

  return (
    <div>
      <MessageList messages={messages} />
      {isStreaming && <button onClick={stopGeneration}>Stop</button>}
      <ChatInput onSend={handleSend} />
    </div>
  );
}
```

### Time Tracker Hook

Track user time spent in application:

```tsx
import { useTimeTracker } from '@iblai/web-utils';

function App() {
  useTimeTracker({
    endpoint: 'https://api.example.com/time-tracking',
    token: 'your-token',
    tenantKey: 'my-tenant',
    mentorId: 'mentor-123',
    interval: 60000, // Track every minute
  });

  return <YourApp />;
}
```

### Subscription Handler Hook

Manage subscription state and paywall logic:

```tsx
import { useSubscriptionHandler } from '@iblai/web-utils';

function FeatureGate({ children }) {
  const {
    isSubscribed,
    showPaywall,
    subscription,
  } = useSubscriptionHandler({
    tenantKey: 'my-tenant',
    userId: 'user-123',
  });

  if (!isSubscribed && showPaywall) {
    return <PaywallModal />;
  }

  return children;
}
```

### External Pricing Plan Hook

Fetch and manage external pricing plans:

```tsx
import { useExternalPricingPlan } from '@iblai/web-utils';

function PricingPage() {
  const {
    pricingPlans,
    isLoading,
    error,
  } = useExternalPricingPlan({
    tenantKey: 'my-tenant',
  });

  if (isLoading) return <div>Loading pricing...</div>;

  return (
    <div>
      {pricingPlans.map(plan => (
        <PricingCard key={plan.id} plan={plan} />
      ))}
    </div>
  );
}
```

### Tenant Metadata Hook

Fetch tenant configuration and metadata:

```tsx
import { useTenantMetadata } from '@iblai/web-utils';

function TenantSettings() {
  const { metadata, isLoading } = useTenantMetadata('my-tenant');

  return (
    <div>
      <h1>{metadata?.name}</h1>
      <p>{metadata?.description}</p>
      <img src={metadata?.logo} alt="Logo" />
    </div>
  );
}
```

## Utility Functions

### Cookie Management

```tsx
import {
  setCookieForAuth,
  deleteCookie,
  clearCookies,
} from '@iblai/web-utils';

// Set auth cookie
setCookieForAuth('token', 'abc123', 7); // 7 days

// Delete specific cookie
deleteCookie('token');

// Clear all auth cookies
clearCookies(['token', 'refresh_token']);
```

### Iframe Detection

```tsx
import { isInIframe, sendMessageToParentWebsite } from '@iblai/web-utils';

if (isInIframe()) {
  // Send message to parent window
  sendMessageToParentWebsite({
    type: 'LOGGED_IN',
    userId: 'user-123',
  });
}
```

### Time Utilities

```tsx
import { getTimeAgo, useDayJs } from '@iblai/web-utils';

// Get relative time
const timeAgo = getTimeAgo('2024-01-01T00:00:00Z');
// Returns: "2 months ago"

// Use Day.js in components
function DateDisplay({ date }) {
  const dayjs = useDayJs();
  return <span>{dayjs(date).format('MMM D, YYYY')}</span>;
}
```

### Profile Utilities

```tsx
import { getInitials } from '@iblai/web-utils';

function Avatar({ name }) {
  const initials = getInitials(name);
  // "John Doe" => "JD"

  return <div className="avatar">{initials}</div>;
}
```

### Validation

```tsx
import { isAlphaNumeric32 } from '@iblai/web-utils';

const isValid = isAlphaNumeric32('abc123XYZ');
// Validates alphanumeric strings up to 32 chars
```

## TypeScript Support

All utilities and hooks are fully typed:

```tsx
import type {
  RedirectToAuthSpaOptions,
  HandleLogoutOptions,
  AuthContextType,
  TenantContextType,
  Message,
  ChatState,
} from '@iblai/web-utils';

const authOptions: RedirectToAuthSpaOptions = {
  authUrl: 'https://auth.example.com',
  appName: 'mentor',
  platformKey: 'my-tenant',
};
```

## Advanced Features

### Custom Metadata Loading

```tsx
import { loadMetadataConfig } from '@iblai/web-utils';

const metadata = await loadMetadataConfig('my-tenant', {
  endpoint: 'https://api.example.com/metadata',
  headers: {
    'Authorization': 'Bearer token',
  },
});
```

### File Upload with S3

```tsx
import { requestPresignedUrl, uploadToS3 } from '@iblai/web-utils';

async function uploadFile(file: File) {
  // Get presigned URL
  const { url, fields } = await requestPresignedUrl({
    fileName: file.name,
    fileType: file.type,
  });

  // Upload to S3
  await uploadToS3(url, fields, file, {
    onProgress: (percent) => {
      console.log(`Upload progress: ${percent}%`);
    },
  });
}
```

## Contributing

We welcome contributions! Please read our [contributing guidelines](CONTRIBUTING.md).

## Development

### Building

```bash
pnpm build
```

### Testing

```bash
pnpm test
```

### Type Checking

```bash
pnpm typecheck
```

## License

ISC
