@echortech/bot-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.
Files changed (63) hide show
  1. package/README.md +145 -0
  2. package/dist/native/core/api-client.d.ts +57 -0
  3. package/dist/native/core/api-client.d.ts.map +1 -0
  4. package/dist/native/core/api-client.js +196 -0
  5. package/dist/native/core/api-client.js.map +1 -0
  6. package/dist/native/core/index.d.ts +4 -0
  7. package/dist/native/core/index.d.ts.map +1 -0
  8. package/dist/native/core/index.js +5 -0
  9. package/dist/native/core/index.js.map +1 -0
  10. package/dist/native/core/types.d.ts +109 -0
  11. package/dist/native/core/types.d.ts.map +1 -0
  12. package/dist/native/core/types.js +2 -0
  13. package/dist/native/core/types.js.map +1 -0
  14. package/dist/native/core/utils.d.ts +46 -0
  15. package/dist/native/core/utils.d.ts.map +1 -0
  16. package/dist/native/core/utils.js +127 -0
  17. package/dist/native/core/utils.js.map +1 -0
  18. package/dist/native/native/ChatWidget.d.ts +9 -0
  19. package/dist/native/native/ChatWidget.d.ts.map +1 -0
  20. package/dist/native/native/ChatWidget.js +265 -0
  21. package/dist/native/native/ChatWidget.js.map +1 -0
  22. package/dist/native/native/GreetingModal.d.ts +11 -0
  23. package/dist/native/native/GreetingModal.d.ts.map +1 -0
  24. package/dist/native/native/GreetingModal.js +228 -0
  25. package/dist/native/native/GreetingModal.js.map +1 -0
  26. package/dist/native/native/index.d.ts +4 -0
  27. package/dist/native/native/index.d.ts.map +1 -0
  28. package/dist/native/native/index.js +5 -0
  29. package/dist/native/native/index.js.map +1 -0
  30. package/dist/tsconfig.native.tsbuildinfo +1 -0
  31. package/dist/tsconfig.web.tsbuildinfo +1 -0
  32. package/dist/web/core/api-client.d.ts +57 -0
  33. package/dist/web/core/api-client.d.ts.map +1 -0
  34. package/dist/web/core/api-client.js +196 -0
  35. package/dist/web/core/api-client.js.map +1 -0
  36. package/dist/web/core/index.d.ts +4 -0
  37. package/dist/web/core/index.d.ts.map +1 -0
  38. package/dist/web/core/index.js +5 -0
  39. package/dist/web/core/index.js.map +1 -0
  40. package/dist/web/core/types.d.ts +109 -0
  41. package/dist/web/core/types.d.ts.map +1 -0
  42. package/dist/web/core/types.js +2 -0
  43. package/dist/web/core/types.js.map +1 -0
  44. package/dist/web/core/utils.d.ts +46 -0
  45. package/dist/web/core/utils.d.ts.map +1 -0
  46. package/dist/web/core/utils.js +127 -0
  47. package/dist/web/core/utils.js.map +1 -0
  48. package/dist/web/web/ChatWidget.css +240 -0
  49. package/dist/web/web/ChatWidget.d.ts +11 -0
  50. package/dist/web/web/ChatWidget.d.ts.map +1 -0
  51. package/dist/web/web/ChatWidget.js +72 -0
  52. package/dist/web/web/ChatWidget.js.map +1 -0
  53. package/dist/web/web/GreetingPopup.css +224 -0
  54. package/dist/web/web/GreetingPopup.d.ts +12 -0
  55. package/dist/web/web/GreetingPopup.d.ts.map +1 -0
  56. package/dist/web/web/GreetingPopup.js +71 -0
  57. package/dist/web/web/GreetingPopup.js.map +1 -0
  58. package/dist/web/web/index.d.ts +4 -0
  59. package/dist/web/web/index.d.ts.map +1 -0
  60. package/dist/web/web/index.js +5 -0
  61. package/dist/web/web/index.js.map +1 -0
  62. package/native/package.json +4 -0
  63. package/package.json +83 -0
