# 📚 Storyfyd React Integration

Easy-to-use React components and hooks for integrating Storyfyd into your React applications.

## 🚀 Quick Start

### Installation

1. Copy the `storyfyd-web.js` file to your project's `public` folder

2. Add it to your HTML:
```html
<script src="/storyfyd-web.js"></script>
```

3. Copy the React components to your project (or install from npm if published):
```bash
# Copy these files to your project:
# - src/react/StoryfydWidget.jsx
# - src/react/useStoryfyd.js
# - src/react/index.js
```

### Basic Usage

```jsx
import { StoryfydWidget } from './react/StoryfydWidget';

function App() {
  return (
    <StoryfydWidget
      token="YOUR_TOKEN_HERE"
      user={{ id: "user123", name: "John Doe", email: "john@example.com" }}
      layout={{
        view: 'classic',
        style: {
          width: '80px',
          height: '80px'
        }
      }}
      onReady={() => console.log('Stories loaded!')}
      onStoryOpen={(data) => console.log('Story opened:', data)}
      onStoryClosed={() => console.log('Story closed')}
    />
  );
}
```

That's it! 🎉

## 📖 API Reference

### `<StoryfydWidget />` Component

A simple React component that wraps the Storyfyd web component.

#### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `token` | `string` | ✅ | - | Your Storyfyd API token |
| `user` | `object` | ❌ | - | User object (must have `id` if provided) |
| `layout` | `object` | ❌ | - | Layout configuration |
| `className` | `string` | ❌ | `''` | Additional CSS classes |
| `style` | `object` | ❌ | `{}` | Inline styles |
| `onReady` | `function` | ❌ | - | Called when widget is ready |
| `onStoryOpen` | `function` | ❌ | - | Called when a story opens |
| `onStoryClosed` | `function` | ❌ | - | Called when a story closes |
| `onStoryChanged` | `function` | ❌ | - | Called when story changes |
| `onInteraction` | `function` | ❌ | - | Called on user interaction |
| `onError` | `function` | ❌ | - | Called on error |

#### User Configuration

The `user` object is optional and allows you to pass custom user data to the API. If provided, it **must** contain an `id` field. You can include any additional fields you need:

```jsx
<StoryfydWidget
  token="YOUR_TOKEN"
  user={{
    id: "user123",           // Required if user object is provided
    name: "John Doe",        // Optional: any custom field
    email: "john@example.com", // Optional: any custom field
    age: 25,                 // Optional: any custom field
    labels: ["LANG_PL", "VIP"] // Optional: array of strings
    // ... any other fields you need
  }}
/>
```

Each field in the `user` object will be sent as an HTTP header to the API:
- `id` → `X-User-Id: "user123"`
- `name` → `X-User-Name: "John Doe"`
- `email` → `X-User-Email: "john@example.com"`
- `age` → `X-User-Age: "25"`
- `labels` → `X-User-Labels: ["LANG_PL","VIP"]` (arrays are JSON stringified)

This allows you to track user interactions and personalize content based on user data.

#### Layout Configuration

```typescript
layout: {
  view: 'classic' | 'rounded',  // View style
  style: {
    width: string,               // e.g., '80px', '100px'
    height: string,              // e.g., '80px', '100px'
    titleColor?: string          // Optional title color
  }
}
```

### `useStoryfyd()` Hook

A React hook that provides programmatic control over the Storyfyd widget.

```jsx
import { useStoryfyd } from './react/useStoryfyd';

function MyComponent() {
  const storyfyd = useStoryfyd('YOUR_TOKEN', {
    onReady: () => console.log('Ready!')
  });

  return (
    <div>
      <storyfyd-web ref={storyfyd.ref} />
      
      <button onClick={storyfyd.play}>▶️ Play</button>
      <button onClick={storyfyd.pause}>⏸️ Pause</button>
      <button onClick={storyfyd.close}>❌ Close</button>
      <button onClick={() => storyfyd.navigate(0, 0)}>📍 Navigate</button>
    </div>
  );
}
```

#### Returns

| Property | Type | Description |
|----------|------|-------------|
| `ref` | `RefObject` | React ref to pass to `<storyfyd-web>` |
| `play` | `function` | Start playing the current story |
| `pause` | `function` | Pause the current story |
| `close` | `function` | Close the story viewer |
| `navigate` | `function` | Navigate to specific story |
| `destroy` | `function` | Destroy and cleanup the widget |
| `isInitialized` | `boolean` | Whether the widget is initialized |

#### Navigate Function

```javascript
storyfyd.navigate(groupIndex, storyIndex)
```

- `groupIndex` (number): Index of the story group (0-based)
- `storyIndex` (number): Index of the story within the group (0-based)

## 🎯 Examples

### Example 1: Simple Widget

```jsx
import React from 'react';
import { StoryfydWidget } from './react/StoryfydWidget';

function HomePage() {
  return (
    <div>
      <h1>Welcome to My Site</h1>
      
      <StoryfydWidget
        token="YOUR_TOKEN"
        onReady={() => console.log('✅ Widget ready!')}
      />
    </div>
  );
}
```

### Example 2: Custom Styling

