andy-widget-react 2.3.2 → 3.0.0-next.10
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 +77 -57
- package/dist/index.cjs +92 -5214
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +88 -5193
- package/dist/index.esm.js.map +1 -1
- package/dist/types/AndyChat.d.ts +7 -0
- package/dist/types/index.d.ts +3 -10
- package/dist/types/types/index.d.ts +38 -161
- package/package.json +3 -10
- package/dist/types/SupportChat.d.ts +0 -4
- package/dist/types/components/ChatBubble.d.ts +0 -9
- package/dist/types/components/ChatWindow.d.ts +0 -11
- package/dist/types/components/FAQ.d.ts +0 -8
- package/dist/types/components/MessageInput.d.ts +0 -8
- package/dist/types/components/MessageList.d.ts +0 -10
- package/dist/types/components/UserInfoForm.d.ts +0 -10
- package/dist/types/components/WelcomePopup.d.ts +0 -8
- package/dist/types/hooks/index.d.ts +0 -1
- package/dist/types/hooks/useAndyChat.d.ts +0 -8
- package/dist/types/hooks/useSupportChat.d.ts +0 -24
- package/src/AndyChat.tsx +0 -1151
- package/src/SupportChat.tsx +0 -106
- package/src/components/ChatBubble.tsx +0 -48
- package/src/components/ChatWindow.tsx +0 -53
- package/src/components/FAQ.tsx +0 -48
- package/src/components/MessageInput.tsx +0 -83
- package/src/components/MessageList.tsx +0 -124
- package/src/components/UserInfoForm.tsx +0 -186
- package/src/components/WelcomePopup.tsx +0 -70
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useAndyChat.ts +0 -312
- package/src/hooks/useSupportChat.ts +0 -29
- package/src/index.ts +0 -67
- package/src/styles/main.css +0 -14
- package/src/types/index.ts +0 -235
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, MouseEvent } from 'react'
|
|
2
|
-
|
|
3
|
-
interface WelcomePopupProps {
|
|
4
|
-
message: string
|
|
5
|
-
brandColor?: string
|
|
6
|
-
onClose: () => void
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const WelcomePopup: React.FC<WelcomePopupProps> = ({ message, onClose }) => {
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
const timer = setTimeout(() => {
|
|
12
|
-
onClose()
|
|
13
|
-
}, 5000)
|
|
14
|
-
|
|
15
|
-
return () => clearTimeout(timer)
|
|
16
|
-
}, [onClose])
|
|
17
|
-
|
|
18
|
-
const handleBackdropClick = (e: MouseEvent<HTMLDivElement>) => {
|
|
19
|
-
if (e.target === e.currentTarget) {
|
|
20
|
-
onClose()
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
const handleEscape = (e: KeyboardEvent) => {
|
|
26
|
-
if (e.key === 'Escape') {
|
|
27
|
-
onClose()
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
document.addEventListener('keydown', handleEscape)
|
|
32
|
-
return () => document.removeEventListener('keydown', handleEscape)
|
|
33
|
-
}, [onClose])
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<div className='andy-chat-welcome-popup__backdrop' onClick={handleBackdropClick}>
|
|
37
|
-
<div className='andy-chat-welcome-popup'>
|
|
38
|
-
<button
|
|
39
|
-
className='andy-chat-welcome-popup__close'
|
|
40
|
-
onClick={onClose}
|
|
41
|
-
aria-label='Close welcome message'
|
|
42
|
-
type='button'
|
|
43
|
-
>
|
|
44
|
-
✕
|
|
45
|
-
</button>
|
|
46
|
-
|
|
47
|
-
<div className='andy-chat-welcome-popup__icon'>
|
|
48
|
-
<svg width='32' height='32' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
|
49
|
-
<path
|
|
50
|
-
d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'
|
|
51
|
-
fill='currentColor'
|
|
52
|
-
/>
|
|
53
|
-
</svg>
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<div className='andy-chat-welcome-popup__message'>{message}</div>
|
|
57
|
-
|
|
58
|
-
<button className='andy-chat-welcome-popup__button' onClick={onClose} type='button'>
|
|
59
|
-
Get Started
|
|
60
|
-
</button>
|
|
61
|
-
|
|
62
|
-
<div className='andy-chat-welcome-popup__timer'>
|
|
63
|
-
<div className='andy-chat-welcome-popup__timer-bar'></div>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
</div>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export default WelcomePopup
|
package/src/hooks/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { useAndyChat } from './useAndyChat'
|
package/src/hooks/useAndyChat.ts
DELETED
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useRef, useEffect } from 'react'
|
|
2
|
-
import {
|
|
3
|
-
fetchChatbotConfig,
|
|
4
|
-
generateSessionId,
|
|
5
|
-
createGreetingMessage,
|
|
6
|
-
sendMessageForWidget as sendMessageToAPI,
|
|
7
|
-
submitUserInfo as submitUserInfoAPI,
|
|
8
|
-
initializeConfig,
|
|
9
|
-
validateChatbotConfig,
|
|
10
|
-
normalizeConfig,
|
|
11
|
-
CONFIG
|
|
12
|
-
} from 'andy-widget-core'
|
|
13
|
-
import type { ChatbotConfig, Message, UserInfo, UseAndyChatReturn } from '../types'
|
|
14
|
-
import type { SupportOptions } from 'andy-widget-core'
|
|
15
|
-
import { useSupportChat } from './useSupportChat'
|
|
16
|
-
|
|
17
|
-
const { SESSION_STORAGE_KEY, FORM_DISPLAY_DELAY_MS, PERSIST_SESSION } = CONFIG
|
|
18
|
-
|
|
19
|
-
const useSalesAndyChat = (embedId: string, enabled: boolean): UseAndyChatReturn => {
|
|
20
|
-
if (enabled) initializeConfig('andy-widget-react')
|
|
21
|
-
|
|
22
|
-
const [config, setConfig] = useState<Partial<ChatbotConfig>>({})
|
|
23
|
-
const [isLoading, setIsLoading] = useState(true)
|
|
24
|
-
const [isOpen, setIsOpen] = useState(false)
|
|
25
|
-
const [error, setError] = useState<string | null>(null)
|
|
26
|
-
|
|
27
|
-
const [messages, setMessages] = useState<Message[]>([])
|
|
28
|
-
const [showingFaq, setShowingFaq] = useState(false)
|
|
29
|
-
const [sessionId, setSessionId] = useState(() => generateSessionId())
|
|
30
|
-
|
|
31
|
-
const [userInfoCollected, setUserInfoCollected] = useState(false)
|
|
32
|
-
const [showingWelcomePopup, setShowingWelcomePopup] = useState(false)
|
|
33
|
-
const [showingUserInfoForm, setShowingUserInfoForm] = useState(false)
|
|
34
|
-
const [welcomePopupShown, setWelcomePopupShown] = useState(false)
|
|
35
|
-
|
|
36
|
-
const activeReplyRef = useRef<AbortController | null>(null)
|
|
37
|
-
useEffect(() => () => {
|
|
38
|
-
activeReplyRef.current?.abort()
|
|
39
|
-
activeReplyRef.current = null
|
|
40
|
-
}, [embedId])
|
|
41
|
-
|
|
42
|
-
const welcomeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
43
|
-
const userInfoTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
44
|
-
|
|
45
|
-
const initializeChatbot = useCallback(async () => {
|
|
46
|
-
if (!enabled) return
|
|
47
|
-
if (!embedId) {
|
|
48
|
-
throw new Error('Embed ID is required')
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
setIsLoading(true)
|
|
53
|
-
setError(null)
|
|
54
|
-
|
|
55
|
-
const rawConfig = await fetchChatbotConfig(embedId)
|
|
56
|
-
|
|
57
|
-
const validationResult = validateChatbotConfig(rawConfig)
|
|
58
|
-
if (!validationResult.isValid) {
|
|
59
|
-
throw new Error(`Invalid configuration: ${validationResult.errors.join(', ')}`)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const normalizedConfig = normalizeConfig(rawConfig as unknown as Record<string, unknown>) as unknown as ChatbotConfig
|
|
63
|
-
setConfig(normalizedConfig)
|
|
64
|
-
|
|
65
|
-
if (PERSIST_SESSION) {
|
|
66
|
-
const storedSessionId = localStorage.getItem(SESSION_STORAGE_KEY)
|
|
67
|
-
if (storedSessionId) {
|
|
68
|
-
setSessionId(storedSessionId)
|
|
69
|
-
} else {
|
|
70
|
-
setSessionId(currentSessionId => {
|
|
71
|
-
localStorage.setItem(SESSION_STORAGE_KEY, currentSessionId)
|
|
72
|
-
return currentSessionId
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (normalizedConfig.welcomeMessage) {
|
|
78
|
-
const greeting = createGreetingMessage(normalizedConfig)
|
|
79
|
-
if (greeting) {
|
|
80
|
-
const greetingMessage: Message = {
|
|
81
|
-
id: Date.now(),
|
|
82
|
-
content: greeting,
|
|
83
|
-
sender: 'bot',
|
|
84
|
-
timestamp: new Date().toISOString()
|
|
85
|
-
}
|
|
86
|
-
setMessages([greetingMessage])
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
setIsLoading(false)
|
|
91
|
-
} catch (err) {
|
|
92
|
-
console.error('Failed to initialize chatbot:', err)
|
|
93
|
-
setError(err instanceof Error ? err.message : 'Unknown error')
|
|
94
|
-
setIsLoading(false)
|
|
95
|
-
throw err
|
|
96
|
-
}
|
|
97
|
-
}, [embedId, enabled])
|
|
98
|
-
|
|
99
|
-
const toggleChat = useCallback(() => {
|
|
100
|
-
setIsOpen(prev => {
|
|
101
|
-
const newIsOpen = !prev
|
|
102
|
-
|
|
103
|
-
if (newIsOpen) {
|
|
104
|
-
setShowingFaq(false)
|
|
105
|
-
|
|
106
|
-
const typedConfig = config as ChatbotConfig
|
|
107
|
-
if (typedConfig?.showWelcomePopup?.enabled && !welcomePopupShown) {
|
|
108
|
-
setShowingWelcomePopup(true)
|
|
109
|
-
setWelcomePopupShown(true)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (typedConfig?.collectUserInfo?.enabled && !userInfoCollected) {
|
|
113
|
-
if (userInfoTimeoutRef.current) {
|
|
114
|
-
clearTimeout(userInfoTimeoutRef.current)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
userInfoTimeoutRef.current = setTimeout(() => {
|
|
118
|
-
setShowingUserInfoForm(true)
|
|
119
|
-
}, FORM_DISPLAY_DELAY_MS)
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
setShowingWelcomePopup(false)
|
|
123
|
-
setShowingUserInfoForm(false)
|
|
124
|
-
|
|
125
|
-
if (welcomeTimeoutRef.current) {
|
|
126
|
-
clearTimeout(welcomeTimeoutRef.current)
|
|
127
|
-
}
|
|
128
|
-
if (userInfoTimeoutRef.current) {
|
|
129
|
-
clearTimeout(userInfoTimeoutRef.current)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return newIsOpen
|
|
134
|
-
})
|
|
135
|
-
}, [config, welcomePopupShown, userInfoCollected])
|
|
136
|
-
|
|
137
|
-
const sendMessage = useCallback(
|
|
138
|
-
async (messageText: string) => {
|
|
139
|
-
if (!enabled || !messageText.trim() || !config || !sessionId || activeReplyRef.current) {
|
|
140
|
-
return
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const controller = new AbortController()
|
|
144
|
-
activeReplyRef.current = controller
|
|
145
|
-
const userMessage: Message = {
|
|
146
|
-
id: Date.now(),
|
|
147
|
-
content: messageText,
|
|
148
|
-
sender: 'user',
|
|
149
|
-
timestamp: new Date().toISOString()
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
setMessages(prev => [...prev, userMessage])
|
|
153
|
-
|
|
154
|
-
const replyId = Date.now() + 1
|
|
155
|
-
const showReply = (content: string, isStreaming: boolean) => {
|
|
156
|
-
if (controller.signal.aborted) return
|
|
157
|
-
const reply: Message = { id: replyId, content, sender: 'bot', timestamp: new Date().toISOString(), isStreaming }
|
|
158
|
-
setMessages(prev => prev.some(message => message.id === replyId)
|
|
159
|
-
? prev.map(message => message.id === replyId ? reply : message)
|
|
160
|
-
: [...prev, reply])
|
|
161
|
-
}
|
|
162
|
-
try {
|
|
163
|
-
const response = await sendMessageToAPI(embedId, sessionId, messageText, { signal: controller.signal, onText: text => showReply(text, true) })
|
|
164
|
-
if (controller.signal.aborted) return
|
|
165
|
-
if (response.status === 'waiting') {
|
|
166
|
-
setMessages(prev => prev.filter(message => message.id !== replyId))
|
|
167
|
-
return response
|
|
168
|
-
}
|
|
169
|
-
showReply(response.text, false)
|
|
170
|
-
|
|
171
|
-
return response
|
|
172
|
-
} catch (err) {
|
|
173
|
-
if (controller.signal.aborted) return
|
|
174
|
-
console.error('Error sending message:', err)
|
|
175
|
-
|
|
176
|
-
const errorMessage: Message = {
|
|
177
|
-
id: Date.now() + 1,
|
|
178
|
-
content: 'Sorry, I encountered an error. Please try again.',
|
|
179
|
-
sender: 'bot',
|
|
180
|
-
timestamp: new Date().toISOString(),
|
|
181
|
-
isError: true
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
setMessages(prev => [...prev.filter(message => message.id !== replyId), errorMessage])
|
|
185
|
-
throw err
|
|
186
|
-
} finally {
|
|
187
|
-
if (activeReplyRef.current === controller) activeReplyRef.current = null
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
[embedId, sessionId, config, enabled]
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
const showFaq = useCallback(() => {
|
|
194
|
-
setShowingFaq(true)
|
|
195
|
-
}, [])
|
|
196
|
-
|
|
197
|
-
const hideFaq = useCallback(() => {
|
|
198
|
-
setShowingFaq(false)
|
|
199
|
-
}, [])
|
|
200
|
-
|
|
201
|
-
const showWelcomePopup = useCallback(() => {
|
|
202
|
-
setShowingWelcomePopup(true)
|
|
203
|
-
}, [])
|
|
204
|
-
|
|
205
|
-
const hideWelcomePopup = useCallback(() => {
|
|
206
|
-
setShowingWelcomePopup(false)
|
|
207
|
-
}, [])
|
|
208
|
-
|
|
209
|
-
const showUserInfoForm = useCallback(() => {
|
|
210
|
-
setShowingUserInfoForm(true)
|
|
211
|
-
}, [])
|
|
212
|
-
|
|
213
|
-
const hideUserInfoForm = useCallback(() => {
|
|
214
|
-
setShowingUserInfoForm(false)
|
|
215
|
-
}, [])
|
|
216
|
-
|
|
217
|
-
const submitUserInfo = useCallback(
|
|
218
|
-
async (userInfo: UserInfo) => {
|
|
219
|
-
if (!enabled) return
|
|
220
|
-
try {
|
|
221
|
-
await submitUserInfoAPI(embedId, sessionId, userInfo)
|
|
222
|
-
setUserInfoCollected(true)
|
|
223
|
-
setShowingUserInfoForm(false)
|
|
224
|
-
|
|
225
|
-
const confirmMessage: Message = {
|
|
226
|
-
id: Date.now(),
|
|
227
|
-
content: 'Thank you for providing your information! How can I help you today?',
|
|
228
|
-
sender: 'bot',
|
|
229
|
-
timestamp: new Date().toISOString()
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
setMessages(prev => [...prev, confirmMessage])
|
|
233
|
-
} catch (err) {
|
|
234
|
-
console.error('Error submitting user info:', err)
|
|
235
|
-
throw err
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
[embedId, sessionId, enabled]
|
|
239
|
-
)
|
|
240
|
-
|
|
241
|
-
const startNewSession = useCallback(() => {
|
|
242
|
-
if (!enabled) return
|
|
243
|
-
activeReplyRef.current?.abort()
|
|
244
|
-
activeReplyRef.current = null
|
|
245
|
-
const newSessionId = generateSessionId()
|
|
246
|
-
setSessionId(newSessionId)
|
|
247
|
-
|
|
248
|
-
if (PERSIST_SESSION) {
|
|
249
|
-
localStorage.setItem(SESSION_STORAGE_KEY, newSessionId)
|
|
250
|
-
} else {
|
|
251
|
-
localStorage.removeItem(SESSION_STORAGE_KEY)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
setMessages([])
|
|
255
|
-
setUserInfoCollected(false)
|
|
256
|
-
setShowingFaq(false)
|
|
257
|
-
setShowingUserInfoForm(false)
|
|
258
|
-
setWelcomePopupShown(false)
|
|
259
|
-
|
|
260
|
-
const typedConfig = config as ChatbotConfig
|
|
261
|
-
if (typedConfig?.welcomeMessage) {
|
|
262
|
-
const greeting = createGreetingMessage(typedConfig)
|
|
263
|
-
if (greeting) {
|
|
264
|
-
const greetingMessage: Message = {
|
|
265
|
-
id: Date.now(),
|
|
266
|
-
content: greeting,
|
|
267
|
-
sender: 'bot',
|
|
268
|
-
timestamp: new Date().toISOString()
|
|
269
|
-
}
|
|
270
|
-
setMessages([greetingMessage])
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}, [config, enabled])
|
|
274
|
-
|
|
275
|
-
const addMessage = useCallback((message: Message) => {
|
|
276
|
-
setMessages(prev => [...prev, message])
|
|
277
|
-
}, [])
|
|
278
|
-
|
|
279
|
-
return {
|
|
280
|
-
config,
|
|
281
|
-
isLoading,
|
|
282
|
-
isOpen,
|
|
283
|
-
showingFaq,
|
|
284
|
-
showingWelcomePopup,
|
|
285
|
-
showingUserInfoForm,
|
|
286
|
-
messages,
|
|
287
|
-
userInfoCollected,
|
|
288
|
-
sessionId,
|
|
289
|
-
error,
|
|
290
|
-
|
|
291
|
-
initializeChatbot,
|
|
292
|
-
toggleChat,
|
|
293
|
-
sendMessage,
|
|
294
|
-
showFaq,
|
|
295
|
-
hideFaq,
|
|
296
|
-
showWelcomePopup,
|
|
297
|
-
hideWelcomePopup,
|
|
298
|
-
showUserInfoForm,
|
|
299
|
-
hideUserInfoForm,
|
|
300
|
-
submitUserInfo,
|
|
301
|
-
startNewSession,
|
|
302
|
-
addMessage
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
export function useAndyChat(embedId: string): UseAndyChatReturn
|
|
307
|
-
export function useAndyChat(options: { mode: 'support'; support: SupportOptions }): ReturnType<typeof useSupportChat>
|
|
308
|
-
export function useAndyChat(input: string | { mode: 'support'; support: SupportOptions }) {
|
|
309
|
-
const support = useSupportChat(typeof input === 'string' ? null : input.support)
|
|
310
|
-
const sales = useSalesAndyChat(typeof input === 'string' ? input : '', typeof input === 'string')
|
|
311
|
-
return typeof input === 'string' ? sales : support
|
|
312
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState, useSyncExternalStore } from 'react'
|
|
2
|
-
import { createSupportController, type SupportOptions, type SupportState } from 'andy-widget-core'
|
|
3
|
-
|
|
4
|
-
const empty: SupportState = { config: null, view: 'conversation', messages: [], transcript: [], tickets: [], ticket: null, entries: [], loading: true, busy: false, error: null, submission: null, followup: null, unreadCount: 0 }
|
|
5
|
-
const noSubscribe = () => () => {}
|
|
6
|
-
const emptySnapshot = () => empty
|
|
7
|
-
|
|
8
|
-
/** The host context key changes before a new user/company is allowed to see any previous state. */
|
|
9
|
-
export const useSupportChat = (options: SupportOptions | null) => {
|
|
10
|
-
const key = options ? JSON.stringify([options.installationId, options.contextKey, options.apiBaseUrl]) : null
|
|
11
|
-
const callback = useRef(options?.getRequesterPass)
|
|
12
|
-
callback.current = options?.getRequesterPass
|
|
13
|
-
const [owned, setOwned] = useState<{ key: string; controller: ReturnType<typeof createSupportController> } | null>(null)
|
|
14
|
-
const controller = owned?.key === key ? owned?.controller : null
|
|
15
|
-
const state = useSyncExternalStore(controller?.subscribe || noSubscribe, controller?.getSnapshot || emptySnapshot, emptySnapshot)
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (!options || !key) return
|
|
18
|
-
const controller = createSupportController({ ...options, getRequesterPass: () => callback.current!() })
|
|
19
|
-
setOwned({ key, controller })
|
|
20
|
-
void controller.bootstrap()
|
|
21
|
-
return () => controller.dispose()
|
|
22
|
-
}, [key])
|
|
23
|
-
useEffect(() => { controller?.setLanguage(options?.lang) }, [controller, options?.lang])
|
|
24
|
-
const ready = !!state.config
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (ready && options?.ticketId) void controller?.inspect(options.ticketId)
|
|
27
|
-
}, [controller, ready, options?.ticketId])
|
|
28
|
-
return { mode: 'support' as const, state, controller }
|
|
29
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
// Main export for AndyChat React package
|
|
2
|
-
export { default as AndyChat } from './AndyChat'
|
|
3
|
-
// Back-compat: older integrations import { Andy } from 'andy-widget-react'
|
|
4
|
-
export { default as Andy } from './AndyChat'
|
|
5
|
-
|
|
6
|
-
// Export the custom hook for advanced usage
|
|
7
|
-
export { useAndyChat } from './hooks/useAndyChat'
|
|
8
|
-
|
|
9
|
-
// Export individual components for advanced customization
|
|
10
|
-
export { default as ChatBubble } from './components/ChatBubble'
|
|
11
|
-
export { default as ChatWindow } from './components/ChatWindow'
|
|
12
|
-
export { default as MessageList } from './components/MessageList'
|
|
13
|
-
export { default as MessageInput } from './components/MessageInput'
|
|
14
|
-
export { default as FAQ } from './components/FAQ'
|
|
15
|
-
export { default as WelcomePopup } from './components/WelcomePopup'
|
|
16
|
-
export { default as UserInfoForm } from './components/UserInfoForm'
|
|
17
|
-
|
|
18
|
-
// Export types for consumers
|
|
19
|
-
export type {
|
|
20
|
-
AndyChatProps,
|
|
21
|
-
SupportAndyChatProps,
|
|
22
|
-
SalesAndyChatProps,
|
|
23
|
-
ChatbotConfig,
|
|
24
|
-
Message,
|
|
25
|
-
FAQItem,
|
|
26
|
-
PredefinedQuestion,
|
|
27
|
-
WelcomePopupConfig,
|
|
28
|
-
CollectUserInfoConfig,
|
|
29
|
-
UserInfo,
|
|
30
|
-
UseAndyChatReturn,
|
|
31
|
-
ChatBubbleProps,
|
|
32
|
-
ChatWindowProps,
|
|
33
|
-
MessageListProps,
|
|
34
|
-
MessageInputProps,
|
|
35
|
-
FAQProps,
|
|
36
|
-
WelcomePopupProps,
|
|
37
|
-
UserInfoFormProps,
|
|
38
|
-
FaqItemProps
|
|
39
|
-
} from './types'
|
|
40
|
-
|
|
41
|
-
// Re-export core utilities for React users who need them
|
|
42
|
-
export {
|
|
43
|
-
// Design tokens for custom styling
|
|
44
|
-
theme,
|
|
45
|
-
colors,
|
|
46
|
-
typography,
|
|
47
|
-
spacing,
|
|
48
|
-
borderRadius,
|
|
49
|
-
shadows,
|
|
50
|
-
zIndex,
|
|
51
|
-
animation,
|
|
52
|
-
chat,
|
|
53
|
-
|
|
54
|
-
// Utility functions
|
|
55
|
-
generateSessionId,
|
|
56
|
-
parseMarkdown,
|
|
57
|
-
sanitizeUrl,
|
|
58
|
-
|
|
59
|
-
// Configuration helpers
|
|
60
|
-
isValidEmbedId,
|
|
61
|
-
getEmbedId,
|
|
62
|
-
getApiBaseUrl,
|
|
63
|
-
setApiBaseUrl
|
|
64
|
-
} from 'andy-widget-core'
|
|
65
|
-
|
|
66
|
-
// Default export is the main AndyChat component
|
|
67
|
-
export { default } from './AndyChat'
|
package/src/styles/main.css
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/* AndyChat React Styles */
|
|
2
|
-
/* Placeholder CSS file - can be expanded with custom styles */
|
|
3
|
-
|
|
4
|
-
.andychat-react-container {
|
|
5
|
-
/* Container styles */
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.andychat-bubble {
|
|
9
|
-
/* Chat bubble styles - handled inline for now */
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.andychat-window {
|
|
13
|
-
/* Chat window styles - handled inline for now */
|
|
14
|
-
}
|