@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,127 @@
1
+ /**
2
+ * Format timestamp to readable format
3
+ */
4
+ export function formatTimestamp(timestamp) {
5
+ const date = new Date(timestamp);
6
+ return date.toLocaleTimeString('en-US', {
7
+ hour: 'numeric',
8
+ minute: '2-digit',
9
+ hour12: true,
10
+ });
11
+ }
12
+ /**
13
+ * Check if token is expired (basic check)
14
+ */
15
+ export function isTokenExpired(token) {
16
+ try {
17
+ const payload = JSON.parse(atob(token.split('.')[1]));
18
+ const expirationTime = payload.exp * 1000;
19
+ return Date.now() > expirationTime;
20
+ }
21
+ catch {
22
+ return true;
23
+ }
24
+ }
25
+ /**
26
+ * Handle API error and return user-friendly message
27
+ */
28
+ export function getErrorMessage(error) {
29
+ const statusCode = error.status_code;
30
+ if (statusCode === 401) {
31
+ return 'Your session expired. Please log in again.';
32
+ }
33
+ if (statusCode === 429) {
34
+ const retryAfter = error.retry_after || 3600;
35
+ const minutes = Math.ceil(retryAfter / 60);
36
+ return `Too many requests. Please try again in ${minutes} minute${minutes > 1 ? 's' : ''}.`;
37
+ }
38
+ if (statusCode === 503) {
39
+ return 'Bot service is temporarily unavailable. Please try again later.';
40
+ }
41
+ if (statusCode === 400) {
42
+ return 'Invalid request. Please check your input.';
43
+ }
44
+ return error.detail || 'An error occurred. Please try again.';
45
+ }
46
+ /**
47
+ * Debounce function for API calls
48
+ */
49
+ export function debounce(func, wait) {
50
+ let timeout;
51
+ return function executedFunction(...args) {
52
+ const later = () => {
53
+ clearTimeout(timeout);
54
+ func(...args);
55
+ };
56
+ clearTimeout(timeout);
57
+ timeout = setTimeout(later, wait);
58
+ };
59
+ }
60
+ /**
61
+ * Throttle function for API calls
62
+ */
63
+ export function throttle(func, limit) {
64
+ let inThrottle;
65
+ return function executedFunction(...args) {
66
+ if (!inThrottle) {
67
+ func(...args);
68
+ inThrottle = true;
69
+ setTimeout(() => (inThrottle = false), limit);
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * Validate JWT token format
75
+ */
76
+ export function isValidToken(token) {
77
+ const parts = token.split('.');
78
+ return parts.length === 3;
79
+ }
80
+ /**
81
+ * Get priority color
82
+ */
83
+ export function getPriorityColor(priority) {
84
+ const colors = {
85
+ 1: '#dc2626', // red - urgent
86
+ 2: '#f59e0b', // amber - high
87
+ 3: '#3b82f6', // blue - medium
88
+ 4: '#10b981', // green - low
89
+ 5: '#6b7280', // gray - info
90
+ };
91
+ return colors[priority] || colors[3];
92
+ }
93
+ /**
94
+ * Get priority label
95
+ */
96
+ export function getPriorityLabel(priority) {
97
+ const labels = {
98
+ 1: 'Urgent',
99
+ 2: 'High',
100
+ 3: 'Medium',
101
+ 4: 'Low',
102
+ 5: 'Info',
103
+ };
104
+ return labels[priority] || labels[3];
105
+ }
106
+ /**
107
+ * Truncate text to specified length
108
+ */
109
+ export function truncateText(text, length) {
110
+ if (text.length <= length)
111
+ return text;
112
+ return text.substring(0, length) + '...';
113
+ }
114
+ /**
115
+ * Check if message is too long
116
+ */
117
+ export function isMessageTooLong(message, maxLength = 2000) {
118
+ return message.length > maxLength;
119
+ }
120
+ /**
121
+ * Format progress percentage
122
+ */
123
+ export function formatProgress(progress) {
124
+ const match = progress.match(/(\d+)%/);
125
+ return match ? parseInt(match[1]) : 0;
126
+ }
127
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/core/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { BotWidgetConfig } from '../core';
3
+ interface ChatWidgetProps extends Omit<BotWidgetConfig, 'theme' | 'position'> {
4
+ height?: number;
5
+ width?: number;
6
+ }
7
+ export declare const ChatWidget: React.FC<ChatWidgetProps>;
8
+ export default ChatWidget;
9
+ //# sourceMappingURL=ChatWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../../src/native/ChatWidget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAGL,eAAe,EAIhB,MAAM,SAAS,CAAC;AAEjB,UAAU,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsLhD,CAAC;AAkJF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,265 @@
1
+ import React, { useState, useRef, useEffect, useCallback } from 'react';
2
+ import { View, Text, TextInput, ScrollView, TouchableOpacity, ActivityIndicator, StyleSheet, Dimensions, KeyboardAvoidingView, Platform, } from 'react-native';
3
+ import { BotAPIClient, getErrorMessage, formatTimestamp, debounce, } from '../core';
4
+ export const ChatWidget = ({ jwtToken, firmId, botUrl, chatId = 1001, filingId, taxYear, height = 500, width = Dimensions.get('window').width, onError, onSuccess, }) => {
5
+ const [messages, setMessages] = useState([]);
6
+ const [input, setInput] = useState('');
7
+ const [loading, setLoading] = useState(false);
8
+ const [error, setError] = useState(null);
9
+ const scrollViewRef = useRef(null);
10
+ const clientRef = useRef(null);
11
+ // Initialize API client
12
+ useEffect(() => {
13
+ clientRef.current = new BotAPIClient(botUrl, jwtToken, firmId);
14
+ }, [botUrl, jwtToken, firmId]);
15
+ // Auto-scroll to bottom
16
+ const scrollToBottom = useCallback(() => {
17
+ scrollViewRef.current?.scrollToEnd({ animated: true });
18
+ }, []);
19
+ useEffect(() => {
20
+ scrollToBottom();
21
+ }, [messages, scrollToBottom]);
22
+ // Debounced send message
23
+ const sendMessage = useCallback(debounce(async (message) => {
24
+ if (!message.trim() || !clientRef.current)
25
+ return;
26
+ setLoading(true);
27
+ setError(null);
28
+ try {
29
+ // Add user message
30
+ const userMessage = {
31
+ role: 'user',
32
+ content: message,
33
+ timestamp: new Date().toISOString(),
34
+ };
35
+ setMessages((prev) => [...prev, userMessage]);
36
+ setInput('');
37
+ // Get bot response
38
+ const response = await clientRef.current.sendMessage(message, chatId, {
39
+ filing_id: filingId,
40
+ tax_year: taxYear,
41
+ });
42
+ // Add bot message
43
+ const botMessage = {
44
+ role: 'assistant',
45
+ content: response.reply,
46
+ toolCalls: response.toolCalls,
47
+ responseTimeMs: response.responseTimeMs,
48
+ timestamp: new Date().toISOString(),
49
+ };
50
+ setMessages((prev) => [...prev, botMessage]);
51
+ onSuccess?.(response);
52
+ }
53
+ catch (err) {
54
+ const errorMessage = getErrorMessage(err);
55
+ setError(errorMessage);
56
+ onError?.(err);
57
+ }
58
+ finally {
59
+ setLoading(false);
60
+ }
61
+ }, 300), [chatId, filingId, taxYear, onError, onSuccess]);
62
+ const handleSubmit = () => {
63
+ if (input.trim()) {
64
+ sendMessage(input);
65
+ }
66
+ };
67
+ return (<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={[styles.container, { height, width }]}>
68
+ {/* Messages Container */}
69
+ <ScrollView ref={scrollViewRef} style={styles.messagesContainer} contentContainerStyle={messages.length === 0 ? styles.emptyStateContainer : null} onContentSizeChange={scrollToBottom}>
70
+ {messages.length === 0 && (<View style={styles.emptyState}>
71
+ <Text style={styles.emptyStateText}>Start a conversation with Spirit Bot</Text>
72
+ </View>)}
73
+
74
+ {messages.map((msg, idx) => (<View key={idx} style={[
75
+ styles.message,
76
+ msg.role === 'user' ? styles.userMessage : styles.assistantMessage,
77
+ ]}>
78
+ <View style={[
79
+ styles.messageBubble,
80
+ msg.role === 'user' ? styles.userBubble : styles.assistantBubble,
81
+ ]}>
82
+ <Text style={[
83
+ styles.messageContent,
84
+ msg.role === 'user' ? styles.userText : styles.assistantText,
85
+ ]}>
86
+ {msg.content}
87
+ </Text>
88
+ </View>
89
+ {msg.responseTimeMs && (<Text style={[
90
+ styles.messageMeta,
91
+ msg.role === 'user' ? styles.userMeta : styles.assistantMeta,
92
+ ]}>
93
+ {msg.responseTimeMs}ms{msg.timestamp ? ` • ${formatTimestamp(msg.timestamp)}` : ''}
94
+ </Text>)}
95
+ </View>))}
96
+
97
+ {loading && (<View style={styles.message}>
98
+ <View style={styles.loadingBubble}>
99
+ <ActivityIndicator color="#3b82f6"/>
100
+ </View>
101
+ </View>)}
102
+ </ScrollView>
103
+
104
+ {/* Error Display */}
105
+ {error && (<View style={styles.errorBanner}>
106
+ <Text style={styles.errorText}>{error}</Text>
107
+ <TouchableOpacity onPress={() => setError(null)} style={styles.errorCloseButton}>
108
+ <Text style={styles.errorCloseText}>×</Text>
109
+ </TouchableOpacity>
110
+ </View>)}
111
+
112
+ {/* Input Form */}
113
+ <View style={styles.inputForm}>
114
+ <TextInput style={styles.chatInput} placeholder="Ask a question..." value={input} onChangeText={setInput} editable={!loading} placeholderTextColor="#9ca3af" maxLength={2000} multiline/>
115
+ <TouchableOpacity style={[styles.sendButton, (!input.trim() || loading) && styles.sendButtonDisabled]} onPress={handleSubmit} disabled={loading || !input.trim()}>
116
+ <Text style={styles.sendButtonText}>{loading ? '...' : '→'}</Text>
117
+ </TouchableOpacity>
118
+ </View>
119
+ </KeyboardAvoidingView>);
120
+ };
121
+ const styles = StyleSheet.create({
122
+ container: {
123
+ backgroundColor: '#ffffff',
124
+ borderRadius: 8,
125
+ overflow: 'hidden',
126
+ },
127
+ messagesContainer: {
128
+ flex: 1,
129
+ paddingHorizontal: 12,
130
+ paddingVertical: 12,
131
+ backgroundColor: '#fafafa',
132
+ },
133
+ emptyStateContainer: {
134
+ flexGrow: 1,
135
+ justifyContent: 'center',
136
+ },
137
+ emptyState: {
138
+ alignItems: 'center',
139
+ justifyContent: 'center',
140
+ paddingVertical: 32,
141
+ },
142
+ emptyStateText: {
143
+ color: '#9ca3af',
144
+ fontSize: 15,
145
+ textAlign: 'center',
146
+ },
147
+ message: {
148
+ marginBottom: 12,
149
+ display: 'flex',
150
+ },
151
+ userMessage: {
152
+ alignItems: 'flex-end',
153
+ },
154
+ assistantMessage: {
155
+ alignItems: 'flex-start',
156
+ },
157
+ messageBubble: {
158
+ maxWidth: '85%',
159
+ paddingHorizontal: 12,
160
+ paddingVertical: 8,
161
+ borderRadius: 16,
162
+ },
163
+ userBubble: {
164
+ backgroundColor: '#3b82f6',
165
+ borderBottomRightRadius: 4,
166
+ },
167
+ assistantBubble: {
168
+ backgroundColor: '#e5e7eb',
169
+ borderBottomLeftRadius: 4,
170
+ },
171
+ messageContent: {
172
+ fontSize: 14,
173
+ lineHeight: 18,
174
+ },
175
+ userText: {
176
+ color: '#ffffff',
177
+ },
178
+ assistantText: {
179
+ color: '#1f2937',
180
+ },
181
+ messageMeta: {
182
+ fontSize: 12,
183
+ marginTop: 4,
184
+ marginHorizontal: 12,
185
+ },
186
+ userMeta: {
187
+ color: '#9ca3af',
188
+ textAlign: 'right',
189
+ },
190
+ assistantMeta: {
191
+ color: '#9ca3af',
192
+ textAlign: 'left',
193
+ },
194
+ loadingBubble: {
195
+ paddingHorizontal: 12,
196
+ paddingVertical: 8,
197
+ backgroundColor: '#e5e7eb',
198
+ borderRadius: 16,
199
+ borderBottomLeftRadius: 4,
200
+ },
201
+ errorBanner: {
202
+ backgroundColor: '#fee2e2',
203
+ borderTopColor: '#fecaca',
204
+ borderTopWidth: 1,
205
+ paddingHorizontal: 12,
206
+ paddingVertical: 10,
207
+ flexDirection: 'row',
208
+ justifyContent: 'space-between',
209
+ alignItems: 'center',
210
+ },
211
+ errorText: {
212
+ color: '#7f1d1d',
213
+ fontSize: 13,
214
+ flex: 1,
215
+ marginRight: 8,
216
+ },
217
+ errorCloseButton: {
218
+ padding: 4,
219
+ },
220
+ errorCloseText: {
221
+ color: '#7f1d1d',
222
+ fontSize: 20,
223
+ fontWeight: '300',
224
+ },
225
+ inputForm: {
226
+ flexDirection: 'row',
227
+ paddingHorizontal: 12,
228
+ paddingVertical: 10,
229
+ borderTopColor: '#e5e7eb',
230
+ borderTopWidth: 1,
231
+ backgroundColor: '#ffffff',
232
+ gap: 8,
233
+ alignItems: 'flex-end',
234
+ },
235
+ chatInput: {
236
+ flex: 1,
237
+ paddingHorizontal: 12,
238
+ paddingVertical: 8,
239
+ borderColor: '#d1d5db',
240
+ borderWidth: 1,
241
+ borderRadius: 6,
242
+ fontSize: 14,
243
+ color: '#1f2937',
244
+ maxHeight: 100,
245
+ },
246
+ sendButton: {
247
+ paddingHorizontal: 14,
248
+ paddingVertical: 8,
249
+ backgroundColor: '#3b82f6',
250
+ borderRadius: 6,
251
+ justifyContent: 'center',
252
+ alignItems: 'center',
253
+ minWidth: 48,
254
+ },
255
+ sendButtonDisabled: {
256
+ backgroundColor: '#d1d5db',
257
+ },
258
+ sendButtonText: {
259
+ color: '#ffffff',
260
+ fontSize: 16,
261
+ fontWeight: '500',
262
+ },
263
+ });
264
+ export default ChatWidget;
265
+ //# sourceMappingURL=ChatWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWidget.js","sourceRoot":"","sources":["../../../src/native/ChatWidget.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { BotWidgetConfig } from '../core';
3
+ interface GreetingModalProps extends Omit<BotWidgetConfig, 'theme' | 'position'> {
4
+ onClose?: () => void;
5
+ onActionClick?: (action: any) => void;
6
+ autoClose?: boolean;
7
+ autoCloseDuration?: number;
8
+ }
9
+ export declare const GreetingModal: React.FC<GreetingModalProps>;
10
+ export default GreetingModal;
11
+ //# sourceMappingURL=GreetingModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GreetingModal.d.ts","sourceRoot":"","sources":["../../../src/native/GreetingModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAW3D,OAAO,EAGL,eAAe,EAGhB,MAAM,SAAS,CAAC;AAEjB,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,CAmJtD,CAAC;AAuHF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,228 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import { View, Text, Modal, TouchableOpacity, ScrollView, StyleSheet, Dimensions, ActivityIndicator, } from 'react-native';
3
+ import { BotAPIClient, getPriorityColor, getPriorityLabel, } from '../core';
4
+ export const GreetingModal = ({ jwtToken, firmId, botUrl, onClose, onActionClick, onError, autoClose = false, autoCloseDuration = 10000, }) => {
5
+ const [greeting, setGreeting] = useState(null);
6
+ const [loading, setLoading] = useState(true);
7
+ const [visible, setVisible] = useState(false);
8
+ const clientRef = useRef(null);
9
+ const autoCloseTimerRef = useRef(null);
10
+ // Initialize API client and fetch greeting
11
+ useEffect(() => {
12
+ const fetchGreeting = async () => {
13
+ try {
14
+ clientRef.current = new BotAPIClient(botUrl, jwtToken, firmId);
15
+ const response = await clientRef.current.getGreeting();
16
+ setGreeting(response);
17
+ setVisible(true);
18
+ // Auto-close if enabled
19
+ if (autoClose) {
20
+ autoCloseTimerRef.current = setTimeout(() => {
21
+ handleClose();
22
+ }, autoCloseDuration);
23
+ }
24
+ }
25
+ catch (error) {
26
+ onError?.(error);
27
+ setVisible(false);
28
+ }
29
+ finally {
30
+ setLoading(false);
31
+ }
32
+ };
33
+ fetchGreeting();
34
+ return () => {
35
+ if (autoCloseTimerRef.current) {
36
+ clearTimeout(autoCloseTimerRef.current);
37
+ }
38
+ };
39
+ }, [botUrl, jwtToken, firmId, onError, autoClose, autoCloseDuration]);
40
+ const handleClose = () => {
41
+ setVisible(false);
42
+ onClose?.();
43
+ };
44
+ const handleActionClick = (action) => {
45
+ onActionClick?.(action);
46
+ if (action.type === 'navigate') {
47
+ // Navigate to the target route
48
+ // This would typically use React Navigation
49
+ // Example: navigation.navigate('Filing', { filingId: action.target })
50
+ }
51
+ else if (action.type === 'chat') {
52
+ // Emit event to open chat with pre-filled message
53
+ // For RN, this could be done via event emitter or navigation params
54
+ }
55
+ else if (action.type === 'external') {
56
+ // Open external URL
57
+ // import { Linking } from 'react-native';
58
+ // Linking.openURL(action.target);
59
+ }
60
+ handleClose();
61
+ };
62
+ if (!visible || !greeting) {
63
+ return null;
64
+ }
65
+ const priorityColor = getPriorityColor(greeting.priority);
66
+ const priorityLabel = getPriorityLabel(greeting.priority);
67
+ return (<Modal visible={visible} transparent animationType="fade" onRequestClose={handleClose}>
68
+ <View style={styles.overlay}>
69
+ <View style={[styles.popup, { borderLeftColor: priorityColor }]}>
70
+ {/* Header */}
71
+ <View style={styles.header}>
72
+ <View style={[styles.priorityBadge, { backgroundColor: priorityColor }]}>
73
+ <Text style={styles.priorityLabel}>{priorityLabel}</Text>
74
+ </View>
75
+ <TouchableOpacity onPress={handleClose} style={styles.closeButton} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
76
+ <Text style={styles.closeButtonText}>×</Text>
77
+ </TouchableOpacity>
78
+ </View>
79
+
80
+ {/* Loading State */}
81
+ {loading && (<View style={styles.loadingState}>
82
+ <ActivityIndicator size="large" color="#3b82f6"/>
83
+ <Text style={styles.loadingText}>Loading greeting...</Text>
84
+ </View>)}
85
+
86
+ {/* Greeting Content */}
87
+ {!loading && (<ScrollView style={styles.contentWrapper}>
88
+ <View style={styles.content}>
89
+ <Text style={styles.greetingText}>{greeting.greeting}</Text>
90
+ </View>
91
+
92
+ {/* Actions */}
93
+ {greeting.actions && greeting.actions.length > 0 && (<View style={styles.actionsContainer}>
94
+ {greeting.actions.map((action, idx) => (<TouchableOpacity key={idx} style={styles.actionButton} onPress={() => handleActionClick(action)}>
95
+ <Text style={styles.actionLabel}>{action.label}</Text>
96
+ <Text style={styles.arrow}>→</Text>
97
+ </TouchableOpacity>))}
98
+ </View>)}
99
+
100
+ {/* Filing Context */}
101
+ {greeting.filing_context && (<View style={styles.filingContext}>
102
+ <Text style={styles.filingContextText}>
103
+ Filing: {greeting.filing_context.filing_id} • {greeting.filing_context.tax_year}
104
+ </Text>
105
+ </View>)}
106
+ </ScrollView>)}
107
+ </View>
108
+ </View>
109
+ </Modal>);
110
+ };
111
+ const styles = StyleSheet.create({
112
+ overlay: {
113
+ flex: 1,
114
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
115
+ justifyContent: 'flex-start',
116
+ paddingTop: 60,
117
+ paddingHorizontal: 12,
118
+ },
119
+ popup: {
120
+ backgroundColor: '#ffffff',
121
+ borderRadius: 12,
122
+ borderLeftWidth: 5,
123
+ overflow: 'hidden',
124
+ maxWidth: 420,
125
+ width: '100%',
126
+ shadowColor: '#000',
127
+ shadowOffset: { width: 0, height: 10 },
128
+ shadowOpacity: 0.16,
129
+ shadowRadius: 40,
130
+ elevation: 10,
131
+ },
132
+ header: {
133
+ flexDirection: 'row',
134
+ alignItems: 'center',
135
+ justifyContent: 'space-between',
136
+ paddingHorizontal: 12,
137
+ paddingVertical: 12,
138
+ borderBottomColor: '#e5e7eb',
139
+ borderBottomWidth: 1,
140
+ },
141
+ priorityBadge: {
142
+ paddingHorizontal: 12,
143
+ paddingVertical: 4,
144
+ borderRadius: 20,
145
+ },
146
+ priorityLabel: {
147
+ color: '#ffffff',
148
+ fontSize: 12,
149
+ fontWeight: '600',
150
+ textTransform: 'uppercase',
151
+ letterSpacing: 0.5,
152
+ },
153
+ closeButton: {
154
+ paddingHorizontal: 8,
155
+ paddingVertical: 8,
156
+ },
157
+ closeButtonText: {
158
+ color: '#9ca3af',
159
+ fontSize: 28,
160
+ lineHeight: 28,
161
+ },
162
+ contentWrapper: {
163
+ maxHeight: Dimensions.get('window').height * 0.6,
164
+ },
165
+ content: {
166
+ paddingHorizontal: 12,
167
+ paddingVertical: 12,
168
+ },
169
+ greetingText: {
170
+ fontSize: 15,
171
+ lineHeight: 22,
172
+ color: '#1f2937',
173
+ fontWeight: '500',
174
+ },
175
+ loadingState: {
176
+ paddingVertical: 32,
177
+ alignItems: 'center',
178
+ justifyContent: 'center',
179
+ gap: 12,
180
+ },
181
+ loadingText: {
182
+ color: '#6b7280',
183
+ fontSize: 14,
184
+ },
185
+ actionsContainer: {
186
+ paddingHorizontal: 12,
187
+ paddingVertical: 8,
188
+ borderTopColor: '#e5e7eb',
189
+ borderTopWidth: 1,
190
+ gap: 8,
191
+ },
192
+ actionButton: {
193
+ flexDirection: 'row',
194
+ justifyContent: 'space-between',
195
+ alignItems: 'center',
196
+ paddingHorizontal: 12,
197
+ paddingVertical: 10,
198
+ backgroundColor: '#f3f4f6',
199
+ borderColor: '#d1d5db',
200
+ borderWidth: 1,
201
+ borderRadius: 6,
202
+ },
203
+ actionLabel: {
204
+ color: '#1f2937',
205
+ fontSize: 14,
206
+ fontWeight: '500',
207
+ flex: 1,
208
+ },
209
+ arrow: {
210
+ fontSize: 16,
211
+ color: '#1f2937',
212
+ marginLeft: 8,
213
+ },
214
+ filingContext: {
215
+ paddingHorizontal: 12,
216
+ paddingVertical: 10,
217
+ backgroundColor: '#f9fafb',
218
+ borderTopColor: '#e5e7eb',
219
+ borderTopWidth: 1,
220
+ },
221
+ filingContextText: {
222
+ fontSize: 12,
223
+ color: '#6b7280',
224
+ lineHeight: 18,
225
+ },
226
+ });
227
+ export default GreetingModal;
228
+ //# sourceMappingURL=GreetingModal.js.map