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,117 @@
1
+ export const moneyFormat = (money: any, currency: string, options: any) => {
2
+ try {
3
+ // 解构options参数,提供默认值
4
+ const { showCurrency = true, locale = '', fallbackValue = '-' } = options;
5
+ // 如果没传 currency 或者传空串,就认为不需要做货币格式化
6
+ const propsCurrency = currency || '';
7
+ let targetMoney = money;
8
+ // 如果money是null, undefined或空字符串,或者不是数字或者字符串,直接返回 fallbackValue
9
+ if (
10
+ targetMoney === null ||
11
+ targetMoney === undefined ||
12
+ targetMoney === ''
13
+ ) {
14
+ return fallbackValue;
15
+ }
16
+ // 完善判断非数字情况
17
+ if (typeof money === 'string') {
18
+ targetMoney = Number(money); // 或者可以使用 parseFloat(money)
19
+ }
20
+ // 如果转换后的值不是有效的数字,返回 fallbackValue
21
+ if (Number.isNaN(targetMoney)) return fallbackValue;
22
+ // 如果没有传入currency,把原数据返回,如果不是数字则显示 fallbackValue
23
+ if (!propsCurrency) return targetMoney;
24
+ // 检查 Intl.NumberFormat 是否支持
25
+ if (
26
+ typeof Intl === 'undefined' ||
27
+ typeof Intl.NumberFormat === 'undefined'
28
+ ) {
29
+ // 降级处理:简单格式化
30
+ if (showCurrency) {
31
+ return `${targetMoney} ${propsCurrency}`;
32
+ }
33
+ return `${targetMoney}`;
34
+ }
35
+ // 币种locale 映射
36
+ const currencyLocaleMap: any = {
37
+ USD: 'en-US',
38
+ CAD: 'en-CA',
39
+ AUD: 'en-AU',
40
+ EUR: 'de-DE',
41
+ GBP: 'en-GB',
42
+ NZD: 'en-NZ',
43
+ HKD: 'zh-HK',
44
+ SGD: 'zh-SG',
45
+ DKK: 'da-DK',
46
+ };
47
+ const usedLocale =
48
+ locale ||
49
+ (propsCurrency.toUpperCase() in currencyLocaleMap
50
+ ? currencyLocaleMap[propsCurrency.toUpperCase()]
51
+ : '') ||
52
+ 'en-US';
53
+ const numberFormat = new Intl.NumberFormat(usedLocale, {
54
+ style: 'currency',
55
+ currency: propsCurrency,
56
+ minimumFractionDigits: 2,
57
+ maximumFractionDigits: 2,
58
+ });
59
+ // 检查 formatToParts 是否支持
60
+ if (typeof numberFormat.formatToParts !== 'function') {
61
+ // 降级处理:使用 format 方法
62
+ const formatted = numberFormat.format(targetMoney || 0);
63
+ if (showCurrency) {
64
+ return `${formatted} ${propsCurrency}`;
65
+ }
66
+ return formatted;
67
+ }
68
+ // 获取货币格式化后的各个部分,包括货币符号
69
+ const parts = numberFormat.formatToParts(targetMoney || 0);
70
+ // 兼容性处理:避免使用可选链操作符
71
+ const currencyPart = parts.find((part) => part.type === 'currency');
72
+ const currencySymbol = currencyPart ? currencyPart.value : '';
73
+ // 特殊处理 HKD 货币,使用 $ 符号而不是 HK$
74
+ if (propsCurrency.toUpperCase() === 'HKD') {
75
+ const formattedNumber = numberFormat
76
+ .format(targetMoney || 0)
77
+ .replace(currencySymbol, '$')
78
+ .trim();
79
+ if (showCurrency) {
80
+ return `${formattedNumber} ${propsCurrency}`;
81
+ }
82
+ return formattedNumber;
83
+ }
84
+ // 判断货币符号是否与 currency 一致
85
+ if (currencySymbol === propsCurrency) {
86
+ if (showCurrency) {
87
+ return `${targetMoney} ${propsCurrency}`; // 如果符号一致且需要显示货币符号,返回 money + currency
88
+ }
89
+ return `${targetMoney}`; // 如果符号一致但不需要显示货币符号,返回只有 money
90
+ }
91
+ if (showCurrency) {
92
+ return `${numberFormat.format(targetMoney || 0)} ${propsCurrency}`;
93
+ }
94
+ return `${numberFormat.format(targetMoney || 0)}`;
95
+ } catch (error) {
96
+ console.warn('moneyFormat error:', error);
97
+ // 降级处理:返回简单的格式化结果
98
+ const propsCurrency = currency || '';
99
+ const { showCurrency = true, fallbackValue = '-' } = options;
100
+ const targetMoney = money;
101
+ if (
102
+ targetMoney === null ||
103
+ targetMoney === undefined ||
104
+ targetMoney === ''
105
+ ) {
106
+ return fallbackValue;
107
+ }
108
+ const num =
109
+ typeof targetMoney === 'string' ? Number(targetMoney) : targetMoney;
110
+ if (Number.isNaN(num)) return fallbackValue;
111
+ if (!propsCurrency) return num;
112
+ if (showCurrency) {
113
+ return `${num} ${propsCurrency}`;
114
+ }
115
+ return `${num}`;
116
+ }
117
+ };
@@ -0,0 +1,30 @@
1
+ import { SeelWidgetSDK } from '../core/SeelWidgetSDK';
2
+ import type { IEvents } from '../dto/IEvents';
3
+ import type { IQuotesRequest } from '../dto/IQuotesRequest';
4
+ import type IQuotesResponse from '../dto/IQuotesResponse';
5
+ import { post } from '../network/request';
6
+
7
+ export enum NetworkErrorEnum {
8
+ InvalidURL,
9
+ NoData,
10
+ DecodingError,
11
+ NetworkError,
12
+ ServerError,
13
+ /**
14
+ * Configuration error
15
+ */
16
+ ConfigError,
17
+ Unknown,
18
+ }
19
+
20
+ const defaultBaseURL: string = SeelWidgetSDK.shared.baseURL;
21
+
22
+ export const createQuote = (body: IQuotesRequest) => {
23
+ const url = defaultBaseURL + '/v1/ecommerce/quotes';
24
+ return post<IQuotesResponse>(url, JSON.stringify(body), {});
25
+ };
26
+
27
+ export const createEvent = (body: IEvents) => {
28
+ const url = defaultBaseURL + '/v1/ecommerce/events';
29
+ return post<IQuotesResponse>(url, JSON.stringify(body), {});
30
+ };
@@ -0,0 +1,42 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+
3
+ const StorageValue = {
4
+ True: '1',
5
+ False: '0',
6
+ } as const;
7
+
8
+ export const AsyncStorageKey = {
9
+ OptedIn: 'SeelWFPWidget.OptedIn',
10
+ };
11
+
12
+ function logSetError(key: string, error: unknown) {
13
+ console.error('Failed to set [', key, '] error:', error);
14
+ }
15
+
16
+ function logGetError(key: string, error: unknown) {
17
+ console.error('Failed to get [', key, '] error:', error);
18
+ }
19
+
20
+ export const writeOptedIn = async (value: boolean): Promise<void> => {
21
+ const key = AsyncStorageKey.OptedIn;
22
+ try {
23
+ await AsyncStorage.setItem(
24
+ key,
25
+ value ? StorageValue.True : StorageValue.False
26
+ );
27
+ } catch (error) {
28
+ logSetError(key, error);
29
+ throw error;
30
+ }
31
+ };
32
+
33
+ export const readOptedIn = async (): Promise<boolean> => {
34
+ const key = AsyncStorageKey.OptedIn;
35
+ try {
36
+ const value = await AsyncStorage.getItem(key);
37
+ return value !== null && value !== '' && value !== StorageValue.False;
38
+ } catch (error) {
39
+ logGetError(key, error);
40
+ return false;
41
+ }
42
+ };
@@ -0,0 +1,18 @@
1
+ /* eslint-disable no-bitwise */
2
+ /**
3
+ * Generate a random UUID (v4)
4
+ * @returns A UUID string in the format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
5
+ */
6
+ export function randomUUID(): string {
7
+ // Use crypto.randomUUID if available (browser/Node.js 19+)
8
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
9
+ return crypto.randomUUID();
10
+ }
11
+
12
+ // Fallback implementation for React Native
13
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
14
+ const r = (Math.random() * 16) | 0;
15
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
16
+ return v.toString(16);
17
+ });
18
+ }