@originallyus/feedback-rn-sdk 4.0.0-beta.6 → 4.0.0-beta.8

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.

Potentially problematic release.


This version of @originallyus/feedback-rn-sdk might be problematic. Click here for more details.

Files changed (56) hide show
  1. package/lib/module/AIAContentUsefulness.js +1 -1
  2. package/lib/module/AIAContentUsefulness.js.map +1 -1
  3. package/lib/module/AIAFeedback.js +8 -8
  4. package/lib/module/AIAFeedback.js.map +1 -1
  5. package/lib/module/AIAFeedbackForm.js.map +1 -1
  6. package/lib/module/AIAFeedbackSplash.js.map +1 -1
  7. package/lib/module/AIAFeedbackStyles.js.map +1 -1
  8. package/lib/module/AIAFeedbackSuccess.js.map +1 -1
  9. package/lib/module/component/ButtonSubmit.js +2 -2
  10. package/lib/module/component/ButtonSubmit.js.map +1 -1
  11. package/lib/module/component/Input.js +3 -3
  12. package/lib/module/component/Input.js.map +1 -1
  13. package/lib/module/component/MultiSelectButtons.js +5 -5
  14. package/lib/module/component/MultiSelectButtons.js.map +1 -1
  15. package/lib/module/component/Rating.js +4 -4
  16. package/lib/module/component/Rating.js.map +1 -1
  17. package/lib/module/component/RatingNumber.js +3 -3
  18. package/lib/module/component/RatingNumber.js.map +1 -1
  19. package/lib/module/component/Textarea.js +3 -3
  20. package/lib/module/component/Textarea.js.map +1 -1
  21. package/lib/module/component/YesNoButtons.js +2 -2
  22. package/lib/module/component/YesNoButtons.js.map +1 -1
  23. package/lib/module/index.js +8 -8
  24. package/lib/module/index.js.map +1 -1
  25. package/lib/module/service/feedbackService.js +1 -1
  26. package/lib/module/service/feedbackService.js.map +1 -1
  27. package/lib/module/utils/networking.js +3 -3
  28. package/lib/module/utils/networking.js.map +1 -1
  29. package/package.json +4 -4
  30. package/src/AIAContentUsefulness.tsx +0 -296
  31. package/src/AIAFeedback.tsx +0 -354
  32. package/src/AIAFeedbackForm.tsx +0 -267
  33. package/src/AIAFeedbackSplash.tsx +0 -49
  34. package/src/AIAFeedbackStyles.ts +0 -311
  35. package/src/AIAFeedbackSuccess.tsx +0 -67
  36. package/src/assets/CheckIcon.tsx +0 -18
  37. package/src/assets/CloseIcon.tsx +0 -18
  38. package/src/assets/ErrorIcon.tsx +0 -18
  39. package/src/assets/PlusIcon.tsx +0 -18
  40. package/src/assets/StarIcon.tsx +0 -18
  41. package/src/component/Button.tsx +0 -68
  42. package/src/component/ButtonSubmit.tsx +0 -335
  43. package/src/component/Input.tsx +0 -288
  44. package/src/component/MultiSelectButtons.tsx +0 -272
  45. package/src/component/README.md +0 -215
  46. package/src/component/READMEVI.md +0 -192
  47. package/src/component/Rating.tsx +0 -248
  48. package/src/component/RatingNumber.tsx +0 -421
  49. package/src/component/Textarea.tsx +0 -282
  50. package/src/component/YesNoButtons.tsx +0 -236
  51. package/src/index.tsx +0 -33
  52. package/src/service/feedbackService.ts +0 -108
  53. package/src/utils/common.ts +0 -241
  54. package/src/utils/constants.ts +0 -60
  55. package/src/utils/index.ts +0 -167
  56. package/src/utils/networking.ts +0 -134
