@controleonline/ui-common 1.2.70 → 1.2.71

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 (61) hide show
  1. package/package.json +31 -28
  2. package/src/api/index.js +237 -37
  3. package/src/react/components/AddImportModal.js +1 -1
  4. package/src/react/components/AnimatedModal.js +171 -0
  5. package/src/react/components/AnimatedModal.styles.js +21 -0
  6. package/src/react/components/AppTypeSwitcher.js +164 -0
  7. package/src/react/components/AppTypeSwitcher.styles.js +109 -0
  8. package/src/react/components/BackgroundRuntimeBridge.js +5 -4
  9. package/src/react/components/BottomNavigationBar.js +86 -31
  10. package/src/react/components/BottomNavigationBar.styles.js +118 -110
  11. package/src/react/components/DefaultProvider.native.js +68 -66
  12. package/src/react/components/DefaultProvider.web.js +44 -42
  13. package/src/react/components/DeliveryPushBridge.native.js +2 -2
  14. package/src/react/components/DeviceAlertSoundService.js +3 -3
  15. package/src/react/components/KioskModeBridge.js +2 -2
  16. package/src/react/components/LauncherModeBridge.js +2 -2
  17. package/src/react/components/ManagerPushBridge.native.js +2 -2
  18. package/src/react/components/RemoteCheckoutService.js +28 -20
  19. package/src/react/components/RuntimeBottomNavigationBar.js +146 -119
  20. package/src/react/components/RuntimeInfoFooter.js +37 -9
  21. package/src/react/components/StateStore.js +258 -0
  22. package/src/react/components/WebsocketListener.native.js +11 -11
  23. package/src/react/config/deviceConfigBootstrap.js +66 -27
  24. package/src/react/css/orders.js +72 -0
  25. package/src/react/pages/SettingsPage/PaymentTypesByWalletTab.js +484 -454
  26. package/src/react/pages/SettingsPage/index.js +1266 -1167
  27. package/src/react/print/providers/local.js +1 -1
  28. package/src/react/router/publicRoutes.js +25 -0
  29. package/src/react/services/Cielo/Checkout.js +39 -0
  30. package/src/react/services/Cielo/Cielo.js +193 -0
  31. package/src/react/services/Cielo/Print.js +7 -0
  32. package/src/react/services/InfinitePay/Checkout.js +33 -0
  33. package/src/react/services/InfinitePay/InfinitePay.js +24 -0
  34. package/src/react/{utils → services}/paymentGatewayExecution.js +91 -91
  35. package/src/react/styles/global.js +115 -0
  36. package/src/react/utils/fileUrl.js +182 -16
  37. package/src/react/utils/menuNavigation.js +31 -0
  38. package/src/react/utils/orderIdentity.js +277 -0
  39. package/src/react/utils/remotePayment.js +115 -61
  40. package/src/react/utils/runtimeMenu.js +35 -3
  41. package/src/react/utils/shopConfig.js +50 -24
  42. package/src/react/utils/shopFranchises.js +56 -22
  43. package/src/react/utils/socketRuntimePipeline.js +14 -14
  44. package/src/store/configs/index.js +2 -2
  45. package/src/tests/react/api/loadSmokeIndex.test.js +75 -0
  46. package/src/tests/react/config/deviceConfigBootstrap.test.js +47 -0
  47. package/src/tests/react/print/localPrintProvider.test.js +1 -1
  48. package/src/tests/react/services/Cielo.test.js +190 -0
  49. package/src/tests/react/utils/fileUrl.test.js +62 -0
  50. package/src/tests/react/utils/importStatus.test.js +2 -2
  51. package/src/tests/react/utils/orderIdentity.test.js +139 -0
  52. package/src/tests/react/utils/remotePayment.test.js +62 -0
  53. package/src/tests/react/utils/runtimeFooter.test.js +4 -6
  54. package/src/tests/react/utils/runtimeLanguage.test.js +2 -2
  55. package/src/tests/react/utils/runtimeMenu.test.js +23 -3
  56. package/src/tests/react/utils/shopConfig.test.js +74 -0
  57. package/src/tests/react/utils/shopFranchises.test.js +79 -12
  58. package/src/tests/react/utils/translate.test.mjs +166 -102
  59. package/src/utils/formatter.js +18 -0
  60. package/src/utils/integrationConfigs.js +80 -79
  61. package/src/utils/translate.js +125 -30
