# @banorte/chat-ui

A decoupled React chat UI component library with Tailwind CSS styling.

## Installation

```bash
npm install @banorte/chat-ui
```

## Setup

### 1. Add the Tailwind Plugin

To ensure all the necessary CSS classes are included, add the chat-ui Tailwind plugin to your `tailwind.config.js`:

```javascript
module.exports = {
  content: [
    "./src/**/*.{js,ts,jsx,tsx}",
    // ... your other content paths
  ],
  theme: {
    extend: {},
  },
  plugins: [
    require("daisyui"),
    require("@banorte/chat-ui/tailwind"), // Add this line
  ],
  // ... rest of your config
}
```

### 2. Install Required Dependencies

Make sure you have the following peer dependencies installed:

```bash
npm install react react-dom @iconify-icon/react
```

## Components

### Chat

The main chat interface component.

```tsx
import { Chat } from "@banorte/chat-ui";

function App() {
  const [messages, setMessages] = useState([]);
  const [conversationId, setConversationId] = useState("");
  const [receivingMsg, setReceivingMsg] = useState(false);

  const pushMessage = (message) => {
    setMessages(prev => [...prev, message]);
  };

  const handleStartConversation = async (user, assistant) => {
    const response = await fetch("/api/v1/conversation", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ user, assistant }),
    });
    const data = await response.json();
    return data.conversation_id;
  };

  const handleFeedback = async (key, rating) => {
    await fetch("/api/v1/feedback", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ key, rating }),
    });
  };

  return (
    <Chat
      assistant="Maya"
      messages={messages}
      pushMessage={pushMessage}
      conversationId={conversationId}
      setConversationId={setConversationId}
      setAssistantName={(name) => console.log("Assistant:", name)}
      receivingMsg={receivingMsg}
      setReceivingMsg={setReceivingMsg}
      onStartConversation={handleStartConversation}
      sendIcon="/path/to/send-icon.png"
      userAvatar="/path/to/user-avatar.png"
      botAvatar="/path/to/bot-avatar.png"
      onFeedback={handleFeedback} // Optional
    />
  );
}
```

### ChatSidebar

A sidebar component for the chat interface.

```tsx
import { ChatSidebar } from "@banorte/chat-ui";

function App() {
  return (
    <ChatSidebar
      assistant="Maya"
      logoSrc="/path/to/logo.png"
      sidebarImageSrc="/path/to/sidebar-image.png"
      assistantAvatarSrc="/path/to/assistant-avatar.png"
    />
  );
}
```

### FeedbackButton

A standalone feedback component.

```tsx
import { FeedbackButton } from "@banorte/chat-ui";

function MessageComponent() {
  const handleFeedback = async (key, rating) => {
    // Handle feedback submission
    console.log("Feedback:", key, rating);
  };

  return (
    <div>
      <p>Some message content...</p>
      <FeedbackButton
        messageKey="message-123"
        onFeedback={handleFeedback}
      />
    </div>
  );
}
```

## Props

### Chat Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `assistant` | `string` | Yes | Name of the assistant |
| `messages` | `Message[]` | Yes | Array of chat messages |
| `pushMessage` | `(message: Message) => void` | Yes | Function to add new messages |
| `conversationId` | `string` | Yes | Current conversation ID |
| `setConversationId` | `(id: string) => void` | Yes | Function to set conversation ID |
| `setAssistantName` | `(name: string) => void` | Yes | Function to set assistant name |
| `receivingMsg` | `boolean` | Yes | Whether currently receiving a message |
| `setReceivingMsg` | `(receiving: boolean) => void` | Yes | Function to update receiving state |
| `onStartConversation` | `(user: string, assistant: string) => Promise<string>` | Yes | Function to start a new conversation |
| `sendIcon` | `string` | Yes | Image source for send button |
| `userAvatar` | `string` | Yes | User avatar image source |
| `botAvatar` | `string` | Yes | Bot avatar image source |
| `onFeedback` | `(key: string, rating: string) => Promise<void>` | No | Optional feedback handler |

### ChatSidebar Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `assistant` | `string` | Yes | Name of the assistant |
| `logoSrc` | `string` | Yes | Logo image source |
| `sidebarImageSrc` | `string` | Yes | Sidebar image source |
| `assistantAvatarSrc` | `string` | Yes | Assistant avatar image source |

### FeedbackButton Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `messageKey` | `string` | Yes | Unique identifier for the message |
| `onFeedback` | `(key: string, rating: string) => Promise<void>` | Yes | Callback function for feedback submission |

## Message Type

```typescript
interface Message {
  user: boolean;
  content: string;
}
```

## Features

- **Decoupled Architecture**: Components accept all dependencies as props
- **TypeScript Support**: Full TypeScript definitions included
- **Tailwind CSS**: Styled with Tailwind CSS classes
- **DaisyUI Integration**: Uses DaisyUI components for consistent styling
- **Responsive Design**: Mobile-friendly responsive layout
- **Image Support**: Built-in image viewer for AI-generated images
- **Feedback System**: Optional feedback collection for messages
- **Streaming Support**: Real-time message streaming via SSE
- **Markdown Support**: Rich text rendering with markdown support

## Requirements

- React 18+
- Tailwind CSS 3+
- DaisyUI plugin for Tailwind CSS
- Node.js 16+

## License

Private package - All rights reserved.