@@ -1,354 +0,0 @@
1
- import {feedbackService} from '@service/feedbackService'
2
- import {forwardRef, useCallback, useEffect, useImperativeHandle, useState} from 'react'
3
- import {Linking, Modal, Platform, StyleSheet, TouchableOpacity, View} from 'react-native'
4
- import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
5
- import Animated, {Easing, FadeIn, FadeOut, LinearTransition, SlideInDown, SlideOutDown} from 'react-native-reanimated'
6
- import {SafeAreaProvider, useSafeAreaInsets} from 'react-native-safe-area-context'
7
- import AIAFeedbackForm from '@/AIAFeedbackForm'
8
- import AIAFeedbackSplash from '@/AIAFeedbackSplash'
9
- import {feedbackStyles} from '@/AIAFeedbackStyles'
10
- import AIAFeedbackSuccess from '@/AIAFeedbackSuccess'
11
- import * as f from '@/utils/common'
12
- import {type InitOptions, OUS_VARS} from '@/utils/constants'
13
- import CloseIcon from '@/assets/CloseIcon'
14
-
15
- export interface AIAFeedbackProps extends InitOptions {
16
- onClose?: () => void
17
- onSubmit?: (res: any) => void
18
- }
19
-
20
- export interface AIAFeedbackRef {
21
- show: (slug?: string, internalOptions?: {forceModal?: boolean; initialData?: any}) => void
22
- hide: () => void
23
- }
24
-
25
- const AIAFeedback = forwardRef<AIAFeedbackRef, AIAFeedbackProps>((props, ref) => {
26
- const {debug, metadata, onClose, onSubmit} = props
27
- const insets = useSafeAreaInsets()
28
- const [visible, setVisible] = useState(false)
29
- const [loading, setLoading] = useState(false)
30
- const [formData, setFormData] = useState<any>(null)
31
- const [submissionError, setSubmissionError] = useState<string | null>(null)
32
- const [isSubmitting, setIsSubmitting] = useState(false)
33
- const [didSubmit, setDidSubmit] = useState(false)
34
- const [submitRes, setSubmitRes] = useState<any>(null)
35
- const [showSplash, setShowSplash] = useState(false)
36
- const [step, setStep] = useState<'PROMPT' | 'FORM'>('FORM')
37
-
38
- // Form internal state
39
- const [rating, setRating] = useState<number>(0)
40
- const [freeText, setFreeText] = useState('')
41
- const [selectedOptions, setSelectedOptions] = useState<string[]>([])
42
-
43
- const isSplash = showSplash && !didSubmit
44
- const intrusive = !isSplash && !!formData?.instrusive_style
45
- const isNPSFlow = formData?.type === 'nps' || formData?.type === 'effort' || formData?.type === 'ces'
46
- const showSecondary = (!isNPSFlow && rating > 0 && formData?.show_comment) || (isNPSFlow && formData?.show_comment)
47
- const shouldCenter = intrusive && (didSubmit || !showSecondary)
48
-
49
- const resetForm = useCallback(() => {
50
- setRating(0)
51
- setFreeText('')
52
- setSelectedOptions([])
53
- setDidSubmit(false)
54
- setSubmitRes(null)
55
- setStep('FORM')
56
- setSubmissionError(null)
57
- }, [])
58
-
59
- useEffect(() => {
60
- // Initialize device UUID if not already set
61
- if (!OUS_VARS.uuid) {
62
- f.getUniqueID().then(id => {
63
- if (id) OUS_VARS.uuid = id
64
- })
65
- }
66
- }, [])
67
-
68
- const hide = useCallback(() => {
69
- setVisible(false)
70
- resetForm()
71
- setShowSplash(false)
72
- onClose?.()
73
- }, [onClose, resetForm])
74
-
75
- const show = useCallback(
76
- (slug?: string, internalOptions?: {forceModal?: boolean; initialData?: any}) => {
77
- const targetSlug = slug || props.formSlug
78
- // Check if any inline component wants to handle this slug
79
- // If forceModal is true, we bypass this check
80
- if (!internalOptions?.forceModal) {
81
- const handled = feedbackService.emitShow(targetSlug || '')
82
- if (handled) return
83
- }
84
-
85
- const options: InitOptions = {
86
- ...props,
87
- formSlug: targetSlug,
88
- }
89
-
90
- setLoading(true)
91
- setFormData(null)
92
- setSubmissionError(null)
93
-
94
- if (internalOptions?.initialData) {
95
- const res = internalOptions.initialData
96
- if (debug) console.log('Feedback SDK: Showing with initial data', res)
97
- setLoading(false)
98
- setFormData(res)
99
- setStep('FORM')
100
- if (res.splash_screen_enabled === 1) {
101
- setShowSplash(true)
102
- }
103
- setVisible(true)
104
- return
105
- }
106
-
107
- if (debug) console.log('Feedback SDK: Requesting form', targetSlug)
108
- feedbackService.requestForm(options, (res: any) => {
109
- if (debug) console.log('Feedback SDK: Form response', res)
110
- setLoading(false)
111
- if (res && res.type) {
112
- if (res.type === 'external_link' && res.button_url) {
113
- Linking.openURL(res.button_url)
114
- setVisible(false)
115
- return
116
- }
117
- if (res.type === 'content_usefulness') {
118
- setStep('PROMPT')
119
- } else {
120
- setStep('FORM')
121
- }
122
- setFormData(res)
123
- if (res.splash_screen_enabled === 1) {
124
- setShowSplash(true)
125
- }
126
- setVisible(true)
127
- } else {
128
- console.warn('Feedback SDK: Failed to load form or invalid response', res)
129
- setVisible(false)
130
- }
131
- })
132
- },
133
- [props, debug],
134
- )
135
- useEffect(() => {
136
- const unsubscribe = feedbackService.onShow((s, opts) => {
137
- if (opts?.forceModal) {
138
- show(s, {forceModal: true, initialData: opts.initialData})
139
- return true
140
- }
141
- return false
142
- })
143
- return unsubscribe
144
- }, [show])
145
-
146
- useImperativeHandle(ref, () => ({
147
- show,
148
- hide,
149
- }))
150
-
151
- const handlePromptSelect = useCallback(
152
- async (value: 'yes' | 'no') => {
153
- setLoading(true)
154
- try {
155
- const selectionData = {
156
- slug: formData.slug,
157
- debug: !!debug,
158
- event_tag: formData.event_tag || '',
159
- metadata: metadata || {},
160
- rating: value === 'yes' ? 2 : 1,
161
- request_id: formData.id || '',
162
- }
163
- const res = await feedbackService.submitSelection(selectionData, props)
164
- setLoading(false)
165
- if (res && !res.error) {
166
- setFormData(res)
167
- if (res.type === 'success' || !res.type) {
168
- setSubmitRes(res)
169
- setDidSubmit(true)
170
- } else {
171
- setStep('FORM')
172
- if (value === 'yes') setRating(5)
173
- else setRating(1)
174
- }
175
- }
176
- } catch (error) {
177
- console.error('Feedback SDK: Prompt select failed', error)
178
- setLoading(false)
179
- }
180
- },
181
- [formData, debug, metadata, props],
182
- )
183
-
184
- const handleSubmit = useCallback(async () => {
185
- if (isSubmitting) return
186
- setIsSubmitting(true)
187
-
188
- const data = {
189
- slug: formData.slug,
190
- debug: !!debug,
191
- event_tag: formData.event_tag || '',
192
- metadata: metadata || {},
193
- request_id: formData.id,
194
- rating: rating,
195
- selected_options: selectedOptions.join(','),
196
- free_text: freeText,
197
- }
198
-
199
- try {
200
- setSubmissionError(null)
201
- const res = await feedbackService.submitForm(data, props)
202
- if (formData.type === 'external' && formData.url) {
203
- Linking.openURL(formData.url)
204
- }
205
- setSubmitRes(res)
206
- setDidSubmit(true)
207
- onSubmit?.(res)
208
- } catch (error: any) {
209
- console.log('Feedback SDK: Submit failed', error)
210
- setSubmissionError(error?.message || 'Submit failed. Please try again.')
211
- } finally {
212
- setIsSubmitting(false)
213
- }
214
- }, [formData, debug, metadata, rating, selectedOptions, freeText, isSubmitting, props, onSubmit])
215
-
216
- const getThemeColor = (key: string, fallback: string) => {
217
- return formData?.theme?.[key] || fallback
218
- }
219
-
220
- const isTabletNonIntrusive = f.isTablet && !intrusive && !isSplash && !loading
221
-
222
- const feedbackContent = (
223
- <Animated.View
224
- entering={FadeIn.duration(300)}
225
- exiting={FadeOut.duration(200)}
226
- style={[
227
- styles.overlay,
228
- intrusive && !f.isTablet && styles.intrusiveOverlay,
229
- isSplash && styles.splashOverlay,
230
- loading && styles.splashOverlay,
231
- f.isTablet && styles.tabletOverlay,
232
- isTabletNonIntrusive && styles.nonBlockingOverlay,
233
- ]}
234
- pointerEvents={isTabletNonIntrusive ? 'box-none' : 'auto'}
235
- >
236
- <>
237
- {!intrusive && !isSplash && !isTabletNonIntrusive && (
238
- <TouchableOpacity style={styles.dismissArea} activeOpacity={1} onPress={hide} />
239
- )}
240
-
241
- <Animated.View
242
- entering={isSplash ? FadeIn.duration(400) : SlideInDown.duration(400)}
243
- exiting={isSplash ? FadeOut.duration(300) : SlideOutDown.duration(300)}
244
- layout={LinearTransition.duration(400).easing(Easing.out(Easing.cubic))}
245
- style={[
246
- styles.modalContent,
247
- isSplash && styles.splashContent,
248
- isSplash && f.isTablet && styles.splashTabletContent,
249
- intrusive && !f.isTablet && styles.intrusiveContent,
250
- f.isTablet && !isSplash && (intrusive ? styles.tabletIntrusive : styles.tabletNonIntrusive),
251
- ]}
252
- >
253
- {isSplash ? (
254
- <View style={styles.splashInner}>
255
- <AIAFeedbackSplash
256
- formData={formData}
257
- getThemeColor={getThemeColor}
258
- onSkip={hide}
259
- onProceed={() => setShowSplash(false)}
260
- />
261
- </View>
262
- ) : (
263
- <View style={[styles.safeArea, isTabletNonIntrusive && styles.autoHeightReset]}>
264
- <View style={styles.header}>
265
- {Platform.OS === 'ios' && insets.top > 0 && intrusive && (
266
- <View style={{height: insets.top}} />
267
- )}
268
-
269
- <View style={styles.headerRow}>
270
- {!intrusive && !f.isTablet && <View style={styles.handle} />}
271
- {(intrusive || f.isTablet) && (
272
- <TouchableOpacity
273
- onPress={hide}
274
- style={[styles.closeBtn, intrusive && styles.intrusiveCloseBtn]}
275
- >
276
- <CloseIcon />
277
- </TouchableOpacity>
278
- )}
279
- </View>
280
- </View>
281
- <KeyboardAwareScrollView
282
- bottomOffset={32}
283
- style={isTabletNonIntrusive ? styles.autoHeightReset : undefined}
284
- contentContainerStyle={[
285
- styles.scrollContent,
286
- isTabletNonIntrusive && styles.autoHeightReset,
287
- shouldCenter && styles.centeredScrollContent,
288
- ]}
289
- showsVerticalScrollIndicator={false}
290
- >
291
- <View
292
- key={didSubmit ? 'success' : 'form'}
293
- style={[
294
- styles.scrollContentInner,
295
- isTabletNonIntrusive && styles.autoHeightFlexReset,
296
- ]}
297
- >
298
- {didSubmit ? (
299
- <AIAFeedbackSuccess
300
- submitRes={submitRes}
301
- shouldCenter={shouldCenter}
302
- getThemeColor={getThemeColor}
303
- onClose={hide}
304
- autoHeight={isTabletNonIntrusive}
305
- />
306
- ) : (
307
- <AIAFeedbackForm
308
- formData={formData}
309
- rating={rating}
310
- freeText={freeText}
311
- selectedOptions={selectedOptions}
312
- step={step}
313
- isNPSFlow={isNPSFlow}
314
- showSecondary={showSecondary}
315
- onRate={setRating}
316
- onChangeFreeText={setFreeText}
317
- onChangeSelectedOptions={setSelectedOptions}
318
- getThemeColor={getThemeColor}
319
- onPromptSelect={handlePromptSelect}
320
- onSubmit={handleSubmit}
321
- isSubmitting={isSubmitting}
322
- submissionError={submissionError}
323
- autoHeight={isTabletNonIntrusive}
324
- />
325
- )}
326
- </View>
327
- </KeyboardAwareScrollView>
328
- </View>
329
- )}
330
- </Animated.View>
331
- </>
332
- </Animated.View>
333
- )
334
-
335
- if (isTabletNonIntrusive) {
336
- return (
337
- <View style={StyleSheet.absoluteFill} pointerEvents="box-none">
338
- {visible && feedbackContent}
339
- </View>
340
- )
341
- }
342
-
343
- return (
344
- <SafeAreaProvider>
345
- <Modal visible={visible} transparent={true} animationType="none" onRequestClose={hide}>
346
- {feedbackContent}
347
- </Modal>
348
- </SafeAreaProvider>
349
- )
350
- })
351
-
352
- export default AIAFeedback
353
-
354
- const styles = feedbackStyles
@@ -1,267 +0,0 @@
1
- import React from 'react'
2
- import {Image, Text, View} from 'react-native'
3
- import {feedbackStyles as styles} from './AIAFeedbackStyles'
4
- import ErrorIcon from './assets/ErrorIcon'
5
- import ButtonSubmit from './component/ButtonSubmit'
6
- import MultiSelectButtons from './component/MultiSelectButtons'
7
- import Rating from './component/Rating'
8
- import RatingNumber from './component/RatingNumber'
9
- import Textarea from './component/Textarea'
10
- import YesNoButtons from './component/YesNoButtons'
11
- import * as f from './utils/common'
12
- import {ERROR_COLOR} from './utils/constants'
13
-
14
- interface Props {
15
- formData: any
16
- rating: number
17
- freeText: string
18
- selectedOptions: string[]
19
- step: 'PROMPT' | 'FORM'
20
- isNPSFlow: boolean
21
- showSecondary: boolean
22
- isSubmitting: boolean
23
- submissionError: string | null
24
- autoHeight?: boolean
25
- onRate: (value: number) => void
26
- onChangeFreeText: (value: string) => void
27
- onChangeSelectedOptions: (value: string[]) => void
28
- onSubmit: () => void
29
- getThemeColor: (key: string, fallback: string) => string
30
- onPromptSelect: (value: 'yes' | 'no') => void
31
- }
32
-
33
- const AIAFeedbackForm: React.FC<Props> = ({
34
- formData,
35
- rating,
36
- freeText,
37
- selectedOptions,
38
- step,
39
- isNPSFlow,
40
- showSecondary,
41
- isSubmitting,
42
- submissionError,
43
- onRate,
44
- onChangeFreeText,
45
- onChangeSelectedOptions,
46
- onSubmit,
47
- getThemeColor,
48
- onPromptSelect,
49
- autoHeight,
50
- }) => {
51
- if (!formData) return null
52
-
53
- const appWidth = f.getAppWidth(true)
54
- const align: any = formData.alignment === 'left' ? 'flex-start' : 'center'
55
- const textAlign: any = formData.alignment === 'left' ? 'left' : 'center'
56
- const titleFont = getThemeColor('title_font', '')
57
- const questionFont = getThemeColor('question_font', '')
58
- const textareaFont = getThemeColor('textarea_font', '')
59
-
60
- const renderPrompt = () => (
61
- <YesNoButtons
62
- question={formData.question}
63
- value={null}
64
- yesLabel={formData.positive_feedback_button || 'Yes'}
65
- noLabel={formData.negative_feedback_button || 'No'}
66
- onSelect={onPromptSelect}
67
- appWidth={appWidth}
68
- selectedVariant="secondary"
69
- questionStyle={{
70
- color: getThemeColor('question_color', '#14181C'),
71
- textAlign,
72
- fontFamily: questionFont || undefined,
73
- }}
74
- />
75
- )
76
-
77
- const renderSatisfaction = () => (
78
- <Rating
79
- title={formData.title}
80
- question={formData.question}
81
- value={rating}
82
- onRate={onRate}
83
- rating_max={formData.rating_max || 5}
84
- titleStyle={{
85
- color: getThemeColor('title_color', '#14181C'),
86
- textAlign,
87
- fontFamily: titleFont || undefined,
88
- }}
89
- questionStyle={{
90
- color: getThemeColor('question_color', '#14181C'),
91
- textAlign,
92
- fontFamily: questionFont || undefined,
93
- }}
94
- normalStarColor={getThemeColor('normal_star_color', '#D0D0D0')}
95
- selectedStarColor={getThemeColor('selected_star_color', '#F7C926')}
96
- style={styles.satisfactionRating}
97
- />
98
- )
99
-
100
- const renderNPS = () => (
101
- <View style={[styles.section, {alignItems: align}]}>
102
- <Text
103
- style={[
104
- styles.title,
105
- // {color: getThemeColor('title_color', '#082065'), textAlign, fontFamily: titleFont},
106
- ]}
107
- >
108
- {formData.title}
109
- </Text>
110
- <RatingNumber
111
- numStar={rating}
112
- handlePressRating={onRate}
113
- rating_min={formData.rating_min || 0}
114
- rating_max={formData.rating_max || 10}
115
- scale_label_left={formData.scale_label_left}
116
- scale_label_right={formData.scale_label_right}
117
- scale_label_color={getThemeColor('scale_label_color', '#858B91')}
118
- scale_label_font={getThemeColor('scale_label_font', '')}
119
- appWidth={appWidth}
120
- compact={false}
121
- label={formData.question}
122
- />
123
- </View>
124
- )
125
-
126
- const renderPoll = () => (
127
- <View style={styles.section}>
128
- <Text style={[styles.title, {color: getThemeColor('title_color', '#14181C'), fontFamily: titleFont}]}>
129
- {formData.title}
130
- </Text>
131
-
132
- {formData.type === 'poll' && formData.options && (
133
- <MultiSelectButtons
134
- question={formData.instruction}
135
- options={formData.options.map((o: any) => ({
136
- label: o.title || o.label || String(o),
137
- value: o.slug || o.value || String(o),
138
- }))}
139
- value={selectedOptions}
140
- onSelect={onChangeSelectedOptions}
141
- appWidth={appWidth}
142
- />
143
- )}
144
- {(formData.type === 'comment' || (formData.type === 'poll' && formData.show_comment)) && (
145
- <Textarea
146
- value={freeText}
147
- onChangeText={onChangeFreeText}
148
- placeholder={formData.comment_placeholder}
149
- label={formData.question}
150
- appWidth={appWidth}
151
- maxLength={formData.comment_max_length || 150}
152
- fontFamily={textareaFont}
153
- style={formData.type === 'poll' ? styles.mt16 : undefined}
154
- note={formData.fineprint}
155
- />
156
- )}
157
- </View>
158
- )
159
-
160
- const renderExternal = () => (
161
- <View style={[styles.section, {alignItems: align}]}>
162
- {formData.image_file_url && (
163
- <Image source={{uri: formData.image_file_url}} style={styles.externalIcon} resizeMode="contain" />
164
- )}
165
- <Text
166
- style={[
167
- styles.title,
168
- {color: getThemeColor('title_color', '#14181C'), textAlign, fontFamily: titleFont},
169
- ]}
170
- >
171
- {formData.title}
172
- </Text>
173
- </View>
174
- )
175
-
176
- const renderSecondary = () => {
177
- if (!showSecondary) return null
178
-
179
- return (
180
- <View style={[styles.secondarySection, autoHeight && styles.autoHeightReset, {alignItems: align}]}>
181
- {formData.type === 'satisfaction' && formData.options && formData.options.length > 0 && (
182
- <>
183
- <View style={styles.divider} />
184
-
185
- <MultiSelectButtons
186
- question={rating === 5 ? formData.instruction_5_star : formData.instruction}
187
- options={formData.options.map((o: any) => ({
188
- label: o.title || o.label || String(o),
189
- value: o.slug || o.value || String(o),
190
- }))}
191
- value={selectedOptions}
192
- onSelect={onChangeSelectedOptions}
193
- appWidth={appWidth}
194
- />
195
- </>
196
- )}
197
-
198
- <Textarea
199
- value={freeText}
200
- onChangeText={onChangeFreeText}
201
- placeholder={
202
- formData.type === 'satisfaction' && rating === 5
203
- ? formData.comment_placeholder_5_star
204
- : formData.comment_placeholder
205
- }
206
- label={formData.secondary_question || formData.comment_label || ''}
207
- appWidth={appWidth}
208
- maxLength={formData.comment_max_length || 150}
209
- fontFamily={textareaFont}
210
- style={styles.mt16}
211
- note={formData.fineprint}
212
- />
213
- </View>
214
- )
215
- }
216
-
217
- return (
218
- <View style={[styles.formRoot, autoHeight && styles.autoHeightFlexReset]}>
219
- <View
220
- style={[
221
- styles.formContent,
222
- autoHeight && styles.autoHeightReset,
223
- !showSecondary && formData.type !== 'poll' && styles.centeredContent,
224
- ]}
225
- >
226
- {step === 'PROMPT' && renderPrompt()}
227
-
228
- {step === 'FORM' && (
229
- <>
230
- {formData.type === 'satisfaction' && renderSatisfaction()}
231
- {isNPSFlow && renderNPS()}
232
- {(formData.type === 'poll' || formData.type === 'comment') && renderPoll()}
233
- {formData.type === 'external' && renderExternal()}
234
- {renderSecondary()}
235
- </>
236
- )}
237
- </View>
238
-
239
- <View style={[styles.submitSection, autoHeight && styles.autoHeightMargin]}>
240
- {submissionError && (
241
- <View style={[styles.errorWrap, styles.mb12]}>
242
- <ErrorIcon size={20} color={ERROR_COLOR} />
243
- <Text style={[styles.error, {color: ERROR_COLOR}]}>{submissionError}</Text>
244
- </View>
245
- )}
246
-
247
- {(rating > 0 ||
248
- formData.type === 'comment' ||
249
- formData.type === 'external' ||
250
- (formData.type === 'poll' && selectedOptions.length > 0)) && (
251
- <ButtonSubmit
252
- title={formData.button_text || 'Submit'}
253
- onPress={onSubmit}
254
- loading={isSubmitting}
255
- appWidth={appWidth}
256
- containerStyle={styles.mt24}
257
- backgroundColor={getThemeColor('button_bg_color', '#D31145')}
258
- textColor={getThemeColor('button_text_color', '#FFF')}
259
- fontFamily={getThemeColor('button_font', '')}
260
- />
261
- )}
262
- </View>
263
- </View>
264
- )
265
- }
266
-
267
- export default AIAFeedbackForm
@@ -1,49 +0,0 @@
1
- import React from 'react'
2
- import {Text, TouchableOpacity, View} from 'react-native'
3
- import ButtonSubmit from './component/ButtonSubmit'
4
- import * as f from './utils/common'
5
- import {feedbackStyles as styles} from './AIAFeedbackStyles'
6
-
7
- interface Props {
8
- formData: any
9
- getThemeColor: (key: string, fallback: string) => string
10
- onSkip: () => void
11
- onProceed: () => void
12
- }
13
-
14
- const AIAFeedbackSplash: React.FC<Props> = ({formData, getThemeColor, onSkip, onProceed}) => {
15
- if (!formData) return null
16
-
17
- const textAlign: any = formData.alignment === 'left' ? 'left' : 'center'
18
- const btnBg = getThemeColor('button_bg_color', '#D31145')
19
- const btnText = getThemeColor('button_text_color', '#FFFFFF')
20
- const titleColor = getThemeColor('title_color', '#082065')
21
- const questionColor = getThemeColor('question_color', '#082065')
22
- const titleFont = getThemeColor('title_font', '')
23
- const questionFont = getThemeColor('question_font', '')
24
-
25
- return (
26
- <View style={styles.splashContainer}>
27
- <Text style={[styles.splashTitle, {color: titleColor, textAlign, fontFamily: titleFont}]}>
28
- {formData.splash_screen_title}
29
- </Text>
30
- <Text style={[styles.splashQuestion, {color: questionColor, textAlign, fontFamily: questionFont}]}>
31
- {formData.splash_screen_question}
32
- </Text>
33
-
34
- <ButtonSubmit
35
- title={formData.splash_screen_button_proceed || "Yes, Let's go!"}
36
- onPress={onProceed}
37
- appWidth={f.getAppWidth(true)}
38
- backgroundColor={btnBg}
39
- textColor={btnText}
40
- containerStyle={styles.mt24}
41
- />
42
- <TouchableOpacity onPress={onSkip} style={styles.skipBtn}>
43
- <Text style={styles.skipBtnText}>{formData.splash_screen_button_skip || 'Another time'}</Text>
44
- </TouchableOpacity>
45
- </View>
46
- )
47
- }
48
-
49
- export default AIAFeedbackSplash