# React Collaborative Whiteboard

A React component library for creating collaborative whiteboards with real-time synchronization via WebSockets.

## ✨ Features

- 🎨 **Real-time collaborative drawing** - Multiple users can draw simultaneously
- 🔧 **Multiple drawing tools** - Pencil, shapes (rectangle, ellipse, arrow), eraser, line tools
- ↩️ **Undo/Redo functionality** - Per-user undo/redo with collaborative support
- 👥 **Multi-user support** - Admin controls and user permissions
- 📱 **Responsive design** - Works on desktop, tablet, and mobile
- 🔒 **Admin controls** - Lock/unlock canvas, clear canvas, user management
- 💾 **Export functionality** - PNG, JPEG, PDF export options
- 🗜️ **Data compression** - Optimized performance with automatic compression
- ⚡ **Real-time sync** - Ultra-smooth 60fps collaborative drawing experience
- 🎯 **TypeScript support** - Fully typed for better development experience

## 📋 Prerequisites

This package requires the following dependencies in your project:

- **React** 16.8+ (with Hooks support)
- **Tailwind CSS** 3.0+ (for styling)
- **Vite** or similar modern bundler (recommended)

### Optional but Recommended:
- **shadcn/ui** setup for consistent design system

## 📦 Installation

### Step 1: Install the Package

```bash
npm install @ngenux/ngage-whiteboarding
```

### Step 2: Setup Tailwind CSS (if not already installed)

```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

### Step 3: Configure Tailwind

Update your `tailwind.config.js` to include the package components:

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx}",
    "./node_modules/@ngenux/ngage-whiteboarding/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

### Step 4: Import Styles

Add the package CSS to your main CSS file or import it in your main component:

```css
/* In your main CSS file (e.g., src/index.css) */
@tailwind base;
@tailwind components;
@tailwind utilities;
```

```tsx
// Or import in your main component
import '@ngenux/ngage-whiteboarding/dist/styles.css';
```

### Step 5: Verify Setup

Create a simple test component to verify everything is working:

```tsx
import React from 'react';
import '@ngenux/ngage-whiteboarding/dist/styles.css';
import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';

function TestWhiteboard() {
  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <WhiteboardProvider webSocketUrl="ws://localhost:3001">
        <Whiteboard
          roomId="test-room"
          userId="test-user"
          isAdmin={true}
          allowedUsers={['test-user']}
        />
      </WhiteboardProvider>
    </div>
  );
}

export default TestWhiteboard;
```

If you see a styled whiteboard with a toolbar and sidebar, your setup is complete! 🎉

## 🚀 Quick Start

### Basic Setup

```tsx
import React from 'react';
import '@ngenux/ngage-whiteboarding/dist/styles.css'; // Import the CSS
import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';

function App() {
  return (
    <WhiteboardProvider webSocketUrl="ws://localhost:3001">
      <Whiteboard
        roomId="room-123"
        userId="user-456"
        isAdmin={true}
        allowedUsers={['user-456', 'user-789']}
      />
    </WhiteboardProvider>
  );
}

export default App;
```

### For Vite Projects

If you're using Vite, make sure your `vite.config.js` includes:

```js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  css: {
    postcss: './postcss.config.js', // Ensure PostCSS is configured
  },
})
```

### For shadcn/ui Projects

If you're using shadcn/ui, you can enhance the integration with our utility functions:

```tsx
import { cn } from '@ngenux/ngage-whiteboarding'; // Use our cn utility

// Or use with your existing shadcn/ui cn function
import { cn } from '@/lib/utils';
import { Whiteboard } from '@ngenux/ngage-whiteboarding';

const customClasses = cn('your-custom-classes', 'conditional-class');
```

### Advanced Usage with Multiple Rooms

```tsx
import React, { useState } from 'react';
import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';