@@ -1,4 +1,4 @@
1
- import {CieloPrint} from '@controleonline/ui-orders/src/react/services/Cielo/Print';
1
+ import {CieloPrint} from '../../services/Cielo/Print';
2
2
 
3
3
  export const LOCAL_CIELO_PRINT_UNAVAILABLE_MESSAGE =
4
4
  'Impressao local Cielo indisponivel neste equipamento.';
@@ -0,0 +1,25 @@
1
+ import {app_type} from '@appType';
2
+
3
+ export const PUBLIC_ROUTES = new Set([
4
+ 'SignInPage',
5
+ 'CreateAccount',
6
+ 'ConfirmAccountPage',
7
+ 'ResetPasswordPage',
8
+ 'ShopIndex',
9
+ 'ShopFranchiseLocatorPage',
10
+ 'ShopSearchPage',
11
+ 'ShopCategoryPage',
12
+ 'ShopProductPage',
13
+ 'ShopCartPage',
14
+ 'ShopCheckoutPage',
15
+ 'ShopOrdersPage',
16
+ 'ShopOrderDetailsPage',
17
+ 'ShopProfilePage',
18
+ 'ShopCardsPage',
19
+ 'ShopLoyaltyPage',
20
+ 'ShopDownloadPage',
21
+ ]);
22
+
23
+ export const isPublicRoute = routeName =>
24
+ PUBLIC_ROUTES.has(routeName) ||
25
+ (routeName === 'HomePage' && String(app_type || '').toUpperCase() === 'SHOP');
@@ -0,0 +1,39 @@
1
+ import CieloService from './Cielo';
2
+
3
+ export const formatCieloCheckoutProducts = orderProducts =>
4
+ (Array.isArray(orderProducts) ? orderProducts : []).map(orderProduct => ({
5
+ name: orderProduct?.product?.product,
6
+ quantity: orderProduct?.quantity,
7
+ sku:
8
+ orderProduct?.product?.sku ||
9
+ String(orderProduct?.product?.['@id'] || '').replace(/\D/g, ''),
10
+ unitOfMeasure: 'unidade',
11
+ unitPrice: Math.round(Number(orderProduct?.price || 0) * 100).toString(),
12
+ }));
13
+
14
+ export const runCieloCheckoutPayment = async ({
15
+ orderProducts = [],
16
+ payment = null,
17
+ total = 0,
18
+ }) => {
19
+ const resolvedTotal = Number(total || 0);
20
+
21
+ if (!payment?.paymentCode) {
22
+ throw new Error('Meio de pagamento sem codigo de gateway.');
23
+ }
24
+
25
+ if (resolvedTotal <= 0) {
26
+ throw new Error('Informe um valor de pagamento valido.');
27
+ }
28
+
29
+ const response = await new CieloService().payment(
30
+ payment.paymentCode,
31
+ formatCieloCheckoutProducts(orderProducts),
32
+ Math.round(resolvedTotal * 100).toString(),
33
+ );
34
+
35
+ return {
36
+ paidAmount: resolvedTotal,
37
+ response,
38
+ };
39
+ };
@@ -0,0 +1,193 @@
1
+ import Cielo from '@controleonline-rn/react-native-cielo-payment';
2
+ import {env} from '@env';
3
+ import {api} from '@controleonline/ui-common/src/api';
4
+ import {getAllStores} from '@store';
5
+ import {
6
+ DEFAULT_CIELO_CONFIG,
7
+ resolveCieloConfig,
8
+ } from '@controleonline/ui-common/src/utils/integrationConfigs';
9
+
10
+ const isConfigMap = value =>
11
+ value && typeof value === 'object' && !Array.isArray(value);
12
+
13
+ const normalizeEntityId = value =>
14
+ String(value?.id || value?.['@id'] || value || '')
15
+ .replace(/\D+/g, '')
16
+ .trim();
17
+
18
+ const extractCollectionItems = response => {
19
+ if (Array.isArray(response)) return response;
20
+ if (Array.isArray(response?.member)) return response.member;
21
+ if (Array.isArray(response?.['hydra:member'])) return response['hydra:member'];
22
+ return [];
23
+ };
24
+
25
+ const hasRequiredCieloConfig = config =>
26
+ Boolean(
27
+ String(config?.ACCESS_TOKEN || '').trim() &&
28
+ String(config?.CLIENT_ID || '').trim() &&
29
+ String(config?.EMAIL || '').trim(),
30
+ );
31
+
32
+ const hasExpectedMerchantCode = (result, expectedMerchantCode) => {
33
+ if (!expectedMerchantCode) return true;
34
+
35
+ const payments = Array.isArray(result?.payments) ? result.payments : [];
36
+
37
+ return (
38
+ payments.length > 0 &&
39
+ payments.every(
40
+ payment => String(payment?.merchantCode || '').trim() === expectedMerchantCode,
41
+ )
42
+ );
43
+ };
44
+
45
+ let technicalCieloConfigCache = DEFAULT_CIELO_CONFIG;
46
+ let technicalCieloConfigCompanyId = '';
47
+ let technicalCieloConfigPromise = null;
48
+
49
+ const resolveRuntimeCompanyConfigs = () => {
50
+ const stores = getAllStores();
51
+ const peopleStore = stores?.people?.getters || {};
52
+ const configsStore = stores?.configs?.getters || {};
53
+
54
+ if (isConfigMap(configsStore.items)) {
55
+ return configsStore.items;
56
+ }
57
+
58
+ if (isConfigMap(peopleStore.currentCompany?.configs)) {
59
+ return peopleStore.currentCompany.configs;
60
+ }
61
+
62
+ if (isConfigMap(peopleStore.defaultCompany?.configs)) {
63
+ return peopleStore.defaultCompany.configs;
64
+ }
65
+
66
+ return {};
67
+ };
68
+
69
+ const resolveDefaultCompanyId = () => {
70
+ const stores = getAllStores();
71
+ const peopleStore = stores?.people?.getters || {};
72
+
73
+ return normalizeEntityId(
74
+ peopleStore.defaultCompany?.id || peopleStore.defaultCompany?.['@id'],
75
+ );
76
+ };
77
+
78
+ const loadTechnicalCieloConfig = async () => {
79
+ const defaultCompanyId = resolveDefaultCompanyId();
80
+
81
+ if (!defaultCompanyId) {
82
+ return DEFAULT_CIELO_CONFIG;
83
+ }
84
+
85
+ if (
86
+ technicalCieloConfigCompanyId === defaultCompanyId &&
87
+ hasRequiredCieloConfig(technicalCieloConfigCache)
88
+ ) {
89
+ return technicalCieloConfigCache;
90
+ }
91
+
92
+ if (technicalCieloConfigPromise) {
93
+ return technicalCieloConfigPromise;
94
+ }
95
+
96
+ technicalCieloConfigPromise = api
97
+ .fetch('/configs', {
98
+ params: {
99
+ configKey: 'CIELO',
100
+ people: '/people/' + defaultCompanyId,
101
+ visibility: 'private',
102
+ },
103
+ })
104
+ .then(response => {
105
+ const item = extractCollectionItems(response)[0];
106
+ technicalCieloConfigCompanyId = defaultCompanyId;
107
+ technicalCieloConfigCache = resolveCieloConfig(
108
+ item?.configKey ? {[item.configKey]: item?.configValue} : {},
109
+ );
110
+
111
+ return technicalCieloConfigCache;
112
+ })
113
+ .catch(() => DEFAULT_CIELO_CONFIG)
114
+ .finally(() => {
115
+ technicalCieloConfigPromise = null;
116
+ });
117
+
118
+ return technicalCieloConfigPromise;
119
+ };
120
+
121
+ const resolveRuntimeCieloConfig = async () => {
122
+ const runtimeConfig = resolveCieloConfig(resolveRuntimeCompanyConfigs());
123
+ const technicalConfig = hasRequiredCieloConfig(runtimeConfig)
124
+ ? DEFAULT_CIELO_CONFIG
125
+ : await loadTechnicalCieloConfig();
126
+
127
+ return {
128
+ ACCESS_TOKEN:
129
+ runtimeConfig.ACCESS_TOKEN ||
130
+ technicalConfig.ACCESS_TOKEN ||
131
+ env?.CIELO?.ACCESS_TOKEN ||
132
+ '',
133
+ CLIENT_ID:
134
+ runtimeConfig.CLIENT_ID ||
135
+ technicalConfig.CLIENT_ID ||
136
+ env?.CIELO?.CLIENT_ID ||
137
+ '',
138
+ EMAIL: runtimeConfig.EMAIL || technicalConfig.EMAIL || env?.CIELO?.EMAIL || '',
139
+ MERCHANT_CODE:
140
+ runtimeConfig.MERCHANT_CODE ||
141
+ technicalConfig.MERCHANT_CODE ||
142
+ env?.CIELO?.MERCHANT_CODE ||
143
+ '',
144
+ };
145
+ };
146
+
147
+ class CieloService {
148
+ async payment(paymentCode, items, orderPrice) {
149
+ const cieloConfig = await resolveRuntimeCieloConfig();
150
+
151
+ if (
152
+ !cieloConfig.ACCESS_TOKEN ||
153
+ !cieloConfig.CLIENT_ID ||
154
+ !cieloConfig.EMAIL
155
+ ) {
156
+ throw new Error('Configuracao da Cielo incompleta.');
157
+ }
158
+
159
+ const json = {
160
+ accessToken: cieloConfig.ACCESS_TOKEN,
161
+ clientID: cieloConfig.CLIENT_ID,
162
+ email: cieloConfig.EMAIL,
163
+ installments: 0,
164
+ items: items,
165
+ paymentCode: paymentCode,
166
+ value: orderPrice,
167
+ };
168
+
169
+ if (cieloConfig.MERCHANT_CODE) {
170
+ json.merchantCode = cieloConfig.MERCHANT_CODE;
171
+ }
172
+
173
+ const response = await Cielo.payment(JSON.stringify(json));
174
+
175
+ const result = response.success
176
+ ? JSON.parse(response.result)
177
+ : response.result;
178
+ const hasValidMerchantCode = hasExpectedMerchantCode(
179
+ result,
180
+ cieloConfig.MERCHANT_CODE,
181
+ );
182
+
183
+ return {
184
+ success: response.success && hasValidMerchantCode,
185
+ code: response.code,
186
+ result: hasValidMerchantCode
187
+ ? result
188
+ : 'Pagamento processado em estabelecimento Cielo diferente do configurado.',
189
+ };
190
+ }
191
+ }
192
+
193
+ export default CieloService;
@@ -0,0 +1,7 @@
1
+ import Cielo from '@controleonline-rn/react-native-cielo-payment';
2
+
3
+ export class CieloPrint {
4
+ async print(printRequest) {
5
+ return await Cielo.print(printRequest);
6
+ }
7
+ }
@@ -0,0 +1,33 @@
1
+ import InfinitePayService from './InfinitePay';
2
+
3
+ export const runInfinitePayCheckoutPayment = async ({
4
+ installments = null,
5
+ order = null,
6
+ payment = null,
7
+ total = 0,
8
+ }) => {
9
+ const resolvedTotal = Number(total || 0);
10
+
11
+ if (!payment?.paymentCode) {
12
+ throw new Error('Meio de pagamento sem codigo de gateway.');
13
+ }
14
+
15
+ if (resolvedTotal <= 0) {
16
+ throw new Error('Informe um valor de pagamento valido.');
17
+ }
18
+
19
+ const response = await new InfinitePayService().payment(
20
+ payment.paymentCode,
21
+ installments || payment.installments || 1,
22
+ order?.['@id'] || order?.id || '',
23
+ Math.round(resolvedTotal * 100).toString(),
24
+ );
25
+
26
+ return {
27
+ paidAmount:
28
+ Number(response?.result?.paidAmount || 0) > 0
29
+ ? Number(response.result.paidAmount) / 100
30
+ : resolvedTotal,
31
+ response,
32
+ };
33
+ };
@@ -0,0 +1,24 @@
1
+ import InfinitePay from '@controleonline-rn/react-native-infinitepay-payment';
2
+
3
+ class InfinitePayService {
4
+ async payment(paymentMethod, installments, orderId, amount) {
5
+ const json = {
6
+ amount: amount,
7
+ payment_method: paymentMethod,
8
+ installments: installments,
9
+ order_id: orderId,
10
+ app_client_referrer: 'ControleOnline',
11
+ af_force_deeplink: 'true',
12
+ };
13
+
14
+ const response = await InfinitePay.payment(JSON.stringify(json));
15
+
16
+ return {
17
+ success: response.success,
18
+ code: response.code,
19
+ result: response.success ? JSON.parse(response.result) : response.result,
20
+ };
21
+ }
22
+ }
23
+
24
+ export default InfinitePayService;
@@ -1,91 +1,91 @@
1
- import {runCieloCheckoutPayment} from '@controleonline/ui-orders/src/react/services/Cielo/Checkout';
2
- import {runInfinitePayCheckoutPayment} from '@controleonline/ui-orders/src/react/services/InfinitePay/Checkout';
3
-
4
- import {
5
- PAYMENT_GATEWAY_CIELO,
6
- PAYMENT_GATEWAY_INFINITE_PAY,
7
- } from './paymentDevices';
8
-
9
- export const normalizeGatewayPaymentError = (
10
- error,
11
- fallback = 'Nao foi possivel concluir o pagamento.',
12
- ) => {
13
- if (typeof error === 'string' && error.trim()) {
14
- return error;
15
- }
16
-
17
- if (typeof error?.message === 'string' && error.message.trim()) {
18
- return error.message;
19
- }
20
-
21
- if (typeof error?.result === 'string' && error.result.trim()) {
22
- return error.result;
23
- }
24
-
25
- if (typeof error?.error === 'string' && error.error.trim()) {
26
- return error.error;
27
- }
28
-
29
- try {
30
- const serialized = JSON.stringify(error);
31
- return serialized && serialized !== '{}' ? serialized : fallback;
32
- } catch {
33
- return fallback;
34
- }
35
- };
36
-
37
- export const runConfiguredGatewayPayment = async ({
38
- gateway = '',
39
- installments = null,
40
- order = null,
41
- orderProducts = [],
42
- payment = null,
43
- total = 0,
44
- }) => {
45
- const resolvedTotal = Number(total || 0);
46
-
47
- if (!payment?.paymentCode) {
48
- throw new Error('Meio de pagamento sem codigo de gateway.');
49
- }
50
-
51
- if (resolvedTotal <= 0) {
52
- throw new Error('Informe um valor de pagamento valido.');
53
- }
54
-
55
- if (gateway === PAYMENT_GATEWAY_CIELO) {
56
- const {response, paidAmount} = await runCieloCheckoutPayment({
57
- orderProducts,
58
- payment,
59
- total: resolvedTotal,
60
- });
61
-
62
- if (!response?.success) {
63
- throw new Error(normalizeGatewayPaymentError(response?.result));
64
- }
65
-
66
- return {
67
- paidAmount,
68
- response,
69
- };
70
- }
71
-
72
- if (gateway === PAYMENT_GATEWAY_INFINITE_PAY) {
73
- const {response, paidAmount} = await runInfinitePayCheckoutPayment({
74
- installments,
75
- order,
76
- payment,
77
- total: resolvedTotal,
78
- });
79
-
80
- if (!response?.success || response?.code === 1 || response?.code === 2) {
81
- throw response;
82
- }
83
-
84
- return {
85
- paidAmount,
86
- response,
87
- };
88
- }
89
-
90
- throw new Error('Gateway de pagamento indisponível neste equipamento.');
91
- };
1
+ import {runCieloCheckoutPayment} from './Cielo/Checkout';
2
+ import {runInfinitePayCheckoutPayment} from './InfinitePay/Checkout';
3
+
4
+ import {
5
+ PAYMENT_GATEWAY_CIELO,
6
+ PAYMENT_GATEWAY_INFINITE_PAY,
7
+ } from '../utils/paymentDevices';
8
+
9
+ export const normalizeGatewayPaymentError = (
10
+ error,
11
+ fallback = 'Nao foi possivel concluir o pagamento.',
12
+ ) => {
13
+ if (typeof error === 'string' && error.trim()) {
14
+ return error;
15
+ }
16
+
17
+ if (typeof error?.message === 'string' && error.message.trim()) {
18
+ return error.message;
19
+ }
20
+
21
+ if (typeof error?.result === 'string' && error.result.trim()) {
22
+ return error.result;
23
+ }
24
+
25
+ if (typeof error?.error === 'string' && error.error.trim()) {
26
+ return error.error;
27
+ }
28
+
29
+ try {
30
+ const serialized = JSON.stringify(error);
31
+ return serialized && serialized !== '{}' ? serialized : fallback;
32
+ } catch {
33
+ return fallback;
34
+ }
35
+ };
36
+
37
+ export const runConfiguredGatewayPayment = async ({
38
+ gateway = '',
39
+ installments = null,
40
+ order = null,
41
+ orderProducts = [],
42
+ payment = null,
43
+ total = 0,
44
+ }) => {
45
+ const resolvedTotal = Number(total || 0);
46
+
47
+ if (!payment?.paymentCode) {
48
+ throw new Error('Meio de pagamento sem codigo de gateway.');
49
+ }
50
+
51
+ if (resolvedTotal <= 0) {
52
+ throw new Error('Informe um valor de pagamento valido.');
53
+ }
54
+
55
+ if (gateway === PAYMENT_GATEWAY_CIELO) {
56
+ const {response, paidAmount} = await runCieloCheckoutPayment({
57
+ orderProducts,
58
+ payment,
59
+ total: resolvedTotal,
60
+ });
61
+
62
+ if (!response?.success) {
63
+ throw new Error(normalizeGatewayPaymentError(response?.result));
64
+ }
65
+
66
+ return {
67
+ paidAmount,
68
+ response,
69
+ };
70
+ }
71
+
72
+ if (gateway === PAYMENT_GATEWAY_INFINITE_PAY) {
73
+ const {response, paidAmount} = await runInfinitePayCheckoutPayment({
74
+ installments,
75
+ order,
76
+ payment,
77
+ total: resolvedTotal,
78
+ });
79
+
80
+ if (!response?.success || response?.code === 1 || response?.code === 2) {
81
+ throw response;
82
+ }
83
+
84
+ return {
85
+ paidAmount,
86
+ response,
87
+ };
88
+ }
89
+
90
+ throw new Error('Gateway de pagamento indisponível neste equipamento.');
91
+ };
@@ -0,0 +1,115 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {useStore} from '@store';
3
+
4
+ const css = () => {
5
+ const themeStore = useStore('theme');
6
+ const getters = themeStore.getters;
7
+ const {colors} = getters;
8
+
9
+ return StyleSheet.create({
10
+ container: {
11
+ flex: 1,
12
+ backgroundColor: '#f4f4f4',
13
+ paddingTop: 20,
14
+ paddingHorizontal: 20,
15
+ },
16
+ loadingContainer: {
17
+ flex: 1,
18
+ justifyContent: 'center',
19
+ alignItems: 'center',
20
+ },
21
+ button: {
22
+ padding: 11,
23
+ justifyContent: 'center',
24
+ alignItems: 'center',
25
+ marginHorizontal: 5,
26
+ flex: 1,
27
+ color: '#fff',
28
+ backgroundColor: colors['primary'],
29
+ flexDirection: 'row',
30
+ },
31
+ btnText: {
32
+ color: '#fff',
33
+ fontSize: 16,
34
+ fontWeight: 'bold',
35
+ },
36
+ primary: {
37
+ backgroundColor: colors['primary'],
38
+ color: '#000000',
39
+ },
40
+ state: {
41
+ container: {
42
+ flex: 1,
43
+ justifyContent: 'center',
44
+ alignItems: 'center',
45
+ padding: 20,
46
+ },
47
+ displayContainer: {
48
+ flex: 1,
49
+ justifyContent: 'center',
50
+ alignItems: 'center',
51
+ paddingVertical: 24,
52
+ paddingHorizontal: 20,
53
+ },
54
+ compactContainer: {
55
+ width: '100%',
56
+ justifyContent: 'center',
57
+ alignItems: 'center',
58
+ paddingVertical: 12,
59
+ paddingHorizontal: 16,
60
+ },
61
+ content: {
62
+ width: '100%',
63
+ maxWidth: 520,
64
+ gap: 8,
65
+ padding: 20,
66
+ backgroundColor: '#fff',
67
+ borderRadius: 10,
68
+ elevation: 5,
69
+ },
70
+ displayContent: {
71
+ width: '100%',
72
+ maxWidth: 640,
73
+ gap: 10,
74
+ paddingVertical: 24,
75
+ paddingHorizontal: 22,
76
+ backgroundColor: '#fff',
77
+ borderRadius: 16,
78
+ borderWidth: 1,
79
+ borderColor: '#E2E8F0',
80
+ elevation: 8,
81
+ },
82
+ compactContent: {
83
+ width: '100%',
84
+ gap: 8,
85
+ paddingVertical: 12,
86
+ paddingHorizontal: 16,
87
+ alignItems: 'center',
88
+ justifyContent: 'center',
89
+ },
90
+ loadingContainer: {
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ },
94
+ errorContainer: {
95
+ justifyContent: 'center',
96
+ alignItems: 'center',
97
+ padding: 20,
98
+ backgroundColor: '#fff',
99
+ borderRadius: 10,
100
+ elevation: 5,
101
+ },
102
+ messageText: {
103
+ color: '#475569',
104
+ textAlign: 'center',
105
+ },
106
+ errorText: {
107
+ color: '#000',
108
+ textAlign: 'center',
109
+ fontWeight: '700',
110
+ },
111
+ },
112
+ });
113
+ };
114
+
115
+ export default css;