npm package: @foxpixel/react
Description: React SDK for FoxPixel API - Headless integration for custom sites and portals
Author: FoxPixel
Latest version: 0.2.4

# @foxpixel/react

React SDK for FoxPixel API - Headless integration for custom sites and portals.

## Installation

```bash
npm install @foxpixel/react
# or
yarn add @foxpixel/react
# or
pnpm add @foxpixel/react
```

## Quick Start

### 1. Wrap your app with FoxPixelProvider

```tsx
// app.tsx or _app.tsx
import { FoxPixelProvider } from '@foxpixel/react';

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

### 2. Use hooks in your components

```tsx
import { useServices } from '@foxpixel/react';

function ServicesPage() {
  const { services, isLoading, error } = useServices({ active: true });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      {services?.map(service => (
        <div key={service.id}>
          <h3>{service.name}</h3>
          <p>{service.description}</p>
        </div>
      ))}
    </div>
  );
}
```

## Configuration

### Environment Variables

```env
# Client-side (public)
NEXT_PUBLIC_FOXPIXEL_API_URL=https://api.foxpixel.com

# Server-side only (NEVER expose in client)
FOXPIXEL_API_KEY=sk_live_your_key_here
FOXPIXEL_TENANT_ID=your_tenant_id_here
```

### Provider Configuration

```tsx
<FoxPixelProvider
  config={{
    apiUrl: 'https://api.foxpixel.com',
    // apiKey: Only use server-side (via proxy)
    // tenantId: Optional, can be set per request
  }}
>
  <App />
</FoxPixelProvider>
```

## Security: Server-Side Proxy

**IMPORTANT:** API Keys should NEVER be exposed in client-side code.

Use Next.js API routes to proxy requests:

```tsx
// pages/api/foxpixel/[...path].ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const apiKey = process.env.FOXPIXEL_API_KEY;
  const apiUrl = process.env.NEXT_PUBLIC_FOXPIXEL_API_URL;

  // Proxy request with API Key
  const response = await fetch(`${apiUrl}${req.url}`, {
    method: req.method,
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: req.method !== 'GET' ? JSON.stringify(req.body) : undefined,
  });

  const data = await response.json();
  res.status(response.status).json(data);
}
```

Then configure SDK to use proxy:

```tsx
<FoxPixelProvider
  config={{
    apiUrl: '/api/foxpixel', // Use proxy instead of direct API
  }}
>
  <App />
</FoxPixelProvider>
```

## Hooks

### `useServices(options?)`

Fetch services from Projects module.

```tsx
const { services, isLoading, error, refetch } = useServices({
  category: 'pools',
  active: true,
});
```

### `useLeadCapture()`

Capture leads (create lead in CRM).

```tsx
const { captureLead, isLoading, error } = useLeadCapture();

await captureLead({
  fullName: 'John Doe',
  email: 'john@example.com',
  phone: '+1234567890',
  source: 'website',
});
```

### `useAuth()`

Authenticate End Users (clients of your tenant).

```tsx
const { user, isAuthenticated, login, logout, isLoading } = useAuth();

// Login
await login({
  email: 'user@example.com',
  password: 'password123',
});

// Logout
await logout();
```

## End User Authentication

End Users are authenticated via httpOnly cookies (secure, XSS-resistant).

```tsx
function LoginPage() {
  const { login, isLoading, error } = useAuth();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      await login({
        email: e.target.email.value,
        password: e.target.password.value,
      });
      router.push('/dashboard');
    } catch (err) {
      console.error('Login failed:', err);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" required />
      <input name="password" type="password" required />
      <button type="submit" disabled={isLoading}>
        {isLoading ? 'Logging in...' : 'Login'}
      </button>
      {error && <div>{error.message}</div>}
    </form>
  );
}
```

## TypeScript

Full TypeScript support with exported types:

```tsx
import type { Service, Lead, EndUser } from '@foxpixel/react';
```

## License

MIT