@controleonline/ui-common 1.2.70

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 (203) hide show
  1. package/.github/agents/developer.agent.md +30 -0
  2. package/.github/agents/devops.agent.md +30 -0
  3. package/.github/agents/qa.agent.md +30 -0
  4. package/.github/agents/security.agent.md +30 -0
  5. package/.github/workflows/npmjs.yml +35 -0
  6. package/.github/workflows/pull-request-checks.yml +19 -0
  7. package/.scrutinizer.yml +24 -0
  8. package/FUNDING.yml +1 -0
  9. package/package.json +28 -0
  10. package/src/api/fetch.js +74 -0
  11. package/src/api/index.js +155 -0
  12. package/src/api/localDB.js +131 -0
  13. package/src/api/queue.js +66 -0
  14. package/src/react/assets/tap.mp3 +0 -0
  15. package/src/react/components/AddImportModal.js +157 -0
  16. package/src/react/components/AddImportModal.styles.js +81 -0
  17. package/src/react/components/BackgroundRuntimeBridge.js +219 -0
  18. package/src/react/components/BottomNavigationBar.config.js +238 -0
  19. package/src/react/components/BottomNavigationBar.js +120 -0
  20. package/src/react/components/BottomNavigationBar.styles.js +110 -0
  21. package/src/react/components/CategoryForm.js +572 -0
  22. package/src/react/components/CategoryForm.styles.js +334 -0
  23. package/src/react/components/ConfirmModal.js +24 -0
  24. package/src/react/components/ConfirmModal.styles.js +43 -0
  25. package/src/react/components/ContextHelpButton.js +69 -0
  26. package/src/react/components/ContextHelpButton.styles.js +62 -0
  27. package/src/react/components/DefaultProvider.native.js +848 -0
  28. package/src/react/components/DefaultProvider.styles.js +21 -0
  29. package/src/react/components/DefaultProvider.web.js +909 -0
  30. package/src/react/components/DeliveryPushBridge.native.js +314 -0
  31. package/src/react/components/DeliveryPushBridge.web.js +5 -0
  32. package/src/react/components/DeviceAlertSoundService.js +499 -0
  33. package/src/react/components/EntityLogContent.js +909 -0
  34. package/src/react/components/EntityLogContent.styles.js +400 -0
  35. package/src/react/components/EventBus.js +12 -0
  36. package/src/react/components/KioskModeBridge.js +65 -0
  37. package/src/react/components/LauncherModeBridge.js +47 -0
  38. package/src/react/components/LinkedOrderProductsTab.js +388 -0
  39. package/src/react/components/LinkedOrderProductsTab.styles.js +180 -0
  40. package/src/react/components/ManagerPushBridge.native.js +345 -0
  41. package/src/react/components/MessageService.js +314 -0
  42. package/src/react/components/Paywall/Google.js +89 -0
  43. package/src/react/components/PrintService.js +778 -0
  44. package/src/react/components/ProductCatalogCacheService.js +45 -0
  45. package/src/react/components/RemoteCheckoutService.js +292 -0
  46. package/src/react/components/RuntimeBottomNavigationBar.js +151 -0
  47. package/src/react/components/RuntimeInfoFooter.js +214 -0
  48. package/src/react/components/RuntimeInfoFooter.styles.js +56 -0
  49. package/src/react/components/SystemErrorToast.js +29 -0
  50. package/src/react/components/SystemErrorToast.styles.js +38 -0
  51. package/src/react/components/TouchFeedbackProvider.js +65 -0
  52. package/src/react/components/UnifiedPaymentBar.js +155 -0
  53. package/src/react/components/UnifiedPaymentBar.styles.js +174 -0
  54. package/src/react/components/WebsocketListener.native.js +487 -0
  55. package/src/react/components/WebsocketListener.web.js +102 -0
  56. package/src/react/components/inputs/IdInput.js +49 -0
  57. package/src/react/components/inputs/IdInput.styles.js +26 -0
  58. package/src/react/components/inputs/InvoiceDueDateFilterInput.js +74 -0
  59. package/src/react/components/inputs/InvoiceDueDateFilterInput.styles.js +34 -0
  60. package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.js +115 -0
  61. package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.styles.js +39 -0
  62. package/src/react/components/lists/CategoriesList.js +56 -0
  63. package/src/react/components/lists/PaymentTypeList.js +55 -0
  64. package/src/react/components/lists/ReceiverList.js +56 -0
  65. package/src/react/components/lists/SelectList.styles.js +18 -0
  66. package/src/react/components/lists/StatusList.js +55 -0
  67. package/src/react/components/lists/WalletList.js +54 -0
  68. package/src/react/components/radio/Spotify.js +144 -0
  69. package/src/react/components/radio/Spotify.styles.js +32 -0
  70. package/src/react/components/radio/YouTube.js +82 -0
  71. package/src/react/components/radio/YouTube.styles.js +16 -0
  72. package/src/react/components/toastConfig.js +16 -0
  73. package/src/react/config/deviceConfigBootstrap.js +571 -0
  74. package/src/react/index.js +4 -0
  75. package/src/react/localStorage.js +30 -0
  76. package/src/react/pages/EntityLogPage.js +124 -0
  77. package/src/react/pages/EntityLogPage.styles.js +17 -0
  78. package/src/react/pages/GenericLogPage.js +760 -0
  79. package/src/react/pages/GenericLogPage.styles.js +401 -0
  80. package/src/react/pages/Imports.js +361 -0
  81. package/src/react/pages/Imports.styles.js +223 -0
  82. package/src/react/pages/SettingsPage/PaymentTypesByWalletTab.js +462 -0
  83. package/src/react/pages/SettingsPage/index.js +1171 -0
  84. package/src/react/pages/SettingsPage/index.styles.js +122 -0
  85. package/src/react/print/jobs.js +147 -0
  86. package/src/react/print/providers/local.js +53 -0
  87. package/src/react/print/providers/remote.js +81 -0
  88. package/src/react/print/selection.js +296 -0
  89. package/src/react/print/usePrintButtonController.js +474 -0
  90. package/src/react/router/routes.js +42 -0
  91. package/src/react/services/NetworkPrinterService.native.js +391 -0
  92. package/src/react/services/NetworkPrinterService.web.js +15 -0
  93. package/src/react/stores/index.js +128 -0
  94. package/src/react/stores/storeErrorBridge.js +36 -0
  95. package/src/react/utils/backgroundRuntimeRegistration.js +69 -0
  96. package/src/react/utils/cashPayment.js +87 -0
  97. package/src/react/utils/commercialDocumentOrders.js +269 -0
  98. package/src/react/utils/dateRangeFilter.js +264 -0
  99. package/src/react/utils/deviceRuntime.js +193 -0
  100. package/src/react/utils/entityDisplay.js +231 -0
  101. package/src/react/utils/entityLog.js +649 -0
  102. package/src/react/utils/fileUrl.js +102 -0
  103. package/src/react/utils/frontendDebugLog.js +45 -0
  104. package/src/react/utils/googleMapsConfig.js +49 -0
  105. package/src/react/utils/importStatus.js +100 -0
  106. package/src/react/utils/invoiceDueDateMessages.js +14 -0
  107. package/src/react/utils/invoicePresentation.js +46 -0
  108. package/src/react/utils/logSettings.js +143 -0
  109. package/src/react/utils/maintenanceSettings.js +53 -0
  110. package/src/react/utils/managerOrderNotifications.js +523 -0
  111. package/src/react/utils/mapNavigation.js +76 -0
  112. package/src/react/utils/menuCatalogConfig.js +8 -0
  113. package/src/react/utils/menuCatalogDownload.js +157 -0
  114. package/src/react/utils/networkCameraDevices.js +175 -0
  115. package/src/react/utils/networkDeviceProfiles.js +135 -0
  116. package/src/react/utils/normalizedCatalogDownload.js +157 -0
  117. package/src/react/utils/notificationNavigation.js +94 -0
  118. package/src/react/utils/notificationSound.js +42 -0
  119. package/src/react/utils/paymentDevices.js +397 -0
  120. package/src/react/utils/paymentGatewayExecution.js +91 -0
  121. package/src/react/utils/paymentOptions.js +88 -0
  122. package/src/react/utils/peopleDisplay.js +39 -0
  123. package/src/react/utils/printerDevices.js +465 -0
  124. package/src/react/utils/remotePayment.js +61 -0
  125. package/src/react/utils/runtimeFooter.js +475 -0
  126. package/src/react/utils/runtimeLanguage.js +50 -0
  127. package/src/react/utils/runtimeMenu.js +224 -0
  128. package/src/react/utils/screenMetrics.js +30 -0
  129. package/src/react/utils/shopConfig.js +294 -0
  130. package/src/react/utils/shopFranchises.js +114 -0
  131. package/src/react/utils/socketRuntimePipeline.js +454 -0
  132. package/src/react/utils/spoolAckTracker.js +77 -0
  133. package/src/react/utils/storeColumns.js +427 -0
  134. package/src/react/utils/systemErrorChannel.js +109 -0
  135. package/src/react/utils/systemErrorMessage.js +67 -0
  136. package/src/react/utils/toastPresentation.js +53 -0
  137. package/src/react/utils/websocketSharedRuntime.js +826 -0
  138. package/src/store/acl/getters.js +4 -0
  139. package/src/store/acl/index.js +19 -0
  140. package/src/store/acl/mutation_types.js +4 -0
  141. package/src/store/acl/mutations.js +17 -0
  142. package/src/store/address/city.js +22 -0
  143. package/src/store/categories/category_file/index.js +25 -0
  144. package/src/store/categories/index.js +93 -0
  145. package/src/store/configs/customActions.js +131 -0
  146. package/src/store/configs/index.js +25 -0
  147. package/src/store/connections/customActions.js +26 -0
  148. package/src/store/connections/index.js +124 -0
  149. package/src/store/device/index.js +22 -0
  150. package/src/store/device_config/customActions.js +190 -0
  151. package/src/store/device_config/index.js +28 -0
  152. package/src/store/entity_log/customActions.js +63 -0
  153. package/src/store/entity_log/index.js +25 -0
  154. package/src/store/extra/data.js +85 -0
  155. package/src/store/extra/fields.js +88 -0
  156. package/src/store/file/actions.js +27 -0
  157. package/src/store/file/index.js +24 -0
  158. package/src/store/imports/index.js +88 -0
  159. package/src/store/print/customActions.js +251 -0
  160. package/src/store/print/index.js +28 -0
  161. package/src/store/printer/customActions.js +54 -0
  162. package/src/store/printer/index.js +26 -0
  163. package/src/store/runtime_debug/customActions.js +71 -0
  164. package/src/store/runtime_debug/index.js +30 -0
  165. package/src/store/status/index.js +65 -0
  166. package/src/store/timezones/index.js +43 -0
  167. package/src/store/websocket/customActions.js +24 -0
  168. package/src/store/websocket/index.js +28 -0
  169. package/src/tests/react/components/LauncherModeBridge.test.js +93 -0
  170. package/src/tests/react/config/deviceConfigBootstrap.test.js +337 -0
  171. package/src/tests/react/print/localPrintProvider.test.js +45 -0
  172. package/src/tests/react/utils/backgroundRuntimeRegistration.test.js +123 -0
  173. package/src/tests/react/utils/cashPayment.test.js +41 -0
  174. package/src/tests/react/utils/dateRangeFilter.test.mjs +29 -0
  175. package/src/tests/react/utils/entityDisplay.test.js +18 -0
  176. package/src/tests/react/utils/googleMapsConfig.test.js +32 -0
  177. package/src/tests/react/utils/importStatus.test.js +85 -0
  178. package/src/tests/react/utils/invoicePresentation.test.mjs +40 -0
  179. package/src/tests/react/utils/managerOrderNotifications.test.js +127 -0
  180. package/src/tests/react/utils/mapNavigation.test.js +58 -0
  181. package/src/tests/react/utils/notificationNavigation.test.js +39 -0
  182. package/src/tests/react/utils/notificationSound.test.js +27 -0
  183. package/src/tests/react/utils/paymentDevices.test.js +88 -0
  184. package/src/tests/react/utils/runtimeFooter.test.js +429 -0
  185. package/src/tests/react/utils/runtimeLanguage.test.js +80 -0
  186. package/src/tests/react/utils/runtimeMenu.test.js +174 -0
  187. package/src/tests/react/utils/shopFranchises.test.js +82 -0
  188. package/src/tests/react/utils/socketRuntimePipeline.test.js +124 -0
  189. package/src/tests/react/utils/spoolAckTracker.test.js +40 -0
  190. package/src/tests/react/utils/storeErrorBridge.test.js +66 -0
  191. package/src/tests/react/utils/systemErrorChannel.test.js +58 -0
  192. package/src/tests/react/utils/systemErrorMessage.test.js +59 -0
  193. package/src/tests/react/utils/toastPresentation.test.js +75 -0
  194. package/src/tests/react/utils/translate.test.mjs +396 -0
  195. package/src/tests/react/utils/websocketSharedRuntime.test.js +245 -0
  196. package/src/utils/apiEntryPoint.js +31 -0
  197. package/src/utils/appDomain.js +50 -0
  198. package/src/utils/config.js +14 -0
  199. package/src/utils/formatter.js +419 -0
  200. package/src/utils/integrationConfigs.js +79 -0
  201. package/src/utils/methods.js +23 -0
  202. package/src/utils/oauth.js +42 -0
  203. package/src/utils/translate.js +620 -0
