rohit-chat-widget 1.0.0
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 +455 -0
- package/lib/components/ChatContainer/ChatContainer.d.ts +10 -0
- package/lib/components/ChatContainer/ChatContainer.d.ts.map +1 -0
- package/lib/components/ChatContainer/ChatContainer.js +9 -0
- package/lib/components/ChatContainer/ChatContainer.js.map +1 -0
- package/lib/components/ChatContainer/index.d.ts +2 -0
- package/lib/components/ChatContainer/index.d.ts.map +1 -0
- package/lib/components/ChatContainer/index.js +2 -0
- package/lib/components/ChatContainer/index.js.map +1 -0
- package/lib/components/ChatHeader/ChatHeader.d.ts +12 -0
- package/lib/components/ChatHeader/ChatHeader.d.ts.map +1 -0
- package/lib/components/ChatHeader/ChatHeader.js +25 -0
- package/lib/components/ChatHeader/ChatHeader.js.map +1 -0
- package/lib/components/ChatHeader/index.d.ts +2 -0
- package/lib/components/ChatHeader/index.d.ts.map +1 -0
- package/lib/components/ChatHeader/index.js +2 -0
- package/lib/components/ChatHeader/index.js.map +1 -0
- package/lib/components/ChatWidget/ChatWidget.d.ts +13 -0
- package/lib/components/ChatWidget/ChatWidget.d.ts.map +1 -0
- package/lib/components/ChatWidget/ChatWidget.js +69 -0
- package/lib/components/ChatWidget/ChatWidget.js.map +1 -0
- package/lib/components/ChatWidget/index.d.ts +2 -0
- package/lib/components/ChatWidget/index.d.ts.map +1 -0
- package/lib/components/ChatWidget/index.js +2 -0
- package/lib/components/ChatWidget/index.js.map +1 -0
- package/lib/components/DropdownMenu/DropdownMenu.d.ts +16 -0
- package/lib/components/DropdownMenu/DropdownMenu.d.ts.map +1 -0
- package/lib/components/DropdownMenu/DropdownMenu.js +78 -0
- package/lib/components/DropdownMenu/DropdownMenu.js.map +1 -0
- package/lib/components/DropdownMenu/index.d.ts +3 -0
- package/lib/components/DropdownMenu/index.d.ts.map +1 -0
- package/lib/components/DropdownMenu/index.js +2 -0
- package/lib/components/DropdownMenu/index.js.map +1 -0
- package/lib/components/ErrorBoundary/ErrorBoundary.d.ts +21 -0
- package/lib/components/ErrorBoundary/ErrorBoundary.d.ts.map +1 -0
- package/lib/components/ErrorBoundary/ErrorBoundary.js +40 -0
- package/lib/components/ErrorBoundary/ErrorBoundary.js.map +1 -0
- package/lib/components/ErrorBoundary/index.d.ts +2 -0
- package/lib/components/ErrorBoundary/index.d.ts.map +1 -0
- package/lib/components/ErrorBoundary/index.js +2 -0
- package/lib/components/ErrorBoundary/index.js.map +1 -0
- package/lib/components/ErrorDisplay/ErrorDisplay.d.ts +9 -0
- package/lib/components/ErrorDisplay/ErrorDisplay.d.ts.map +1 -0
- package/lib/components/ErrorDisplay/ErrorDisplay.js +11 -0
- package/lib/components/ErrorDisplay/ErrorDisplay.js.map +1 -0
- package/lib/components/ErrorDisplay/index.d.ts +3 -0
- package/lib/components/ErrorDisplay/index.d.ts.map +1 -0
- package/lib/components/ErrorDisplay/index.js +3 -0
- package/lib/components/ErrorDisplay/index.js.map +1 -0
- package/lib/components/LoadingIndicator/LoadingIndicator.d.ts +10 -0
- package/lib/components/LoadingIndicator/LoadingIndicator.d.ts.map +1 -0
- package/lib/components/LoadingIndicator/LoadingIndicator.js +10 -0
- package/lib/components/LoadingIndicator/LoadingIndicator.js.map +1 -0
- package/lib/components/LoadingIndicator/index.d.ts +2 -0
- package/lib/components/LoadingIndicator/index.d.ts.map +1 -0
- package/lib/components/LoadingIndicator/index.js +3 -0
- package/lib/components/LoadingIndicator/index.js.map +1 -0
- package/lib/components/MenuButton/MenuButton.d.ts +10 -0
- package/lib/components/MenuButton/MenuButton.d.ts.map +1 -0
- package/lib/components/MenuButton/MenuButton.js +7 -0
- package/lib/components/MenuButton/MenuButton.js.map +1 -0
- package/lib/components/MenuButton/index.d.ts +2 -0
- package/lib/components/MenuButton/index.d.ts.map +1 -0
- package/lib/components/MenuButton/index.js +2 -0
- package/lib/components/MenuButton/index.js.map +1 -0
- package/lib/components/MenuItem/MenuItem.d.ts +12 -0
- package/lib/components/MenuItem/MenuItem.d.ts.map +1 -0
- package/lib/components/MenuItem/MenuItem.js +12 -0
- package/lib/components/MenuItem/MenuItem.js.map +1 -0
- package/lib/components/MenuItem/index.d.ts +2 -0
- package/lib/components/MenuItem/index.d.ts.map +1 -0
- package/lib/components/MenuItem/index.js +2 -0
- package/lib/components/MenuItem/index.js.map +1 -0
- package/lib/components/MessageBubble/MessageBubble.d.ts +17 -0
- package/lib/components/MessageBubble/MessageBubble.d.ts.map +1 -0
- package/lib/components/MessageBubble/MessageBubble.js +111 -0
- package/lib/components/MessageBubble/MessageBubble.js.map +1 -0
- package/lib/components/MessageBubble/index.d.ts +2 -0
- package/lib/components/MessageBubble/index.d.ts.map +1 -0
- package/lib/components/MessageBubble/index.js +2 -0
- package/lib/components/MessageBubble/index.js.map +1 -0
- package/lib/components/MessageInput/MessageInput.d.ts +9 -0
- package/lib/components/MessageInput/MessageInput.d.ts.map +1 -0
- package/lib/components/MessageInput/MessageInput.js +75 -0
- package/lib/components/MessageInput/MessageInput.js.map +1 -0
- package/lib/components/MessageInput/index.d.ts +2 -0
- package/lib/components/MessageInput/index.d.ts.map +1 -0
- package/lib/components/MessageInput/index.js +2 -0
- package/lib/components/MessageInput/index.js.map +1 -0
- package/lib/components/MessageList/MessageList.d.ts +21 -0
- package/lib/components/MessageList/MessageList.d.ts.map +1 -0
- package/lib/components/MessageList/MessageList.js +61 -0
- package/lib/components/MessageList/MessageList.js.map +1 -0
- package/lib/components/MessageList/index.d.ts +2 -0
- package/lib/components/MessageList/index.d.ts.map +1 -0
- package/lib/components/MessageList/index.js +2 -0
- package/lib/components/MessageList/index.js.map +1 -0
- package/lib/components/StatusIndicator/StatusIndicator.d.ts +10 -0
- package/lib/components/StatusIndicator/StatusIndicator.d.ts.map +1 -0
- package/lib/components/StatusIndicator/StatusIndicator.js +19 -0
- package/lib/components/StatusIndicator/StatusIndicator.js.map +1 -0
- package/lib/components/StatusIndicator/index.d.ts +2 -0
- package/lib/components/StatusIndicator/index.d.ts.map +1 -0
- package/lib/components/StatusIndicator/index.js +2 -0
- package/lib/components/StatusIndicator/index.js.map +1 -0
- package/lib/components/index.d.ts +21 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/index.js +13 -0
- package/lib/components/index.js.map +1 -0
- package/lib/config/api.d.ts +79 -0
- package/lib/config/api.d.ts.map +1 -0
- package/lib/config/api.js +10 -0
- package/lib/config/api.js.map +1 -0
- package/lib/config/constants.d.ts +5 -0
- package/lib/config/constants.d.ts.map +1 -0
- package/lib/config/constants.js +5 -0
- package/lib/config/constants.js.map +1 -0
- package/lib/hooks/index.d.ts +2 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +2 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/hooks/useChatInit.d.ts +21 -0
- package/lib/hooks/useChatInit.d.ts.map +1 -0
- package/lib/hooks/useChatInit.js +66 -0
- package/lib/hooks/useChatInit.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.esm.js +21148 -0
- package/lib/index.esm.js.map +1 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/services/acs/acsClient.d.ts +29 -0
- package/lib/services/acs/acsClient.d.ts.map +1 -0
- package/lib/services/acs/acsClient.js +101 -0
- package/lib/services/acs/acsClient.js.map +1 -0
- package/lib/services/acs/index.d.ts +2 -0
- package/lib/services/acs/index.d.ts.map +1 -0
- package/lib/services/acs/index.js +2 -0
- package/lib/services/acs/index.js.map +1 -0
- package/lib/services/api/backendApi.d.ts +842 -0
- package/lib/services/api/backendApi.d.ts.map +1 -0
- package/lib/services/api/backendApi.js +70 -0
- package/lib/services/api/backendApi.js.map +1 -0
- package/lib/services/api/index.d.ts +3 -0
- package/lib/services/api/index.d.ts.map +1 -0
- package/lib/services/api/index.js +3 -0
- package/lib/services/api/index.js.map +1 -0
- package/lib/services/chatService.d.ts +51 -0
- package/lib/services/chatService.d.ts.map +1 -0
- package/lib/services/chatService.js +232 -0
- package/lib/services/chatService.js.map +1 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/index.js +4 -0
- package/lib/services/index.js.map +1 -0
- package/lib/src/components/ChatContainer/ChatContainer.d.ts +10 -0
- package/lib/src/components/ChatContainer/ChatContainer.d.ts.map +1 -0
- package/lib/src/components/ChatContainer/index.d.ts +2 -0
- package/lib/src/components/ChatContainer/index.d.ts.map +1 -0
- package/lib/src/components/ChatHeader/ChatHeader.d.ts +12 -0
- package/lib/src/components/ChatHeader/ChatHeader.d.ts.map +1 -0
- package/lib/src/components/ChatHeader/index.d.ts +2 -0
- package/lib/src/components/ChatHeader/index.d.ts.map +1 -0
- package/lib/src/components/ChatWidget/ChatWidget.d.ts +13 -0
- package/lib/src/components/ChatWidget/ChatWidget.d.ts.map +1 -0
- package/lib/src/components/ChatWidget/index.d.ts +2 -0
- package/lib/src/components/ChatWidget/index.d.ts.map +1 -0
- package/lib/src/components/DropdownMenu/DropdownMenu.d.ts +16 -0
- package/lib/src/components/DropdownMenu/DropdownMenu.d.ts.map +1 -0
- package/lib/src/components/DropdownMenu/index.d.ts +3 -0
- package/lib/src/components/DropdownMenu/index.d.ts.map +1 -0
- package/lib/src/components/ErrorBoundary/ErrorBoundary.d.ts +21 -0
- package/lib/src/components/ErrorBoundary/ErrorBoundary.d.ts.map +1 -0
- package/lib/src/components/ErrorBoundary/index.d.ts +2 -0
- package/lib/src/components/ErrorBoundary/index.d.ts.map +1 -0
- package/lib/src/components/ErrorDisplay/ErrorDisplay.d.ts +9 -0
- package/lib/src/components/ErrorDisplay/ErrorDisplay.d.ts.map +1 -0
- package/lib/src/components/ErrorDisplay/index.d.ts +3 -0
- package/lib/src/components/ErrorDisplay/index.d.ts.map +1 -0
- package/lib/src/components/LoadingIndicator/LoadingIndicator.d.ts +10 -0
- package/lib/src/components/LoadingIndicator/LoadingIndicator.d.ts.map +1 -0
- package/lib/src/components/LoadingIndicator/index.d.ts +2 -0
- package/lib/src/components/LoadingIndicator/index.d.ts.map +1 -0
- package/lib/src/components/MenuButton/MenuButton.d.ts +10 -0
- package/lib/src/components/MenuButton/MenuButton.d.ts.map +1 -0
- package/lib/src/components/MenuButton/index.d.ts +2 -0
- package/lib/src/components/MenuButton/index.d.ts.map +1 -0
- package/lib/src/components/MenuItem/MenuItem.d.ts +12 -0
- package/lib/src/components/MenuItem/MenuItem.d.ts.map +1 -0
- package/lib/src/components/MenuItem/index.d.ts +2 -0
- package/lib/src/components/MenuItem/index.d.ts.map +1 -0
- package/lib/src/components/MessageBubble/MessageBubble.d.ts +17 -0
- package/lib/src/components/MessageBubble/MessageBubble.d.ts.map +1 -0
- package/lib/src/components/MessageBubble/index.d.ts +2 -0
- package/lib/src/components/MessageBubble/index.d.ts.map +1 -0
- package/lib/src/components/MessageInput/MessageInput.d.ts +9 -0
- package/lib/src/components/MessageInput/MessageInput.d.ts.map +1 -0
- package/lib/src/components/MessageInput/index.d.ts +2 -0
- package/lib/src/components/MessageInput/index.d.ts.map +1 -0
- package/lib/src/components/MessageList/MessageList.d.ts +21 -0
- package/lib/src/components/MessageList/MessageList.d.ts.map +1 -0
- package/lib/src/components/MessageList/index.d.ts +2 -0
- package/lib/src/components/MessageList/index.d.ts.map +1 -0
- package/lib/src/components/StatusIndicator/StatusIndicator.d.ts +10 -0
- package/lib/src/components/StatusIndicator/StatusIndicator.d.ts.map +1 -0
- package/lib/src/components/StatusIndicator/index.d.ts +2 -0
- package/lib/src/components/StatusIndicator/index.d.ts.map +1 -0
- package/lib/src/components/index.d.ts +21 -0
- package/lib/src/components/index.d.ts.map +1 -0
- package/lib/src/config/api.d.ts +79 -0
- package/lib/src/config/api.d.ts.map +1 -0
- package/lib/src/config/constants.d.ts +5 -0
- package/lib/src/config/constants.d.ts.map +1 -0
- package/lib/src/hooks/index.d.ts +2 -0
- package/lib/src/hooks/index.d.ts.map +1 -0
- package/lib/src/hooks/useChatInit.d.ts +21 -0
- package/lib/src/hooks/useChatInit.d.ts.map +1 -0
- package/lib/src/index.d.ts +14 -0
- package/lib/src/index.d.ts.map +1 -0
- package/lib/src/services/acs/acsClient.d.ts +29 -0
- package/lib/src/services/acs/acsClient.d.ts.map +1 -0
- package/lib/src/services/acs/index.d.ts +2 -0
- package/lib/src/services/acs/index.d.ts.map +1 -0
- package/lib/src/services/api/backendApi.d.ts +842 -0
- package/lib/src/services/api/backendApi.d.ts.map +1 -0
- package/lib/src/services/api/index.d.ts +3 -0
- package/lib/src/services/api/index.d.ts.map +1 -0
- package/lib/src/services/chatService.d.ts +51 -0
- package/lib/src/services/chatService.d.ts.map +1 -0
- package/lib/src/services/index.d.ts +4 -0
- package/lib/src/services/index.d.ts.map +1 -0
- package/lib/src/store/index.d.ts +36 -0
- package/lib/src/store/index.d.ts.map +1 -0
- package/lib/src/store/slices/index.d.ts +5 -0
- package/lib/src/store/slices/index.d.ts.map +1 -0
- package/lib/src/store/slices/messagesSlice.d.ts +73 -0
- package/lib/src/store/slices/messagesSlice.d.ts.map +1 -0
- package/lib/src/store/slices/threadSlice.d.ts +42 -0
- package/lib/src/store/slices/threadSlice.d.ts.map +1 -0
- package/lib/src/store/store.d.ts +36 -0
- package/lib/src/store/store.d.ts.map +1 -0
- package/lib/src/types/index.d.ts +29 -0
- package/lib/src/types/index.d.ts.map +1 -0
- package/lib/src/utils/dateUtils.d.ts +13 -0
- package/lib/src/utils/dateUtils.d.ts.map +1 -0
- package/lib/src/utils/index.d.ts +4 -0
- package/lib/src/utils/index.d.ts.map +1 -0
- package/lib/src/utils/styleManager.d.ts +45 -0
- package/lib/src/utils/styleManager.d.ts.map +1 -0
- package/lib/src/utils/validation.d.ts +17 -0
- package/lib/src/utils/validation.d.ts.map +1 -0
- package/lib/store/index.d.ts +36 -0
- package/lib/store/index.d.ts.map +1 -0
- package/lib/store/index.js +9 -0
- package/lib/store/index.js.map +1 -0
- package/lib/store/slices/index.d.ts +5 -0
- package/lib/store/slices/index.d.ts.map +1 -0
- package/lib/store/slices/index.js +7 -0
- package/lib/store/slices/index.js.map +1 -0
- package/lib/store/slices/messagesSlice.d.ts +73 -0
- package/lib/store/slices/messagesSlice.d.ts.map +1 -0
- package/lib/store/slices/messagesSlice.js +81 -0
- package/lib/store/slices/messagesSlice.js.map +1 -0
- package/lib/store/slices/threadSlice.d.ts +42 -0
- package/lib/store/slices/threadSlice.d.ts.map +1 -0
- package/lib/store/slices/threadSlice.js +54 -0
- package/lib/store/slices/threadSlice.js.map +1 -0
- package/lib/store/store.d.ts +36 -0
- package/lib/store/store.d.ts.map +1 -0
- package/lib/store/store.js +17 -0
- package/lib/store/store.js.map +1 -0
- package/lib/styles.css +3534 -0
- package/lib/types/index.d.ts +29 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +2 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/dateUtils.d.ts +13 -0
- package/lib/utils/dateUtils.d.ts.map +1 -0
- package/lib/utils/dateUtils.js +33 -0
- package/lib/utils/dateUtils.js.map +1 -0
- package/lib/utils/index.d.ts +4 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +5 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/styleManager.d.ts +45 -0
- package/lib/utils/styleManager.d.ts.map +1 -0
- package/lib/utils/styleManager.js +69 -0
- package/lib/utils/styleManager.js.map +1 -0
- package/lib/utils/validation.d.ts +17 -0
- package/lib/utils/validation.d.ts.map +1 -0
- package/lib/utils/validation.js +32 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +93 -0
package/README.md
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# @smarteremr/chat-widget
|
|
2
|
+
|
|
3
|
+
A comprehensive React-based chat widget component for SmarterEMR client applications with real-time messaging capabilities powered by Azure Communication Services (ACS).
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- 💬 **Real-time messaging** - Powered by Azure Communication Services
|
|
8
|
+
- 🎨 **Customizable theming** - Full control over colors and styling
|
|
9
|
+
- 📱 **Responsive design** - Works seamlessly on desktop and mobile
|
|
10
|
+
- ⚡ **TypeScript support** - Full type definitions included
|
|
11
|
+
- 🔒 **Error boundaries** - Graceful error handling and recovery
|
|
12
|
+
- ♿ **Accessibility** - WCAG compliant components
|
|
13
|
+
- 🎯 **Redux integration** - Built-in state management
|
|
14
|
+
- 🔧 **Configurable menu** - Customizable dropdown menu options
|
|
15
|
+
- 📊 **Message history** - Load and display conversation history
|
|
16
|
+
- 🛡️ **Input validation** - Built-in XSS protection and validation
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @smarteremr/chat-widget
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Peer Dependencies
|
|
25
|
+
|
|
26
|
+
Ensure you have the required peer dependencies installed:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install react@>=16.8.0 react-dom@>=16.8.0
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 🎯 Quick Start
|
|
33
|
+
|
|
34
|
+
### Basic Implementation
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import React from 'react';
|
|
38
|
+
import { ChatWidget } from '@smarteremr/chat-widget';
|
|
39
|
+
import '@smarteremr/chat-widget/lib/styles.css';
|
|
40
|
+
|
|
41
|
+
function App() {
|
|
42
|
+
const initParams = {
|
|
43
|
+
baseUrl: 'https://your-api-endpoint.com',
|
|
44
|
+
apiKey: 'your-api-key',
|
|
45
|
+
userInfo: {
|
|
46
|
+
userEmail: 'user@example.com',
|
|
47
|
+
firstName: 'John',
|
|
48
|
+
lastName: 'Doe'
|
|
49
|
+
},
|
|
50
|
+
metaData: {
|
|
51
|
+
orderNumber: 'ORD-12345'
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const menuItems = [
|
|
56
|
+
{
|
|
57
|
+
id: 'help',
|
|
58
|
+
label: 'Help Center',
|
|
59
|
+
onClick: () => window.open('/help', '_blank')
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 'feedback',
|
|
63
|
+
label: 'Send Feedback',
|
|
64
|
+
onClick: () => console.log('Feedback clicked')
|
|
65
|
+
}
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div className="app">
|
|
70
|
+
<ChatWidget
|
|
71
|
+
initParams={initParams}
|
|
72
|
+
primaryColor="#007bff"
|
|
73
|
+
secondaryColor="#6c757d"
|
|
74
|
+
menuItems={menuItems}
|
|
75
|
+
showMenu={true}
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default App;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### With Custom Redux Store
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import React from 'react';
|
|
88
|
+
import { Provider } from 'react-redux';
|
|
89
|
+
import { ChatWidget } from '@smarteremr/chat-widget';
|
|
90
|
+
import { store } from './store';
|
|
91
|
+
|
|
92
|
+
function App() {
|
|
93
|
+
return (
|
|
94
|
+
<Provider store={store}>
|
|
95
|
+
<ChatWidget
|
|
96
|
+
initParams={initParams}
|
|
97
|
+
primaryColor="#007bff"
|
|
98
|
+
secondaryColor="#6c757d"
|
|
99
|
+
menuItems={[]}
|
|
100
|
+
showMenu={false}
|
|
101
|
+
/>
|
|
102
|
+
</Provider>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 📚 API Reference
|
|
108
|
+
|
|
109
|
+
### ChatWidget Props
|
|
110
|
+
|
|
111
|
+
| Prop | Type | Required | Description |
|
|
112
|
+
|------|------|----------|-------------|
|
|
113
|
+
| `initParams` | `InitiateChatRequest` | ✅ | API configuration and user information |
|
|
114
|
+
| `primaryColor` | `string` | ✅ | Primary theme color (hex format) |
|
|
115
|
+
| `secondaryColor` | `string` | ✅ | Secondary theme color (hex format) |
|
|
116
|
+
| `menuItems` | `MenuItemConfig[]` | ✅ | Dropdown menu configuration |
|
|
117
|
+
| `showMenu` | `boolean` | ✅ | Whether to show the dropdown menu |
|
|
118
|
+
|
|
119
|
+
### InitiateChatRequest Interface
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
interface InitiateChatRequest {
|
|
123
|
+
baseUrl: string; // Your backend API base URL
|
|
124
|
+
apiKey: string; // API authentication key
|
|
125
|
+
userInfo: {
|
|
126
|
+
userEmail: string; // User's email address
|
|
127
|
+
firstName: string; // User's first name
|
|
128
|
+
lastName: string; // User's last name
|
|
129
|
+
};
|
|
130
|
+
metaData: {
|
|
131
|
+
orderNumber?: string; // Optional order/reference number
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### MenuItemConfig Interface
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
interface MenuItemConfig {
|
|
140
|
+
id: string; // Unique identifier
|
|
141
|
+
label: string; // Display text
|
|
142
|
+
onClick: () => void; // Click handler function
|
|
143
|
+
icon?: string; // Optional icon class/name
|
|
144
|
+
disabled?: boolean; // Whether item is disabled
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 🎨 Theming & Customization
|
|
149
|
+
|
|
150
|
+
### CSS Custom Properties
|
|
151
|
+
|
|
152
|
+
The widget uses CSS custom properties for theming. You can override these in your CSS:
|
|
153
|
+
|
|
154
|
+
```css
|
|
155
|
+
:root {
|
|
156
|
+
--chat-primary-color: #007bff;
|
|
157
|
+
--chat-primary-hover: #0056b3;
|
|
158
|
+
--chat-background-color: #ffffff;
|
|
159
|
+
--chat-text-color: #333333;
|
|
160
|
+
--chat-border-color: #e0e0e0;
|
|
161
|
+
--chat-shadow-color: rgba(0, 0, 0, 0.1);
|
|
162
|
+
--chat-user-message-bg: #007bff;
|
|
163
|
+
--chat-agent-message-bg: #e9ecef;
|
|
164
|
+
--chat-input-bg: #ffffff;
|
|
165
|
+
--chat-header-bg: #007bff;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Using StyleManager
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { StyleManager, applyDefaultTheme } from '@smarteremr/chat-widget';
|
|
173
|
+
|
|
174
|
+
// Apply default theme
|
|
175
|
+
applyDefaultTheme();
|
|
176
|
+
|
|
177
|
+
// Or customize individual properties
|
|
178
|
+
const styleManager = StyleManager.getInstance();
|
|
179
|
+
styleManager.setProperty('primary-color', '#ff6b6b');
|
|
180
|
+
styleManager.setProperty('background-color', '#f8f9fa');
|
|
181
|
+
|
|
182
|
+
// Set multiple properties at once
|
|
183
|
+
styleManager.setTheme({
|
|
184
|
+
'primary-color': '#28a745',
|
|
185
|
+
'user-message-bg': '#28a745',
|
|
186
|
+
'header-bg': '#28a745'
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 🔧 Advanced Usage
|
|
191
|
+
|
|
192
|
+
### Using Hooks
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
import { useChatInit } from '@smarteremr/chat-widget';
|
|
196
|
+
|
|
197
|
+
function CustomChatComponent() {
|
|
198
|
+
const {
|
|
199
|
+
isInitializing,
|
|
200
|
+
isInitialized,
|
|
201
|
+
error,
|
|
202
|
+
initializeChat,
|
|
203
|
+
sendMessage,
|
|
204
|
+
loadMessages
|
|
205
|
+
} = useChatInit();
|
|
206
|
+
|
|
207
|
+
const handleSendMessage = async (message: string) => {
|
|
208
|
+
const result = await sendMessage(message);
|
|
209
|
+
if (!result.success) {
|
|
210
|
+
console.error('Failed to send message:', result.error);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<div>
|
|
216
|
+
{isInitializing && <div>Initializing chat...</div>}
|
|
217
|
+
{error && <div>Error: {error}</div>}
|
|
218
|
+
{/* Your custom UI */}
|
|
219
|
+
</div>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Redux Store Integration
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
import {
|
|
228
|
+
store,
|
|
229
|
+
useAppDispatch,
|
|
230
|
+
useAppSelector,
|
|
231
|
+
selectMessages,
|
|
232
|
+
addNewMessage
|
|
233
|
+
} from '@smarteremr/chat-widget';
|
|
234
|
+
|
|
235
|
+
function MessageDisplay() {
|
|
236
|
+
const messages = useAppSelector(selectMessages);
|
|
237
|
+
const dispatch = useAppDispatch();
|
|
238
|
+
|
|
239
|
+
const handleAddMessage = () => {
|
|
240
|
+
dispatch(addNewMessage({
|
|
241
|
+
id: Date.now().toString(),
|
|
242
|
+
content: 'New message',
|
|
243
|
+
senderDisplayName: 'User',
|
|
244
|
+
senderACSId: 'user-123',
|
|
245
|
+
version: 1,
|
|
246
|
+
createdOn: new Date().toISOString(),
|
|
247
|
+
updatedOn: new Date().toISOString()
|
|
248
|
+
}));
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<div>
|
|
253
|
+
{messages.map(message => (
|
|
254
|
+
<div key={message.id}>{message.content}</div>
|
|
255
|
+
))}
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## 🛠️ Utilities
|
|
262
|
+
|
|
263
|
+
### Date Utilities
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
import { formatTime, formatDate, getRelativeTime } from '@smarteremr/chat-widget';
|
|
267
|
+
|
|
268
|
+
const now = new Date();
|
|
269
|
+
console.log(formatTime(now)); // "2:30 PM"
|
|
270
|
+
console.log(formatDate(now)); // "12/25/2023"
|
|
271
|
+
console.log(getRelativeTime(now)); // "Just now"
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Validation Utilities
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
import {
|
|
278
|
+
validateMessage,
|
|
279
|
+
validateEmail,
|
|
280
|
+
sanitizeInput,
|
|
281
|
+
isValidUUID
|
|
282
|
+
} from '@smarteremr/chat-widget';
|
|
283
|
+
|
|
284
|
+
console.log(validateMessage('Hello')); // true
|
|
285
|
+
console.log(validateEmail('user@example.com')); // true
|
|
286
|
+
console.log(sanitizeInput('<script>alert("xss")</script>')); // Safe HTML
|
|
287
|
+
console.log(isValidUUID('123e4567-e89b-12d3-a456-426614174000')); // true
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## 📁 Project Structure
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
@smarteremr-chat-widget/
|
|
294
|
+
├── src/
|
|
295
|
+
│ ├── components/ # React components
|
|
296
|
+
│ │ ├── ChatWidget/ # Main widget component
|
|
297
|
+
│ │ ├── ChatContainer/ # Message container
|
|
298
|
+
│ │ ├── ChatHeader/ # Header with controls
|
|
299
|
+
│ │ ├── MessageList/ # Message display
|
|
300
|
+
│ │ ├── MessageInput/ # Input component
|
|
301
|
+
│ │ ├── MessageBubble/ # Individual message
|
|
302
|
+
│ │ ├── LoadingIndicator/# Loading states
|
|
303
|
+
│ │ ├── ErrorBoundary/ # Error handling
|
|
304
|
+
│ │ ├── ErrorDisplay/ # Error UI
|
|
305
|
+
│ │ ├── DropdownMenu/ # Menu component
|
|
306
|
+
│ │ ├── MenuButton/ # Menu button
|
|
307
|
+
│ │ ├── MenuItem/ # Menu items
|
|
308
|
+
│ │ └── StatusIndicator/ # Status display
|
|
309
|
+
│ ├── config/ # Configuration
|
|
310
|
+
│ │ ├── api.ts # API interfaces
|
|
311
|
+
│ │ └── constants.ts # Constants
|
|
312
|
+
│ ├── hooks/ # Custom hooks
|
|
313
|
+
│ │ ├── useChatInit.ts # Chat initialization
|
|
314
|
+
│ │ └── index.ts # Hook exports
|
|
315
|
+
│ ├── services/ # Business logic
|
|
316
|
+
│ │ ├── chatService.ts # Main chat service
|
|
317
|
+
│ │ ├── acs/ # Azure Communication Services
|
|
318
|
+
│ │ └── api/ # API services
|
|
319
|
+
│ ├── store/ # Redux store
|
|
320
|
+
│ │ ├── store.ts # Store configuration
|
|
321
|
+
│ │ └── slices/ # Redux slices
|
|
322
|
+
│ ├── styles/ # SCSS styles
|
|
323
|
+
│ │ ├── global.scss # Global styles
|
|
324
|
+
│ │ ├── reset.scss # CSS reset
|
|
325
|
+
│ │ └── components/ # Component styles
|
|
326
|
+
│ ├── types/ # TypeScript types
|
|
327
|
+
│ ├── utils/ # Utility functions
|
|
328
|
+
│ │ ├── dateUtils.ts # Date formatting
|
|
329
|
+
│ │ ├── validation.ts # Input validation
|
|
330
|
+
│ │ └── styleManager.ts # Theme management
|
|
331
|
+
│ └── index.ts # Main export
|
|
332
|
+
├── lib/ # Compiled output
|
|
333
|
+
├── tests/ # Test files
|
|
334
|
+
├── package.json # Package configuration
|
|
335
|
+
├── tsconfig.json # TypeScript config
|
|
336
|
+
├── rollup.config.cjs # Build configuration
|
|
337
|
+
└── README.md # This file
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## 🧪 Testing
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
# Run tests
|
|
344
|
+
npm test
|
|
345
|
+
|
|
346
|
+
# Run tests in watch mode
|
|
347
|
+
npm run test:watch
|
|
348
|
+
|
|
349
|
+
# Run linting
|
|
350
|
+
npm run lint
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## 🏗️ Development
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Install dependencies
|
|
357
|
+
npm install
|
|
358
|
+
|
|
359
|
+
# Build the package
|
|
360
|
+
npm run build
|
|
361
|
+
|
|
362
|
+
# Build in watch mode
|
|
363
|
+
npm run build:watch
|
|
364
|
+
|
|
365
|
+
# Clean build artifacts
|
|
366
|
+
npm run clean
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## 📋 Requirements
|
|
370
|
+
|
|
371
|
+
- **Node.js**: >= 16.0.0
|
|
372
|
+
- **npm**: >= 8.0.0
|
|
373
|
+
- **React**: >= 16.8.0
|
|
374
|
+
- **React DOM**: >= 16.8.0
|
|
375
|
+
|
|
376
|
+
## 🌐 Browser Support
|
|
377
|
+
|
|
378
|
+
- Chrome (latest)
|
|
379
|
+
- Firefox (latest)
|
|
380
|
+
- Safari (latest)
|
|
381
|
+
- Edge (latest)
|
|
382
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
383
|
+
|
|
384
|
+
## 🔒 Security
|
|
385
|
+
|
|
386
|
+
The widget includes built-in security features:
|
|
387
|
+
|
|
388
|
+
- **XSS Protection**: All user inputs are sanitized
|
|
389
|
+
- **Input Validation**: Message length and format validation
|
|
390
|
+
- **Error Boundaries**: Prevents crashes from propagating
|
|
391
|
+
- **Secure API Communication**: Uses API keys for authentication
|
|
392
|
+
|
|
393
|
+
## 🚨 Error Handling
|
|
394
|
+
|
|
395
|
+
The widget provides comprehensive error handling:
|
|
396
|
+
|
|
397
|
+
```tsx
|
|
398
|
+
// Error boundary catches component errors
|
|
399
|
+
<ErrorBoundary
|
|
400
|
+
onError={(error, errorInfo) => {
|
|
401
|
+
console.error('Chat widget error:', error, errorInfo);
|
|
402
|
+
}}
|
|
403
|
+
fallback={<CustomErrorComponent />}
|
|
404
|
+
>
|
|
405
|
+
<ChatWidget {...props} />
|
|
406
|
+
</ErrorBoundary>
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
## 📈 Performance
|
|
410
|
+
|
|
411
|
+
- **Code Splitting**: Components are lazy-loaded where possible
|
|
412
|
+
- **Memoization**: React.memo used for expensive components
|
|
413
|
+
- **Efficient Rendering**: Redux selectors prevent unnecessary re-renders
|
|
414
|
+
- **Bundle Size**: Optimized build with tree-shaking
|
|
415
|
+
|
|
416
|
+
## 🤝 Contributing
|
|
417
|
+
|
|
418
|
+
1. Fork the repository
|
|
419
|
+
2. Create a feature branch: `git checkout -b feature/new-feature`
|
|
420
|
+
3. Make your changes and add tests
|
|
421
|
+
4. Run tests: `npm test`
|
|
422
|
+
5. Commit your changes: `git commit -am 'Add new feature'`
|
|
423
|
+
6. Push to the branch: `git push origin feature/new-feature`
|
|
424
|
+
7. Submit a pull request
|
|
425
|
+
|
|
426
|
+
## 📄 License
|
|
427
|
+
|
|
428
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
429
|
+
|
|
430
|
+
## 👥 Author
|
|
431
|
+
|
|
432
|
+
**SmarterEMR Dev Team**
|
|
433
|
+
|
|
434
|
+
## 🆘 Support
|
|
435
|
+
|
|
436
|
+
For support and questions:
|
|
437
|
+
|
|
438
|
+
1. Check the [documentation](#-api-reference)
|
|
439
|
+
2. Search existing [issues](https://github.com/your-repo/issues)
|
|
440
|
+
3. Create a new issue with detailed information
|
|
441
|
+
4. Contact the development team
|
|
442
|
+
|
|
443
|
+
## 📝 Changelog
|
|
444
|
+
|
|
445
|
+
### v1.1.21
|
|
446
|
+
- Current stable release
|
|
447
|
+
- Full TypeScript support
|
|
448
|
+
- Azure Communication Services integration
|
|
449
|
+
- Comprehensive theming system
|
|
450
|
+
- Error boundary implementation
|
|
451
|
+
- Mobile responsiveness improvements
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
**Made with ❤️ for SmarterEMR**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ChatContainerProps {
|
|
3
|
+
isLoading?: boolean;
|
|
4
|
+
className?: string;
|
|
5
|
+
showDateSeparator?: boolean;
|
|
6
|
+
welcomeMessage?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const ChatContainer: React.FC<ChatContainerProps>;
|
|
9
|
+
export default ChatContainer;
|
|
10
|
+
//# sourceMappingURL=ChatContainer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatContainer.d.ts","sourceRoot":"","sources":["../../../src/components/ChatContainer/ChatContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAqBtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styles from './ChatContainer.module.scss';
|
|
3
|
+
import { MessageList } from '../MessageList';
|
|
4
|
+
import { MessageInput } from '../MessageInput';
|
|
5
|
+
export const ChatContainer = ({ isLoading = false, className }) => {
|
|
6
|
+
return (_jsxs("div", { className: `${styles.chatContainer} ${className || ''}`, children: [_jsx("div", { className: styles.messagesSection, children: _jsx(MessageList, { isLoading: isLoading }) }), _jsx("div", { className: styles.disclaimer, role: "note", "aria-live": "polite", children: "This is a private channel with your doctor for clinical questions. For billing/shipping/account issues, please reach out to support." }), _jsx("div", { className: styles.chatInputWrapper, children: _jsx(MessageInput, { disabled: false }) })] }));
|
|
7
|
+
};
|
|
8
|
+
export default ChatContainer;
|
|
9
|
+
//# sourceMappingURL=ChatContainer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatContainer.js","sourceRoot":"","sources":["../../../src/components/ChatContainer/ChatContainer.tsx"],"names":[],"mappings":";AACA,OAAO,MAAM,MAAM,6BAA6B,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAS/C,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAC1D,SAAS,GAAG,KAAK,EACjB,SAAS,EACV,EAAE,EAAE;IACH,OAAO,CACL,eAAK,SAAS,EAAE,GAAG,MAAM,CAAC,aAAa,IAAI,SAAS,IAAI,EAAE,EAAE,aAC1D,cAAK,SAAS,EAAE,MAAM,CAAC,eAAe,YACpC,KAAC,WAAW,IAAC,SAAS,EAAE,SAAS,GAAI,GACjC,EAGN,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAC,MAAM,eAAW,QAAQ,qJAE3D,EAGN,cAAK,SAAS,EAAE,MAAM,CAAC,gBAAgB,YACrC,KAAC,YAAY,IAAC,QAAQ,EAAE,KAAK,GAAI,GAC7B,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ChatContainer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ChatContainer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MenuItemConfig } from '../DropdownMenu';
|
|
3
|
+
export interface ChatHeaderProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
onRefresh?: () => void;
|
|
7
|
+
menuItems?: MenuItemConfig[];
|
|
8
|
+
showMenu?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const ChatHeader: React.FC<ChatHeaderProps>;
|
|
11
|
+
export default ChatHeader;
|
|
12
|
+
//# sourceMappingURL=ChatHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatHeader.d.ts","sourceRoot":"","sources":["../../../src/components/ChatHeader/ChatHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAkGhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import styles from './ChatHeader.module.scss';
|
|
4
|
+
import { DropdownMenu } from '../DropdownMenu';
|
|
5
|
+
import { useSelector } from 'react-redux';
|
|
6
|
+
import { selectThread } from '@/store/slices/threadSlice';
|
|
7
|
+
export const ChatHeader = ({ title = 'Provider', className, onRefresh, menuItems = [], showMenu = false, }) => {
|
|
8
|
+
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
9
|
+
const thread = useSelector(selectThread);
|
|
10
|
+
const headerTitle = thread?.threadType === 'medical' ? 'Provider' : 'Support';
|
|
11
|
+
const toggleMenu = () => {
|
|
12
|
+
setIsMenuOpen(!isMenuOpen);
|
|
13
|
+
};
|
|
14
|
+
const handleMenuButtonClick = (event) => {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
event.preventDefault();
|
|
17
|
+
toggleMenu();
|
|
18
|
+
};
|
|
19
|
+
const closeMenu = () => {
|
|
20
|
+
setIsMenuOpen(false);
|
|
21
|
+
};
|
|
22
|
+
return (_jsx("div", { className: `${styles.chatHeader} chat-header ${className || ''}`, children: _jsxs("div", { className: styles.headerContent, children: [_jsxs("div", { className: styles.leftSection, children: [_jsx("svg", { width: "26", height: "26", viewBox: "0 0 26 26", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M5 10.9998H6C6.92047 10.9998 7.66667 11.746 7.66667 12.6665V17.3332C7.66667 18.2536 6.92047 18.9998 6 18.9998H5C2.79086 18.9998 1 17.209 1 14.9998C1 12.7907 2.79086 10.9998 5 10.9998ZM5 10.9998V9.6665C5 5.24823 8.58172 1.6665 13 1.6665C17.4183 1.6665 21 5.24823 21 9.6665V10.9998M21 10.9998H20C19.0795 10.9998 18.3333 11.746 18.3333 12.6665V17.3332C18.3333 18.2536 19.0795 18.9998 20 18.9998H21M21 10.9998C23.2091 10.9998 25 12.7907 25 14.9998C25 17.209 23.2091 18.9998 21 18.9998M21 18.9998L20.1716 22.3133C19.8749 23.5004 18.8082 24.3332 17.5846 24.3332H14.3333", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }), _jsx("h3", { className: styles.title, children: headerTitle })] }), _jsxs("div", { className: styles.headerActions, children: [_jsx("button", { className: styles.actionButton, "aria-label": "Refresh", onClick: onRefresh, children: _jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("g", { clipPath: "url(#clip0_55864_4683)", children: _jsx("path", { d: "M8 0C6.03034 0.00140425 4.13075 0.731081 2.66667 2.04867V0.666667C2.66667 0.489856 2.59643 0.320286 2.4714 0.195262C2.34638 0.0702379 2.17681 0 2 0C1.82319 0 1.65362 0.0702379 1.5286 0.195262C1.40357 0.320286 1.33333 0.489856 1.33333 0.666667V2.66667C1.33333 3.1971 1.54405 3.70581 1.91912 4.08088C2.29419 4.45595 2.8029 4.66667 3.33333 4.66667H5.33333C5.51015 4.66667 5.67971 4.59643 5.80474 4.47141C5.92976 4.34638 6 4.17681 6 4C6 3.82319 5.92976 3.65362 5.80474 3.5286C5.67971 3.40357 5.51015 3.33333 5.33333 3.33333H3.33333C3.31085 3.33 3.28859 3.32533 3.26667 3.31933C4.35301 2.22522 5.78542 1.54205 7.31938 1.38644C8.85333 1.23084 10.3938 1.61244 11.6777 2.46611C12.9616 3.31978 13.9095 4.5926 14.3595 6.0673C14.8094 7.54201 14.7337 9.12717 14.1451 10.5522C13.5564 11.9773 12.4915 13.1539 11.132 13.8812C9.77246 14.6085 8.20266 14.8414 6.69054 14.5401C5.17843 14.2389 3.81772 13.4222 2.8407 12.2295C1.86368 11.0367 1.33091 9.54183 1.33333 8C1.33333 7.82319 1.2631 7.65362 1.13807 7.5286C1.01305 7.40357 0.843478 7.33333 0.666667 7.33333C0.489856 7.33333 0.320286 7.40357 0.195262 7.5286C0.0702379 7.65362 0 7.82319 0 8C0 9.58225 0.469192 11.129 1.34824 12.4446C2.22729 13.7602 3.47672 14.7855 4.93853 15.391C6.40034 15.9965 8.00887 16.155 9.56072 15.8463C11.1126 15.5376 12.538 14.7757 13.6569 13.6569C14.7757 12.538 15.5376 11.1126 15.8463 9.56072C16.155 8.00887 15.9965 6.40034 15.391 4.93853C14.7855 3.47672 13.7602 2.22729 12.4446 1.34824C11.129 0.469192 9.58225 0 8 0V0Z", fill: "currentColor" }) }), _jsx("defs", { children: _jsx("clipPath", { id: "clip0_55864_4683", children: _jsx("rect", { width: "16", height: "16", fill: "white" }) }) })] }) }), showMenu && (_jsxs("div", { className: styles.menuButtonContainer, onClick: (e) => e.stopPropagation(), children: [_jsx("button", { className: styles.actionButton, "aria-label": "Menu", onClick: handleMenuButtonClick, type: "button", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 13a1 1 0 100-2 1 1 0 000 2zM12 7a1 1 0 100-2 1 1 0 000 2zM12 19a1 1 0 100-2 1 1 0 000 2z" }) }) }), _jsx(DropdownMenu, { isOpen: isMenuOpen, onClose: closeMenu, menuItems: menuItems, position: "bottom-right" })] }))] })] }) }));
|
|
23
|
+
};
|
|
24
|
+
export default ChatHeader;
|
|
25
|
+
//# sourceMappingURL=ChatHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatHeader.js","sourceRoot":"","sources":["../../../src/components/ChatHeader/ChatHeader.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ChatHeader/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ChatHeader/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { InitiateChatRequest } from '../../config/api';
|
|
3
|
+
import { MenuItemConfig } from '../DropdownMenu';
|
|
4
|
+
export interface ChatWidgetProps {
|
|
5
|
+
initParams: InitiateChatRequest;
|
|
6
|
+
primaryColor: string;
|
|
7
|
+
secondaryColor: string;
|
|
8
|
+
menuItems: MenuItemConfig[];
|
|
9
|
+
showMenu: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const ChatWidget: React.FC<ChatWidgetProps>;
|
|
12
|
+
export default ChatWidget;
|
|
13
|
+
//# sourceMappingURL=ChatWidget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../../src/components/ChatWidget/ChatWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAOzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,WAAW,eAAe;IAE9B,UAAU,EAAE,mBAAmB,CAAC;IAGhC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IAGvB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AA2ED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA4BhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { Provider, ReactReduxContext } from 'react-redux';
|
|
4
|
+
import { store } from '../../store';
|
|
5
|
+
import { updateApiConfig } from '../../services/api/backendApi';
|
|
6
|
+
import styles from './ChatWidget.module.scss';
|
|
7
|
+
import { ChatContainer } from '../ChatContainer';
|
|
8
|
+
import { ChatHeader } from '../ChatHeader';
|
|
9
|
+
import { useChatInit } from '../../hooks';
|
|
10
|
+
import { ErrorBoundary } from '../ErrorBoundary';
|
|
11
|
+
import { ErrorDisplay } from '../ErrorDisplay';
|
|
12
|
+
const InnerChatWidget = ({ initParams, primaryColor, secondaryColor, menuItems, showMenu }) => {
|
|
13
|
+
const { isInitializing, error, initializeChat } = useChatInit();
|
|
14
|
+
// Apply primary color to CSS custom properties
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (primaryColor) {
|
|
17
|
+
document.documentElement.style.setProperty('--chat-primary-color', primaryColor);
|
|
18
|
+
}
|
|
19
|
+
if (secondaryColor) {
|
|
20
|
+
document.documentElement.style.setProperty('--chat-secondary-color', secondaryColor);
|
|
21
|
+
}
|
|
22
|
+
}, [primaryColor, secondaryColor]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const initialize = async () => {
|
|
25
|
+
if (!initParams || !initParams.baseUrl || !initParams.apiKey) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const result = await initializeChat(initParams);
|
|
30
|
+
if (!result.success && result.error) {
|
|
31
|
+
console.error('Chat initialization failed:', result.error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
36
|
+
console.error('Error during chat initialization:', errorMessage);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
initialize();
|
|
40
|
+
}, [initParams]);
|
|
41
|
+
const handleRefresh = () => {
|
|
42
|
+
// Check if we have valid API credentials before making any API calls
|
|
43
|
+
if (!initParams.baseUrl || !initParams.apiKey) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Clear existing messages before reinitializing
|
|
47
|
+
initializeChat(initParams);
|
|
48
|
+
};
|
|
49
|
+
// If there's an initialization error, show error UI directly
|
|
50
|
+
if (error) {
|
|
51
|
+
return (_jsx(ErrorDisplay, { primaryColor: primaryColor, message: "We're having trouble loading this page. Please try again. If the issue persists, contact support.", onRetry: handleRefresh }));
|
|
52
|
+
}
|
|
53
|
+
return (_jsx("div", { className: styles.chatWidget, children: _jsxs("div", { className: styles.chatWindow, children: [_jsx(ChatHeader, { className: styles.header, onRefresh: handleRefresh, menuItems: menuItems, showMenu: showMenu }), _jsx(ChatContainer, { isLoading: isInitializing })] }) }));
|
|
54
|
+
};
|
|
55
|
+
export const ChatWidget = (props) => {
|
|
56
|
+
// Ensure API config is set synchronously so any initialization that runs
|
|
57
|
+
// during mount has the correct headers available. Calling this during
|
|
58
|
+
// render is safe because it only updates a module-level config object.
|
|
59
|
+
if (props.initParams && props.initParams.baseUrl && props.initParams.apiKey) {
|
|
60
|
+
updateApiConfig(props.initParams.baseUrl, props.initParams.apiKey);
|
|
61
|
+
}
|
|
62
|
+
return (_jsx(ReactReduxContext.Consumer, { children: (context) =>
|
|
63
|
+
// If the host app provides a Redux store via context, give that store
|
|
64
|
+
// reference to the chatService so service actions dispatch to the
|
|
65
|
+
// host store and selectors in components will update correctly.
|
|
66
|
+
context && context.store ? (_jsx(ErrorBoundary, { primaryColor: props.primaryColor, children: _jsx(InnerChatWidget, { ...props }) })) : (_jsx(Provider, { store: store, children: _jsx(ErrorBoundary, { primaryColor: props.primaryColor, children: _jsx(InnerChatWidget, { ...props }) }) })) }));
|
|
67
|
+
};
|
|
68
|
+
export default ChatWidget;
|
|
69
|
+
//# sourceMappingURL=ChatWidget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWidget.js","sourceRoot":"","sources":["../../../src/components/ChatWidget/ChatWidget.tsx"],"names":[],"mappings":"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"}
|