react-native-seel-widget 0.1.0 → 0.1.1

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 (39) hide show
  1. package/package.json +1 -1
  2. package/src/assets/images/accredited.png +0 -0
  3. package/src/assets/images/background_image.jpg +0 -0
  4. package/src/assets/images/button_close.png +0 -0
  5. package/src/assets/images/button_close_background.png +0 -0
  6. package/src/assets/images/checkbox_normal.png +0 -0
  7. package/src/assets/images/checkbox_selected.png +0 -0
  8. package/src/assets/images/close_white.png +0 -0
  9. package/src/assets/images/ic_launcher.png +0 -0
  10. package/src/assets/images/icon_arrow_left.png +0 -0
  11. package/src/assets/images/icon_bg_select.png +0 -0
  12. package/src/assets/images/icon_check_selected_black.png +0 -0
  13. package/src/assets/images/icon_select.png +0 -0
  14. package/src/assets/images/info_black.png +0 -0
  15. package/src/assets/images/seel_icon.png +0 -0
  16. package/src/assets/images/seel_logo.png +0 -0
  17. package/src/assets/images/seel_word.png +0 -0
  18. package/src/assets/images/tick_small_minor.png +0 -0
  19. package/src/constants/key_value.ts +48 -0
  20. package/src/constants/network_request_statue_enum.ts +13 -0
  21. package/src/core/SeelWidgetSDK.ts +103 -0
  22. package/src/dto/EventsRequest.ts +71 -0
  23. package/src/dto/EventsResponse.ts +13 -0
  24. package/src/dto/IEvents.ts +51 -0
  25. package/src/dto/IQuotes.ts +36 -0
  26. package/src/dto/IQuotesRequest.ts +220 -0
  27. package/src/dto/IQuotesResponse.ts +111 -0
  28. package/src/network/request.ts +214 -0
  29. package/src/ui/coverage-info-footer.tsx +186 -0
  30. package/src/ui/gradient-animation-text.tsx +185 -0
  31. package/src/ui/gradient-animation-view.tsx +150 -0
  32. package/src/ui/index.ts +4 -0
  33. package/src/ui/seel-wfp-info-view.tsx +351 -0
  34. package/src/ui/seel-wfp-title-view.tsx +388 -0
  35. package/src/ui/seel-wfp-widget.tsx +270 -0
  36. package/src/utils/format_util.ts +117 -0
  37. package/src/utils/http_util.ts +30 -0
  38. package/src/utils/storage_util.ts +42 -0
  39. package/src/utils/uuid.ts +18 -0