function CollaborativeApp() {
  const [currentRoom, setCurrentRoom] = useState('room-1');
  const [currentUser] = useState('user-' + Math.random().toString(36).substr(2, 9));

  return (
    <WhiteboardProvider webSocketUrl="wss://your-websocket-server.com">
      <div>
        <select value={currentRoom} onChange={(e) => setCurrentRoom(e.target.value)}>
          <option value="room-1">Room 1</option>
          <option value="room-2">Room 2</option>
          <option value="room-3">Room 3</option>
        </select>
        
        <Whiteboard
          roomId={currentRoom}
          userId={currentUser}
          isAdmin={currentUser === 'admin-user'}
          allowedUsers={[currentUser, 'other-user-1', 'other-user-2']}
        />
      </div>
    </WhiteboardProvider>
  );
}
```

## 📝 API Reference

### WhiteboardProvider Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `webSocketUrl` | `string` | ✅ | WebSocket server URL for real-time collaboration |
| `children` | `ReactNode` | ✅ | Child components (typically contains `<Whiteboard>`) |

### Whiteboard Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `roomId` | `string` | ✅ | - | Unique identifier for the collaboration room |
| `userId` | `string` | ✅ | - | Unique identifier for the current user |
| `isAdmin` | `boolean` | ❌ | `false` | Whether user has admin privileges (clear, lock/unlock) |
| `allowedUsers` | `string[]` | ❌ | `[]` | Array of user IDs who have drawing permissions |
| `transparentBackground` | `boolean` | ❌ | `false` | Forces transparent background and disables color picker |
| `videoStream` | `MediaStream` | ❌ | `undefined` | Live video stream for background layer (screen-share/video annotation) |

### Hooks

#### useWhiteboardStream

Automatically captures the whiteboard canvas as a video stream (30 FPS). No manual start/stop controls needed.

```tsx
import { useWhiteboardStream } from '@ngenux/ngage-whiteboarding';

function VideoStreamComponent() {
  const { mediaStream } = useWhiteboardStream();
  
  return (
    <div>
      {mediaStream && (
        <video 
          srcObject={mediaStream} 
          autoPlay 
          muted 
          style={{ width: '300px', height: '200px' }}
        />
      )}
    </div>
  );
}
```

**Note:** Stream capture starts automatically when the whiteboard canvas is available and can be controlled via the whiteboard context's `captureEnabled` state.

## 🎨 Features in Detail

### Drawing Tools
- **Pencil**: Freehand drawing
- **Shapes**: Rectangle, Ellipse, Arrow, Line
- **Eraser**: Remove parts of drawings
- **Select**: Move and transform shapes
- **Pan**: Navigate around the canvas

### Collaborative Features
- **Real-time drawing**: See other users draw in real-time
- **User permissions**: Control who can draw
- **Admin controls**: Lock/unlock canvas, clear all drawings
- **Per-user undo/redo**: Each user maintains their own undo stack

### Export Options
- **PNG**: Transparent or solid background
- **JPEG**: Solid background (white if transparent is selected)
- **PDF-format**: High-quality PNG optimized for printing/PDF conversion

## 🔧 TypeScript Support

The package includes full TypeScript definitions:

```tsx
import type { 
  WhiteboardProps, 
  WhiteboardProviderProps,
  ToolType, 
  StrokeStyle 
} from '@ngenux/ngage-whiteboarding';

const MyWhiteboard: React.FC<WhiteboardProps> = (props) => {
  // Your implementation
};
```

## 🌐 Browser Support

- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+

**Note:** Requires a modern browser with WebSocket support and ES6+ features.

## 📱 Responsive Design

The whiteboard automatically adapts to different screen sizes and supports touch interactions on mobile devices.

## ⚡ Performance

- **Optimized rendering**: Uses Konva.js for high-performance 2D canvas rendering
- **Data compression**: Automatic compression of collaborative data
- **Throttled updates**: Optimized for 60fps real-time collaboration
- **Memory efficient**: Smart cleanup of stale collaborative data

## 🐛 Troubleshooting

### Common Issues

1. **Styles not appearing / Components look unstyled**
   - ✅ Ensure Tailwind CSS is installed and configured in your project
   - ✅ Add the package path to your `tailwind.config.js` content array
   - ✅ Import the package CSS: `import '@ngenux/ngage-whiteboarding/dist/styles.css'`
   - ✅ Verify your PostCSS configuration is working

2. **WebSocket connection fails**
   - Ensure your WebSocket server is running and accessible
   - Check CORS configuration on your server
   - Verify the `webSocketUrl` is correct

3. **Drawing doesn't sync between users**
   - Verify all users are in the same `roomId`
   - Check WebSocket server is properly broadcasting messages
   - Ensure `userId` is unique for each user

4. **TypeScript errors**
   - Make sure you're importing types correctly
   - Verify your TypeScript configuration includes the package types
   - Ensure React types are properly installed

5. **Build errors with Vite/bundler**
   - Update to the latest version of your bundler
   - Ensure PostCSS and Tailwind plugins are properly configured
   - Check that the package is included in your bundler's dependency optimization

## 📄 License

MIT


## 📞 Support

If you encounter any issues or have questions, please file an issue on the [GitHub repository](https://github.com/ngenux-accelerators/ngage-whiteboarding/issues).

---

## 👨‍💻 Author

**ng-sushil**
- GitHub: [@ng-sushil](https://github.com/ng-sushil)

**Happy collaborating! 🎨✨** 