nextjs-chatbot-ui 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,330 +1,468 @@
1
- # Chatbot UI Component
2
-
3
- A beautiful, configurable chatbot UI component for Next.js applications with Tailwind CSS. Inspired by Sendbird's modern chat interface.
4
-
5
- ## Features
6
-
7
- - 🎨 Modern, Sendbird-inspired UI design
8
- - ⚙️ Fully configurable (labels, position, colors, backend URL)
9
- - 📱 Responsive and mobile-friendly
10
- - 🎯 TypeScript support
11
- - 🚀 Easy to integrate
12
- - 💬 Real-time messaging support
13
- - 🎭 Customizable user and bot avatars
14
- - ⏰ Optional timestamp display
15
-
16
- ## Compatibility Requirements
17
-
18
- This package requires:
19
- - **Next.js 14+** (with App Router or Pages Router support)
20
- - **React 18+**
21
- - **TypeScript 5+** (for TypeScript projects)
22
- - **Tailwind CSS 3+** (must be configured in your project)
23
-
24
- **Important Notes:**
25
- - The package exports TypeScript source files directly, which Next.js will compile automatically
26
- - Make sure your `tailwind.config.js` includes the package path in the `content` array (see setup instructions)
27
- - This package uses the `'use client'` directive and requires client-side rendering
28
-
29
- ## Installation
30
-
31
- ```bash
32
- npm install nextjs-chatbot-ui
33
- ```
34
-
35
- ## Usage
36
-
37
- ### Basic Setup
38
-
39
- 1. **Configure Tailwind CSS** - Make sure your `tailwind.config.js` includes the component:
40
-
41
- ```javascript
42
- // tailwind.config.js
43
- module.exports = {
44
- content: [
45
- './node_modules/nextjs-chatbot-ui/**/*.{js,ts,jsx,tsx}',
46
- './app/**/*.{js,ts,jsx,tsx,mdx}',
47
- './pages/**/*.{js,ts,jsx,tsx,mdx}',
48
- './components/**/*.{js,ts,jsx,tsx,mdx}',
49
- ],
50
- // ... rest of your config
51
- }
52
- ```
53
-
54
- 2. **Import the component and types**:
55
-
56
- ```javascript
57
- import { Chatbot } from 'nextjs-chatbot-ui';
58
- import type { ChatbotConfig } from 'nextjs-chatbot-ui';
59
- ```
60
-
61
- 2. Configure and use the component:
62
-
63
- ```javascript
64
- const config: ChatbotConfig = {
65
- backendUrl: 'https://your-backend-api.com/chat',
66
- labels: {
67
- title: 'Support Chat',
68
- placeholder: 'Type your message...',
69
- sendButton: 'Send',
70
- welcomeMessage: 'Hello! How can I help you?',
71
- },
72
- position: 'bottom-right',
73
- botInfo: {
74
- name: 'Support Bot',
75
- avatar: 'https://example.com/bot-avatar.png',
76
- },
77
- userInfo: {
78
- name: 'User',
79
- avatar: 'https://example.com/user-avatar.png',
80
- },
81
- primaryColor: '#0ea5e9',
82
- autoOpen: false,
83
- showTimestamp: true,
84
- };
85
-
86
- export default function Page() {
87
- return <Chatbot config={config} />;
88
- }
89
- ```
90
-
91
- ### Configuration Options
92
-
93
- #### `ChatbotConfig` Interface
94
-
95
- ```typescript
96
- interface ChatbotConfig {
97
- // Required
98
- backendUrl: string; // Your backend API endpoint for handling messages
99
-
100
- // Optional Labels
101
- labels?: {
102
- title?: string; // Chat header title (default: "Chat Support")
103
- placeholder?: string; // Input placeholder (default: "Type your message...")
104
- sendButton?: string; // Send button text (default: "Send")
105
- typingIndicator?: string; // Loading message (default: "Typing...")
106
- welcomeMessage?: string; // Initial bot message (default: "Hello! How can I help you today?")
107
- errorMessage?: string; // Error message (default: "Sorry, something went wrong. Please try again.")
108
- };
109
-
110
- // Position
111
- position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'; // Default: 'bottom-right'
112
-
113
- // User Information
114
- userInfo?: {
115
- name?: string; // User name
116
- avatar?: string; // User avatar URL
117
- };
118
-
119
- // Bot Information
120
- botInfo?: {
121
- name?: string; // Bot name (default: uses title)
122
- avatar?: string; // Bot avatar URL
123
- };
124
-
125
- // Styling
126
- primaryColor?: string; // Primary color (hex code)
127
- backgroundColor?: string; // Chat background color (hex code)
128
-
129
- // Behavior
130
- autoOpen?: boolean; // Auto-open chat on load (default: false)
131
- showTimestamp?: boolean; // Show message timestamps (default: false)
132
- showDateSeparator?: boolean; // Show date separators between messages (default: false)
133
- poweredByText?: string; // Footer text (e.g., "Powered by sendbird")
134
- }
135
- ```
136
-
137
- ### Backend API Requirements
138
-
139
- Your backend should accept POST requests with the following format:
140
-
141
- **Request:**
142
- ```json
143
- {
144
- "message": "User's message text",
145
- "userInfo": {
146
- "name": "User",
147
- "avatar": "https://example.com/avatar.png"
148
- }
149
- }
150
- ```
151
-
152
- **Response:**
153
- ```json
154
- {
155
- "message": "Bot's response text",
156
- "suggestedReplies": ["Option 1", "Option 2", "Option 3"]
157
- }
158
- ```
159
-
160
- or
161
-
162
- ```json
163
- {
164
- "response": "Bot's response text",
165
- "suggestions": ["Option 1", "Option 2", "Option 3"]
166
- }
167
- ```
168
-
169
- **Note:** The `suggestedReplies` or `suggestions` field is optional and will display as clickable buttons below the bot's message, similar to Sendbird's interface.
170
-
171
- ### Example Implementation
172
-
173
- ```javascript
174
- // pages/index.js or app/page.js
175
- 'use client';
176
-
177
- import { Chatbot } from 'nextjs-chatbot-ui';
178
- import type { ChatbotConfig } from 'nextjs-chatbot-ui';
179
-
180
- export default function Home() {
181
- const chatbotConfig: ChatbotConfig = {
182
- backendUrl: 'https://api.example.com/chat',
183
- labels: {
184
- title: 'Customer Support',
185
- placeholder: 'Ask us anything...',
186
- sendButton: 'Send',
187
- welcomeMessage: 'Welcome! We\'re here to help.',
188
- },
189
- position: 'bottom-right',
190
- botInfo: {
191
- name: 'Support Assistant',
192
- avatar: '/bot-avatar.png',
193
- },
194
- userInfo: {
195
- name: 'Guest User',
196
- },
197
- primaryColor: '#6B46C1', // Purple like Sendbird
198
- autoOpen: false,
199
- showTimestamp: true,
200
- showDateSeparator: true,
201
- poweredByText: 'Powered by nextjs-chatbot-ui',
202
- };
203
-
204
- return (
205
- <div>
206
- <h1>My Website</h1>
207
- <Chatbot config={chatbotConfig} />
208
- </div>
209
- );
210
- }
211
- ```
212
-
213
- ### Tailwind CSS Setup
214
-
215
- Make sure you have Tailwind CSS configured in your Next.js project. The component uses Tailwind classes, so ensure your `tailwind.config.js` includes the component:
216
-
217
- ```javascript
218
- // tailwind.config.js
219
- module.exports = {
220
- content: [
221
- './node_modules/nextjs-chatbot-ui/**/*.{js,ts,jsx,tsx}',
222
- // ... your other paths
223
- ],
224
- // ... rest of your config
225
- }
226
- ```
227
-
228
- ## Development
229
-
230
- To develop or modify this package:
231
-
232
- ```bash
233
- # Install dependencies
234
- npm install
235
-
236
- # Run development server
237
- npm run dev
238
-
239
- # Build for production
240
- npm run build
241
- ```
242
-
243
- ## Admin Setup Component
244
-
245
- The package also includes an `AdminSetup` component for configuring database connections in your admin panel.
246
-
247
- ### Usage
248
-
249
- ```javascript
250
- import { AdminSetup } from 'nextjs-chatbot-ui';
251
- import type { DatabaseConfig, DatabaseConnection } from 'nextjs-chatbot-ui';
252
-
253
- function AdminPanel() {
254
- const handleSave = (config: DatabaseConfig) => {
255
- // Save configuration to your backend
256
- console.log('Config:', config);
257
- };
258
-
259
- const handleTestConnection = async (connection: DatabaseConnection) => {
260
- // Test database connection
261
- const response = await fetch('/api/database/test', {
262
- method: 'POST',
263
- body: JSON.stringify(connection),
264
- });
265
- return response.ok;
266
- };
267
-
268
- const handleFetchColumns = async (connection: DatabaseConnection) => {
269
- // Fetch columns from database
270
- const response = await fetch('/api/database/columns', {
271
- method: 'POST',
272
- body: JSON.stringify(connection),
273
- });
274
- const data = await response.json();
275
- return data.columns || [];
276
- };
277
-
278
- return (
279
- <aside className="sidebar">
280
- <AdminSetup
281
- onSave={handleSave}
282
- onTestConnection={handleTestConnection}
283
- onFetchColumns={handleFetchColumns}
284
- />
285
- </aside>
286
- );
287
- }
288
- ```
289
-
290
- ### Features
291
-
292
- - **Database Selection**: Choose between MongoDB and PostgreSQL
293
- - **Connection Configuration**: Configure all necessary connection parameters
294
- - **Connection Testing**: Test database connection before proceeding
295
- - **Column Selection**: Select columns for:
296
- - Embedding processing
297
- - LLM processing
298
- - ChromaDB storage
299
- - **Modal Interface**: Clean, step-by-step modal interface
300
- - **Sidebar Integration**: Ready to integrate into admin panel sidebars
301
-
302
- ### Database Configuration
303
-
304
- The component supports:
305
- - **MongoDB**: Connection string or individual fields (host, port, database, SSL)
306
- - **PostgreSQL**: Host, port, database, username, password, SSL
307
-
308
- ### Backend API Requirements
309
-
310
- Your backend should provide:
311
-
312
- 1. **Test Connection Endpoint** (`POST /api/database/test`)
313
- - Accepts `DatabaseConnection` object
314
- - Returns success/failure status
315
-
316
- 2. **Fetch Columns Endpoint** (`POST /api/database/columns`)
317
- - Accepts `DatabaseConnection` object
318
- - Returns array of column names
319
-
320
- 3. **Save Configuration Endpoint** (your implementation)
321
- - Accepts `DatabaseConfig` object
322
- - Saves configuration to your storage
323
-
324
- ## License
325
-
326
- MIT
327
-
328
- ## Contributing
329
-
330
- Contributions are welcome! Please feel free to submit a Pull Request.
1
+ # Chatbot UI Component
2
+
3
+ A beautiful, configurable chatbot UI component for Next.js applications with Tailwind CSS. Inspired by Sendbird's modern chat interface.
4
+
5
+ ## Features
6
+
7
+ - 🎨 Modern, Sendbird-inspired UI design
8
+ - ⚙️ Fully configurable (labels, position, colors, backend URL)
9
+ - 📱 Responsive and mobile-friendly
10
+ - 🎯 TypeScript support
11
+ - 🚀 Easy to integrate
12
+ - 💬 Real-time messaging support
13
+ - 🎭 Customizable user and bot avatars
14
+ - ⏰ Optional timestamp display
15
+
16
+ ## Compatibility Requirements
17
+
18
+ This package requires:
19
+ - **Next.js 13+** (with App Router or Pages Router support)
20
+ - **React 18+**
21
+ - **TypeScript** (optional, but recommended)
22
+ - **Tailwind CSS 3+** (must be configured in your project)
23
+
24
+ **Important Notes:**
25
+ - The package exports TypeScript source files directly, which Next.js will compile automatically
26
+ - Make sure your `tailwind.config.js` includes the package path in the `content` array
27
+ - This package uses the `'use client'` directive and requires client-side rendering
28
+ - Works with both **App Router** (`app/` directory) and **Pages Router** (`pages/` directory)
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install nextjs-chatbot-ui
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ### Basic Setup
39
+
40
+ **Step 1: Configure Next.js** - Add the package to your `next.config.js`:
41
+
42
+ ```javascript
43
+ // next.config.js
44
+ /** @type {import('next').NextConfig} */
45
+ const nextConfig = {
46
+ transpilePackages: ['nextjs-chatbot-ui'],
47
+ // ... your other config
48
+ }
49
+
50
+ module.exports = nextConfig
51
+ ```
52
+
53
+ **Step 2: Configure Tailwind CSS** - Make sure your `tailwind.config.js` includes the component:
54
+
55
+ ```javascript
56
+ // tailwind.config.js
57
+ module.exports = {
58
+ content: [
59
+ './node_modules/nextjs-chatbot-ui/**/*.{js,ts,jsx,tsx}',
60
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
61
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
62
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
63
+ ],
64
+ // ... rest of your config
65
+ }
66
+ ```
67
+
68
+ **Step 3: Import and use the component**:
69
+
70
+ For **App Router** (app directory):
71
+ ```javascript
72
+ // app/page.tsx or app/any-page.tsx
73
+ 'use client'; // Required for App Router
74
+
75
+ import { Chatbot } from 'nextjs-chatbot-ui';
76
+ import type { ChatbotConfig } from 'nextjs-chatbot-ui';
77
+ ```
78
+
79
+ For **Pages Router** (pages directory):
80
+ ```javascript
81
+ // pages/index.js or pages/any-page.js
82
+ import { Chatbot } from 'nextjs-chatbot-ui';
83
+ import type { ChatbotConfig } from 'nextjs-chatbot-ui';
84
+ ```
85
+
86
+ **Step 4: Configure and use the component**:
87
+
88
+ ```javascript
89
+ const config: ChatbotConfig = {
90
+ backendUrl: 'https://your-backend-api.com/chat',
91
+ labels: {
92
+ title: 'Support Chat',
93
+ placeholder: 'Type your message...',
94
+ sendButton: 'Send',
95
+ welcomeMessage: 'Hello! How can I help you?',
96
+ },
97
+ position: 'bottom-right',
98
+ botInfo: {
99
+ name: 'Support Bot',
100
+ avatar: 'https://example.com/bot-avatar.png',
101
+ },
102
+ userInfo: {
103
+ name: 'User',
104
+ avatar: 'https://example.com/user-avatar.png',
105
+ },
106
+ primaryColor: '#0ea5e9',
107
+ autoOpen: false,
108
+ showTimestamp: true,
109
+ };
110
+
111
+ export default function Page() {
112
+ return (
113
+ <div>
114
+ <h1>My Website</h1>
115
+ <Chatbot config={config} />
116
+ </div>
117
+ );
118
+ }
119
+ ```
120
+
121
+ ### Complete Example (App Router)
122
+
123
+ ```javascript
124
+ // app/page.tsx
125
+ 'use client';
126
+
127
+ import { Chatbot } from 'nextjs-chatbot-ui';
128
+ import type { ChatbotConfig } from 'nextjs-chatbot-ui';
129
+
130
+ export default function Home() {
131
+ const config: ChatbotConfig = {
132
+ backendUrl: 'https://api.example.com/chat',
133
+ labels: {
134
+ title: 'Support Chat',
135
+ placeholder: 'Type your message...',
136
+ sendButton: 'Send',
137
+ welcomeMessage: 'Hello! How can I help you today?',
138
+ },
139
+ position: 'bottom-right',
140
+ botInfo: {
141
+ name: 'Support Bot',
142
+ },
143
+ userInfo: {
144
+ name: 'User',
145
+ },
146
+ primaryColor: '#6B46C1',
147
+ autoOpen: false,
148
+ showTimestamp: true,
149
+ };
150
+
151
+ return (
152
+ <main>
153
+ <h1>Welcome to My Site</h1>
154
+ <Chatbot config={config} />
155
+ </main>
156
+ );
157
+ }
158
+ ```
159
+
160
+ ### Complete Example (Pages Router)
161
+
162
+ ```javascript
163
+ // pages/index.js
164
+ import { Chatbot } from 'nextjs-chatbot-ui';
165
+
166
+ export default function Home() {
167
+ const config = {
168
+ backendUrl: 'https://api.example.com/chat',
169
+ labels: {
170
+ title: 'Support Chat',
171
+ placeholder: 'Type your message...',
172
+ },
173
+ position: 'bottom-right',
174
+ };
175
+
176
+ return (
177
+ <div>
178
+ <h1>Welcome to My Site</h1>
179
+ <Chatbot config={config} />
180
+ </div>
181
+ );
182
+ }
183
+ ```
184
+
185
+ ### Configuration Options
186
+
187
+ #### `ChatbotConfig` Interface
188
+
189
+ ```typescript
190
+ interface ChatbotConfig {
191
+ // Required
192
+ backendUrl: string; // Your backend API endpoint for handling messages
193
+
194
+ // Optional Labels
195
+ labels?: {
196
+ title?: string; // Chat header title (default: "Chat Support")
197
+ placeholder?: string; // Input placeholder (default: "Type your message...")
198
+ sendButton?: string; // Send button text (default: "Send")
199
+ typingIndicator?: string; // Loading message (default: "Typing...")
200
+ welcomeMessage?: string; // Initial bot message (default: "Hello! How can I help you today?")
201
+ errorMessage?: string; // Error message (default: "Sorry, something went wrong. Please try again.")
202
+ };
203
+
204
+ // Position
205
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'; // Default: 'bottom-right'
206
+
207
+ // User Information
208
+ userInfo?: {
209
+ name?: string; // User name
210
+ avatar?: string; // User avatar URL
211
+ };
212
+
213
+ // Bot Information
214
+ botInfo?: {
215
+ name?: string; // Bot name (default: uses title)
216
+ avatar?: string; // Bot avatar URL
217
+ };
218
+
219
+ // Styling
220
+ primaryColor?: string; // Primary color (hex code)
221
+ backgroundColor?: string; // Chat background color (hex code)
222
+
223
+ // Behavior
224
+ autoOpen?: boolean; // Auto-open chat on load (default: false)
225
+ showTimestamp?: boolean; // Show message timestamps (default: false)
226
+ showDateSeparator?: boolean; // Show date separators between messages (default: false)
227
+ poweredByText?: string; // Footer text (e.g., "Powered by sendbird")
228
+ }
229
+ ```
230
+
231
+ ### Backend API Requirements
232
+
233
+ Your backend should accept POST requests with the following format:
234
+
235
+ **Request:**
236
+ ```json
237
+ {
238
+ "message": "User's message text",
239
+ "userInfo": {
240
+ "name": "User",
241
+ "avatar": "https://example.com/avatar.png"
242
+ }
243
+ }
244
+ ```
245
+
246
+ **Response:**
247
+ ```json
248
+ {
249
+ "message": "Bot's response text",
250
+ "suggestedReplies": ["Option 1", "Option 2", "Option 3"]
251
+ }
252
+ ```
253
+
254
+ or
255
+
256
+ ```json
257
+ {
258
+ "response": "Bot's response text",
259
+ "suggestions": ["Option 1", "Option 2", "Option 3"]
260
+ }
261
+ ```
262
+
263
+ **Note:** The `suggestedReplies` or `suggestions` field is optional and will display as clickable buttons below the bot's message, similar to Sendbird's interface.
264
+
265
+ ### Example Implementation
266
+
267
+ ```javascript
268
+ // pages/index.js or app/page.js
269
+ 'use client';
270
+
271
+ import { Chatbot } from 'nextjs-chatbot-ui';
272
+ import type { ChatbotConfig } from 'nextjs-chatbot-ui';
273
+
274
+ export default function Home() {
275
+ const chatbotConfig: ChatbotConfig = {
276
+ backendUrl: 'https://api.example.com/chat',
277
+ labels: {
278
+ title: 'Customer Support',
279
+ placeholder: 'Ask us anything...',
280
+ sendButton: 'Send',
281
+ welcomeMessage: 'Welcome! We\'re here to help.',
282
+ },
283
+ position: 'bottom-right',
284
+ botInfo: {
285
+ name: 'Support Assistant',
286
+ avatar: '/bot-avatar.png',
287
+ },
288
+ userInfo: {
289
+ name: 'Guest User',
290
+ },
291
+ primaryColor: '#6B46C1', // Purple like Sendbird
292
+ autoOpen: false,
293
+ showTimestamp: true,
294
+ showDateSeparator: true,
295
+ poweredByText: 'Powered by nextjs-chatbot-ui',
296
+ };
297
+
298
+ return (
299
+ <div>
300
+ <h1>My Website</h1>
301
+ <Chatbot config={chatbotConfig} />
302
+ </div>
303
+ );
304
+ }
305
+ ```
306
+
307
+ ### Tailwind CSS Setup
308
+
309
+ Make sure you have Tailwind CSS configured in your Next.js project. The component uses Tailwind classes, so ensure your `tailwind.config.js` includes the component:
310
+
311
+ ```javascript
312
+ // tailwind.config.js
313
+ module.exports = {
314
+ content: [
315
+ './node_modules/nextjs-chatbot-ui/**/*.{js,ts,jsx,tsx}',
316
+ // ... your other paths
317
+ ],
318
+ // ... rest of your config
319
+ }
320
+ ```
321
+
322
+ ## Development
323
+
324
+ To develop or modify this package:
325
+
326
+ ```bash
327
+ # Install dependencies
328
+ npm install
329
+
330
+ # Run development server
331
+ npm run dev
332
+
333
+ # Build for production
334
+ npm run build
335
+ ```
336
+
337
+ ## Admin Setup Component
338
+
339
+ The package also includes an `AdminSetup` component for configuring database connections in your admin panel.
340
+
341
+ ### Usage
342
+
343
+ ```javascript
344
+ import { AdminSetup } from 'nextjs-chatbot-ui';
345
+ import type { DatabaseConfig, DatabaseConnection } from 'nextjs-chatbot-ui';
346
+
347
+ function AdminPanel() {
348
+ const handleSave = (config: DatabaseConfig) => {
349
+ // Save configuration to your backend
350
+ console.log('Config:', config);
351
+ };
352
+
353
+ const handleTestConnection = async (connection: DatabaseConnection) => {
354
+ // Test database connection
355
+ const response = await fetch('/api/database/test', {
356
+ method: 'POST',
357
+ body: JSON.stringify(connection),
358
+ });
359
+ return response.ok;
360
+ };
361
+
362
+ const handleFetchColumns = async (connection: DatabaseConnection) => {
363
+ // Fetch columns from database
364
+ const response = await fetch('/api/database/columns', {
365
+ method: 'POST',
366
+ body: JSON.stringify(connection),
367
+ });
368
+ const data = await response.json();
369
+ return data.columns || [];
370
+ };
371
+
372
+ return (
373
+ <aside className="sidebar">
374
+ <AdminSetup
375
+ onSave={handleSave}
376
+ onTestConnection={handleTestConnection}
377
+ onFetchColumns={handleFetchColumns}
378
+ />
379
+ </aside>
380
+ );
381
+ }
382
+ ```
383
+
384
+ ### Features
385
+
386
+ - **Database Selection**: Choose between MongoDB and PostgreSQL
387
+ - **Connection Configuration**: Configure all necessary connection parameters
388
+ - **Connection Testing**: Test database connection before proceeding
389
+ - **Column Selection**: Select columns for:
390
+ - Embedding processing
391
+ - LLM processing
392
+ - ChromaDB storage
393
+ - **Modal Interface**: Clean, step-by-step modal interface
394
+ - **Sidebar Integration**: Ready to integrate into admin panel sidebars
395
+
396
+ ### Database Configuration
397
+
398
+ The component supports:
399
+ - **MongoDB**: Connection string or individual fields (host, port, database, SSL)
400
+ - **PostgreSQL**: Host, port, database, username, password, SSL
401
+
402
+ ### Backend API Requirements
403
+
404
+ Your backend should provide:
405
+
406
+ 1. **Test Connection Endpoint** (`POST /api/database/test`)
407
+ - Accepts `DatabaseConnection` object
408
+ - Returns success/failure status
409
+
410
+ 2. **Fetch Columns Endpoint** (`POST /api/database/columns`)
411
+ - Accepts `DatabaseConnection` object
412
+ - Returns array of column names
413
+
414
+ 3. **Save Configuration Endpoint** (your implementation)
415
+ - Accepts `DatabaseConfig` object
416
+ - Saves configuration to your storage
417
+
418
+ ## Troubleshooting
419
+
420
+ ### Component not rendering or styles not working
421
+
422
+ 1. **Check Tailwind Configuration**: Make sure `nextjs-chatbot-ui` is in your `tailwind.config.js` content array:
423
+ ```javascript
424
+ content: [
425
+ './node_modules/nextjs-chatbot-ui/**/*.{js,ts,jsx,tsx}',
426
+ // ... other paths
427
+ ]
428
+ ```
429
+
430
+ 2. **Check Next.js Configuration**: Ensure `transpilePackages` is set in `next.config.js`:
431
+ ```javascript
432
+ transpilePackages: ['nextjs-chatbot-ui']
433
+ ```
434
+
435
+ 3. **Restart Development Server**: After configuration changes, restart your Next.js dev server.
436
+
437
+ ### TypeScript Errors
438
+
439
+ If you see TypeScript errors:
440
+ - Make sure you're using TypeScript 5+ (optional but recommended)
441
+ - The package includes type definitions, so TypeScript should work out of the box
442
+ - If using JavaScript, you can ignore type imports: `import { Chatbot } from 'nextjs-chatbot-ui';`
443
+
444
+ ### "Module not found" or Import Errors
445
+
446
+ 1. **Verify Installation**: Run `npm install nextjs-chatbot-ui` again
447
+ 2. **Check Node Modules**: Ensure the package exists in `node_modules/nextjs-chatbot-ui`
448
+ 3. **Clear Cache**: Try deleting `.next` folder and `node_modules`, then reinstall
449
+
450
+ ### Component not appearing
451
+
452
+ - Make sure you're using `'use client'` directive in App Router
453
+ - Check that the component is not hidden by CSS (z-index, overflow, etc.)
454
+ - Verify the `position` prop is set correctly
455
+
456
+ ### Backend API Issues
457
+
458
+ - Ensure your backend URL is correct and accessible
459
+ - Check CORS settings if making cross-origin requests
460
+ - Verify the API response format matches the expected structure (see Backend API Requirements)
461
+
462
+ ## License
463
+
464
+ MIT
465
+
466
+ ## Contributing
467
+
468
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -13,6 +13,7 @@ const AdminSetup: React.FC<AdminSetupProps> = ({
13
13
  const [currentStep, setCurrentStep] = useState<'connection' | 'columns'>('connection');
14
14
  const [isConnecting, setIsConnecting] = useState(false);
15
15
  const [connectionError, setConnectionError] = useState<string | null>(null);
16
+ const [connectionSuccess, setConnectionSuccess] = useState(false);
16
17
  const [availableColumns, setAvailableColumns] = useState<string[]>([]);
17
18
  const [isLoadingColumns, setIsLoadingColumns] = useState(false);
18
19
 
@@ -52,52 +53,69 @@ const AdminSetup: React.FC<AdminSetupProps> = ({
52
53
  setConnectionError(null);
53
54
  };
54
55
 
55
- const handleTestConnection = async () => {
56
+ const handleTestConnection = async (): Promise<boolean> => {
56
57
  if (!onTestConnection) {
57
58
  // Default test - just validate fields
58
59
  if (!connection.host || !connection.database) {
59
60
  setConnectionError('Please fill in all required fields');
60
- return;
61
+ setConnectionSuccess(false);
62
+ return false;
61
63
  }
62
64
  setConnectionError(null);
63
- return;
65
+ setConnectionSuccess(true);
66
+ return true;
64
67
  }
65
68
 
66
69
  setIsConnecting(true);
67
70
  setConnectionError(null);
71
+ setConnectionSuccess(false);
68
72
 
69
73
  try {
70
74
  const isValid = await onTestConnection(connection);
71
75
  if (isValid) {
72
76
  setConnectionError(null);
73
- // Fetch columns after successful connection
74
- await handleFetchColumns();
77
+ setConnectionSuccess(true);
78
+ return true;
75
79
  } else {
76
80
  setConnectionError('Connection failed. Please check your credentials.');
81
+ setConnectionSuccess(false);
82
+ return false;
77
83
  }
78
84
  } catch (error: any) {
79
85
  setConnectionError(error.message || 'Connection failed. Please try again.');
86
+ setConnectionSuccess(false);
87
+ return false;
80
88
  } finally {
81
89
  setIsConnecting(false);
82
90
  }
83
91
  };
84
92
 
85
- const handleFetchColumns = async () => {
93
+ const handleFetchColumns = async (): Promise<string[]> => {
86
94
  if (!onFetchColumns) {
87
95
  // Mock columns for demo
88
- setAvailableColumns(['id', 'title', 'content', 'description', 'category', 'tags', 'created_at', 'updated_at']);
96
+ const mockColumns = ['id', 'title', 'content', 'description', 'category', 'tags', 'created_at', 'updated_at'];
97
+ setAvailableColumns(mockColumns);
89
98
  setIsLoadingColumns(false);
90
- return;
99
+ return mockColumns;
91
100
  }
92
101
 
93
102
  setIsLoadingColumns(true);
103
+ setConnectionError(null);
94
104
  try {
95
105
  const columns = await onFetchColumns(connection);
96
- setAvailableColumns(columns);
106
+ if (columns && columns.length > 0) {
107
+ setAvailableColumns(columns);
108
+ setIsLoadingColumns(false);
109
+ return columns;
110
+ } else {
111
+ setConnectionError('No columns found in the database.');
112
+ setIsLoadingColumns(false);
113
+ return [];
114
+ }
97
115
  } catch (error: any) {
98
116
  setConnectionError(error.message || 'Failed to fetch columns');
99
- } finally {
100
117
  setIsLoadingColumns(false);
118
+ return [];
101
119
  }
102
120
  };
103
121
 
@@ -106,21 +124,39 @@ const AdminSetup: React.FC<AdminSetupProps> = ({
106
124
  if (dbType === 'mongodb') {
107
125
  if (!connection.connectionString && (!connection.host || !connection.database)) {
108
126
  setConnectionError('Please provide connection string or host and database');
127
+ setConnectionSuccess(false);
109
128
  return;
110
129
  }
111
130
  } else {
112
131
  if (!connection.host || !connection.database || !connection.username || !connection.password) {
113
132
  setConnectionError('Please fill in all required fields');
133
+ setConnectionSuccess(false);
114
134
  return;
115
135
  }
116
136
  }
117
137
 
118
- // Test connection
119
- await handleTestConnection();
138
+ // Clear previous errors
139
+ setConnectionError(null);
140
+ setConnectionSuccess(false);
141
+
142
+ // Test connection first
143
+ const connectionSuccess = await handleTestConnection();
120
144
 
121
- // If no error, move to next step
122
- if (!connectionError) {
145
+ if (!connectionSuccess) {
146
+ // Connection failed, don't proceed
147
+ return;
148
+ }
149
+
150
+ // If connection successful, fetch columns
151
+ const fetchedColumns = await handleFetchColumns();
152
+
153
+ if (fetchedColumns && fetchedColumns.length > 0) {
154
+ // Successfully fetched columns, move to next step
123
155
  setCurrentStep('columns');
156
+ setConnectionError(null);
157
+ } else {
158
+ // Column fetching failed, show error but keep connection success
159
+ // Error is already set in handleFetchColumns
124
160
  }
125
161
  };
126
162
 
@@ -158,6 +194,8 @@ const AdminSetup: React.FC<AdminSetupProps> = ({
158
194
  setIsModalOpen(false);
159
195
  setCurrentStep('connection');
160
196
  setConnectionError(null);
197
+ setConnectionSuccess(false);
198
+ setAvailableColumns([]);
161
199
  setColumnSelection({
162
200
  embeddingColumns: [],
163
201
  llmColumns: [],
@@ -435,88 +473,131 @@ const AdminSetup: React.FC<AdminSetupProps> = ({
435
473
  <p className="text-sm text-red-800">{connectionError}</p>
436
474
  </div>
437
475
  )}
476
+ {connectionSuccess && !connectionError && !isConnecting && (
477
+ <div className="bg-green-50 border border-green-200 rounded-lg p-4">
478
+ <p className="text-sm text-green-800">✓ Connection successful!</p>
479
+ </div>
480
+ )}
438
481
  </div>
439
482
  ) : (
440
483
  <div className="space-y-6">
441
484
  {isLoadingColumns ? (
442
- <div className="flex items-center justify-center py-8">
443
- <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
485
+ <div className="flex flex-col items-center justify-center py-8">
486
+ <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mb-3"></div>
487
+ <p className="text-sm text-gray-600">Loading columns...</p>
488
+ </div>
489
+ ) : availableColumns.length === 0 ? (
490
+ <div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
491
+ <p className="text-sm text-yellow-800">No columns available. Please go back and check your connection.</p>
444
492
  </div>
445
493
  ) : (
446
494
  <>
447
495
  <div>
448
- <p className="text-sm text-gray-600 mb-4">
449
- Select which columns to use for embedding, LLM processing, and ChromaDB storage.
496
+ <p className="text-sm text-gray-600 mb-2">
497
+ Select which columns to use for <strong>Embeddings</strong>, <strong>LLM processing</strong>, and <strong>ChromaDB storage</strong>.
498
+ </p>
499
+ <p className="text-xs text-gray-500 mb-4">
500
+ Found {availableColumns.length} column{availableColumns.length !== 1 ? 's' : ''} in your database.
450
501
  </p>
451
502
  </div>
452
503
 
453
504
  {/* Embedding Columns */}
454
505
  <div>
455
- <label className="block text-sm font-medium text-gray-700 mb-3">
456
- Embedding Columns
506
+ <label className="block text-sm font-medium text-gray-700 mb-2">
507
+ Works with Embeddings
457
508
  </label>
458
- <div className="grid grid-cols-2 gap-2 max-h-32 overflow-y-auto border border-gray-200 rounded-lg p-3">
459
- {availableColumns.map((column) => (
460
- <label
461
- key={`embedding-${column}`}
462
- className="flex items-center gap-2 cursor-pointer hover:bg-gray-50 p-2 rounded"
463
- >
464
- <input
465
- type="checkbox"
466
- checked={columnSelection.embeddingColumns.includes(column)}
467
- onChange={() => handleColumnToggle(column, 'embeddingColumns')}
468
- className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
469
- />
470
- <span className="text-sm text-gray-700">{column}</span>
471
- </label>
472
- ))}
509
+ <p className="text-xs text-gray-500 mb-3">Select columns that will be used for embedding generation</p>
510
+ <div className="grid grid-cols-2 gap-2 max-h-40 overflow-y-auto border border-gray-200 rounded-lg p-3 bg-gray-50">
511
+ {availableColumns.length === 0 ? (
512
+ <p className="text-sm text-gray-500 col-span-2 text-center py-2">No columns available</p>
513
+ ) : (
514
+ availableColumns.map((column) => (
515
+ <label
516
+ key={`embedding-${column}`}
517
+ className="flex items-center gap-2 cursor-pointer hover:bg-white p-2 rounded transition-colors"
518
+ >
519
+ <input
520
+ type="checkbox"
521
+ checked={columnSelection.embeddingColumns.includes(column)}
522
+ onChange={() => handleColumnToggle(column, 'embeddingColumns')}
523
+ className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
524
+ />
525
+ <span className="text-sm text-gray-700">{column}</span>
526
+ </label>
527
+ ))
528
+ )}
473
529
  </div>
530
+ {columnSelection.embeddingColumns.length > 0 && (
531
+ <p className="text-xs text-green-600 mt-1">
532
+ {columnSelection.embeddingColumns.length} column{columnSelection.embeddingColumns.length !== 1 ? 's' : ''} selected
533
+ </p>
534
+ )}
474
535
  </div>
475
536
 
476
537
  {/* LLM Columns */}
477
538
  <div>
478
- <label className="block text-sm font-medium text-gray-700 mb-3">
479
- LLM Columns
539
+ <label className="block text-sm font-medium text-gray-700 mb-2">
540
+ Works with LLM
480
541
  </label>
481
- <div className="grid grid-cols-2 gap-2 max-h-32 overflow-y-auto border border-gray-200 rounded-lg p-3">
482
- {availableColumns.map((column) => (
483
- <label
484
- key={`llm-${column}`}
485
- className="flex items-center gap-2 cursor-pointer hover:bg-gray-50 p-2 rounded"
486
- >
487
- <input
488
- type="checkbox"
489
- checked={columnSelection.llmColumns.includes(column)}
490
- onChange={() => handleColumnToggle(column, 'llmColumns')}
491
- className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
492
- />
493
- <span className="text-sm text-gray-700">{column}</span>
494
- </label>
495
- ))}
542
+ <p className="text-xs text-gray-500 mb-3">Select columns that will be processed by the LLM</p>
543
+ <div className="grid grid-cols-2 gap-2 max-h-40 overflow-y-auto border border-gray-200 rounded-lg p-3 bg-gray-50">
544
+ {availableColumns.length === 0 ? (
545
+ <p className="text-sm text-gray-500 col-span-2 text-center py-2">No columns available</p>
546
+ ) : (
547
+ availableColumns.map((column) => (
548
+ <label
549
+ key={`llm-${column}`}
550
+ className="flex items-center gap-2 cursor-pointer hover:bg-white p-2 rounded transition-colors"
551
+ >
552
+ <input
553
+ type="checkbox"
554
+ checked={columnSelection.llmColumns.includes(column)}
555
+ onChange={() => handleColumnToggle(column, 'llmColumns')}
556
+ className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
557
+ />
558
+ <span className="text-sm text-gray-700">{column}</span>
559
+ </label>
560
+ ))
561
+ )}
496
562
  </div>
563
+ {columnSelection.llmColumns.length > 0 && (
564
+ <p className="text-xs text-green-600 mt-1">
565
+ {columnSelection.llmColumns.length} column{columnSelection.llmColumns.length !== 1 ? 's' : ''} selected
566
+ </p>
567
+ )}
497
568
  </div>
498
569
 
499
570
  {/* ChromaDB Columns */}
500
571
  <div>
501
- <label className="block text-sm font-medium text-gray-700 mb-3">
502
- ChromaDB Columns
572
+ <label className="block text-sm font-medium text-gray-700 mb-2">
573
+ Works with ChromaDB
503
574
  </label>
504
- <div className="grid grid-cols-2 gap-2 max-h-32 overflow-y-auto border border-gray-200 rounded-lg p-3">
505
- {availableColumns.map((column) => (
506
- <label
507
- key={`chroma-${column}`}
508
- className="flex items-center gap-2 cursor-pointer hover:bg-gray-50 p-2 rounded"
509
- >
510
- <input
511
- type="checkbox"
512
- checked={columnSelection.chromaColumns.includes(column)}
513
- onChange={() => handleColumnToggle(column, 'chromaColumns')}
514
- className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
515
- />
516
- <span className="text-sm text-gray-700">{column}</span>
517
- </label>
518
- ))}
575
+ <p className="text-xs text-gray-500 mb-3">Select columns that will be stored in ChromaDB</p>
576
+ <div className="grid grid-cols-2 gap-2 max-h-40 overflow-y-auto border border-gray-200 rounded-lg p-3 bg-gray-50">
577
+ {availableColumns.length === 0 ? (
578
+ <p className="text-sm text-gray-500 col-span-2 text-center py-2">No columns available</p>
579
+ ) : (
580
+ availableColumns.map((column) => (
581
+ <label
582
+ key={`chroma-${column}`}
583
+ className="flex items-center gap-2 cursor-pointer hover:bg-white p-2 rounded transition-colors"
584
+ >
585
+ <input
586
+ type="checkbox"
587
+ checked={columnSelection.chromaColumns.includes(column)}
588
+ onChange={() => handleColumnToggle(column, 'chromaColumns')}
589
+ className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
590
+ />
591
+ <span className="text-sm text-gray-700">{column}</span>
592
+ </label>
593
+ ))
594
+ )}
519
595
  </div>
596
+ {columnSelection.chromaColumns.length > 0 && (
597
+ <p className="text-xs text-green-600 mt-1">
598
+ {columnSelection.chromaColumns.length} column{columnSelection.chromaColumns.length !== 1 ? 's' : ''} selected
599
+ </p>
600
+ )}
520
601
  </div>
521
602
  </>
522
603
  )}
@@ -537,9 +618,12 @@ const AdminSetup: React.FC<AdminSetupProps> = ({
537
618
  <button
538
619
  onClick={handleConnectAndNext}
539
620
  disabled={isConnecting || isLoadingColumns}
540
- className="px-6 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
621
+ className="px-6 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2"
541
622
  >
542
- {isConnecting ? 'Connecting...' : 'Connect & Next'}
623
+ {isConnecting && (
624
+ <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
625
+ )}
626
+ {isLoadingColumns ? 'Loading Columns...' : isConnecting ? 'Connecting...' : 'Connect & Next'}
543
627
  </button>
544
628
  ) : (
545
629
  <button
package/package.json CHANGED
@@ -1,68 +1,68 @@
1
- {
2
- "name": "nextjs-chatbot-ui",
3
-
4
- "version": "1.0.1",
5
- "description": "A configurable chatbot UI component for Next.js with Tailwind CSS",
6
- "main": "./index.tsx",
7
- "module": "./index.tsx",
8
- "types": "./types/index.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./types/index.ts",
12
- "import": "./index.tsx",
13
- "require": "./index.tsx",
14
- "default": "./index.tsx"
15
- },
16
- "./components/Chatbot": {
17
- "types": "./types/index.ts",
18
- "import": "./components/Chatbot.tsx",
19
- "require": "./components/Chatbot.tsx",
20
- "default": "./components/Chatbot.tsx"
21
- },
22
- "./types": {
23
- "types": "./types/index.ts",
24
- "import": "./types/index.ts",
25
- "require": "./types/index.ts",
26
- "default": "./types/index.ts"
27
- }
28
- },
29
- "files": [
30
- "components",
31
- "types",
32
- "index.tsx",
33
- "README.md"
34
- ],
35
- "scripts": {
36
- "build": "echo 'Package is ready to use. Source files are included.'",
37
- "dev": "next dev",
38
- "prepare": "npm run build",
39
- "type-check": "tsc --noEmit"
40
- },
41
- "keywords": [
42
- "chatbot",
43
- "ui",
44
- "component",
45
- "nextjs",
46
- "tailwind",
47
- "react"
48
- ],
49
- "author": "",
50
- "license": "MIT",
51
- "peerDependencies": {
52
- "react": "^18.0.0",
53
- "react-dom": "^18.0.0",
54
- "next": "^14.0.0"
55
- },
56
- "dependencies": {
57
- "clsx": "^2.1.0"
58
- },
59
- "devDependencies": {
60
- "@types/node": "^20.0.0",
61
- "@types/react": "^18.0.0",
62
- "@types/react-dom": "^18.0.0",
63
- "autoprefixer": "^10.4.16",
64
- "postcss": "^8.4.32",
65
- "tailwindcss": "^3.4.0",
66
- "typescript": "^5.3.3"
67
- }
68
- }
1
+ {
2
+ "name": "nextjs-chatbot-ui",
3
+
4
+ "version": "1.1.1",
5
+ "description": "A configurable chatbot UI component for Next.js with Tailwind CSS",
6
+ "main": "./index.tsx",
7
+ "module": "./index.tsx",
8
+ "types": "./types/index.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./types/index.ts",
12
+ "import": "./index.tsx",
13
+ "require": "./index.tsx",
14
+ "default": "./index.tsx"
15
+ },
16
+ "./components/Chatbot": {
17
+ "types": "./types/index.ts",
18
+ "import": "./components/Chatbot.tsx",
19
+ "require": "./components/Chatbot.tsx",
20
+ "default": "./components/Chatbot.tsx"
21
+ },
22
+ "./types": {
23
+ "types": "./types/index.ts",
24
+ "import": "./types/index.ts",
25
+ "require": "./types/index.ts",
26
+ "default": "./types/index.ts"
27
+ }
28
+ },
29
+ "files": [
30
+ "components",
31
+ "types",
32
+ "index.tsx",
33
+ "README.md"
34
+ ],
35
+ "scripts": {
36
+ "build": "echo 'Package is ready to use. Source files are included.'",
37
+ "dev": "next dev",
38
+ "prepare": "npm run build",
39
+ "type-check": "tsc --noEmit"
40
+ },
41
+ "keywords": [
42
+ "chatbot",
43
+ "ui",
44
+ "component",
45
+ "nextjs",
46
+ "tailwind",
47
+ "react"
48
+ ],
49
+ "author": "",
50
+ "license": "MIT",
51
+ "peerDependencies": {
52
+ "react": "^18.0.0 || ^19.0.0",
53
+ "react-dom": "^18.0.0 || ^19.0.0",
54
+ "next": "^13.0.0 || ^14.0.0 || ^15.0.0"
55
+ },
56
+ "dependencies": {
57
+ "clsx": "^2.1.0"
58
+ },
59
+ "devDependencies": {
60
+ "@types/node": "^20.0.0",
61
+ "@types/react": "^18.0.0",
62
+ "@types/react-dom": "^18.0.0",
63
+ "autoprefixer": "^10.4.16",
64
+ "postcss": "^8.4.32",
65
+ "tailwindcss": "^3.4.0",
66
+ "typescript": "^5.3.3"
67
+ }
68
+ }