@@ -0,0 +1,334 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ form: {
5
+ paddingBottom: 8,
6
+ },
7
+ field: {
8
+ marginBottom: 16,
9
+ },
10
+ label: {
11
+ fontSize: 11,
12
+ fontWeight: '700',
13
+ color: '#94A3B8',
14
+ textTransform: 'uppercase',
15
+ letterSpacing: 0.5,
16
+ marginBottom: 8,
17
+ },
18
+ input: {
19
+ borderWidth: 1,
20
+ borderColor: '#E2E8F0',
21
+ backgroundColor: '#F8FAFC',
22
+ paddingHorizontal: 14,
23
+ paddingVertical: 13,
24
+ borderRadius: 10,
25
+ fontSize: 15,
26
+ color: '#0F172A',
27
+ },
28
+ colorButton: {
29
+ flexDirection: 'row',
30
+ alignItems: 'center',
31
+ borderWidth: 1,
32
+ borderColor: '#E2E8F0',
33
+ backgroundColor: '#F8FAFC',
34
+ borderRadius: 10,
35
+ paddingHorizontal: 14,
36
+ paddingVertical: 13,
37
+ gap: 10,
38
+ },
39
+ colorSwatch: {
40
+ width: 24,
41
+ height: 24,
42
+ borderRadius: 6,
43
+ borderWidth: 1,
44
+ borderColor: 'rgba(0,0,0,0.12)',
45
+ },
46
+ colorButtonText: {
47
+ flex: 1,
48
+ fontSize: 15,
49
+ color: '#0F172A',
50
+ fontFamily: 'monospace',
51
+ },
52
+ colorGrid: {
53
+ flexDirection: 'row',
54
+ flexWrap: 'wrap',
55
+ padding: 16,
56
+ gap: 10,
57
+ justifyContent: 'center',
58
+ },
59
+ colorCell: {
60
+ padding: 2,
61
+ },
62
+ colorCircle: {
63
+ width: 44,
64
+ height: 44,
65
+ borderRadius: 22,
66
+ alignItems: 'center',
67
+ justifyContent: 'center',
68
+ borderWidth: 1,
69
+ borderColor: 'rgba(0,0,0,0.08)',
70
+ },
71
+ colorCircleWhite: {
72
+ borderColor: '#E2E8F0',
73
+ borderWidth: 2,
74
+ },
75
+ colorCircleSelected: {
76
+ borderWidth: 3,
77
+ borderColor: '#3B82F6',
78
+ },
79
+ hexInputRow: {
80
+ flexDirection: 'row',
81
+ alignItems: 'center',
82
+ gap: 10,
83
+ paddingHorizontal: 16,
84
+ paddingTop: 8,
85
+ paddingBottom: 24,
86
+ borderTopWidth: 1,
87
+ borderTopColor: '#F1F5F9',
88
+ },
89
+ hexInput: {
90
+ flex: 1,
91
+ borderWidth: 1,
92
+ borderColor: '#E2E8F0',
93
+ backgroundColor: '#F8FAFC',
94
+ borderRadius: 10,
95
+ paddingHorizontal: 12,
96
+ paddingVertical: 10,
97
+ fontSize: 15,
98
+ color: '#0F172A',
99
+ fontFamily: 'monospace',
100
+ },
101
+ hexApplyBtn: {
102
+ backgroundColor: '#3B82F6',
103
+ borderRadius: 10,
104
+ paddingHorizontal: 18,
105
+ paddingVertical: 11,
106
+ },
107
+ hexApplyText: {
108
+ color: '#fff',
109
+ fontWeight: '700',
110
+ fontSize: 15,
111
+ },
112
+ iconButton: {
113
+ flexDirection: 'row',
114
+ alignItems: 'center',
115
+ borderWidth: 1,
116
+ borderColor: '#E2E8F0',
117
+ backgroundColor: '#F8FAFC',
118
+ borderRadius: 10,
119
+ paddingHorizontal: 14,
120
+ paddingVertical: 13,
121
+ gap: 10,
122
+ },
123
+ iconButtonText: {
124
+ flex: 1,
125
+ fontSize: 15,
126
+ color: '#0F172A',
127
+ },
128
+ emptyPickerText: {
129
+ color: '#CBD5E1',
130
+ },
131
+ iconSearchWrap: {
132
+ flexDirection: 'row',
133
+ alignItems: 'center',
134
+ marginHorizontal: 16,
135
+ marginBottom: 8,
136
+ paddingHorizontal: 12,
137
+ paddingVertical: 10,
138
+ backgroundColor: '#F8FAFC',
139
+ borderRadius: 10,
140
+ borderWidth: 1,
141
+ borderColor: '#E2E8F0',
142
+ },
143
+ searchIcon: {
144
+ marginRight: 8,
145
+ },
146
+ iconSearchInput: {
147
+ flex: 1,
148
+ fontSize: 15,
149
+ color: '#0F172A',
150
+ padding: 0,
151
+ },
152
+ iconNoneRow: {
153
+ flexDirection: 'row',
154
+ alignItems: 'center',
155
+ paddingVertical: 12,
156
+ paddingHorizontal: 16,
157
+ borderBottomWidth: 1,
158
+ borderBottomColor: '#F1F5F9',
159
+ marginBottom: 4,
160
+ },
161
+ iconNoneCircle: {
162
+ width: 32,
163
+ height: 32,
164
+ borderRadius: 8,
165
+ backgroundColor: '#F1F5F9',
166
+ alignItems: 'center',
167
+ justifyContent: 'center',
168
+ marginRight: 12,
169
+ },
170
+ iconNoneText: {
171
+ flex: 1,
172
+ fontSize: 14,
173
+ color: '#64748B',
174
+ },
175
+ iconGrid: {
176
+ paddingHorizontal: 12,
177
+ paddingBottom: 24,
178
+ },
179
+ iconList: {
180
+ maxHeight: 340,
181
+ },
182
+ iconCell: {
183
+ flex: 1,
184
+ alignItems: 'center',
185
+ paddingVertical: 12,
186
+ marginHorizontal: 2,
187
+ borderRadius: 10,
188
+ backgroundColor: '#F8FAFC',
189
+ marginBottom: 6,
190
+ },
191
+ iconCellSelected: {
192
+ backgroundColor: '#EFF6FF',
193
+ borderWidth: 1,
194
+ borderColor: '#BFDBFE',
195
+ },
196
+ iconCellLabel: {
197
+ fontSize: 9,
198
+ color: '#64748B',
199
+ marginTop: 4,
200
+ textAlign: 'center',
201
+ },
202
+ iconCellLabelSelected: {
203
+ color: '#3B82F6',
204
+ },
205
+ parentColorDot: {
206
+ width: 12,
207
+ height: 12,
208
+ borderRadius: 6,
209
+ borderWidth: 1,
210
+ borderColor: 'rgba(0,0,0,0.1)',
211
+ },
212
+ parentSearchList: {
213
+ maxHeight: 380,
214
+ },
215
+ parentRow: {
216
+ flexDirection: 'row',
217
+ alignItems: 'center',
218
+ paddingVertical: 14,
219
+ paddingHorizontal: 16,
220
+ borderBottomWidth: 1,
221
+ borderBottomColor: '#F8FAFC',
222
+ },
223
+ parentLeadingIcon: {
224
+ marginRight: 10,
225
+ },
226
+ parentColorDotSpacing: {
227
+ marginRight: 10,
228
+ },
229
+ parentIconSpacing: {
230
+ marginRight: 6,
231
+ },
232
+ parentRowText: {
233
+ flex: 1,
234
+ fontSize: 15,
235
+ color: '#0F172A',
236
+ },
237
+ parentRowTextMuted: {
238
+ color: '#94A3B8',
239
+ },
240
+ parentRowTextSelected: {
241
+ color: '#3B82F6',
242
+ fontWeight: '700',
243
+ },
244
+ parentSelectedIcon: {
245
+ marginLeft: 'auto',
246
+ },
247
+ parentEmpty: {
248
+ paddingVertical: 32,
249
+ alignItems: 'center',
250
+ },
251
+ parentEmptyText: {
252
+ fontSize: 14,
253
+ color: '#94A3B8',
254
+ },
255
+ channelWrap: {
256
+ flexDirection: 'row',
257
+ flexWrap: 'wrap',
258
+ gap: 8,
259
+ },
260
+ channelChip: {
261
+ flexDirection: 'row',
262
+ alignItems: 'center',
263
+ paddingHorizontal: 12,
264
+ paddingVertical: 8,
265
+ borderRadius: 20,
266
+ borderWidth: 1.5,
267
+ borderColor: '#E2E8F0',
268
+ backgroundColor: '#F8FAFC',
269
+ },
270
+ channelChipActive: {
271
+ backgroundColor: '#0F172A',
272
+ borderColor: '#0F172A',
273
+ },
274
+ channelChipText: {
275
+ fontSize: 13,
276
+ fontWeight: '600',
277
+ color: '#475569',
278
+ },
279
+ channelChipTextActive: {
280
+ color: '#fff',
281
+ },
282
+ channelIcon: {
283
+ marginRight: 5,
284
+ },
285
+ modalOverlay: {
286
+ flex: 1,
287
+ backgroundColor: 'rgba(0,0,0,0.4)',
288
+ },
289
+ modalSheet: {
290
+ backgroundColor: '#fff',
291
+ borderTopLeftRadius: 24,
292
+ borderTopRightRadius: 24,
293
+ maxHeight: '80%',
294
+ paddingBottom: 0,
295
+ },
296
+ modalHandle: {
297
+ width: 40,
298
+ height: 4,
299
+ borderRadius: 2,
300
+ backgroundColor: '#E2E8F0',
301
+ alignSelf: 'center',
302
+ marginTop: 10,
303
+ marginBottom: 4,
304
+ },
305
+ modalHeader: {
306
+ flexDirection: 'row',
307
+ justifyContent: 'space-between',
308
+ alignItems: 'center',
309
+ paddingHorizontal: 20,
310
+ paddingVertical: 14,
311
+ borderBottomWidth: 1,
312
+ borderBottomColor: '#F1F5F9',
313
+ },
314
+ modalTitle: {
315
+ fontSize: 16,
316
+ fontWeight: '700',
317
+ color: '#0F172A',
318
+ },
319
+ modalClose: {
320
+ width: 32,
321
+ height: 32,
322
+ borderRadius: 16,
323
+ backgroundColor: '#F8FAFC',
324
+ alignItems: 'center',
325
+ justifyContent: 'center',
326
+ },
327
+ });
328
+
329
+ export default styles;
330
+
331
+ export const inlineStyle_240_75 = {
332
+ marginRight: 8,
333
+ };
334
+
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Modal, View, Text, TouchableOpacity } from 'react-native';
3
+ import styles from './ConfirmModal.styles';
4
+
5
+ export const ConfirmModal = ({ visible, title, message, onConfirm, onCancel }) => {
6
+ return (
7
+ <Modal visible={visible} transparent animationType="fade">
8
+ <View style={styles.overlay}>
9
+ <View style={styles.card}>
10
+ <Text style={styles.title}>{title}</Text>
11
+ <Text style={styles.message}>{message}</Text>
12
+ <View style={styles.actions}>
13
+ <TouchableOpacity onPress={onCancel} style={styles.cancelButton}>
14
+ <Text>{global.t?.t('confirmModal', 'button', 'cancel')}</Text>
15
+ </TouchableOpacity>
16
+ <TouchableOpacity onPress={onConfirm} style={styles.confirmButton}>
17
+ <Text style={styles.confirmButtonText}>{global.t?.t('confirmModal', 'button', 'confirm')}</Text>
18
+ </TouchableOpacity>
19
+ </View>
20
+ </View>
21
+ </View>
22
+ </Modal>
23
+ );
24
+ };
@@ -0,0 +1,43 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ overlay: {
5
+ flex: 1,
6
+ justifyContent: 'center',
7
+ alignItems: 'center',
8
+ backgroundColor: 'rgba(0,0,0,0.5)',
9
+ },
10
+ card: {
11
+ backgroundColor: '#fff',
12
+ padding: 20,
13
+ borderRadius: 10,
14
+ width: '80%',
15
+ },
16
+ title: {
17
+ fontSize: 18,
18
+ fontWeight: 'bold',
19
+ marginBottom: 10,
20
+ },
21
+ message: {
22
+ fontSize: 14,
23
+ marginBottom: 20,
24
+ },
25
+ actions: {
26
+ flexDirection: 'row',
27
+ justifyContent: 'flex-end',
28
+ gap: 10,
29
+ },
30
+ cancelButton: {
31
+ padding: 10,
32
+ },
33
+ confirmButton: {
34
+ padding: 10,
35
+ backgroundColor: '#007AFF',
36
+ borderRadius: 5,
37
+ },
38
+ confirmButtonText: {
39
+ color: '#fff',
40
+ },
41
+ });
42
+
43
+ export default styles;
@@ -0,0 +1,69 @@
1
+ import React, {useMemo, useState} from 'react';
2
+ import {Modal, Text, TouchableOpacity, View} from 'react-native';
3
+ import {MaterialCommunityIcons} from '@expo/vector-icons';
4
+ import styles from './ContextHelpButton.styles';
5
+
6
+ const normalizeLines = value => {
7
+ if (Array.isArray(value)) {
8
+ return value.map(item => String(item ?? '').trim()).filter(Boolean);
9
+ }
10
+
11
+ return String(value ?? '')
12
+ .split(/\n+/)
13
+ .map(line => line.trim())
14
+ .filter(Boolean);
15
+ };
16
+
17
+ const ContextHelpButton = ({
18
+ title = '',
19
+ message = '',
20
+ iconName = 'help-circle-outline',
21
+ iconColor = '#0EA5E9',
22
+ iconSize = 16,
23
+ accessibilityLabel = '',
24
+ }) => {
25
+ const [visible, setVisible] = useState(false);
26
+ const lines = useMemo(() => normalizeLines(message), [message]);
27
+ const label = String(title || accessibilityLabel || 'Ajuda').trim();
28
+
29
+ return (
30
+ <>
31
+ <TouchableOpacity
32
+ onPress={() => setVisible(true)}
33
+ style={styles.trigger}
34
+ accessibilityRole="button"
35
+ accessibilityLabel={label}
36
+ >
37
+ <MaterialCommunityIcons name={iconName} size={iconSize} color={iconColor} />
38
+ </TouchableOpacity>
39
+
40
+ <Modal visible={visible} transparent animationType="fade" onRequestClose={() => setVisible(false)}>
41
+ <View style={styles.overlay}>
42
+ <View style={styles.card}>
43
+ <View style={styles.header}>
44
+ <Text style={styles.title}>{label}</Text>
45
+ <TouchableOpacity
46
+ onPress={() => setVisible(false)}
47
+ style={styles.closeButton}
48
+ accessibilityRole="button"
49
+ accessibilityLabel="Fechar"
50
+ >
51
+ <MaterialCommunityIcons name="close" size={16} color="#0F172A" />
52
+ </TouchableOpacity>
53
+ </View>
54
+
55
+ <View style={styles.body}>
56
+ {lines.map((line, index) => (
57
+ <Text key={`${label}-${index}-${line}`} style={styles.message}>
58
+ {line}
59
+ </Text>
60
+ ))}
61
+ </View>
62
+ </View>
63
+ </View>
64
+ </Modal>
65
+ </>
66
+ );
67
+ };
68
+
69
+ export default ContextHelpButton;
@@ -0,0 +1,62 @@
1
+ import {StyleSheet} from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ trigger: {
5
+ width: 22,
6
+ height: 22,
7
+ borderRadius: 11,
8
+ borderWidth: 1,
9
+ borderColor: '#0EA5E9',
10
+ backgroundColor: '#EFF8FF',
11
+ alignItems: 'center',
12
+ justifyContent: 'center',
13
+ },
14
+ overlay: {
15
+ flex: 1,
16
+ backgroundColor: 'rgba(15, 23, 42, 0.45)',
17
+ alignItems: 'center',
18
+ justifyContent: 'center',
19
+ padding: 16,
20
+ },
21
+ card: {
22
+ width: '100%',
23
+ maxWidth: 360,
24
+ borderRadius: 16,
25
+ borderWidth: 1,
26
+ borderColor: '#BFDBFE',
27
+ backgroundColor: '#FFFFFF',
28
+ padding: 14,
29
+ gap: 12,
30
+ },
31
+ header: {
32
+ flexDirection: 'row',
33
+ alignItems: 'center',
34
+ justifyContent: 'space-between',
35
+ gap: 12,
36
+ },
37
+ title: {
38
+ flex: 1,
39
+ color: '#0F172A',
40
+ fontSize: 14,
41
+ fontWeight: '900',
42
+ },
43
+ closeButton: {
44
+ width: 26,
45
+ height: 26,
46
+ borderRadius: 13,
47
+ alignItems: 'center',
48
+ justifyContent: 'center',
49
+ backgroundColor: '#F8FAFC',
50
+ },
51
+ body: {
52
+ gap: 8,
53
+ },
54
+ message: {
55
+ color: '#334155',
56
+ fontSize: 12,
57
+ fontWeight: '700',
58
+ lineHeight: 16,
59
+ },
60
+ })
61
+
62
+ export default styles