srs-heritage-chatbot 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 (187) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +194 -0
  3. package/lib/commonjs/assets/chat-icon-mobile.svg +1 -0
  4. package/lib/commonjs/assets/heritage.png +0 -0
  5. package/lib/commonjs/assets/posiden.svg +51 -0
  6. package/lib/commonjs/components/LoadingTips.js +104 -0
  7. package/lib/commonjs/components/LoadingTips.js.map +1 -0
  8. package/lib/commonjs/components/email.js +461 -0
  9. package/lib/commonjs/components/email.js.map +1 -0
  10. package/lib/commonjs/components/feedback.js +114 -0
  11. package/lib/commonjs/components/feedback.js.map +1 -0
  12. package/lib/commonjs/components/header.js +126 -0
  13. package/lib/commonjs/components/header.js.map +1 -0
  14. package/lib/commonjs/components/input.js +144 -0
  15. package/lib/commonjs/components/input.js.map +1 -0
  16. package/lib/commonjs/components/productCard.js +688 -0
  17. package/lib/commonjs/components/productCard.js.map +1 -0
  18. package/lib/commonjs/components/progressCircle.js +99 -0
  19. package/lib/commonjs/components/progressCircle.js.map +1 -0
  20. package/lib/commonjs/components/testing.js +74 -0
  21. package/lib/commonjs/components/testing.js.map +1 -0
  22. package/lib/commonjs/components/voice.js +184 -0
  23. package/lib/commonjs/components/voice.js.map +1 -0
  24. package/lib/commonjs/components/welcomeButton.js +149 -0
  25. package/lib/commonjs/components/welcomeButton.js.map +1 -0
  26. package/lib/commonjs/components/welcomeInput.js +137 -0
  27. package/lib/commonjs/components/welcomeInput.js.map +1 -0
  28. package/lib/commonjs/contexts/AppContext.js +552 -0
  29. package/lib/commonjs/contexts/AppContext.js.map +1 -0
  30. package/lib/commonjs/hooks/Stream.js +599 -0
  31. package/lib/commonjs/hooks/Stream.js.map +1 -0
  32. package/lib/commonjs/hooks/useAsyncStorage.js +36 -0
  33. package/lib/commonjs/hooks/useAsyncStorage.js.map +1 -0
  34. package/lib/commonjs/index.js +44 -0
  35. package/lib/commonjs/index.js.map +1 -0
  36. package/lib/commonjs/layout/disclaimer.js +208 -0
  37. package/lib/commonjs/layout/disclaimer.js.map +1 -0
  38. package/lib/commonjs/layout/ex.js +254 -0
  39. package/lib/commonjs/layout/ex.js.map +1 -0
  40. package/lib/commonjs/layout/icon.js +118 -0
  41. package/lib/commonjs/layout/icon.js.map +1 -0
  42. package/lib/commonjs/layout/layout.js +168 -0
  43. package/lib/commonjs/layout/layout.js.map +1 -0
  44. package/lib/commonjs/layout/welcome.js +160 -0
  45. package/lib/commonjs/layout/welcome.js.map +1 -0
  46. package/lib/commonjs/layout/window.js +396 -0
  47. package/lib/commonjs/layout/window.js.map +1 -0
  48. package/lib/commonjs/utils/audioRecorder.js +412 -0
  49. package/lib/commonjs/utils/audioRecorder.js.map +1 -0
  50. package/lib/commonjs/utils/cloudinary.js +69 -0
  51. package/lib/commonjs/utils/cloudinary.js.map +1 -0
  52. package/lib/commonjs/utils/storage.js +76 -0
  53. package/lib/commonjs/utils/storage.js.map +1 -0
  54. package/lib/commonjs/utils/textToSpeech.js +53 -0
  55. package/lib/commonjs/utils/textToSpeech.js.map +1 -0
  56. package/lib/module/assets/chat-icon-mobile.svg +1 -0
  57. package/lib/module/assets/heritage.png +0 -0
  58. package/lib/module/assets/posiden.svg +51 -0
  59. package/lib/module/components/LoadingTips.js +95 -0
  60. package/lib/module/components/LoadingTips.js.map +1 -0
  61. package/lib/module/components/email.js +452 -0
  62. package/lib/module/components/email.js.map +1 -0
  63. package/lib/module/components/feedback.js +105 -0
  64. package/lib/module/components/feedback.js.map +1 -0
  65. package/lib/module/components/header.js +117 -0
  66. package/lib/module/components/header.js.map +1 -0
  67. package/lib/module/components/input.js +135 -0
  68. package/lib/module/components/input.js.map +1 -0
  69. package/lib/module/components/productCard.js +679 -0
  70. package/lib/module/components/productCard.js.map +1 -0
  71. package/lib/module/components/progressCircle.js +91 -0
  72. package/lib/module/components/progressCircle.js.map +1 -0
  73. package/lib/module/components/testing.js +66 -0
  74. package/lib/module/components/testing.js.map +1 -0
  75. package/lib/module/components/voice.js +175 -0
  76. package/lib/module/components/voice.js.map +1 -0
  77. package/lib/module/components/welcomeButton.js +140 -0
  78. package/lib/module/components/welcomeButton.js.map +1 -0
  79. package/lib/module/components/welcomeInput.js +128 -0
  80. package/lib/module/components/welcomeInput.js.map +1 -0
  81. package/lib/module/contexts/AppContext.js +542 -0
  82. package/lib/module/contexts/AppContext.js.map +1 -0
  83. package/lib/module/hooks/Stream.js +592 -0
  84. package/lib/module/hooks/Stream.js.map +1 -0
  85. package/lib/module/hooks/useAsyncStorage.js +29 -0
  86. package/lib/module/hooks/useAsyncStorage.js.map +1 -0
  87. package/lib/module/index.js +36 -0
  88. package/lib/module/index.js.map +1 -0
  89. package/lib/module/layout/disclaimer.js +199 -0
  90. package/lib/module/layout/disclaimer.js.map +1 -0
  91. package/lib/module/layout/ex.js +253 -0
  92. package/lib/module/layout/ex.js.map +1 -0
  93. package/lib/module/layout/icon.js +108 -0
  94. package/lib/module/layout/icon.js.map +1 -0
  95. package/lib/module/layout/layout.js +160 -0
  96. package/lib/module/layout/layout.js.map +1 -0
  97. package/lib/module/layout/welcome.js +150 -0
  98. package/lib/module/layout/welcome.js.map +1 -0
  99. package/lib/module/layout/window.js +387 -0
  100. package/lib/module/layout/window.js.map +1 -0
  101. package/lib/module/utils/audioRecorder.js +398 -0
  102. package/lib/module/utils/audioRecorder.js.map +1 -0
  103. package/lib/module/utils/cloudinary.js +61 -0
  104. package/lib/module/utils/cloudinary.js.map +1 -0
  105. package/lib/module/utils/storage.js +67 -0
  106. package/lib/module/utils/storage.js.map +1 -0
  107. package/lib/module/utils/textToSpeech.js +43 -0
  108. package/lib/module/utils/textToSpeech.js.map +1 -0
  109. package/lib/typescript/components/LoadingTips.d.ts +3 -0
  110. package/lib/typescript/components/LoadingTips.d.ts.map +1 -0
  111. package/lib/typescript/components/email.d.ts +6 -0
  112. package/lib/typescript/components/email.d.ts.map +1 -0
  113. package/lib/typescript/components/feedback.d.ts +6 -0
  114. package/lib/typescript/components/feedback.d.ts.map +1 -0
  115. package/lib/typescript/components/header.d.ts +3 -0
  116. package/lib/typescript/components/header.d.ts.map +1 -0
  117. package/lib/typescript/components/input.d.ts +6 -0
  118. package/lib/typescript/components/input.d.ts.map +1 -0
  119. package/lib/typescript/components/productCard.d.ts +7 -0
  120. package/lib/typescript/components/productCard.d.ts.map +1 -0
  121. package/lib/typescript/components/progressCircle.d.ts +3 -0
  122. package/lib/typescript/components/progressCircle.d.ts.map +1 -0
  123. package/lib/typescript/components/testing.d.ts +6 -0
  124. package/lib/typescript/components/testing.d.ts.map +1 -0
  125. package/lib/typescript/components/voice.d.ts +5 -0
  126. package/lib/typescript/components/voice.d.ts.map +1 -0
  127. package/lib/typescript/components/welcomeButton.d.ts +4 -0
  128. package/lib/typescript/components/welcomeButton.d.ts.map +1 -0
  129. package/lib/typescript/components/welcomeInput.d.ts +6 -0
  130. package/lib/typescript/components/welcomeInput.d.ts.map +1 -0
  131. package/lib/typescript/contexts/AppContext.d.ts +10 -0
  132. package/lib/typescript/contexts/AppContext.d.ts.map +1 -0
  133. package/lib/typescript/hooks/Stream.d.ts +2 -0
  134. package/lib/typescript/hooks/Stream.d.ts.map +1 -0
  135. package/lib/typescript/hooks/useAsyncStorage.d.ts +2 -0
  136. package/lib/typescript/hooks/useAsyncStorage.d.ts.map +1 -0
  137. package/lib/typescript/index.d.ts +8 -0
  138. package/lib/typescript/index.d.ts.map +1 -0
  139. package/lib/typescript/layout/disclaimer.d.ts +5 -0
  140. package/lib/typescript/layout/disclaimer.d.ts.map +1 -0
  141. package/lib/typescript/layout/ex.d.ts +1 -0
  142. package/lib/typescript/layout/ex.d.ts.map +1 -0
  143. package/lib/typescript/layout/icon.d.ts +3 -0
  144. package/lib/typescript/layout/icon.d.ts.map +1 -0
  145. package/lib/typescript/layout/layout.d.ts +3 -0
  146. package/lib/typescript/layout/layout.d.ts.map +1 -0
  147. package/lib/typescript/layout/welcome.d.ts +6 -0
  148. package/lib/typescript/layout/welcome.d.ts.map +1 -0
  149. package/lib/typescript/layout/window.d.ts +5 -0
  150. package/lib/typescript/layout/window.d.ts.map +1 -0
  151. package/lib/typescript/utils/audioRecorder.d.ts +9 -0
  152. package/lib/typescript/utils/audioRecorder.d.ts.map +1 -0
  153. package/lib/typescript/utils/cloudinary.d.ts +17 -0
  154. package/lib/typescript/utils/cloudinary.d.ts.map +1 -0
  155. package/lib/typescript/utils/storage.d.ts +29 -0
  156. package/lib/typescript/utils/storage.d.ts.map +1 -0
  157. package/lib/typescript/utils/textToSpeech.d.ts +2 -0
  158. package/lib/typescript/utils/textToSpeech.d.ts.map +1 -0
  159. package/package.json +109 -0
  160. package/src/assets/chat-icon-mobile.svg +1 -0
  161. package/src/assets/heritage.png +0 -0
  162. package/src/assets/posiden.svg +51 -0
  163. package/src/components/LoadingTips.js +99 -0
  164. package/src/components/email.js +467 -0
  165. package/src/components/feedback.js +114 -0
  166. package/src/components/header.js +119 -0
  167. package/src/components/input.js +133 -0
  168. package/src/components/productCard.js +815 -0
  169. package/src/components/progressCircle.js +88 -0
  170. package/src/components/testing.js +60 -0
  171. package/src/components/voice.js +228 -0
  172. package/src/components/welcomeButton.js +161 -0
  173. package/src/components/welcomeInput.js +133 -0
  174. package/src/contexts/AppContext.js +678 -0
  175. package/src/hooks/Stream.js +655 -0
  176. package/src/hooks/useAsyncStorage.js +33 -0
  177. package/src/index.js +30 -0
  178. package/src/layout/disclaimer.js +231 -0
  179. package/src/layout/ex.js +252 -0
  180. package/src/layout/icon.js +105 -0
  181. package/src/layout/layout.js +160 -0
  182. package/src/layout/welcome.js +172 -0
  183. package/src/layout/window.js +476 -0
  184. package/src/utils/audioRecorder.js +445 -0
  185. package/src/utils/cloudinary.js +61 -0
  186. package/src/utils/storage.ts +89 -0
  187. package/src/utils/textToSpeech.js +49 -0