```jsx
import React from 'react';
import { StoryfydWidget } from './react/StoryfydWidget';

function StyledWidget() {
  return (
    <StoryfydWidget
      token="YOUR_TOKEN"
      className="my-custom-class"
      style={{ 
        margin: '20px auto',
        maxWidth: '600px'
      }}
      layout={{
        view: 'rounded',
        style: {
          width: '100px',
          height: '100px'
        }
      }}
    />
  );
}
```

### Example 3: With Event Handlers

```jsx
import React from 'react';
import { StoryfydWidget } from './react/StoryfydWidget';

function TrackedWidget() {
  const handleStoryOpen = (data) => {
    console.log('Story opened:', data);
    // Track analytics
    analytics.track('story_opened', {
      storyId: data.storyId,
      userId: data.userId
    });
  };

  const handleInteraction = (data) => {
    console.log('User interacted:', data);
    // Handle interaction
  };

  return (
    <StoryfydWidget
      token="YOUR_TOKEN"
      onReady={() => console.log('Widget ready!')}
      onStoryOpen={handleStoryOpen}
      onStoryClosed={() => console.log('Story closed')}
      onStoryChanged={(data) => console.log('Story changed:', data)}
      onInteraction={handleInteraction}
      onError={(error) => console.error('Error:', error)}
    />
  );
}
```

### Example 4: With Controls Using Hook

```jsx
import React, { useState } from 'react';
import { useStoryfyd } from './react/useStoryfyd';

function ControllableWidget() {
  const [isPlaying, setIsPlaying] = useState(true);
  const storyfyd = useStoryfyd('YOUR_TOKEN', {
    onReady: () => console.log('Ready!')
  });

  const handlePlay = () => {
    storyfyd.play();
    setIsPlaying(true);
  };

  const handlePause = () => {
    storyfyd.pause();
    setIsPlaying(false);
  };

  return (
    <div>
      <storyfyd-web ref={storyfyd.ref} />
      
      <div style={{ marginTop: '20px' }}>
        <button onClick={handlePlay} disabled={isPlaying}>
          ▶️ Play
        </button>
        <button onClick={handlePause} disabled={!isPlaying}>
          ⏸️ Pause
        </button>
        <button onClick={storyfyd.close}>
          ❌ Close
        </button>
      </div>
    </div>
  );
}
```

### Example 5: Multiple Widgets

```jsx
import React from 'react';
import { StoryfydWidget } from './react/StoryfydWidget';

function MultipleWidgets() {
  return (
    <div>
      <section>
        <h2>Featured Stories</h2>
        <StoryfydWidget
          token="TOKEN_1"
          layout={{
            view: 'classic',
            style: { width: '80px', height: '80px' }
          }}
        />
      </section>

      <section>
        <h2>User Stories</h2>
        <StoryfydWidget
          token="TOKEN_2"
          layout={{
            view: 'rounded',
            style: { width: '100px', height: '100px' }
          }}
        />
      </section>
    </div>
  );
}
```

## 🔧 Advanced Usage

### Custom Container

By default, the widget renders inside the `<StoryfydWidget>` component. You can customize the container:

```jsx
<StoryfydWidget
  token="YOUR_TOKEN"
  style={{
    width: '100%',
    maxWidth: '800px',
    margin: '0 auto'
  }}
/>
```

### Conditional Rendering

```jsx
function ConditionalWidget({ showStories }) {
  if (!showStories) {
    return <div>Stories coming soon...</div>;
  }

  return (
    <StoryfydWidget
      token="YOUR_TOKEN"
      onError={(error) => {
        console.error('Failed to load stories:', error);
        // Handle error
      }}
    />
  );
}
```

### Dynamic Token

```jsx
function DynamicWidget({ userId }) {
  const token = useMemo(() => {
    // Generate or fetch token based on user
    return generateToken(userId);
  }, [userId]);

  return (
    <StoryfydWidget
      token={token}
      key={userId} // Force re-mount when userId changes
    />
  );
}
```

## 📦 Publishing as NPM Package (Future)

If you):
- Add `storyfyd-web.js` as an asset
- Update `package.json` with proper exports
- Publish to npm

Then users can install it like:

```bash
npm install @storyfyd/react
```

```jsx
import { StoryfydWidget } from '@storyfyd/react';
```

## 🎨 Styling

The widget is styled internally, but you can add custom styling using the `className` and `style` props:

```jsx
<StoryfydWidget
  token="YOUR_TOKEN"
  className="my-custom-widget"
  style={{ margin: '20px', padding: '10px' }}
/>
```

Then add CSS:

```css
.my-custom-widget {
  border: 2px solid #333;
  border-radius: 12px;
}
```

## 🐛 Troubleshooting

### "Storyfyd inactive"

Make sure you've included the SDK script in your HTML:
```html
<script src="/storyfyd-web.js"></script>
```

### Widget not rendering

Check the browser console for errors. Make sure:
- The token is valid
- The SDK is loaded before the React component mounts
- There are no CORS issues

### Props not updating

The widget initializes once when mounted. If you need to update the token or other props, use the `key` prop to force a re-mount:

```jsx
<StoryfydWidget
  token={token}
  key={token} // Re-mount when token changes
/>
```

## 📝 License

Same as the main Storyfyd SDK.

## 🤝 Contributing

Contributions welcome! Please feel free to submit a Pull Request.