@@ -0,0 +1,150 @@
1
+ import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
2
+ import { Animated, StyleSheet, View } from 'react-native';
3
+ import type { ViewStyle } from 'react-native';
4
+
5
+ export interface GradientAnimationViewProps {
6
+ /**
7
+ * Custom container style
8
+ */
9
+ containerStyle?: ViewStyle;
10
+ /**
11
+ * Initial visibility state (default: false)
12
+ */
13
+ initialVisible?: boolean;
14
+ /**
15
+ * Animation duration in milliseconds (default: 300)
16
+ */
17
+ animationDuration?: number;
18
+ }
19
+
20
+ export interface GradientAnimationViewRef {
21
+ /**
22
+ * Show the content with gradient animation
23
+ */
24
+ show: () => void;
25
+ /**
26
+ * Hide the content with gradient animation
27
+ */
28
+ hide: () => void;
29
+ /**
30
+ * Toggle visibility
31
+ */
32
+ toggle: () => void;
33
+ }
34
+
35
+ const GradientAnimationView = forwardRef<
36
+ GradientAnimationViewRef,
37
+ GradientAnimationViewProps
38
+ >(
39
+ (
40
+ { containerStyle, initialVisible = false, animationDuration = 400 },
41
+ ref
42
+ ) => {
43
+ const [visible, setVisible] = useState(initialVisible);
44
+ // Initialize gradient width: 0 = visible, large value = hidden
45
+ const gradientWidth = useRef(
46
+ new Animated.Value(initialVisible ? 0 : 1000)
47
+ ).current;
48
+
49
+ useImperativeHandle(ref, () => ({
50
+ show: () => {
51
+ setVisible(true);
52
+ Animated.timing(gradientWidth, {
53
+ toValue: 0,
54
+ duration: animationDuration,
55
+ useNativeDriver: false,
56
+ }).start();
57
+ },
58
+ hide: () => {
59
+ Animated.timing(gradientWidth, {
60
+ toValue: 1000, // Large value to cover the content
61
+ duration: animationDuration,
62
+ useNativeDriver: false,
63
+ }).start(() => {
64
+ setVisible(false);
65
+ });
66
+ },
67
+ toggle: () => {
68
+ if (visible) {
69
+ // Hide
70
+ Animated.timing(gradientWidth, {
71
+ toValue: 1000,
72
+ duration: animationDuration,
73
+ useNativeDriver: false,
74
+ }).start(() => {
75
+ setVisible(false);
76
+ });
77
+ } else {
78
+ // Show
79
+ setVisible(true);
80
+ Animated.timing(gradientWidth, {
81
+ toValue: 0,
82
+ duration: animationDuration,
83
+ useNativeDriver: false,
84
+ }).start();
85
+ }
86
+ },
87
+ }));
88
+
89
+ if (!visible) {
90
+ return null;
91
+ }
92
+
93
+ return (
94
+ <View style={[styles.container, containerStyle]}>
95
+ <View style={styles.contentContainer}>
96
+ {/* Gradient mask layer - from left to right */}
97
+ <Animated.View
98
+ style={[
99
+ styles.gradientMask,
100
+ {
101
+ width: gradientWidth,
102
+ },
103
+ ]}
104
+ pointerEvents="none"
105
+ >
106
+ {/* Create gradient effect: from transparent to white */}
107
+ <View style={styles.gradientOverlay}>
108
+ <View style={styles.gradientLeft} />
109
+ <View style={styles.gradientRight} />
110
+ </View>
111
+ </Animated.View>
112
+ </View>
113
+ </View>
114
+ );
115
+ }
116
+ );
117
+
118
+ const styles = StyleSheet.create({
119
+ container: {
120
+ overflow: 'hidden',
121
+ },
122
+ contentContainer: {
123
+ position: 'relative',
124
+ overflow: 'hidden',
125
+ },
126
+ gradientMask: {
127
+ position: 'absolute',
128
+ top: 0,
129
+ left: 0,
130
+ bottom: 0,
131
+ height: '100%',
132
+ overflow: 'hidden',
133
+ },
134
+ gradientOverlay: {
135
+ flex: 1,
136
+ flexDirection: 'row',
137
+ width: '100%',
138
+ height: '100%',
139
+ },
140
+ gradientLeft: {
141
+ flex: 1,
142
+ backgroundColor: 'rgba(255, 255, 255, 0)',
143
+ },
144
+ gradientRight: {
145
+ flex: 1,
146
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
147
+ },
148
+ });
149
+
150
+ export default GradientAnimationView;
@@ -0,0 +1,4 @@
1
+ export * from './coverage-info-footer';
2
+ export * from './seel-wfp-info-view';
3
+ export * from './seel-wfp-title-view';
4
+ export * from './seel-wfp-widget';
@@ -0,0 +1,351 @@
1
+ import {
2
+ Image,
3
+ ImageBackground,
4
+ Platform,
5
+ ScrollView,
6
+ StyleSheet,
7
+ Text,
8
+ TouchableOpacity,
9
+ View,
10
+ useWindowDimensions,
11
+ } from 'react-native';
12
+
13
+ import CoverageInfoFooter from './coverage-info-footer';
14
+ import KeyValue from '../constants/key_value';
15
+
16
+ export type Domain = '' | 'US' | 'EU';
17
+
18
+ interface SeelWFPInfoViewProps {
19
+ domain: Domain;
20
+ widgetTitle: string;
21
+ termsUrl: string;
22
+ privacyPolicyUrl: string;
23
+ dictionary: any;
24
+ onClickClose: () => void;
25
+ onChangeOptedInValue: (value: boolean) => void;
26
+ }
27
+
28
+ export default function SeelWFPInfoView({
29
+ domain = '',
30
+ widgetTitle = '',
31
+ termsUrl = '',
32
+ privacyPolicyUrl = '',
33
+ dictionary = {},
34
+ onClickClose = () => {},
35
+ onChangeOptedInValue = (_: boolean) => {},
36
+ }: SeelWFPInfoViewProps) {
37
+ const spacing = 12;
38
+ const margin = 6;
39
+ const marginTop = 15;
40
+
41
+ const windowWidth = useWindowDimensions().width;
42
+ const imageWidth = windowWidth;
43
+ const imageHeight = imageWidth;
44
+ return (
45
+ <View style={[defaultStyles.container]}>
46
+ <ImageBackground
47
+ resizeMode="cover"
48
+ source={require('../assets/images/background_image.jpg')}
49
+ style={[
50
+ defaultStyles.imageBackground,
51
+ { width: imageWidth, height: imageHeight },
52
+ ]}
53
+ />
54
+ <View style={defaultStyles.absoluteContainer}>
55
+ <View style={[{ padding: spacing }, defaultStyles.titleContainer]}>
56
+ <View style={defaultStyles.seelLogoContainer}>
57
+ <Image
58
+ source={require('../assets/images/seel_logo.png')}
59
+ style={defaultStyles.seelLogoIcon}
60
+ />
61
+ <TouchableOpacity onPress={onClickClose}>
62
+ <Image
63
+ source={require('../assets/images/close_white.png')}
64
+ style={defaultStyles.closeIcon}
65
+ />
66
+ </TouchableOpacity>
67
+ </View>
68
+ <Text style={[defaultStyles.h1]}>
69
+ {dictionary[KeyValue.coverage_title] ?? ''}
70
+ </Text>
71
+ <Text style={[{ marginTop: margin }, defaultStyles.h3]}>
72
+ {dictionary[KeyValue.pricing_message] ?? ''}
73
+ </Text>
74
+ </View>
75
+ <View style={[{ padding: spacing }, defaultStyles.contentContainer]}>
76
+ <Text style={defaultStyles.h2}>{widgetTitle}</Text>
77
+ <View
78
+ style={[defaultStyles.rowContainer, defaultStyles.centerContainer]}
79
+ >
80
+ <Image
81
+ source={require('../assets/images/accredited.png')}
82
+ style={defaultStyles.accreditedIcon}
83
+ />
84
+ <Text
85
+ style={[
86
+ { marginTop: margin },
87
+ defaultStyles.h3,
88
+ defaultStyles.covered,
89
+ ]}
90
+ >
91
+ {dictionary[KeyValue.whats_covered_title] ?? ''}
92
+ </Text>
93
+ </View>
94
+ <ScrollView
95
+ horizontal={false}
96
+ showsVerticalScrollIndicator={true}
97
+ style={[defaultStyles.scrollViewContainer]}
98
+ >
99
+ <View
100
+ style={[
101
+ { marginTop: spacing },
102
+ defaultStyles.scrollViewContentContainer,
103
+ ]}
104
+ >
105
+ {domain === 'US' ? (
106
+ <Text style={defaultStyles.h4}>
107
+ {dictionary[KeyValue.get_full_refund] ?? ''}
108
+ </Text>
109
+ ) : null}
110
+ {domain === 'EU' /*|| domain === 'IE'*/ ? (
111
+ <Text style={defaultStyles.h4}>
112
+ {dictionary[KeyValue.standard_coverage_intro] ?? ''}
113
+ </Text>
114
+ ) : null}
115
+ {(domain === 'US'
116
+ ? [
117
+ dictionary[KeyValue.lost_in_transit] ?? '',
118
+ dictionary[KeyValue.item_not_as_described] ?? '',
119
+ dictionary[KeyValue.item_damaged] ?? '',
120
+ dictionary[KeyValue.package_stolen] ?? '',
121
+ ]
122
+ : [
123
+ dictionary[KeyValue.standard_coverage_not_as_described] ??
124
+ '',
125
+ dictionary[KeyValue.standard_coverage_lost_damaged] ?? '',
126
+ dictionary[KeyValue.standard_coverage_not_matching] ?? '',
127
+ dictionary[KeyValue.standard_coverage_quality] ?? '',
128
+ dictionary[KeyValue.standard_coverage_not_delivered] ?? '',
129
+ ]
130
+ ).map((item, _) => {
131
+ return (
132
+ <View
133
+ key={item}
134
+ style={[{ marginTop: spacing }, defaultStyles.lineView]}
135
+ >
136
+ <Image
137
+ source={require('../assets/images/icon_check_selected_black.png')}
138
+ style={defaultStyles.checkIcon}
139
+ />
140
+ <Text style={[{ marginLeft: spacing }, defaultStyles.p]}>
141
+ {item || ''}
142
+ </Text>
143
+ </View>
144
+ );
145
+ })}
146
+ </View>
147
+ {domain === 'US' ? (
148
+ <View
149
+ style={[
150
+ { marginTop: spacing },
151
+ defaultStyles.scrollViewContentContainer,
152
+ ]}
153
+ >
154
+ <Text style={defaultStyles.h4}>Easy Resolution</Text>
155
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
156
+ {dictionary[KeyValue.resolve_with_clicks] ?? ''}
157
+ </Text>
158
+ <Text style={[{ marginTop: marginTop }, defaultStyles.h4]}>
159
+ {dictionary[KeyValue.complete_peace_of_mind] ?? ''}
160
+ </Text>
161
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
162
+ {dictionary[KeyValue.zero_risk] && '• '}
163
+ {dictionary[KeyValue.zero_risk] ?? ''}
164
+ </Text>
165
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
166
+ {dictionary[KeyValue.get_refund_promptly] && '• '}
167
+ {dictionary[KeyValue.get_refund_promptly] ?? ''}
168
+ </Text>
169
+ </View>
170
+ ) : null}
171
+ {domain === 'EU' /*|| domain === 'IE'*/ ? (
172
+ <View
173
+ style={[
174
+ { marginTop: spacing },
175
+ defaultStyles.scrollViewContentContainer,
176
+ ]}
177
+ >
178
+ <Text style={defaultStyles.h4}>
179
+ {dictionary[KeyValue.additional_coverage_intro] ?? ''}
180
+ </Text>
181
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
182
+ {dictionary[KeyValue.additional_coverage_extended_return] &&
183
+ '• '}
184
+ {dictionary[KeyValue.additional_coverage_extended_return] ??
185
+ ''}
186
+ </Text>
187
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
188
+ {dictionary[KeyValue.additional_coverage_post_delivery] &&
189
+ '• '}
190
+ {dictionary[KeyValue.additional_coverage_post_delivery] ?? ''}
191
+ </Text>
192
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
193
+ {dictionary[KeyValue.additional_coverage_delay] && '• '}
194
+ {dictionary[KeyValue.additional_coverage_delay] ?? ''}
195
+ </Text>
196
+
197
+ <Text style={[{ marginTop: marginTop }, defaultStyles.h4]}>
198
+ {dictionary[KeyValue.concierge_intro] ?? ''}
199
+ </Text>
200
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
201
+ {dictionary[KeyValue.concierge_app_access] && '• '}
202
+ {dictionary[KeyValue.concierge_app_access] ?? ''}
203
+ </Text>
204
+ <Text style={[{ marginTop: margin }, defaultStyles.p]}>
205
+ {dictionary[KeyValue.concierge_support] && '• '}
206
+ {dictionary[KeyValue.concierge_support] ?? ''}
207
+ </Text>
208
+ </View>
209
+ ) : null}
210
+ </ScrollView>
211
+ <CoverageInfoFooter
212
+ termsUrl={termsUrl}
213
+ privacyPolicyUrl={privacyPolicyUrl}
214
+ dictionary={dictionary}
215
+ onChangeOptedInValue={onChangeOptedInValue}
216
+ />
217
+ </View>
218
+ </View>
219
+ </View>
220
+ );
221
+ }
222
+
223
+ const defaultStyles = StyleSheet.create({
224
+ columnContainer: {
225
+ flexDirection: 'column',
226
+ },
227
+ rowContainer: {
228
+ flexDirection: 'row',
229
+ },
230
+ centerContainer: {
231
+ justifyContent: 'center',
232
+ alignItems: 'center',
233
+ },
234
+ container: {
235
+ flex: 1,
236
+ width: '100%',
237
+ height: '100%',
238
+ },
239
+ imageBackground: {
240
+ width: '100%',
241
+ // flex: 1,
242
+ // resizeMode: 'cover',
243
+ aspectRatio: 1,
244
+ },
245
+ absoluteContainer: {
246
+ flexDirection: 'column',
247
+ position: 'absolute',
248
+ top: 30,
249
+ left: 0,
250
+ bottom: 0,
251
+ right: 0,
252
+ },
253
+ titleContainer: {
254
+ flexDirection: 'column',
255
+ },
256
+ seelLogoContainer: {
257
+ flexDirection: 'row',
258
+ justifyContent: 'space-between',
259
+ alignItems: 'center',
260
+ },
261
+ seelLogoIcon: {
262
+ width: 80,
263
+ height: 22,
264
+ },
265
+ closeIcon: {
266
+ width: 26,
267
+ height: 26,
268
+ },
269
+ h1: {
270
+ marginTop: 15,
271
+ color: '#ffffff',
272
+ fontSize: 20,
273
+ fontFamily: Platform.select({
274
+ ios: 'Inter',
275
+ }),
276
+ fontStyle: 'normal',
277
+ fontWeight: 800,
278
+ },
279
+ h2: {
280
+ height: 36,
281
+ color: '#000000',
282
+ fontSize: 24,
283
+ fontFamily: Platform.select({
284
+ ios: 'Inter',
285
+ }),
286
+ fontStyle: 'normal',
287
+ fontWeight: 600,
288
+ textAlign: 'center',
289
+ },
290
+ h3: {
291
+ color: '#ffffff',
292
+ fontSize: 16,
293
+ fontFamily: Platform.select({
294
+ ios: 'Inter',
295
+ }),
296
+ fontStyle: 'normal',
297
+ fontWeight: 500,
298
+ },
299
+ h4: {
300
+ color: '#000000',
301
+ fontSize: 14,
302
+ fontFamily: Platform.select({
303
+ ios: 'Inter',
304
+ }),
305
+ fontStyle: 'normal',
306
+ fontWeight: '600',
307
+ },
308
+ contentContainer: {
309
+ marginTop: 15,
310
+ flex: 1,
311
+ borderTopLeftRadius: 10,
312
+ borderTopRightRadius: 10,
313
+ flexDirection: 'column',
314
+ backgroundColor: 'rgba(255, 255, 255, 0.80)',
315
+ },
316
+ accreditedIcon: {
317
+ width: 32,
318
+ height: 32,
319
+ },
320
+ covered: {
321
+ marginLeft: 4,
322
+ color: '#000000',
323
+ fontWeight: 600,
324
+ },
325
+ scrollViewContainer: {
326
+ flex: 1,
327
+ },
328
+ scrollViewContentContainer: {
329
+ padding: 20,
330
+ borderRadius: 10,
331
+ backgroundColor: '#F8F9FF',
332
+ },
333
+ lineView: {
334
+ flexDirection: 'row',
335
+ },
336
+ checkIcon: {
337
+ width: 20,
338
+ height: 20,
339
+ },
340
+ p: {
341
+ color: '#000000',
342
+ fontSize: 14,
343
+ lineHeight: 20,
344
+ minHeight: 20,
345
+ fontFamily: Platform.select({
346
+ ios: 'Inter',
347
+ }),
348
+ fontStyle: 'normal',
349
+ fontWeight: 400,
350
+ },
351
+ });