@@ -0,0 +1,476 @@
1
+ import React, { useState, useEffect, useContext, useRef } from 'react';
2
+ import {
3
+ Text,
4
+ StyleSheet,
5
+ View,
6
+ TextInput,
7
+ TouchableOpacity,
8
+ Platform,
9
+ KeyboardAvoidingView,
10
+ Keyboard,
11
+ Animated,
12
+ Linking,
13
+ Button,
14
+ } from 'react-native';
15
+ import { Header } from '../components/header';
16
+ import { AppContext } from '../contexts/AppContext';
17
+ import Ionicons from 'react-native-vector-icons/Ionicons';
18
+ import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
19
+ import { Testing } from '../components/testing';
20
+ import { ChatInput } from '../components/input';
21
+ import { useWebSocketMessage } from '../hooks/Stream';
22
+ import { ProductCard } from '../components/productCard';
23
+ import Markdown from 'react-native-markdown-display';
24
+ import { Feedback } from '../components/feedback';
25
+ import { ProgressCircle } from '../components/progressCircle';
26
+
27
+ export const ChatWindow = ({ panHandlers }) => {
28
+ const {
29
+ handleSend,
30
+ messages,
31
+ input,
32
+ setInput,
33
+ ghostMessage,
34
+ handleButtonClick,
35
+ onProductCardClick,
36
+ onAddToCartClick,
37
+ uiConfig,
38
+ ghostCard,
39
+ typingIndicator,
40
+ feedbackOpen,
41
+ setFeedbackOpen,
42
+ theme,
43
+ } = useContext(AppContext);
44
+
45
+ const scrollViewRef = useRef(null);
46
+ const fadeAnim = useRef(new Animated.Value(0.6)).current;
47
+ const [messageCount, setMessageCount] = useState(messages.length);
48
+
49
+ useEffect(() => {
50
+ if (scrollViewRef.current) {
51
+ const timeoutId = setTimeout(() => {
52
+ if (scrollViewRef.current) {
53
+ scrollViewRef.current.scrollToEnd({ animated: false });
54
+ }
55
+ }, 100);
56
+
57
+ return () => clearTimeout(timeoutId);
58
+ }
59
+ }, []);
60
+
61
+ useEffect(() => {
62
+ if (ghostMessage) {
63
+ Animated.loop(
64
+ Animated.sequence([
65
+ Animated.timing(fadeAnim, {
66
+ toValue: 1,
67
+ duration: 500,
68
+ useNativeDriver: false,
69
+ }),
70
+ Animated.timing(fadeAnim, {
71
+ toValue: 0.6,
72
+ duration: 500,
73
+ useNativeDriver: false,
74
+ }),
75
+ ]),
76
+ ).start();
77
+ }
78
+ }, [ghostMessage]);
79
+ // useEffect(() => {
80
+ // if (messages.length === 0) {
81
+ // return;
82
+ // }
83
+ // console.log('=== CHATWINDOW DEBUG ===');
84
+ // console.log('Total messages:', messages.length);
85
+ // messages.forEach((msg, idx) => {
86
+ // if (msg.products && msg.products.length > 0) {
87
+ // console.log(' ✅ PRODUCTS FOUND IN MESSAGE', idx);
88
+ // console.log(' Products:', msg.products.length, 'items');
89
+ // msg.products.forEach((prod, pIdx) => {
90
+ // console.log(` Product ${pIdx}:`, prod);
91
+ // });
92
+ // }
93
+ // });
94
+ // }, [messages]);
95
+
96
+ useWebSocketMessage();
97
+
98
+ const openLink = url => {
99
+ Linking.openURL(url);
100
+ };
101
+
102
+ return (
103
+ <View style={styles.container}>
104
+ <View>
105
+ <Header />
106
+ </View>
107
+
108
+ {/* Messages area */}
109
+ <KeyboardAwareScrollView
110
+ ref={scrollViewRef}
111
+ contentContainerStyle={styles.messagesContent}
112
+ enableOnAndroid
113
+ enableOnIOS
114
+ contentInsetAdjustmentBehavior="never"
115
+ automaticallyAdjustContentInsets={false}
116
+ contentInset={{ bottom: 0 }}
117
+ keyboardShouldPersistTaps="handled"
118
+ showsVerticalScrollIndicator={false}
119
+ extraScrollHeight={200}
120
+ onContentSizeChange={(contentWidth, contentHeight) => {
121
+ const currentLength = messages.length;
122
+
123
+ if (currentLength > messageCount) {
124
+ scrollViewRef.current?.scrollToEnd({ animated: true });
125
+ setMessageCount(currentLength);
126
+ } else if (currentLength == messageCount) {
127
+ const isAnyFeedbackOpen = Object.values(feedbackOpen).some(
128
+ isOpen => isOpen === true,
129
+ );
130
+
131
+ if (isAnyFeedbackOpen) {
132
+ // Do nothing, prevent scrolling
133
+ } else {
134
+ if (typingIndicator) {
135
+ scrollViewRef.current?.scrollToEnd({ animated: true });
136
+ }
137
+ }
138
+ setMessageCount(currentLength);
139
+ } else if (currentLength < messageCount) {
140
+ setMessageCount(currentLength);
141
+ }
142
+ }}
143
+ keyboardDismissMode="none"
144
+ bounces={false}
145
+ enableResetScrollToCoords={false}
146
+ keyboardOpeningTime={0}>
147
+ {messages.map((msg, i) => {
148
+ // Add inline debug logging during render
149
+ const hasProducts = msg.products && msg.products.length > 0;
150
+
151
+ return (
152
+ <View
153
+ key={msg.id || msg.message_id || i}
154
+ style={styles.messageWrapper}>
155
+ {msg.type !== 'middle' && msg.text && (
156
+ <View
157
+ style={[
158
+ styles.messageBubble,
159
+ msg.type === 'user'
160
+ ? [
161
+ styles.userMessage,
162
+ { backgroundColor: theme.userMessage },
163
+ ]
164
+ : styles.aiMessage,
165
+ ]}>
166
+ <Markdown
167
+ style={{
168
+ body: {
169
+ color: msg.type === 'user' ? '#ffffff' : '#161616',
170
+ fontSize: 16,
171
+ lineHeight: 22,
172
+ includeFontPadding: false,
173
+ textAlignVertical: 'center',
174
+ },
175
+ }}>
176
+ {typeof msg.text === 'string'
177
+ ? msg.text
178
+ : String(msg.text || '')}
179
+ </Markdown>
180
+ {msg.type == 'ai' && i != 0 && msg.message_id && (
181
+ <Feedback message={msg} messageId={msg.message_id} />
182
+ )}
183
+ </View>
184
+ )}
185
+
186
+ {msg.type == 'middle' && (
187
+ <View
188
+ style={[styles.middleMessageBubble, styles.middleMessage]}>
189
+ <Text
190
+ style={{ marginRight: 10, marginTop: 10 }}
191
+ allowFontScaling={false}>
192
+ <Ionicons
193
+ name="sparkles-outline"
194
+ size={16}
195
+ color="#161616"
196
+ />
197
+ </Text>
198
+ <View style={styles.middleMessageText}>
199
+ <Markdown
200
+ style={{
201
+ body: {
202
+ color: msg.type === 'user' ? '#ffffff' : '#161616',
203
+ fontSize: 16,
204
+ lineHeight: 22,
205
+ includeFontPadding: false,
206
+ textAlignVertical: 'center',
207
+ },
208
+ }}>
209
+ {typeof msg.text === 'string'
210
+ ? msg.text
211
+ : String(msg.text || '')}
212
+ </Markdown>
213
+ </View>
214
+ </View>
215
+ )}
216
+
217
+ {hasProducts && (
218
+ <View>
219
+ {msg.products.map((prod, index) => {
220
+ return (
221
+ <View key={index} style={styles.productCardWrapper}>
222
+ <ProductCard prod={prod} messageId={msg.message_id} />
223
+ </View>
224
+ );
225
+ })}
226
+ </View>
227
+ )}
228
+
229
+ {msg.resource &&
230
+ msg.resource.length > 0 &&
231
+ msg.resource_type == 'video' && (
232
+ <TouchableOpacity
233
+ style={styles.resourceButton}
234
+ onPress={() => openLink(msg.resource)}>
235
+ <Text style={styles.resourceText}>Watch Video</Text>
236
+ <Ionicons
237
+ name="link"
238
+ size={20}
239
+ color="white"
240
+ style={styles.icon}
241
+ />
242
+ </TouchableOpacity>
243
+ )}
244
+
245
+ {msg.suggested_questions &&
246
+ Array.isArray(msg.questions) &&
247
+ msg.questions.length > 0 &&
248
+ msg.questions.map((question, index) => (
249
+ <TouchableOpacity
250
+ key={index}
251
+ style={[
252
+ styles.suggestedQuestionButton,
253
+ { borderColor: theme.primaryColor },
254
+ ]}
255
+ onPress={() => handleButtonClick(question)}>
256
+ <Text
257
+ style={[
258
+ styles.suggestedQuestionText,
259
+ { color: theme.primaryColor },
260
+ ]}>
261
+ {question}
262
+ </Text>
263
+ </TouchableOpacity>
264
+ ))}
265
+
266
+ {ghostMessage && i === messages.length - 1 && (
267
+ <View style={styles.ghostMessageContainer}>
268
+ <Animated.View
269
+ style={[
270
+ styles.ghostBar,
271
+ styles.ghostBarShort,
272
+ { opacity: fadeAnim },
273
+ ]}
274
+ />
275
+ <Animated.View
276
+ style={[
277
+ styles.ghostBar,
278
+ styles.ghostBarLong,
279
+ { opacity: fadeAnim },
280
+ ]}
281
+ />
282
+ <Animated.View
283
+ style={[
284
+ styles.ghostBar,
285
+ styles.ghostBarMedium,
286
+ { opacity: fadeAnim },
287
+ ]}
288
+ />
289
+ </View>
290
+ )}
291
+
292
+ {ghostCard && i === messages.length - 1 && (
293
+ <View style={styles.ghostCardContainer}>
294
+ <View style={styles.ghostSquare} />
295
+ <View style={styles.ghostBarsContainer}>
296
+ <Animated.View
297
+ style={[
298
+ styles.ghostBar,
299
+ styles.ghostBarShort,
300
+ { opacity: fadeAnim },
301
+ ]}
302
+ />
303
+ <Animated.View
304
+ style={[
305
+ styles.ghostBar,
306
+ styles.ghostBarLong,
307
+ { opacity: fadeAnim },
308
+ ]}
309
+ />
310
+ <Animated.View
311
+ style={[
312
+ styles.ghostBar,
313
+ styles.ghostBarMedium,
314
+ { opacity: fadeAnim },
315
+ ]}
316
+ />
317
+ </View>
318
+ </View>
319
+ )}
320
+ </View>
321
+ );
322
+ })}
323
+ </KeyboardAwareScrollView>
324
+
325
+ <KeyboardAvoidingView
326
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
327
+ keyboardVerticalOffset={Platform.OS === 'ios' ? 10 : 0}
328
+ style={{ width: '100%' }}>
329
+ {uiConfig.testButtons && (
330
+ <Testing
331
+ onProductCardClick={onProductCardClick}
332
+ onAddToCartClick={onAddToCartClick}
333
+ />
334
+ )}
335
+ {!typingIndicator ? <ChatInput /> : <ProgressCircle />}
336
+ </KeyboardAvoidingView>
337
+ </View>
338
+ );
339
+ };
340
+
341
+ const styles = StyleSheet.create({
342
+ container: {
343
+ flex: 1,
344
+ },
345
+ messagesContent: {
346
+ padding: 16,
347
+ justifyContent: 'flex-end',
348
+ paddingBottom: 300,
349
+ },
350
+ messageWrapper: {
351
+ marginBottom: 0,
352
+ },
353
+ messageBubble: {
354
+ padding: 6,
355
+ paddingHorizontal: 16,
356
+ borderRadius: 12,
357
+ marginBottom: 5,
358
+ },
359
+ userMessage: {
360
+ alignSelf: 'flex-end',
361
+ backgroundColor: '#437D3D',
362
+ color: '#ffffff',
363
+ borderTopRightRadius: 0,
364
+ },
365
+ aiMessage: {
366
+ alignSelf: 'flex-start',
367
+ backgroundColor: '#FFFFFF',
368
+ width: '100%',
369
+ },
370
+ productCardWrapper: {
371
+ marginTop: 5,
372
+ },
373
+ suggestedQuestionButton: {
374
+ backgroundColor: 'white',
375
+ borderWidth: 1,
376
+ borderColor: '#437D3D',
377
+ borderRadius: 18,
378
+ paddingVertical: 10,
379
+ paddingHorizontal: 16,
380
+ marginBottom: 7,
381
+ alignSelf: 'flex-start',
382
+ },
383
+ suggestedQuestionText: {
384
+ color: '#437D3D',
385
+ fontSize: 13,
386
+ textAlign: 'left',
387
+ includeFontPadding: false,
388
+ textAlignVertical: 'center',
389
+ },
390
+ ghostMessageContainer: {
391
+ alignSelf: 'flex-start',
392
+ width: '100%',
393
+ backgroundColor: '#FFFFFF',
394
+ borderRadius: 10,
395
+ borderTopLeftRadius: 0,
396
+ padding: 14,
397
+ marginVertical: 5,
398
+ },
399
+ ghostBar: {
400
+ height: 20,
401
+ borderRadius: 10,
402
+ backgroundColor: '#ebebeb',
403
+ marginVertical: 3,
404
+ },
405
+ ghostBarShort: {
406
+ width: '50%',
407
+ },
408
+ ghostBarMedium: {
409
+ width: '75%',
410
+ },
411
+ ghostBarLong: {
412
+ width: '100%',
413
+ },
414
+ ghostCardContainer: {
415
+ flexDirection: 'row', // Arrange elements in a row
416
+ alignItems: 'center', // Vertically align items
417
+ width: '100%',
418
+ backgroundColor: '#FFFFFF',
419
+ borderRadius: 10,
420
+ borderTopLeftRadius: 0,
421
+ padding: 14,
422
+ marginVertical: 5,
423
+ },
424
+ ghostSquare: {
425
+ width: '25%', // Takes up 25% of the container
426
+ aspectRatio: 1, // Makes it a square
427
+ backgroundColor: '#ebebeb', // Adjust color if needed
428
+ borderRadius: 8,
429
+ },
430
+ ghostBarsContainer: {
431
+ width: '75%', // Takes up 75% of the container
432
+ paddingLeft: 10, // Adds some spacing from the square
433
+ },
434
+ resourceButton: {
435
+ flexDirection: 'row',
436
+ alignItems: 'center',
437
+ backgroundColor: '#367CB6',
438
+ paddingVertical: 10,
439
+ paddingHorizontal: 15,
440
+ marginBottom: 5,
441
+ borderRadius: 5,
442
+ alignSelf: 'flex-start',
443
+ },
444
+ resourceText: {
445
+ color: 'white',
446
+ fontSize: 16,
447
+ marginRight: 8,
448
+ includeFontPadding: false,
449
+ textAlignVertical: 'center',
450
+ },
451
+ middleMessageBubble: {
452
+ padding: 6,
453
+ paddingHorizontal: 16,
454
+ borderRadius: 12,
455
+ marginBottom: 5,
456
+ flexDirection: 'row',
457
+ alignItems: 'flex-start',
458
+ },
459
+ middleMessage: {
460
+ color: '#161616',
461
+ alignSelf: 'flex-start',
462
+ backgroundColor: '#e7decd', //'#e0f4fc',
463
+ width: '100%',
464
+ },
465
+ middleMessageText: {
466
+ flex: 1,
467
+ flexShrink: 1,
468
+ },
469
+ });
470
+
471
+ {
472
+ /* <Testing
473
+ onProductCardClick={onProductCardClick}
474
+ onAddToCartClick={onAddToCartClick}
475
+ /> */
476
+ }