@@ -0,0 +1,240 @@
1
+ .spirit-chat-widget {
2
+ display: flex;
3
+ flex-direction: column;
4
+ background: #ffffff;
5
+ border-radius: 8px;
6
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
7
+ overflow: hidden;
8
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
9
+ font-size: 14px;
10
+ color: #1f2937;
11
+ }
12
+
13
+ /* Messages Container */
14
+ .messages-container {
15
+ flex: 1;
16
+ overflow-y: auto;
17
+ padding: 16px;
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 12px;
21
+ background: #fafafa;
22
+ }
23
+
24
+ /* Empty State */
25
+ .empty-state {
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ height: 100%;
30
+ color: #9ca3af;
31
+ text-align: center;
32
+ font-size: 15px;
33
+ }
34
+
35
+ /* Message */
36
+ .message {
37
+ display: flex;
38
+ flex-direction: column;
39
+ gap: 4px;
40
+ animation: slideIn 0.3s ease-out;
41
+ }
42
+
43
+ @keyframes slideIn {
44
+ from {
45
+ opacity: 0;
46
+ transform: translateY(10px);
47
+ }
48
+ to {
49
+ opacity: 1;
50
+ transform: translateY(0);
51
+ }
52
+ }
53
+
54
+ .message-user {
55
+ align-items: flex-end;
56
+ }
57
+
58
+ .message-user .message-content {
59
+ background: #3b82f6;
60
+ color: white;
61
+ border-radius: 16px 16px 4px 16px;
62
+ }
63
+
64
+ .message-assistant {
65
+ align-items: flex-start;
66
+ }
67
+
68
+ .message-assistant .message-content {
69
+ background: #e5e7eb;
70
+ color: #1f2937;
71
+ border-radius: 16px 16px 16px 4px;
72
+ }
73
+
74
+ .message-content {
75
+ padding: 12px 16px;
76
+ max-width: 85%;
77
+ word-wrap: break-word;
78
+ line-height: 1.4;
79
+ font-size: 14px;
80
+ }
81
+
82
+ .message-meta {
83
+ padding: 0 16px;
84
+ font-size: 12px;
85
+ color: #9ca3af;
86
+ }
87
+
88
+ .message-user .message-meta {
89
+ text-align: right;
90
+ }
91
+
92
+ /* Loading Indicator */
93
+ .loading-indicator {
94
+ display: flex;
95
+ align-items: center;
96
+ gap: 4px;
97
+ height: 24px;
98
+ }
99
+
100
+ .loading-indicator span {
101
+ width: 6px;
102
+ height: 6px;
103
+ border-radius: 50%;
104
+ background: #9ca3af;
105
+ animation: bounce 1.4s infinite;
106
+ }
107
+
108
+ .loading-indicator span:nth-child(1) {
109
+ animation-delay: 0s;
110
+ }
111
+
112
+ .loading-indicator span:nth-child(2) {
113
+ animation-delay: 0.2s;
114
+ }
115
+
116
+ .loading-indicator span:nth-child(3) {
117
+ animation-delay: 0.4s;
118
+ }
119
+
120
+ @keyframes bounce {
121
+ 0%, 80%, 100% {
122
+ transform: scale(1);
123
+ opacity: 0.5;
124
+ }
125
+ 40% {
126
+ transform: scale(1.2);
127
+ opacity: 1;
128
+ }
129
+ }
130
+
131
+ /* Error Banner */
132
+ .error-banner {
133
+ background: #fee2e2;
134
+ border-bottom: 1px solid #fecaca;
135
+ padding: 12px 16px;
136
+ display: flex;
137
+ justify-content: space-between;
138
+ align-items: center;
139
+ color: #7f1d1d;
140
+ font-size: 13px;
141
+ gap: 12px;
142
+ }
143
+
144
+ .error-banner p {
145
+ margin: 0;
146
+ flex: 1;
147
+ }
148
+
149
+ .error-close {
150
+ background: none;
151
+ border: none;
152
+ color: #7f1d1d;
153
+ cursor: pointer;
154
+ padding: 0;
155
+ font-size: 18px;
156
+ line-height: 1;
157
+ flex-shrink: 0;
158
+ }
159
+
160
+ .error-close:hover {
161
+ opacity: 0.7;
162
+ }
163
+
164
+ /* Input Form */
165
+ .input-form {
166
+ display: flex;
167
+ gap: 8px;
168
+ padding: 12px 16px;
169
+ border-top: 1px solid #e5e7eb;
170
+ background: #ffffff;
171
+ }
172
+
173
+ .chat-input {
174
+ flex: 1;
175
+ padding: 10px 14px;
176
+ border: 1px solid #d1d5db;
177
+ border-radius: 6px;
178
+ font-family: inherit;
179
+ font-size: 14px;
180
+ outline: none;
181
+ transition: border-color 0.2s, box-shadow 0.2s;
182
+ }
183
+
184
+ .chat-input:focus {
185
+ border-color: #3b82f6;
186
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
187
+ }
188
+
189
+ .chat-input:disabled {
190
+ background: #f3f4f6;
191
+ color: #9ca3af;
192
+ cursor: not-allowed;
193
+ }
194
+
195
+ .send-button {
196
+ padding: 10px 16px;
197
+ background: #3b82f6;
198
+ color: white;
199
+ border: none;
200
+ border-radius: 6px;
201
+ cursor: pointer;
202
+ font-size: 16px;
203
+ font-weight: 500;
204
+ transition: background 0.2s;
205
+ min-width: 48px;
206
+ display: flex;
207
+ align-items: center;
208
+ justify-content: center;
209
+ }
210
+
211
+ .send-button:hover:not(:disabled) {
212
+ background: #2563eb;
213
+ }
214
+
215
+ .send-button:active:not(:disabled) {
216
+ background: #1d4ed8;
217
+ }
218
+
219
+ .send-button:disabled {
220
+ background: #d1d5db;
221
+ cursor: not-allowed;
222
+ }
223
+
224
+ /* Scrollbar styling */
225
+ .messages-container::-webkit-scrollbar {
226
+ width: 6px;
227
+ }
228
+
229
+ .messages-container::-webkit-scrollbar-track {
230
+ background: transparent;
231
+ }
232
+
233
+ .messages-container::-webkit-scrollbar-thumb {
234
+ background: #d1d5db;
235
+ border-radius: 3px;
236
+ }
237
+
238
+ .messages-container::-webkit-scrollbar-thumb:hover {
239
+ background: #9ca3af;
240
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { BotWidgetConfig } from '../core';
3
+ import './ChatWidget.css';
4
+ interface ChatWidgetProps extends Omit<BotWidgetConfig, 'theme' | 'position'> {
5
+ className?: string;
6
+ height?: string;
7
+ width?: string;
8
+ }
9
+ export declare const ChatWidget: React.FC<ChatWidgetProps>;
10
+ export default ChatWidget;
11
+ //# sourceMappingURL=ChatWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../../src/web/ChatWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAGL,eAAe,EAIhB,MAAM,SAAS,CAAC;AACjB,OAAO,kBAAkB,CAAC;AAE1B,UAAU,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgKhD,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useRef, useEffect, useCallback } from 'react';
3
+ import { BotAPIClient, getErrorMessage, formatTimestamp, debounce, } from '../core';
4
+ import './ChatWidget.css';
5
+ export const ChatWidget = ({ jwtToken, firmId, botUrl, chatId = 1001, filingId, taxYear, className, height = '500px', width = '400px', onError, onSuccess, }) => {
6
+ const [messages, setMessages] = useState([]);
7
+ const [input, setInput] = useState('');
8
+ const [loading, setLoading] = useState(false);
9
+ const [error, setError] = useState(null);
10
+ const messagesEndRef = useRef(null);
11
+ const clientRef = useRef(null);
12
+ // Initialize API client
13
+ useEffect(() => {
14
+ clientRef.current = new BotAPIClient(botUrl, jwtToken, firmId);
15
+ }, [botUrl, jwtToken, firmId]);
16
+ // Auto-scroll to bottom
17
+ const scrollToBottom = useCallback(() => {
18
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
19
+ }, []);
20
+ useEffect(() => {
21
+ scrollToBottom();
22
+ }, [messages, scrollToBottom]);
23
+ // Debounced send message
24
+ const sendMessage = useCallback(debounce(async (message) => {
25
+ if (!message.trim() || !clientRef.current)
26
+ return;
27
+ setLoading(true);
28
+ setError(null);
29
+ try {
30
+ // Add user message
31
+ const userMessage = {
32
+ role: 'user',
33
+ content: message,
34
+ timestamp: new Date().toISOString(),
35
+ };
36
+ setMessages((prev) => [...prev, userMessage]);
37
+ setInput('');
38
+ // Get bot response
39
+ const response = await clientRef.current.sendMessage(message, chatId, {
40
+ filing_id: filingId,
41
+ tax_year: taxYear,
42
+ });
43
+ // Add bot message
44
+ const botMessage = {
45
+ role: 'assistant',
46
+ content: response.reply,
47
+ toolCalls: response.toolCalls,
48
+ responseTimeMs: response.responseTimeMs,
49
+ timestamp: new Date().toISOString(),
50
+ };
51
+ setMessages((prev) => [...prev, botMessage]);
52
+ onSuccess?.(response);
53
+ }
54
+ catch (err) {
55
+ const errorMessage = getErrorMessage(err);
56
+ setError(errorMessage);
57
+ onError?.(err);
58
+ }
59
+ finally {
60
+ setLoading(false);
61
+ }
62
+ }, 300), [chatId, filingId, taxYear, onError, onSuccess]);
63
+ const handleSubmit = (e) => {
64
+ e.preventDefault();
65
+ if (input.trim()) {
66
+ sendMessage(input);
67
+ }
68
+ };
69
+ return (_jsxs("div", { className: `spirit-chat-widget ${className || ''}`, style: { height, width, minWidth: '300px', minHeight: '400px' }, children: [_jsxs("div", { className: "messages-container", children: [messages.length === 0 && (_jsx("div", { className: "empty-state", children: _jsx("p", { children: "Start a conversation with Spirit Bot" }) })), messages.map((msg, idx) => (_jsxs("div", { className: `message message-${msg.role}`, children: [_jsx("div", { className: "message-content", children: msg.content }), msg.responseTimeMs && (_jsxs("div", { className: "message-meta", children: [msg.responseTimeMs, "ms", msg.timestamp && ` • ${formatTimestamp(msg.timestamp)}`] }))] }, idx))), loading && (_jsx("div", { className: "message message-assistant", children: _jsxs("div", { className: "loading-indicator", children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }) })), _jsx("div", { ref: messagesEndRef })] }), error && (_jsxs("div", { className: "error-banner", children: [_jsx("p", { children: error }), _jsx("button", { onClick: () => setError(null), className: "error-close", "aria-label": "Close error", children: "\u00D7" })] })), _jsxs("form", { onSubmit: handleSubmit, className: "input-form", children: [_jsx("input", { type: "text", value: input, onChange: (e) => setInput(e.target.value), placeholder: "Ask a question...", disabled: loading, className: "chat-input", maxLength: 2000 }), _jsx("button", { type: "submit", disabled: loading || !input.trim(), className: "send-button", "aria-label": "Send message", children: loading ? '...' : '→' })] })] }));
70
+ };
71
+ export default ChatWidget;
72
+ //# sourceMappingURL=ChatWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWidget.js","sourceRoot":"","sources":["../../../src/web/ChatWidget.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,224 @@
1
+ .spirit-greeting-overlay {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ right: 0;
6
+ bottom: 0;
7
+ background: rgba(0, 0, 0, 0.5);
8
+ display: flex;
9
+ align-items: flex-start;
10
+ justify-content: flex-end;
11
+ padding: 20px;
12
+ z-index: 9999;
13
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
14
+ animation: fadeIn 0.3s ease-out;
15
+ }
16
+
17
+ @keyframes fadeIn {
18
+ from {
19
+ opacity: 0;
20
+ }
21
+ to {
22
+ opacity: 1;
23
+ }
24
+ }
25
+
26
+ .spirit-greeting-popup {
27
+ background: white;
28
+ border-radius: 12px;
29
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.16);
30
+ max-width: 420px;
31
+ width: 100%;
32
+ border-left: 5px solid #3b82f6;
33
+ animation: slideInUp 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
34
+ overflow: hidden;
35
+ }
36
+
37
+ @keyframes slideInUp {
38
+ from {
39
+ opacity: 0;
40
+ transform: translateY(20px);
41
+ }
42
+ to {
43
+ opacity: 1;
44
+ transform: translateY(0);
45
+ }
46
+ }
47
+
48
+ /* Priority-based styling */
49
+ .spirit-greeting-popup.priority-1 {
50
+ border-left-color: #dc2626; /* red - urgent */
51
+ }
52
+
53
+ .spirit-greeting-popup.priority-2 {
54
+ border-left-color: #f59e0b; /* amber - high */
55
+ }
56
+
57
+ .spirit-greeting-popup.priority-3 {
58
+ border-left-color: #3b82f6; /* blue - medium */
59
+ }
60
+
61
+ .spirit-greeting-popup.priority-4 {
62
+ border-left-color: #10b981; /* green - low */
63
+ }
64
+
65
+ .spirit-greeting-popup.priority-5 {
66
+ border-left-color: #6b7280; /* gray - info */
67
+ }
68
+
69
+ /* Header */
70
+ .greeting-header {
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: space-between;
74
+ padding: 16px;
75
+ border-bottom: 1px solid #e5e7eb;
76
+ gap: 12px;
77
+ }
78
+
79
+ .priority-badge {
80
+ display: inline-block;
81
+ padding: 4px 12px;
82
+ border-radius: 20px;
83
+ font-size: 12px;
84
+ font-weight: 600;
85
+ color: white;
86
+ text-transform: uppercase;
87
+ letter-spacing: 0.5px;
88
+ }
89
+
90
+ .close-button {
91
+ background: none;
92
+ border: none;
93
+ font-size: 28px;
94
+ color: #9ca3af;
95
+ cursor: pointer;
96
+ padding: 0;
97
+ width: 32px;
98
+ height: 32px;
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ border-radius: 4px;
103
+ transition: background 0.2s, color 0.2s;
104
+ margin-left: auto;
105
+ flex-shrink: 0;
106
+ }
107
+
108
+ .close-button:hover {
109
+ background: #f3f4f6;
110
+ color: #6b7280;
111
+ }
112
+
113
+ /* Content */
114
+ .greeting-content {
115
+ padding: 16px;
116
+ }
117
+
118
+ .greeting-text {
119
+ margin: 0;
120
+ font-size: 15px;
121
+ line-height: 1.6;
122
+ color: #1f2937;
123
+ font-weight: 500;
124
+ }
125
+
126
+ /* Loading State */
127
+ .loading-state {
128
+ padding: 32px 16px;
129
+ display: flex;
130
+ flex-direction: column;
131
+ align-items: center;
132
+ justify-content: center;
133
+ gap: 12px;
134
+ color: #6b7280;
135
+ font-size: 14px;
136
+ }
137
+
138
+ .spinner {
139
+ width: 32px;
140
+ height: 32px;
141
+ border: 3px solid #e5e7eb;
142
+ border-top-color: #3b82f6;
143
+ border-radius: 50%;
144
+ animation: spin 1s linear infinite;
145
+ }
146
+
147
+ @keyframes spin {
148
+ to {
149
+ transform: rotate(360deg);
150
+ }
151
+ }
152
+
153
+ /* Actions Container */
154
+ .actions-container {
155
+ padding: 12px 16px;
156
+ border-top: 1px solid #e5e7eb;
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: 8px;
160
+ }
161
+
162
+ .action-button {
163
+ display: flex;
164
+ align-items: center;
165
+ justify-content: space-between;
166
+ padding: 12px 16px;
167
+ background: #f3f4f6;
168
+ border: 1px solid #d1d5db;
169
+ border-radius: 6px;
170
+ color: #1f2937;
171
+ font-size: 14px;
172
+ font-weight: 500;
173
+ cursor: pointer;
174
+ transition: all 0.2s;
175
+ font-family: inherit;
176
+ }
177
+
178
+ .action-button:hover {
179
+ background: #e5e7eb;
180
+ border-color: #9ca3af;
181
+ transform: translateX(4px);
182
+ }
183
+
184
+ .action-button:active {
185
+ background: #d1d5db;
186
+ transform: translateX(2px);
187
+ }
188
+
189
+ .action-button .arrow {
190
+ margin-left: 8px;
191
+ font-size: 16px;
192
+ flex-shrink: 0;
193
+ }
194
+
195
+ /* Filing Context */
196
+ .filing-context {
197
+ padding: 12px 16px;
198
+ background: #f9fafb;
199
+ border-top: 1px solid #e5e7eb;
200
+ font-size: 12px;
201
+ color: #6b7280;
202
+ }
203
+
204
+ .filing-context small {
205
+ display: block;
206
+ line-height: 1.4;
207
+ }
208
+
209
+ /* Mobile responsiveness */
210
+ @media (max-width: 480px) {
211
+ .spirit-greeting-overlay {
212
+ align-items: center;
213
+ justify-content: center;
214
+ padding: 16px;
215
+ }
216
+
217
+ .spirit-greeting-popup {
218
+ max-width: 100%;
219
+ }
220
+
221
+ .message-content {
222
+ max-width: 100%;
223
+ }
224
+ }
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { BotWidgetConfig } from '../core';
3
+ import './GreetingPopup.css';
4
+ interface GreetingPopupProps extends Omit<BotWidgetConfig, 'theme' | 'position'> {
5
+ onClose?: () => void;
6
+ onActionClick?: (action: any) => void;
7
+ autoClose?: boolean;
8
+ autoCloseDuration?: number;
9
+ }
10
+ export declare const GreetingPopup: React.FC<GreetingPopupProps>;
11
+ export default GreetingPopup;
12
+ //# sourceMappingURL=GreetingPopup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GreetingPopup.d.ts","sourceRoot":"","sources":["../../../src/web/GreetingPopup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAGL,eAAe,EAGhB,MAAM,SAAS,CAAC;AACjB,OAAO,qBAAqB,CAAC;AAE7B,UAAU,kBAAmB,SAAQ,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,UAAU,CAAC;IAC9E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAkJtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect, useRef } from 'react';
3
+ import { BotAPIClient, getPriorityColor, getPriorityLabel, } from '../core';
4
+ import './GreetingPopup.css';
5
+ export const GreetingPopup = ({ jwtToken, firmId, botUrl, onClose, onActionClick, onError, autoClose = false, autoCloseDuration = 10000, }) => {
6
+ const [greeting, setGreeting] = useState(null);
7
+ const [loading, setLoading] = useState(true);
8
+ const [visible, setVisible] = useState(false);
9
+ const clientRef = useRef(null);
10
+ const autoCloseTimerRef = useRef(null);
11
+ // Initialize API client and fetch greeting
12
+ useEffect(() => {
13
+ const fetchGreeting = async () => {
14
+ try {
15
+ clientRef.current = new BotAPIClient(botUrl, jwtToken, firmId);
16
+ const response = await clientRef.current.getGreeting();
17
+ setGreeting(response);
18
+ setVisible(true);
19
+ // Auto-close if enabled
20
+ if (autoClose) {
21
+ autoCloseTimerRef.current = setTimeout(() => {
22
+ handleClose();
23
+ }, autoCloseDuration);
24
+ }
25
+ }
26
+ catch (error) {
27
+ onError?.(error);
28
+ setVisible(false);
29
+ }
30
+ finally {
31
+ setLoading(false);
32
+ }
33
+ };
34
+ fetchGreeting();
35
+ return () => {
36
+ if (autoCloseTimerRef.current) {
37
+ clearTimeout(autoCloseTimerRef.current);
38
+ }
39
+ };
40
+ }, [botUrl, jwtToken, firmId, onError, autoClose, autoCloseDuration]);
41
+ const handleClose = () => {
42
+ setVisible(false);
43
+ onClose?.();
44
+ };
45
+ const handleActionClick = (action) => {
46
+ onActionClick?.(action);
47
+ if (action.type === 'navigate') {
48
+ window.location.href = action.target;
49
+ }
50
+ else if (action.type === 'chat') {
51
+ // Emit event for parent to open chat with pre-filled message
52
+ window.dispatchEvent(new CustomEvent('spirit-bot-open-chat', {
53
+ detail: { message: action.message },
54
+ }));
55
+ }
56
+ else if (action.type === 'external') {
57
+ window.open(action.target, '_blank');
58
+ }
59
+ handleClose();
60
+ };
61
+ if (!visible || !greeting) {
62
+ return null;
63
+ }
64
+ const priorityColor = getPriorityColor(greeting.priority);
65
+ const priorityLabel = getPriorityLabel(greeting.priority);
66
+ return (_jsx("div", { className: "spirit-greeting-overlay", children: _jsxs("div", { className: `spirit-greeting-popup priority-${greeting.priority}`, style: {
67
+ borderLeftColor: priorityColor,
68
+ }, children: [_jsxs("div", { className: "greeting-header", children: [_jsx("div", { className: "priority-badge", style: { backgroundColor: priorityColor }, children: priorityLabel }), _jsx("button", { className: "close-button", onClick: handleClose, "aria-label": "Close greeting", children: "\u00D7" })] }), loading && (_jsxs("div", { className: "loading-state", children: [_jsx("div", { className: "spinner" }), _jsx("p", { children: "Loading greeting..." })] })), !loading && (_jsxs(_Fragment, { children: [_jsx("div", { className: "greeting-content", children: _jsx("p", { className: "greeting-text", children: greeting.greeting }) }), greeting.actions && greeting.actions.length > 0 && (_jsx("div", { className: "actions-container", children: greeting.actions.map((action, idx) => (_jsxs("button", { className: "action-button", onClick: () => handleActionClick(action), children: [action.label, _jsx("span", { className: "arrow", children: "\u2192" })] }, idx))) })), greeting.filing_context && (_jsx("div", { className: "filing-context", children: _jsxs("small", { children: ["Filing: ", greeting.filing_context.filing_id, " \u2022", ' ', greeting.filing_context.tax_year] }) }))] }))] }) }));
69
+ };
70
+ export default GreetingPopup;
71
+ //# sourceMappingURL=GreetingPopup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GreetingPopup.js","sourceRoot":"","sources":["../../../src/web/GreetingPopup.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { ChatWidget, default as ChatWidgetDefault } from './ChatWidget';
2
+ export { GreetingPopup, default as GreetingPopupDefault } from './GreetingPopup';
3
+ export * from '../core';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/web/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGjF,cAAc,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { ChatWidget, default as ChatWidgetDefault } from './ChatWidget';
2
+ export { GreetingPopup, default as GreetingPopupDefault } from './GreetingPopup';
3
+ // Re-export all types and utilities from core
4
+ export * from '../core';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEjF,8CAA8C;AAC9C,cAAc,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../dist/native/native/index.js",
3
+ "types": "../dist/native/native/index.d.ts"
4
+ }