@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.
- package/.github/agents/developer.agent.md +30 -0
- package/.github/agents/devops.agent.md +30 -0
- package/.github/agents/qa.agent.md +30 -0
- package/.github/agents/security.agent.md +30 -0
- package/.github/workflows/npmjs.yml +35 -0
- package/.github/workflows/pull-request-checks.yml +19 -0
- package/.scrutinizer.yml +24 -0
- package/FUNDING.yml +1 -0
- package/package.json +28 -0
- package/src/api/fetch.js +74 -0
- package/src/api/index.js +155 -0
- package/src/api/localDB.js +131 -0
- package/src/api/queue.js +66 -0
- package/src/react/assets/tap.mp3 +0 -0
- package/src/react/components/AddImportModal.js +157 -0
- package/src/react/components/AddImportModal.styles.js +81 -0
- package/src/react/components/BackgroundRuntimeBridge.js +219 -0
- package/src/react/components/BottomNavigationBar.config.js +238 -0
- package/src/react/components/BottomNavigationBar.js +120 -0
- package/src/react/components/BottomNavigationBar.styles.js +110 -0
- package/src/react/components/CategoryForm.js +572 -0
- package/src/react/components/CategoryForm.styles.js +334 -0
- package/src/react/components/ConfirmModal.js +24 -0
- package/src/react/components/ConfirmModal.styles.js +43 -0
- package/src/react/components/ContextHelpButton.js +69 -0
- package/src/react/components/ContextHelpButton.styles.js +62 -0
- package/src/react/components/DefaultProvider.native.js +848 -0
- package/src/react/components/DefaultProvider.styles.js +21 -0
- package/src/react/components/DefaultProvider.web.js +909 -0
- package/src/react/components/DeliveryPushBridge.native.js +314 -0
- package/src/react/components/DeliveryPushBridge.web.js +5 -0
- package/src/react/components/DeviceAlertSoundService.js +499 -0
- package/src/react/components/EntityLogContent.js +909 -0
- package/src/react/components/EntityLogContent.styles.js +400 -0
- package/src/react/components/EventBus.js +12 -0
- package/src/react/components/KioskModeBridge.js +65 -0
- package/src/react/components/LauncherModeBridge.js +47 -0
- package/src/react/components/LinkedOrderProductsTab.js +388 -0
- package/src/react/components/LinkedOrderProductsTab.styles.js +180 -0
- package/src/react/components/ManagerPushBridge.native.js +345 -0
- package/src/react/components/MessageService.js +314 -0
- package/src/react/components/Paywall/Google.js +89 -0
- package/src/react/components/PrintService.js +778 -0
- package/src/react/components/ProductCatalogCacheService.js +45 -0
- package/src/react/components/RemoteCheckoutService.js +292 -0
- package/src/react/components/RuntimeBottomNavigationBar.js +151 -0
- package/src/react/components/RuntimeInfoFooter.js +214 -0
- package/src/react/components/RuntimeInfoFooter.styles.js +56 -0
- package/src/react/components/SystemErrorToast.js +29 -0
- package/src/react/components/SystemErrorToast.styles.js +38 -0
- package/src/react/components/TouchFeedbackProvider.js +65 -0
- package/src/react/components/UnifiedPaymentBar.js +155 -0
- package/src/react/components/UnifiedPaymentBar.styles.js +174 -0
- package/src/react/components/WebsocketListener.native.js +487 -0
- package/src/react/components/WebsocketListener.web.js +102 -0
- package/src/react/components/inputs/IdInput.js +49 -0
- package/src/react/components/inputs/IdInput.styles.js +26 -0
- package/src/react/components/inputs/InvoiceDueDateFilterInput.js +74 -0
- package/src/react/components/inputs/InvoiceDueDateFilterInput.styles.js +34 -0
- package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.js +115 -0
- package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.styles.js +39 -0
- package/src/react/components/lists/CategoriesList.js +56 -0
- package/src/react/components/lists/PaymentTypeList.js +55 -0
- package/src/react/components/lists/ReceiverList.js +56 -0
- package/src/react/components/lists/SelectList.styles.js +18 -0
- package/src/react/components/lists/StatusList.js +55 -0
- package/src/react/components/lists/WalletList.js +54 -0
- package/src/react/components/radio/Spotify.js +144 -0
- package/src/react/components/radio/Spotify.styles.js +32 -0
- package/src/react/components/radio/YouTube.js +82 -0
- package/src/react/components/radio/YouTube.styles.js +16 -0
- package/src/react/components/toastConfig.js +16 -0
- package/src/react/config/deviceConfigBootstrap.js +571 -0
- package/src/react/index.js +4 -0
- package/src/react/localStorage.js +30 -0
- package/src/react/pages/EntityLogPage.js +124 -0
- package/src/react/pages/EntityLogPage.styles.js +17 -0
- package/src/react/pages/GenericLogPage.js +760 -0
- package/src/react/pages/GenericLogPage.styles.js +401 -0
- package/src/react/pages/Imports.js +361 -0
- package/src/react/pages/Imports.styles.js +223 -0
- package/src/react/pages/SettingsPage/PaymentTypesByWalletTab.js +462 -0
- package/src/react/pages/SettingsPage/index.js +1171 -0
- package/src/react/pages/SettingsPage/index.styles.js +122 -0
- package/src/react/print/jobs.js +147 -0
- package/src/react/print/providers/local.js +53 -0
- package/src/react/print/providers/remote.js +81 -0
- package/src/react/print/selection.js +296 -0
- package/src/react/print/usePrintButtonController.js +474 -0
- package/src/react/router/routes.js +42 -0
- package/src/react/services/NetworkPrinterService.native.js +391 -0
- package/src/react/services/NetworkPrinterService.web.js +15 -0
- package/src/react/stores/index.js +128 -0
- package/src/react/stores/storeErrorBridge.js +36 -0
- package/src/react/utils/backgroundRuntimeRegistration.js +69 -0
- package/src/react/utils/cashPayment.js +87 -0
- package/src/react/utils/commercialDocumentOrders.js +269 -0
- package/src/react/utils/dateRangeFilter.js +264 -0
- package/src/react/utils/deviceRuntime.js +193 -0
- package/src/react/utils/entityDisplay.js +231 -0
- package/src/react/utils/entityLog.js +649 -0
- package/src/react/utils/fileUrl.js +102 -0
- package/src/react/utils/frontendDebugLog.js +45 -0
- package/src/react/utils/googleMapsConfig.js +49 -0
- package/src/react/utils/importStatus.js +100 -0
- package/src/react/utils/invoiceDueDateMessages.js +14 -0
- package/src/react/utils/invoicePresentation.js +46 -0
- package/src/react/utils/logSettings.js +143 -0
- package/src/react/utils/maintenanceSettings.js +53 -0
- package/src/react/utils/managerOrderNotifications.js +523 -0
- package/src/react/utils/mapNavigation.js +76 -0
- package/src/react/utils/menuCatalogConfig.js +8 -0
- package/src/react/utils/menuCatalogDownload.js +157 -0
- package/src/react/utils/networkCameraDevices.js +175 -0
- package/src/react/utils/networkDeviceProfiles.js +135 -0
- package/src/react/utils/normalizedCatalogDownload.js +157 -0
- package/src/react/utils/notificationNavigation.js +94 -0
- package/src/react/utils/notificationSound.js +42 -0
- package/src/react/utils/paymentDevices.js +397 -0
- package/src/react/utils/paymentGatewayExecution.js +91 -0
- package/src/react/utils/paymentOptions.js +88 -0
- package/src/react/utils/peopleDisplay.js +39 -0
- package/src/react/utils/printerDevices.js +465 -0
- package/src/react/utils/remotePayment.js +61 -0
- package/src/react/utils/runtimeFooter.js +475 -0
- package/src/react/utils/runtimeLanguage.js +50 -0
- package/src/react/utils/runtimeMenu.js +224 -0
- package/src/react/utils/screenMetrics.js +30 -0
- package/src/react/utils/shopConfig.js +294 -0
- package/src/react/utils/shopFranchises.js +114 -0
- package/src/react/utils/socketRuntimePipeline.js +454 -0
- package/src/react/utils/spoolAckTracker.js +77 -0
- package/src/react/utils/storeColumns.js +427 -0
- package/src/react/utils/systemErrorChannel.js +109 -0
- package/src/react/utils/systemErrorMessage.js +67 -0
- package/src/react/utils/toastPresentation.js +53 -0
- package/src/react/utils/websocketSharedRuntime.js +826 -0
- package/src/store/acl/getters.js +4 -0
- package/src/store/acl/index.js +19 -0
- package/src/store/acl/mutation_types.js +4 -0
- package/src/store/acl/mutations.js +17 -0
- package/src/store/address/city.js +22 -0
- package/src/store/categories/category_file/index.js +25 -0
- package/src/store/categories/index.js +93 -0
- package/src/store/configs/customActions.js +131 -0
- package/src/store/configs/index.js +25 -0
- package/src/store/connections/customActions.js +26 -0
- package/src/store/connections/index.js +124 -0
- package/src/store/device/index.js +22 -0
- package/src/store/device_config/customActions.js +190 -0
- package/src/store/device_config/index.js +28 -0
- package/src/store/entity_log/customActions.js +63 -0
- package/src/store/entity_log/index.js +25 -0
- package/src/store/extra/data.js +85 -0
- package/src/store/extra/fields.js +88 -0
- package/src/store/file/actions.js +27 -0
- package/src/store/file/index.js +24 -0
- package/src/store/imports/index.js +88 -0
- package/src/store/print/customActions.js +251 -0
- package/src/store/print/index.js +28 -0
- package/src/store/printer/customActions.js +54 -0
- package/src/store/printer/index.js +26 -0
- package/src/store/runtime_debug/customActions.js +71 -0
- package/src/store/runtime_debug/index.js +30 -0
- package/src/store/status/index.js +65 -0
- package/src/store/timezones/index.js +43 -0
- package/src/store/websocket/customActions.js +24 -0
- package/src/store/websocket/index.js +28 -0
- package/src/tests/react/components/LauncherModeBridge.test.js +93 -0
- package/src/tests/react/config/deviceConfigBootstrap.test.js +337 -0
- package/src/tests/react/print/localPrintProvider.test.js +45 -0
- package/src/tests/react/utils/backgroundRuntimeRegistration.test.js +123 -0
- package/src/tests/react/utils/cashPayment.test.js +41 -0
- package/src/tests/react/utils/dateRangeFilter.test.mjs +29 -0
- package/src/tests/react/utils/entityDisplay.test.js +18 -0
- package/src/tests/react/utils/googleMapsConfig.test.js +32 -0
- package/src/tests/react/utils/importStatus.test.js +85 -0
- package/src/tests/react/utils/invoicePresentation.test.mjs +40 -0
- package/src/tests/react/utils/managerOrderNotifications.test.js +127 -0
- package/src/tests/react/utils/mapNavigation.test.js +58 -0
- package/src/tests/react/utils/notificationNavigation.test.js +39 -0
- package/src/tests/react/utils/notificationSound.test.js +27 -0
- package/src/tests/react/utils/paymentDevices.test.js +88 -0
- package/src/tests/react/utils/runtimeFooter.test.js +429 -0
- package/src/tests/react/utils/runtimeLanguage.test.js +80 -0
- package/src/tests/react/utils/runtimeMenu.test.js +174 -0
- package/src/tests/react/utils/shopFranchises.test.js +82 -0
- package/src/tests/react/utils/socketRuntimePipeline.test.js +124 -0
- package/src/tests/react/utils/spoolAckTracker.test.js +40 -0
- package/src/tests/react/utils/storeErrorBridge.test.js +66 -0
- package/src/tests/react/utils/systemErrorChannel.test.js +58 -0
- package/src/tests/react/utils/systemErrorMessage.test.js +59 -0
- package/src/tests/react/utils/toastPresentation.test.js +75 -0
- package/src/tests/react/utils/translate.test.mjs +396 -0
- package/src/tests/react/utils/websocketSharedRuntime.test.js +245 -0
- package/src/utils/apiEntryPoint.js +31 -0
- package/src/utils/appDomain.js +50 -0
- package/src/utils/config.js +14 -0
- package/src/utils/formatter.js +419 -0
- package/src/utils/integrationConfigs.js +79 -0
- package/src/utils/methods.js +23 -0
- package/src/utils/oauth.js +42 -0
- package/src/utils/translate.js +620 -0
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Contract imported from AGENTS.md
|
|
3
|
+
* ## Escopo
|
|
4
|
+
* - Modulo compartilhado de infraestrutura do front.
|
|
5
|
+
* - Reune providers, servicos globais, componentes comuns, rotas compartilhadas, stores e utils.
|
|
6
|
+
*
|
|
7
|
+
* ## Estado
|
|
8
|
+
* - Este modulo tem implementacao ativa em `src/react` e deve constar em novos prompts.
|
|
9
|
+
*
|
|
10
|
+
* ## Quando usar
|
|
11
|
+
* - Prompts sobre helpers compartilhados, `DefaultProvider`, mensageria, impressao, importacao, logs, devices, gateways e utilitarios cross-app.
|
|
12
|
+
* - O helper compartilhado de dinheiro/manual fica aqui e pode ser reutilizado por `ui-orders`, listeners remotos e outros gateways.
|
|
13
|
+
* - A execucao tecnica dos gateways operacionais compartilhados, como `Cielo` e `Infinite Pay`, pode ficar aqui para ser reutilizada pelo checkout principal e pelo listener remoto.
|
|
14
|
+
* - O protocolo de ida e volta do pagamento remoto entre web e device deve ficar centralizado aqui, para que checkout e listener remoto compartilhem a mesma chave de requisicao e o mesmo formato de resposta.
|
|
15
|
+
* - O bridge nativo de kiosk fica aqui e deve apenas ligar/desligar a infraestrutura Android quando `APP_TYPE=POS` e a configuracao `android-kiosk-enabled` estiver ligada. A regra de fluxo do totem continua no modulo dono e nao depende do modo operacional salvo.
|
|
16
|
+
*
|
|
17
|
+
* ## Limites
|
|
18
|
+
* - Nao mover para `ui-common` regra de negocio que pertence claramente a `ui-orders`, `ui-shop`, `ui-manager` ou outro modulo dono.
|
|
19
|
+
* - `ui-common` pode centralizar a parte tecnica de pagamento sem gateway, mas a decisao de quando usar dinheiro continua no modulo dono do fluxo.
|
|
20
|
+
* - `ui-common` nao deve montar uma segunda UI de checkout para gateway. Quando houver listener remoto, ele deve executar o mesmo helper compartilhado do fluxo principal.
|
|
21
|
+
* - Quando a implementacao tecnica do gateway ficar melhor organizada em arquivos separados por provedor no modulo dono, `ui-common` deve apenas orquestrar ou reaproveitar esses arquivos, sem recriar fluxo paralelo.
|
|
22
|
+
*
|
|
23
|
+
* ## Regras de mensageria
|
|
24
|
+
* - Erros visuais transitrios do sistema devem sair por um unico componente compartilhado ligado ao `MessageService`.
|
|
25
|
+
* - `showError` e o ponto canonico para esse feedback. Ele recebe string ou objeto de erro, exibe por alguns segundos e some sozinho.
|
|
26
|
+
* - O card/modal transitorio de erro do `MessageService` e a unica UI permitida para esse feedback. Nao criar segunda tela de erro no modulo.
|
|
27
|
+
* - Stores compartilhadas tambem devem usar esse fluxo. Quando uma store fizer `SET_ERROR`, o erro visual precisa sair pelo `MessageService`, nunca por caixa local do `StateStore`.
|
|
28
|
+
* - `StateStore` e o componente canonico de loading/saving. Ele pode receber `store` e `stores` para configurar quais estados acompanhar, mas nao deve ser substituido por loaders locais nas telas consumidoras.
|
|
29
|
+
* - O `StateStore` deve ler `isLoading` e `isSaving` diretamente dos stores; o erro deve entrar pelo contrato de `SET_ERROR` e ser publicado pelo `storeErrorBridge`, que alimenta o `MessageService`.
|
|
30
|
+
* - Nao criar banners, alerts ou toasts paralelos para erro quando o caso puder usar o `MessageService`.
|
|
31
|
+
* - O contrato canonico de erro HTTP do backend e o envelope do `HydratorService` com `@type: Error`, `hydra:title` e `hydra:description`; o `fetch` e os parsers compartilhados devem ler esse formato como fonte principal de mensagem.
|
|
32
|
+
*
|
|
33
|
+
* ## Regras de runtime em background
|
|
34
|
+
* - O `BackgroundRuntimeBridge` deve manter o registro nativo por package/app, device e empresa para permitir varios APKs instalados no mesmo Android.
|
|
35
|
+
* - O runtime de background pode ser religado pelo Android com `BOOT_COMPLETED` e `MY_PACKAGE_REPLACED`, reutilizando as inscricoes persistidas para seguir notificando mesmo sem a UI aberta.
|
|
36
|
+
* - Em nativo, `WebsocketListener.native.js` deve consumir o stream local exposto pelo `BackgroundRuntimeService`, nao abrir websocket direto no backend.
|
|
37
|
+
* - `WebsocketListener.web.js` e o fluxo web e deve usar runtime compartilhado com owner unico no browser via BroadcastChannel; nao abrir websocket direto do backend nem depender do runtime Android.
|
|
38
|
+
* - Mensagens entregues pelo runtime nativo devem ser marcadas com `source: 'background-runtime'`, mas todos os apps com som configurado devem continuar processando `order.created` para aviso sonoro mesmo que a notificacao do sistema tambem apareca.
|
|
39
|
+
* - O som configurado em `device_config` para `order.created` vale para qualquer `APP_TYPE`, incluindo KDS, Manager e PDV; deve ser enviado ao `BackgroundRuntimeService` como configuracao de device e tocado nativamente para funcionar mesmo com o app fechado.
|
|
40
|
+
* - A configuracao de som do Manager e por usuario e separada da configuracao do device; ela tambem deve ser enviada ao `BackgroundRuntimeService` como configuracao de usuario, sem virar regra global dos demais apps.
|
|
41
|
+
* - Quando a URL personalizada de audio estiver vazia, o runtime deve cair para o asset `src/assets/sound/caixa.m4a` empacotado no app. URL personalizada continua vencendo o fallback.
|
|
42
|
+
* - No `MANAGER` Android, o push FCM humano usa canal nativo com `caixa.m4a`; URL personalizada nao pode tocar quando a notificacao chega com o app fechado.
|
|
43
|
+
* - Alteracoes no protocolo local do runtime precisam manter compatibilidade entre o template do plugin e qualquer arquivo Android gerado.
|
|
44
|
+
*
|
|
45
|
+
* ## Regras de UI compartilhada
|
|
46
|
+
* - Componentes que implementam comportamento default de listagem/filtros pertencem a `ui-default`.
|
|
47
|
+
* - `ui-common` pode fornecer helpers e utilitarios usados por esses componentes, mas nao deve manter uma segunda implementacao de `DateShortcutFilter`, `CompactFilterSelector` ou componentes equivalentes de filtro de listagem.
|
|
48
|
+
* - `DefaultProvider` carrega `menus-people` com `myCompany` e `APP_TYPE` atual e grava o resultado normalizado em `theme.menus`.
|
|
49
|
+
* - Normalizacao de payload de menu runtime deve ficar em helper compartilhado neste modulo.
|
|
50
|
+
* - O `RuntimeInfoFooter` deve montar o texto como `nome (identificador) / versao`, usando em runtime web o IP externo lido de `/runtime/ip` e persistido na metadata do device, com `location.hostname` apenas como fallback. No nativo, deve priorizar a versao persistida na metadata do device salvo no backend e o mesmo identificador mostrado na lista de devices (`device_config.device.device`), com fallback local quando o backend ainda nao tiver esse valor.
|
|
51
|
+
* - O help contextual canônico deve ficar em `ui-common` como componente parametrizado acionado por `?`, com modal proprio e sem reaproveitar `ConfirmModal`. Telas consumidoras nao devem escrever explicacao fixa quando esse padrao estiver disponivel.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
import React, {useEffect, useState, useCallback, useMemo} from 'react';
|
|
55
|
+
|
|
56
|
+
import {
|
|
57
|
+
Text,
|
|
58
|
+
View,
|
|
59
|
+
ScrollView,
|
|
60
|
+
ActivityIndicator,
|
|
61
|
+
TouchableOpacity,
|
|
62
|
+
Switch,
|
|
63
|
+
Alert,
|
|
64
|
+
Platform,
|
|
65
|
+
TextInput,
|
|
66
|
+
} from 'react-native';
|
|
67
|
+
|
|
68
|
+
import {SafeAreaView} from 'react-native-safe-area-context';
|
|
69
|
+
import css from '@controleonline/ui-orders/src/react/css/orders';
|
|
70
|
+
import {useStore} from '@store';
|
|
71
|
+
import {useFocusEffect, useNavigation} from '@react-navigation/native';
|
|
72
|
+
import {Picker} from '@react-native-picker/picker';
|
|
73
|
+
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
74
|
+
import StateStore from '@controleonline/ui-layout/src/react/components/StateStore';
|
|
75
|
+
import packageJson from '@package';
|
|
76
|
+
import PaymentTypesByWalletTab from './PaymentTypesByWalletTab';
|
|
77
|
+
|
|
78
|
+
import {
|
|
79
|
+
appendScreenMetrics,
|
|
80
|
+
buildScreenMetrics,
|
|
81
|
+
hasScreenMetricsChanges,
|
|
82
|
+
} from '@controleonline/ui-common/src/react/utils/screenMetrics';
|
|
83
|
+
|
|
84
|
+
import {
|
|
85
|
+
CIELO_DEVICES,
|
|
86
|
+
DEVICE_ALERT_SOUND_ENABLED_KEY,
|
|
87
|
+
DEVICE_ALERT_SOUND_URL_KEY,
|
|
88
|
+
DEVICE_ORDER_VISIBILITY_COMPANY,
|
|
89
|
+
DEVICE_ORDER_VISIBILITY_DEVICE,
|
|
90
|
+
DEVICE_ORDER_VISIBILITY_KEY,
|
|
91
|
+
DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY,
|
|
92
|
+
isTruthyValue,
|
|
93
|
+
parseConfigsObject,
|
|
94
|
+
POS_CHECK_ORDER_MANAGEMENT_MODE_CONFIG_KEY,
|
|
95
|
+
POS_CHECK_ORDER_MANAGEMENT_MODE_EXISTING_ONLY,
|
|
96
|
+
POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE,
|
|
97
|
+
POS_CHECK_ORDER_TYPE_CONFIG_KEY,
|
|
98
|
+
POS_CHECK_ORDER_TYPE_NONE,
|
|
99
|
+
POS_CHECK_ORDER_TYPE_TAB,
|
|
100
|
+
POS_CHECK_ORDER_TYPE_TABLE,
|
|
101
|
+
resolveDefaultGateway,
|
|
102
|
+
resolveDeviceOrderVisibility,
|
|
103
|
+
resolvePosCheckOrderManagementMode,
|
|
104
|
+
resolvePosCheckOrderType,
|
|
105
|
+
} from '@controleonline/ui-common/src/react/config/deviceConfigBootstrap';
|
|
106
|
+
import {
|
|
107
|
+
PAYMENT_TYPE_IDS_CONFIG_KEY,
|
|
108
|
+
} from '@controleonline/ui-common/src/react/utils/paymentDevices';
|
|
109
|
+
|
|
110
|
+
import {isWebRuntimeDevice as resolveIsWebRuntimeDevice} from '@controleonline/ui-common/src/react/utils/deviceRuntime';
|
|
111
|
+
import {DEFAULT_NOTIFICATION_SOUND_FILE} from '@controleonline/ui-common/src/react/utils/notificationSound';
|
|
112
|
+
|
|
113
|
+
import {
|
|
114
|
+
inlineStyle_565_16,
|
|
115
|
+
inlineStyle_639_14,
|
|
116
|
+
inlineStyle_650_20,
|
|
117
|
+
inlineStyle_659_16,
|
|
118
|
+
inlineStyle_676_16,
|
|
119
|
+
inlineStyle_690_16,
|
|
120
|
+
inlineStyle_704_12,
|
|
121
|
+
inlineStyle_720_12,
|
|
122
|
+
inlineStyle_736_12,
|
|
123
|
+
inlineStyle_743_14,
|
|
124
|
+
inlineStyle_757_14,
|
|
125
|
+
inlineStyle_783_14,
|
|
126
|
+
inlineStyle_798_12,
|
|
127
|
+
inlineStyle_805_14,
|
|
128
|
+
inlineStyle_818_14,
|
|
129
|
+
inlineStyle_830_16,
|
|
130
|
+
inlineStyle_841_16,
|
|
131
|
+
inlineStyle_852_16,
|
|
132
|
+
inlineStyle_871_18,
|
|
133
|
+
inlineStyle_899_18,
|
|
134
|
+
} from './index.styles';
|
|
135
|
+
|
|
136
|
+
const Settings = () => {
|
|
137
|
+
const navigation = useNavigation();
|
|
138
|
+
const {styles, globalStyles} = css();
|
|
139
|
+
const walletStore = useStore('wallet');
|
|
140
|
+
const walletGetters = walletStore.getters;
|
|
141
|
+
const peopleStore = useStore('people');
|
|
142
|
+
const peopleGetters = peopleStore.getters;
|
|
143
|
+
const configsStore = useStore('configs');
|
|
144
|
+
const configsGetters = configsStore.getters;
|
|
145
|
+
const configActions = configsStore.actions;
|
|
146
|
+
const device_configStore = useStore('device_config');
|
|
147
|
+
const deviceConfigGetters = device_configStore.getters;
|
|
148
|
+
const deviceConfigsActions = device_configStore.actions;
|
|
149
|
+
const {item: device, isSaving: isDeviceConfigSaving} = deviceConfigGetters;
|
|
150
|
+
const {currentCompany} = peopleGetters;
|
|
151
|
+
const {isLoading: walletLoading} = walletGetters;
|
|
152
|
+
const {items: companyConfigs, isSaving} = configsGetters;
|
|
153
|
+
const withdrawWallet =
|
|
154
|
+
companyConfigs?.['pos-withdrawl-wallet'] ||
|
|
155
|
+
companyConfigs?.['pos-withdrawal-wallet'];
|
|
156
|
+
|
|
157
|
+
const [selectedMode, setSelectedMode] = useState(null);
|
|
158
|
+
const [printingMode, setPrintingMode] = useState('order');
|
|
159
|
+
const [selectedGateway, setSelectedGateway] = useState(null);
|
|
160
|
+
const [discovered, setDiscovered] = useState(false);
|
|
161
|
+
const deviceStore = useStore('device');
|
|
162
|
+
const deviceGetters = deviceStore.getters;
|
|
163
|
+
const {item: storagedDevice} = deviceGetters;
|
|
164
|
+
const packageVersion = packageJson?.version || packageJson?.default?.version;
|
|
165
|
+
const appVersion = packageVersion || storagedDevice?.appVersion;
|
|
166
|
+
|
|
167
|
+
const [checkType, setCheckType] = useState('manual');
|
|
168
|
+
const [checkOrderType, setCheckOrderType] = useState(POS_CHECK_ORDER_TYPE_NONE);
|
|
169
|
+
const [checkOrderManagementMode, setCheckOrderManagementMode] = useState(
|
|
170
|
+
POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE,
|
|
171
|
+
);
|
|
172
|
+
const [productInputType, setProductInputType] = useState('manual');
|
|
173
|
+
const [selectionType, setSelectionType] = useState('single');
|
|
174
|
+
const [showSound, setShowSound] = useState(false);
|
|
175
|
+
const [showVibration, setShowVibration] = useState(false);
|
|
176
|
+
const [orderVisibility, setOrderVisibility] = useState(DEVICE_ORDER_VISIBILITY_DEVICE);
|
|
177
|
+
const [alertSoundEnabled, setAlertSoundEnabled] = useState(false);
|
|
178
|
+
const [alertSoundUrl, setAlertSoundUrl] = useState('');
|
|
179
|
+
const [showRuntimeDebugInfo, setShowRuntimeDebugInfo] = useState(false);
|
|
180
|
+
const [configsLoaded, setConfigsLoaded] = useState(false);
|
|
181
|
+
const [deviceConfigsLoaded, setDeviceConfigsLoaded] = useState(false);
|
|
182
|
+
const [activeSettingsTab, setActiveSettingsTab] = useState('general');
|
|
183
|
+
const pickerMode = Platform.OS === 'android' ? 'dropdown' : undefined;
|
|
184
|
+
const settingsTabStyles = {
|
|
185
|
+
tabRow: {
|
|
186
|
+
flexDirection: 'row',
|
|
187
|
+
marginTop: 16,
|
|
188
|
+
marginBottom: 12,
|
|
189
|
+
borderRadius: 12,
|
|
190
|
+
borderColor: '#D6E4F0',
|
|
191
|
+
borderWidth: 1,
|
|
192
|
+
overflow: 'hidden',
|
|
193
|
+
backgroundColor: '#F8FAFC',
|
|
194
|
+
},
|
|
195
|
+
tabButton: {
|
|
196
|
+
alignItems: 'center',
|
|
197
|
+
backgroundColor: '#F8FAFC',
|
|
198
|
+
flex: 1,
|
|
199
|
+
justifyContent: 'center',
|
|
200
|
+
paddingVertical: 12,
|
|
201
|
+
},
|
|
202
|
+
tabButtonActive: {
|
|
203
|
+
backgroundColor: '#1B5587',
|
|
204
|
+
},
|
|
205
|
+
tabLabel: {
|
|
206
|
+
color: '#334155',
|
|
207
|
+
fontSize: 13,
|
|
208
|
+
fontWeight: '700',
|
|
209
|
+
},
|
|
210
|
+
tabLabelActive: {
|
|
211
|
+
color: '#FFFFFF',
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const defaultGateway = resolveDefaultGateway(storagedDevice);
|
|
216
|
+
const deviceManufacturer = String(storagedDevice?.manufacturer || '').toLowerCase();
|
|
217
|
+
const isEmulatorDevice = isTruthyValue(storagedDevice?.isEmulator);
|
|
218
|
+
const isCieloDevice = CIELO_DEVICES.includes(deviceManufacturer);
|
|
219
|
+
const showGatewayPicker = !isCieloDevice || isEmulatorDevice;
|
|
220
|
+
const allowCieloOption = isCieloDevice || isEmulatorDevice;
|
|
221
|
+
const isWebRuntimeDevice = resolveIsWebRuntimeDevice(storagedDevice);
|
|
222
|
+
|
|
223
|
+
const screenMetrics = useMemo(() => buildScreenMetrics(), []);
|
|
224
|
+
const runtimeCompanyConfigs = useMemo(
|
|
225
|
+
() =>
|
|
226
|
+
parseConfigsObject(
|
|
227
|
+
companyConfigs && Object.keys(companyConfigs).length > 0
|
|
228
|
+
? companyConfigs
|
|
229
|
+
: currentCompany?.configs,
|
|
230
|
+
),
|
|
231
|
+
[companyConfigs, currentCompany?.configs],
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const applyRuntimeCompanyConfigs = useCallback(() => {
|
|
235
|
+
const nextItem = {
|
|
236
|
+
...(device || {}),
|
|
237
|
+
device: {
|
|
238
|
+
id: storagedDevice?.id,
|
|
239
|
+
device: storagedDevice?.id,
|
|
240
|
+
},
|
|
241
|
+
people: currentCompany?.id ? '/people/' + currentCompany.id : device?.people,
|
|
242
|
+
configs: runtimeCompanyConfigs,
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
deviceConfigsActions.setItem(nextItem);
|
|
246
|
+
return nextItem;
|
|
247
|
+
}, [
|
|
248
|
+
currentCompany?.id,
|
|
249
|
+
device,
|
|
250
|
+
deviceConfigsActions,
|
|
251
|
+
runtimeCompanyConfigs,
|
|
252
|
+
storagedDevice?.id,
|
|
253
|
+
]);
|
|
254
|
+
|
|
255
|
+
const persistDeviceConfigs = useCallback(
|
|
256
|
+
nextConfigs => {
|
|
257
|
+
if (!currentCompany?.id) {
|
|
258
|
+
return Promise.resolve(null);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return deviceConfigsActions.addDeviceConfigs({
|
|
262
|
+
configs: JSON.stringify(nextConfigs),
|
|
263
|
+
people: '/people/' + currentCompany.id,
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
[
|
|
267
|
+
currentCompany?.id,
|
|
268
|
+
deviceConfigsActions,
|
|
269
|
+
],
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const persistCompanyPaymentConfigs = useCallback(
|
|
273
|
+
nextSelectedPaymentTypeIds => {
|
|
274
|
+
if (!currentCompany?.id) {
|
|
275
|
+
return Promise.resolve(null);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return configActions
|
|
279
|
+
.addConfigs({
|
|
280
|
+
configKey: PAYMENT_TYPE_IDS_CONFIG_KEY,
|
|
281
|
+
configValue: JSON.stringify(nextSelectedPaymentTypeIds || []),
|
|
282
|
+
people: '/people/' + currentCompany.id,
|
|
283
|
+
module: 4,
|
|
284
|
+
visibility: 'public',
|
|
285
|
+
})
|
|
286
|
+
.then(async data => {
|
|
287
|
+
await configActions.discoveryMainConfigs({
|
|
288
|
+
people: '/people/' + currentCompany.id,
|
|
289
|
+
});
|
|
290
|
+
return data;
|
|
291
|
+
});
|
|
292
|
+
},
|
|
293
|
+
[configActions, currentCompany?.id],
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
const createDefaultConfigs = useCallback(() => {
|
|
297
|
+
|
|
298
|
+
// ALEMAC //
|
|
299
|
+
if (!currentCompany?.id || configsLoaded || device === undefined || device === null) return;
|
|
300
|
+
|
|
301
|
+
if (isWebRuntimeDevice) {
|
|
302
|
+
applyRuntimeCompanyConfigs();
|
|
303
|
+
setConfigsLoaded(true);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let lc = {...(device?.configs || {})};
|
|
308
|
+
let needsUpdate = false;
|
|
309
|
+
|
|
310
|
+
const metricsConfigs = appendScreenMetrics(lc);
|
|
311
|
+
if (hasScreenMetricsChanges(lc, metricsConfigs)) {
|
|
312
|
+
lc = metricsConfigs;
|
|
313
|
+
needsUpdate = true;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Verifica cada config e cria o padrão se não existir
|
|
317
|
+
if (!lc['pos-type']) {
|
|
318
|
+
lc['pos-type'] = 'full';
|
|
319
|
+
needsUpdate = true;
|
|
320
|
+
}
|
|
321
|
+
if (!lc['print-mode']) {
|
|
322
|
+
lc['print-mode'] = 'order';
|
|
323
|
+
needsUpdate = true;
|
|
324
|
+
}
|
|
325
|
+
if (!lc['check-type']) {
|
|
326
|
+
lc['check-type'] = 'manual';
|
|
327
|
+
needsUpdate = true;
|
|
328
|
+
}
|
|
329
|
+
if (!lc[POS_CHECK_ORDER_TYPE_CONFIG_KEY]) {
|
|
330
|
+
lc[POS_CHECK_ORDER_TYPE_CONFIG_KEY] = POS_CHECK_ORDER_TYPE_NONE;
|
|
331
|
+
needsUpdate = true;
|
|
332
|
+
}
|
|
333
|
+
if (!lc[POS_CHECK_ORDER_MANAGEMENT_MODE_CONFIG_KEY]) {
|
|
334
|
+
lc[POS_CHECK_ORDER_MANAGEMENT_MODE_CONFIG_KEY] =
|
|
335
|
+
POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE;
|
|
336
|
+
needsUpdate = true;
|
|
337
|
+
}
|
|
338
|
+
if (!lc['product-input-type']) {
|
|
339
|
+
lc['product-input-type'] = 'manual';
|
|
340
|
+
needsUpdate = true;
|
|
341
|
+
}
|
|
342
|
+
if (!lc['selection-type']) {
|
|
343
|
+
lc['selection-type'] = 'single';
|
|
344
|
+
needsUpdate = true;
|
|
345
|
+
}
|
|
346
|
+
if (!lc['sound']) {
|
|
347
|
+
lc['sound'] = '0';
|
|
348
|
+
needsUpdate = true;
|
|
349
|
+
}
|
|
350
|
+
if (!lc['vibration']) {
|
|
351
|
+
lc['vibration'] = '0';
|
|
352
|
+
needsUpdate = true;
|
|
353
|
+
}
|
|
354
|
+
if (!lc[DEVICE_ORDER_VISIBILITY_KEY]) {
|
|
355
|
+
lc[DEVICE_ORDER_VISIBILITY_KEY] = DEVICE_ORDER_VISIBILITY_DEVICE;
|
|
356
|
+
needsUpdate = true;
|
|
357
|
+
}
|
|
358
|
+
if (lc[DEVICE_ALERT_SOUND_ENABLED_KEY] === undefined || lc[DEVICE_ALERT_SOUND_ENABLED_KEY] === null) {
|
|
359
|
+
lc[DEVICE_ALERT_SOUND_ENABLED_KEY] = '0';
|
|
360
|
+
needsUpdate = true;
|
|
361
|
+
}
|
|
362
|
+
if (lc[DEVICE_ALERT_SOUND_URL_KEY] === undefined || lc[DEVICE_ALERT_SOUND_URL_KEY] === null) {
|
|
363
|
+
lc[DEVICE_ALERT_SOUND_URL_KEY] = '';
|
|
364
|
+
needsUpdate = true;
|
|
365
|
+
}
|
|
366
|
+
if (lc[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY] === undefined || lc[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY] === null) {
|
|
367
|
+
lc[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY] = '0';
|
|
368
|
+
needsUpdate = true;
|
|
369
|
+
}
|
|
370
|
+
if (!lc['config-version']) {
|
|
371
|
+
// ALEMAC // pega o appVersion ao invés do buildNumber
|
|
372
|
+
lc['config-version'] = appVersion;
|
|
373
|
+
needsUpdate = true;
|
|
374
|
+
}
|
|
375
|
+
if (!lc['pos-gateway']) {
|
|
376
|
+
lc['pos-gateway'] = defaultGateway;
|
|
377
|
+
needsUpdate = true;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Se faltava alguma coisa, grava tudo no banco
|
|
381
|
+
if (needsUpdate && currentCompany?.id) {
|
|
382
|
+
persistDeviceConfigs(lc)
|
|
383
|
+
.then(() => {
|
|
384
|
+
setConfigsLoaded(true);
|
|
385
|
+
})
|
|
386
|
+
.catch(err => {
|
|
387
|
+
console.error('addDeviceConfigs (createDefaultConfigs) failed:', err);
|
|
388
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
setConfigsLoaded(true);
|
|
395
|
+
}, [
|
|
396
|
+
device,
|
|
397
|
+
currentCompany?.id,
|
|
398
|
+
configsLoaded,
|
|
399
|
+
storagedDevice,
|
|
400
|
+
defaultGateway,
|
|
401
|
+
appVersion,
|
|
402
|
+
applyRuntimeCompanyConfigs,
|
|
403
|
+
deviceConfigsActions,
|
|
404
|
+
isWebRuntimeDevice,
|
|
405
|
+
persistDeviceConfigs,
|
|
406
|
+
]);
|
|
407
|
+
|
|
408
|
+
useFocusEffect(
|
|
409
|
+
useCallback(() => {
|
|
410
|
+
setDeviceConfigsLoaded(false);
|
|
411
|
+
setConfigsLoaded(false);
|
|
412
|
+
setDiscovered(false);
|
|
413
|
+
}, []),
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
useFocusEffect(
|
|
417
|
+
useCallback(() => {
|
|
418
|
+
if (!currentCompany?.id || !storagedDevice?.id) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (isWebRuntimeDevice) {
|
|
423
|
+
applyRuntimeCompanyConfigs();
|
|
424
|
+
setDeviceConfigsLoaded(true);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
deviceConfigsActions
|
|
429
|
+
.getItems({
|
|
430
|
+
'device.device': storagedDevice.id,
|
|
431
|
+
people: '/people/' + currentCompany.id,
|
|
432
|
+
})
|
|
433
|
+
.then(data => {
|
|
434
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
435
|
+
let parsedConfigs = {};
|
|
436
|
+
|
|
437
|
+
if (typeof data[0]?.configs === 'string') {
|
|
438
|
+
try {
|
|
439
|
+
parsedConfigs = JSON.parse(data[0].configs);
|
|
440
|
+
} catch {
|
|
441
|
+
parsedConfigs = {};
|
|
442
|
+
}
|
|
443
|
+
} else if (typeof data[0]?.configs === 'object') {
|
|
444
|
+
parsedConfigs = data[0].configs || {};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
deviceConfigsActions.setItem({
|
|
448
|
+
...data[0],
|
|
449
|
+
configs: parsedConfigs,
|
|
450
|
+
});
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
deviceConfigsActions.setItem({});
|
|
455
|
+
})
|
|
456
|
+
.catch(() => {
|
|
457
|
+
deviceConfigsActions.setItem({});
|
|
458
|
+
})
|
|
459
|
+
.finally(() => {
|
|
460
|
+
setDeviceConfigsLoaded(true);
|
|
461
|
+
});
|
|
462
|
+
}, [
|
|
463
|
+
applyRuntimeCompanyConfigs,
|
|
464
|
+
currentCompany?.id,
|
|
465
|
+
deviceConfigsActions,
|
|
466
|
+
isWebRuntimeDevice,
|
|
467
|
+
storagedDevice?.id,
|
|
468
|
+
]),
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
useFocusEffect(
|
|
473
|
+
useCallback(() => {
|
|
474
|
+
if (deviceConfigsLoaded) {
|
|
475
|
+
createDefaultConfigs();
|
|
476
|
+
}
|
|
477
|
+
}, [deviceConfigsLoaded, createDefaultConfigs]),
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
useEffect(() => {
|
|
481
|
+
if (isWebRuntimeDevice && deviceConfigsLoaded && currentCompany?.id) {
|
|
482
|
+
applyRuntimeCompanyConfigs();
|
|
483
|
+
}
|
|
484
|
+
}, [
|
|
485
|
+
applyRuntimeCompanyConfigs,
|
|
486
|
+
currentCompany?.id,
|
|
487
|
+
deviceConfigsLoaded,
|
|
488
|
+
isWebRuntimeDevice,
|
|
489
|
+
runtimeCompanyConfigs,
|
|
490
|
+
]);
|
|
491
|
+
|
|
492
|
+
useFocusEffect(
|
|
493
|
+
useCallback(() => {
|
|
494
|
+
if (device?.configs) {
|
|
495
|
+
setCheckType(device?.configs['check-type'] || 'manual');
|
|
496
|
+
setCheckOrderType(
|
|
497
|
+
resolvePosCheckOrderType(device?.configs),
|
|
498
|
+
);
|
|
499
|
+
setCheckOrderManagementMode(
|
|
500
|
+
resolvePosCheckOrderManagementMode(device?.configs),
|
|
501
|
+
);
|
|
502
|
+
setProductInputType(device?.configs['product-input-type'] || 'manual');
|
|
503
|
+
setSelectionType(device?.configs['selection-type'] || 'single');
|
|
504
|
+
setShowSound(
|
|
505
|
+
device?.configs['sound'] === true ||
|
|
506
|
+
device?.configs['sound'] === '1'
|
|
507
|
+
);
|
|
508
|
+
setShowVibration(
|
|
509
|
+
device?.configs['vibration'] === true ||
|
|
510
|
+
device?.configs['vibration'] === '1'
|
|
511
|
+
);
|
|
512
|
+
setOrderVisibility(resolveDeviceOrderVisibility(device?.configs));
|
|
513
|
+
setAlertSoundEnabled(isTruthyValue(device?.configs[DEVICE_ALERT_SOUND_ENABLED_KEY]));
|
|
514
|
+
setAlertSoundUrl(String(device?.configs[DEVICE_ALERT_SOUND_URL_KEY] || ''));
|
|
515
|
+
setShowRuntimeDebugInfo(
|
|
516
|
+
isTruthyValue(device?.configs[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY]),
|
|
517
|
+
);
|
|
518
|
+
setSelectedMode(device?.configs['pos-type'] || 'full');
|
|
519
|
+
setPrintingMode(device?.configs['print-mode'] || 'order');
|
|
520
|
+
setSelectedGateway(device?.configs['pos-gateway'] || 'infinite-pay');
|
|
521
|
+
} else {
|
|
522
|
+
setCheckType('manual');
|
|
523
|
+
setCheckOrderType(POS_CHECK_ORDER_TYPE_NONE);
|
|
524
|
+
setCheckOrderManagementMode(POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE);
|
|
525
|
+
setProductInputType('manual');
|
|
526
|
+
setSelectionType('single');
|
|
527
|
+
setShowSound(false);
|
|
528
|
+
setShowVibration(false);
|
|
529
|
+
setOrderVisibility(DEVICE_ORDER_VISIBILITY_DEVICE);
|
|
530
|
+
setAlertSoundEnabled(false);
|
|
531
|
+
setAlertSoundUrl('');
|
|
532
|
+
setShowRuntimeDebugInfo(false);
|
|
533
|
+
setSelectedMode('full');
|
|
534
|
+
setPrintingMode('order');
|
|
535
|
+
setSelectedGateway('infinite-pay');
|
|
536
|
+
}
|
|
537
|
+
}, [device]),
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
useFocusEffect(
|
|
541
|
+
useCallback(() => {
|
|
542
|
+
if (!discovered && currentCompany?.id) {
|
|
543
|
+
const params = {
|
|
544
|
+
people: '/people/' + currentCompany.id,
|
|
545
|
+
};
|
|
546
|
+
configActions
|
|
547
|
+
.discoveryMainConfigs(params)
|
|
548
|
+
.then(() => {
|
|
549
|
+
setDiscovered(true);
|
|
550
|
+
})
|
|
551
|
+
.catch(() => {
|
|
552
|
+
setDiscovered(false);
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}, [discovered, currentCompany?.id, configActions]),
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
const handleSelectionTypeChange = (value) => {
|
|
559
|
+
setSelectionType(value);
|
|
560
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
561
|
+
lc['selection-type'] = value;
|
|
562
|
+
lc['config-version'] = appVersion;
|
|
563
|
+
persistDeviceConfigs(lc)
|
|
564
|
+
.catch(err => {
|
|
565
|
+
console.error('addDeviceConfigs (selection-type) failed:', err);
|
|
566
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
567
|
+
});
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
const handleCheckTypeChange = (value) => {
|
|
571
|
+
setCheckType(value);
|
|
572
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
573
|
+
lc['check-type'] = value;
|
|
574
|
+
// ===== ALTERAÇÃO: ADICIONAR VERSÃO DO APP =====
|
|
575
|
+
lc['config-version'] = appVersion;
|
|
576
|
+
// ===== FIM DA ALTERAÇÃO =====
|
|
577
|
+
persistDeviceConfigs(lc)
|
|
578
|
+
.catch(err => {
|
|
579
|
+
console.error('addDeviceConfigs (check-type) failed:', err);
|
|
580
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
581
|
+
});
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
const handleCheckOrderTypeChange = value => {
|
|
585
|
+
setCheckOrderType(value);
|
|
586
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
587
|
+
lc[POS_CHECK_ORDER_TYPE_CONFIG_KEY] = value;
|
|
588
|
+
if (value === POS_CHECK_ORDER_TYPE_NONE) {
|
|
589
|
+
lc[POS_CHECK_ORDER_MANAGEMENT_MODE_CONFIG_KEY] =
|
|
590
|
+
POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE;
|
|
591
|
+
setCheckOrderManagementMode(POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE);
|
|
592
|
+
}
|
|
593
|
+
lc['config-version'] = appVersion;
|
|
594
|
+
persistDeviceConfigs(lc).catch(err => {
|
|
595
|
+
console.error('addDeviceConfigs (check-order-type) failed:', err);
|
|
596
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
597
|
+
});
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
const handleCheckOrderManagementModeChange = value => {
|
|
601
|
+
const nextValue =
|
|
602
|
+
value === POS_CHECK_ORDER_MANAGEMENT_MODE_EXISTING_ONLY
|
|
603
|
+
? POS_CHECK_ORDER_MANAGEMENT_MODE_EXISTING_ONLY
|
|
604
|
+
: POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE;
|
|
605
|
+
|
|
606
|
+
setCheckOrderManagementMode(nextValue);
|
|
607
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
608
|
+
lc[POS_CHECK_ORDER_MANAGEMENT_MODE_CONFIG_KEY] = nextValue;
|
|
609
|
+
lc['config-version'] = appVersion;
|
|
610
|
+
persistDeviceConfigs(lc).catch(err => {
|
|
611
|
+
console.error(
|
|
612
|
+
'addDeviceConfigs (check-order-management-mode) failed:',
|
|
613
|
+
err,
|
|
614
|
+
);
|
|
615
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
616
|
+
});
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
const handleProductInputTypeChange = (value) => {
|
|
620
|
+
setProductInputType(value);
|
|
621
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
622
|
+
lc['product-input-type'] = value;
|
|
623
|
+
// ===== ALTERAÇÃO: ADICIONAR VERSÃO DO APP =====
|
|
624
|
+
lc['config-version'] = appVersion;
|
|
625
|
+
// ===== FIM DA ALTERAÇÃO =====
|
|
626
|
+
persistDeviceConfigs(lc)
|
|
627
|
+
.catch(err => {
|
|
628
|
+
console.error('addDeviceConfigs (product-input-type) failed:', err);
|
|
629
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
630
|
+
});
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
const handleSoundChange = (value) => {
|
|
634
|
+
setShowSound(value);
|
|
635
|
+
localStorage.setItem('sound', String(value));
|
|
636
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
637
|
+
lc['sound'] = value ? '1' : '0';
|
|
638
|
+
// ===== ALTERAÇÃO: ADICIONAR VERSÃO DO APP =====
|
|
639
|
+
lc['config-version'] = appVersion;
|
|
640
|
+
// ===== FIM DA ALTERAÇÃO =====
|
|
641
|
+
persistDeviceConfigs(lc)
|
|
642
|
+
.catch(err => {
|
|
643
|
+
console.error('addDeviceConfigs (sound) failed:', err);
|
|
644
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
645
|
+
});
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
const handleVibrationChange = (value) => {
|
|
649
|
+
setShowVibration(value);
|
|
650
|
+
localStorage.setItem('vibration', String(value));
|
|
651
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
652
|
+
lc['vibration'] = value ? '1' : '0';
|
|
653
|
+
// ===== ALTERAÇÃO: ADICIONAR VERSÃO DO APP =====
|
|
654
|
+
lc['config-version'] = appVersion;
|
|
655
|
+
// ===== FIM DA ALTERAÇÃO =====
|
|
656
|
+
persistDeviceConfigs(lc)
|
|
657
|
+
.catch(err => {
|
|
658
|
+
console.error('addDeviceConfigs (vibration) failed:', err);
|
|
659
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
660
|
+
});
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
const handleOrderVisibilityChange = value => {
|
|
664
|
+
setOrderVisibility(value);
|
|
665
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
666
|
+
lc[DEVICE_ORDER_VISIBILITY_KEY] = value || DEVICE_ORDER_VISIBILITY_DEVICE;
|
|
667
|
+
lc['config-version'] = appVersion;
|
|
668
|
+
persistDeviceConfigs(lc)
|
|
669
|
+
.catch(err => {
|
|
670
|
+
console.error('addDeviceConfigs (order visibility) failed:', err);
|
|
671
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
672
|
+
});
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
const handleAlertSoundEnabledChange = value => {
|
|
676
|
+
setAlertSoundEnabled(value);
|
|
677
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
678
|
+
lc[DEVICE_ALERT_SOUND_ENABLED_KEY] = value ? '1' : '0';
|
|
679
|
+
lc[DEVICE_ALERT_SOUND_URL_KEY] = alertSoundUrl.trim();
|
|
680
|
+
lc['config-version'] = appVersion;
|
|
681
|
+
persistDeviceConfigs(lc)
|
|
682
|
+
.catch(err => {
|
|
683
|
+
console.error('addDeviceConfigs (notification sound enabled) failed:', err);
|
|
684
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
685
|
+
});
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
const handleAlertSoundUrlSubmit = () => {
|
|
689
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
690
|
+
lc[DEVICE_ALERT_SOUND_ENABLED_KEY] = alertSoundEnabled ? '1' : '0';
|
|
691
|
+
lc[DEVICE_ALERT_SOUND_URL_KEY] = alertSoundUrl.trim();
|
|
692
|
+
lc['config-version'] = appVersion;
|
|
693
|
+
persistDeviceConfigs(lc)
|
|
694
|
+
.catch(err => {
|
|
695
|
+
console.error('addDeviceConfigs (notification sound url) failed:', err);
|
|
696
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
697
|
+
});
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
const handleRuntimeDebugInfoChange = value => {
|
|
701
|
+
setShowRuntimeDebugInfo(value);
|
|
702
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
703
|
+
lc[DEVICE_RUNTIME_DEBUG_INFO_ENABLED_KEY] = value ? '1' : '0';
|
|
704
|
+
lc['config-version'] = appVersion;
|
|
705
|
+
persistDeviceConfigs(lc)
|
|
706
|
+
.catch(err => {
|
|
707
|
+
console.error('addDeviceConfigs (runtime debug info) failed:', err);
|
|
708
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const handlePosTypeChange = (value) => {
|
|
713
|
+
setSelectedMode(value);
|
|
714
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
715
|
+
lc['pos-type'] = value;
|
|
716
|
+
lc['config-version'] = appVersion;
|
|
717
|
+
persistDeviceConfigs(lc)
|
|
718
|
+
.catch(err => {
|
|
719
|
+
console.error('addDeviceConfigs (pos-type) failed:', err);
|
|
720
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
721
|
+
});
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
const handlePrintModeChange = (value) => {
|
|
725
|
+
setPrintingMode(value);
|
|
726
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
727
|
+
lc['print-mode'] = value;
|
|
728
|
+
lc['config-version'] = appVersion;
|
|
729
|
+
persistDeviceConfigs(lc)
|
|
730
|
+
.catch(err => {
|
|
731
|
+
console.error('addDeviceConfigs (print-mode) failed:', err);
|
|
732
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
733
|
+
});
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
const handleGatewayChange = (value) => {
|
|
737
|
+
setSelectedGateway(value);
|
|
738
|
+
let lc = appendScreenMetrics({...(device?.configs || {})});
|
|
739
|
+
lc['pos-gateway'] = value;
|
|
740
|
+
lc['config-version'] = appVersion;
|
|
741
|
+
persistDeviceConfigs(lc)
|
|
742
|
+
.catch(err => {
|
|
743
|
+
console.error('addDeviceConfigs (pos-gateway) failed:', err);
|
|
744
|
+
Alert.alert('Erro ao gravar configurações', err.message || JSON.stringify(err));
|
|
745
|
+
});
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
const handleClearTranslate = () => {
|
|
749
|
+
Promise.resolve(global.t?.reload?.())
|
|
750
|
+
.then(() => {
|
|
751
|
+
global.refreshTranslationsUI?.();
|
|
752
|
+
|
|
753
|
+
if (Platform.OS === 'web' && typeof window !== 'undefined') {
|
|
754
|
+
window.location.reload();
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
navigation.reset({
|
|
759
|
+
index: 0,
|
|
760
|
+
routes: [{name: 'SettingsPage'}],
|
|
761
|
+
});
|
|
762
|
+
})
|
|
763
|
+
.catch(() => {});
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
return (
|
|
767
|
+
<SafeAreaView style={styles.Settings.container}>
|
|
768
|
+
<StateStore store="device_config" />
|
|
769
|
+
<ScrollView contentContainerStyle={styles.Settings.scrollContent}>
|
|
770
|
+
<View style={styles.Settings.mainContainer}>
|
|
771
|
+
<View style={inlineStyle_565_16}>
|
|
772
|
+
<View style={styles.Settings.row}>
|
|
773
|
+
<Text style={styles.Settings.value}>{storagedDevice?.appName}:</Text>
|
|
774
|
+
<Text style={styles.Settings.value}>{appVersion}</Text>
|
|
775
|
+
</View>
|
|
776
|
+
<View style={styles.Settings.row}>
|
|
777
|
+
<Text style={styles.Settings.label}>Resolução do monitor: </Text>
|
|
778
|
+
<Text style={styles.Settings.value}>{screenMetrics?.deviceResolution || '-'}</Text>
|
|
779
|
+
</View>
|
|
780
|
+
<View style={styles.Settings.row}>
|
|
781
|
+
<Text style={styles.Settings.label}>Tamanho atual: </Text>
|
|
782
|
+
<Text style={styles.Settings.value}>{screenMetrics?.actualSize || '-'}</Text>
|
|
783
|
+
</View>
|
|
784
|
+
<View style={styles.Settings.row}>
|
|
785
|
+
<Text style={styles.Settings.label}>Tamanho da janela: </Text>
|
|
786
|
+
<Text style={styles.Settings.value}>{screenMetrics?.windosSize || '-'}</Text>
|
|
787
|
+
</View>
|
|
788
|
+
<View style={styles.Settings.row}>
|
|
789
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "machineId")}: </Text>
|
|
790
|
+
<Text style={styles.Settings.value}>{storagedDevice.id}</Text>
|
|
791
|
+
</View>
|
|
792
|
+
<View style={styles.Settings.row}>
|
|
793
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "manufacturer")}: </Text>
|
|
794
|
+
<Text style={styles.Settings.value}>
|
|
795
|
+
{storagedDevice?.manufacturer}
|
|
796
|
+
</Text>
|
|
797
|
+
</View>
|
|
798
|
+
<View style={styles.Settings.row}>
|
|
799
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "systemVersion")}: </Text>
|
|
800
|
+
<Text style={styles.Settings.value}>
|
|
801
|
+
{storagedDevice?.systemName}
|
|
802
|
+
{Platform.OS !== 'web' &&
|
|
803
|
+
storagedDevice?.systemVersion &&
|
|
804
|
+
String(storagedDevice.systemVersion).toLowerCase() !== 'unknown' &&
|
|
805
|
+
String(storagedDevice.systemVersion).toLowerCase() !== 'unknow'
|
|
806
|
+
? `, ${storagedDevice.systemVersion}`
|
|
807
|
+
: ''}
|
|
808
|
+
</Text>
|
|
809
|
+
</View>
|
|
810
|
+
|
|
811
|
+
<View style={styles.Settings.walletRow}>
|
|
812
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "cashWallet")}: </Text>
|
|
813
|
+
<View style={styles.Settings.walletValueContainer}>
|
|
814
|
+
<Text style={styles.Settings.walletValue}>
|
|
815
|
+
{companyConfigs?.['pos-cash-wallet']}
|
|
816
|
+
</Text>
|
|
817
|
+
{walletLoading || isDeviceConfigSaving ? (
|
|
818
|
+
<ActivityIndicator size={22} color={styles.Settings.label} />
|
|
819
|
+
) : companyConfigs?.['pos-cash-wallet'] ? (
|
|
820
|
+
<Icon name={'check'} size={22} color="green" />
|
|
821
|
+
) : (
|
|
822
|
+
<Icon name={'close'} size={22} color="red" />
|
|
823
|
+
)}
|
|
824
|
+
</View>
|
|
825
|
+
</View>
|
|
826
|
+
<View style={styles.Settings.walletRow}>
|
|
827
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "withdrawlWallet")}: </Text>
|
|
828
|
+
<View style={styles.Settings.walletValueContainer}>
|
|
829
|
+
<Text style={styles.Settings.walletValue}>
|
|
830
|
+
{withdrawWallet}
|
|
831
|
+
</Text>
|
|
832
|
+
{walletLoading || isDeviceConfigSaving ? (
|
|
833
|
+
<ActivityIndicator size={22} color={styles.Settings.label} />
|
|
834
|
+
) : withdrawWallet ? (
|
|
835
|
+
<Icon name={'check'} size={22} color="green" />
|
|
836
|
+
) : (
|
|
837
|
+
<Icon name={'close'} size={22} color="red" />
|
|
838
|
+
)}
|
|
839
|
+
</View>
|
|
840
|
+
</View>
|
|
841
|
+
</View>
|
|
842
|
+
|
|
843
|
+
<View style={settingsTabStyles.tabRow}>
|
|
844
|
+
<TouchableOpacity
|
|
845
|
+
activeOpacity={0.85}
|
|
846
|
+
onPress={() => setActiveSettingsTab('general')}
|
|
847
|
+
style={[
|
|
848
|
+
settingsTabStyles.tabButton,
|
|
849
|
+
activeSettingsTab === 'general' && settingsTabStyles.tabButtonActive,
|
|
850
|
+
]}>
|
|
851
|
+
<Text
|
|
852
|
+
style={[
|
|
853
|
+
settingsTabStyles.tabLabel,
|
|
854
|
+
activeSettingsTab === 'general' && settingsTabStyles.tabLabelActive,
|
|
855
|
+
]}>
|
|
856
|
+
Geral
|
|
857
|
+
</Text>
|
|
858
|
+
</TouchableOpacity>
|
|
859
|
+
<TouchableOpacity
|
|
860
|
+
activeOpacity={0.85}
|
|
861
|
+
onPress={() => setActiveSettingsTab('payments')}
|
|
862
|
+
style={[
|
|
863
|
+
settingsTabStyles.tabButton,
|
|
864
|
+
activeSettingsTab === 'payments' && settingsTabStyles.tabButtonActive,
|
|
865
|
+
]}>
|
|
866
|
+
<Text
|
|
867
|
+
style={[
|
|
868
|
+
settingsTabStyles.tabLabel,
|
|
869
|
+
activeSettingsTab === 'payments' && settingsTabStyles.tabLabelActive,
|
|
870
|
+
]}>
|
|
871
|
+
Pagamentos
|
|
872
|
+
</Text>
|
|
873
|
+
</TouchableOpacity>
|
|
874
|
+
</View>
|
|
875
|
+
|
|
876
|
+
{activeSettingsTab === 'payments' ? (
|
|
877
|
+
<PaymentTypesByWalletTab
|
|
878
|
+
currentCompanyId={currentCompany?.id}
|
|
879
|
+
configs={runtimeCompanyConfigs}
|
|
880
|
+
isSaving={isSaving}
|
|
881
|
+
onPersistSelectedPaymentTypeIds={persistCompanyPaymentConfigs}
|
|
882
|
+
title="Pagamentos da empresa"
|
|
883
|
+
introText="Os wallets só organizam a lista. O que vale para o shop é a allowlist de meios de pagamento salva nas configurações da empresa."
|
|
884
|
+
helpText="Esse padrão é usado pelo shop e pelos fluxos que consomem as configs da empresa."
|
|
885
|
+
emptyTitle="Nenhuma wallet da empresa encontrada"
|
|
886
|
+
emptyText="Não há wallets cadastradas para a empresa ativa."
|
|
887
|
+
emptyPaymentsText="Nenhum meio de pagamento vinculado a esta wallet."
|
|
888
|
+
unassignedText="Meios de pagamento sem wallet vinculada."
|
|
889
|
+
/>
|
|
890
|
+
) : (
|
|
891
|
+
<>
|
|
892
|
+
{isWebRuntimeDevice && (
|
|
893
|
+
<View style={inlineStyle_639_14}>
|
|
894
|
+
<Text style={[styles.Settings.label, {marginBottom: 4}]}>
|
|
895
|
+
Configuração sincronizada
|
|
896
|
+
</Text>
|
|
897
|
+
<Text style={inlineStyle_650_20}>
|
|
898
|
+
No navegador este runtime usa configurações sincronizadas do
|
|
899
|
+
device web e da empresa. Ajustes compatíveis ficam refletidos no
|
|
900
|
+
rodapé e nos recursos em tempo real.
|
|
901
|
+
</Text>
|
|
902
|
+
</View>
|
|
903
|
+
)}
|
|
904
|
+
|
|
905
|
+
{/* // // // // // LINKED ORDER INPUT */}
|
|
906
|
+
<View style={inlineStyle_659_16}>
|
|
907
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "tab type")}</Text>
|
|
908
|
+
<Picker
|
|
909
|
+
selectedValue={checkType}
|
|
910
|
+
onValueChange={handleCheckTypeChange}
|
|
911
|
+
enabled={!isWebRuntimeDevice}
|
|
912
|
+
mode={pickerMode}
|
|
913
|
+
style={styles.Settings.picker}>
|
|
914
|
+
|
|
915
|
+
<Picker.Item label={global.t?.t("configs", "option", "manual")} value="manual" />
|
|
916
|
+
<Picker.Item label={global.t?.t("configs", "option", "barcode")} value="barcode" />
|
|
917
|
+
<Picker.Item label={global.t?.t("configs", "option", "rfid")} value="rfid" />
|
|
918
|
+
|
|
919
|
+
</Picker>
|
|
920
|
+
</View>
|
|
921
|
+
|
|
922
|
+
<View style={inlineStyle_676_16}>
|
|
923
|
+
<Text style={styles.Settings.label}>
|
|
924
|
+
{global.t?.t('configs', 'label', 'linkedOrderType') ||
|
|
925
|
+
'Service base order'}
|
|
926
|
+
</Text>
|
|
927
|
+
<Picker
|
|
928
|
+
selectedValue={checkOrderType}
|
|
929
|
+
onValueChange={handleCheckOrderTypeChange}
|
|
930
|
+
enabled={!isWebRuntimeDevice}
|
|
931
|
+
mode={pickerMode}
|
|
932
|
+
style={styles.Settings.picker}>
|
|
933
|
+
<Picker.Item
|
|
934
|
+
label={global.t?.t('configs', 'option', 'none') || 'None'}
|
|
935
|
+
value={POS_CHECK_ORDER_TYPE_NONE}
|
|
936
|
+
/>
|
|
937
|
+
<Picker.Item
|
|
938
|
+
label={global.t?.t('orders', 'title', 'tab') || 'Tab'}
|
|
939
|
+
value={POS_CHECK_ORDER_TYPE_TAB}
|
|
940
|
+
/>
|
|
941
|
+
<Picker.Item
|
|
942
|
+
label={global.t?.t('orders', 'title', 'table') || 'Table'}
|
|
943
|
+
value={POS_CHECK_ORDER_TYPE_TABLE}
|
|
944
|
+
/>
|
|
945
|
+
</Picker>
|
|
946
|
+
</View>
|
|
947
|
+
|
|
948
|
+
{checkOrderType !== POS_CHECK_ORDER_TYPE_NONE && (
|
|
949
|
+
<View style={inlineStyle_676_16}>
|
|
950
|
+
<Text style={styles.Settings.label}>
|
|
951
|
+
{global.t?.t('configs', 'label', 'linkedOrderManagementMode') ||
|
|
952
|
+
'Tab and table access'}
|
|
953
|
+
</Text>
|
|
954
|
+
<Picker
|
|
955
|
+
selectedValue={checkOrderManagementMode}
|
|
956
|
+
onValueChange={handleCheckOrderManagementModeChange}
|
|
957
|
+
enabled={!isWebRuntimeDevice}
|
|
958
|
+
mode={pickerMode}
|
|
959
|
+
style={styles.Settings.picker}>
|
|
960
|
+
<Picker.Item
|
|
961
|
+
label={
|
|
962
|
+
global.t?.t('configs', 'option', 'manageLinkedOrders') ||
|
|
963
|
+
'Open and close tabs/tables'
|
|
964
|
+
}
|
|
965
|
+
value={POS_CHECK_ORDER_MANAGEMENT_MODE_MANAGE}
|
|
966
|
+
/>
|
|
967
|
+
<Picker.Item
|
|
968
|
+
label={
|
|
969
|
+
global.t?.t(
|
|
970
|
+
'configs',
|
|
971
|
+
'option',
|
|
972
|
+
'existingLinkedOrdersOnly',
|
|
973
|
+
) || 'Use open tabs/tables only'
|
|
974
|
+
}
|
|
975
|
+
value={POS_CHECK_ORDER_MANAGEMENT_MODE_EXISTING_ONLY}
|
|
976
|
+
/>
|
|
977
|
+
</Picker>
|
|
978
|
+
</View>
|
|
979
|
+
)}
|
|
980
|
+
|
|
981
|
+
{/* // // // // // TIPO DE LEITURA DE PRODUTO */}
|
|
982
|
+
<View style={inlineStyle_676_16}>
|
|
983
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "product read method")}</Text>
|
|
984
|
+
<Picker
|
|
985
|
+
selectedValue={productInputType}
|
|
986
|
+
onValueChange={handleProductInputTypeChange}
|
|
987
|
+
enabled={!isWebRuntimeDevice}
|
|
988
|
+
mode={pickerMode}
|
|
989
|
+
style={styles.Settings.picker}>
|
|
990
|
+
<Picker.Item label={global.t?.t("configs", "option", "manual")} value="manual" />
|
|
991
|
+
<Picker.Item label={global.t?.t("configs", "option", "barcode")} value="barcode" />
|
|
992
|
+
<Picker.Item label={global.t?.t("configs", "option", "rfid")} value="rfid" />
|
|
993
|
+
</Picker>
|
|
994
|
+
</View>
|
|
995
|
+
|
|
996
|
+
<View style={inlineStyle_690_16}>
|
|
997
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "selection type")}</Text>
|
|
998
|
+
<Picker
|
|
999
|
+
selectedValue={selectionType}
|
|
1000
|
+
onValueChange={handleSelectionTypeChange}
|
|
1001
|
+
enabled={!isWebRuntimeDevice}
|
|
1002
|
+
mode={pickerMode}
|
|
1003
|
+
style={styles.Settings.picker}>
|
|
1004
|
+
<Picker.Item label={global.t?.t("configs", "option", "single")} value="single" />
|
|
1005
|
+
<Picker.Item label={global.t?.t("configs", "option", "multiple")} value="multiple" />
|
|
1006
|
+
</Picker>
|
|
1007
|
+
</View>
|
|
1008
|
+
|
|
1009
|
+
<View
|
|
1010
|
+
style={inlineStyle_704_12}>
|
|
1011
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "sound")}</Text>
|
|
1012
|
+
|
|
1013
|
+
<Switch
|
|
1014
|
+
value={showSound}
|
|
1015
|
+
disabled={isWebRuntimeDevice}
|
|
1016
|
+
onValueChange={handleSoundChange}
|
|
1017
|
+
/>
|
|
1018
|
+
</View>
|
|
1019
|
+
|
|
1020
|
+
<View
|
|
1021
|
+
style={inlineStyle_720_12}>
|
|
1022
|
+
<Text style={styles.Settings.label}>{global.t?.t("configs", "label", "vibration")}</Text>
|
|
1023
|
+
|
|
1024
|
+
<Switch
|
|
1025
|
+
value={showVibration}
|
|
1026
|
+
disabled={isWebRuntimeDevice}
|
|
1027
|
+
onValueChange={handleVibrationChange}
|
|
1028
|
+
/>
|
|
1029
|
+
</View>
|
|
1030
|
+
|
|
1031
|
+
<View
|
|
1032
|
+
style={inlineStyle_736_12}>
|
|
1033
|
+
<View
|
|
1034
|
+
style={inlineStyle_743_14}>
|
|
1035
|
+
<Text style={styles.Settings.label}>Aviso sonoro via websocket</Text>
|
|
1036
|
+
<Switch
|
|
1037
|
+
value={alertSoundEnabled}
|
|
1038
|
+
disabled={isWebRuntimeDevice}
|
|
1039
|
+
onValueChange={handleAlertSoundEnabledChange}
|
|
1040
|
+
/>
|
|
1041
|
+
</View>
|
|
1042
|
+
|
|
1043
|
+
<Text
|
|
1044
|
+
style={inlineStyle_757_14}>
|
|
1045
|
+
Toca quando este device recebe o evento
|
|
1046
|
+
order.created de um novo pedido em preparo via
|
|
1047
|
+
websocket.
|
|
1048
|
+
</Text>
|
|
1049
|
+
|
|
1050
|
+
<Text style={[styles.Settings.label, {marginTop: 12, marginBottom: 6, flex: 0}]}>
|
|
1051
|
+
URL do aviso sonoro
|
|
1052
|
+
</Text>
|
|
1053
|
+
<TextInput
|
|
1054
|
+
value={alertSoundUrl}
|
|
1055
|
+
onChangeText={setAlertSoundUrl}
|
|
1056
|
+
onBlur={handleAlertSoundUrlSubmit}
|
|
1057
|
+
onSubmitEditing={handleAlertSoundUrlSubmit}
|
|
1058
|
+
editable={!isWebRuntimeDevice}
|
|
1059
|
+
placeholder="https://exemplo.com/alerta.mp3"
|
|
1060
|
+
placeholderTextColor="#94A3B8"
|
|
1061
|
+
autoCapitalize="none"
|
|
1062
|
+
autoCorrect={false}
|
|
1063
|
+
keyboardType="url"
|
|
1064
|
+
returnKeyType="done"
|
|
1065
|
+
style={inlineStyle_783_14}
|
|
1066
|
+
/>
|
|
1067
|
+
<Text style={inlineStyle_818_14}>
|
|
1068
|
+
Se a URL ficar vazia, o runtime usa o som padrão do app
|
|
1069
|
+
({DEFAULT_NOTIFICATION_SOUND_FILE}).
|
|
1070
|
+
</Text>
|
|
1071
|
+
</View>
|
|
1072
|
+
|
|
1073
|
+
<View
|
|
1074
|
+
style={inlineStyle_798_12}>
|
|
1075
|
+
<View
|
|
1076
|
+
style={inlineStyle_805_14}>
|
|
1077
|
+
<Text style={styles.Settings.label}>Debug do socket no rodapé</Text>
|
|
1078
|
+
<Switch
|
|
1079
|
+
value={showRuntimeDebugInfo}
|
|
1080
|
+
onValueChange={handleRuntimeDebugInfoChange}
|
|
1081
|
+
/>
|
|
1082
|
+
</View>
|
|
1083
|
+
|
|
1084
|
+
<Text
|
|
1085
|
+
style={inlineStyle_818_14}>
|
|
1086
|
+
Quando desligado, o rodapé mostra só um indicador discreto do
|
|
1087
|
+
socket. Quando ligado, exibe os detalhes completos de realtime e
|
|
1088
|
+
refresh em qualquer tela do sistema.
|
|
1089
|
+
</Text>
|
|
1090
|
+
</View>
|
|
1091
|
+
|
|
1092
|
+
<View style={inlineStyle_830_16}>
|
|
1093
|
+
<Picker
|
|
1094
|
+
selectedValue={selectedMode}
|
|
1095
|
+
onValueChange={handlePosTypeChange}
|
|
1096
|
+
enabled={!isWebRuntimeDevice}
|
|
1097
|
+
mode={pickerMode}
|
|
1098
|
+
style={styles.Settings.picker}>
|
|
1099
|
+
<Picker.Item label={global.t?.t("configs", "option", "simple order")} value="simple" />
|
|
1100
|
+
<Picker.Item label={global.t?.t("configs", "option", "full order")} value="full" />
|
|
1101
|
+
</Picker>
|
|
1102
|
+
</View>
|
|
1103
|
+
<View style={inlineStyle_841_16}>
|
|
1104
|
+
<Picker
|
|
1105
|
+
selectedValue={printingMode}
|
|
1106
|
+
onValueChange={handlePrintModeChange}
|
|
1107
|
+
enabled={!isWebRuntimeDevice}
|
|
1108
|
+
mode={pickerMode}
|
|
1109
|
+
style={styles.Settings.picker}>
|
|
1110
|
+
<Picker.Item label={global.t?.t("configs", "option", "printSingleOrder")} value="order" />
|
|
1111
|
+
<Picker.Item label={global.t?.t("configs", "option", "printFullOrder")} value="form" />
|
|
1112
|
+
</Picker>
|
|
1113
|
+
</View>
|
|
1114
|
+
<View style={inlineStyle_852_16}>
|
|
1115
|
+
<Text style={styles.Settings.label}>Pedidos visíveis no PDV</Text>
|
|
1116
|
+
<Picker
|
|
1117
|
+
selectedValue={orderVisibility}
|
|
1118
|
+
onValueChange={handleOrderVisibilityChange}
|
|
1119
|
+
enabled={!isWebRuntimeDevice}
|
|
1120
|
+
mode={pickerMode}
|
|
1121
|
+
style={styles.Settings.picker}>
|
|
1122
|
+
<Picker.Item
|
|
1123
|
+
label="Somente pedidos deste device"
|
|
1124
|
+
value={DEVICE_ORDER_VISIBILITY_DEVICE}
|
|
1125
|
+
/>
|
|
1126
|
+
<Picker.Item
|
|
1127
|
+
label="Todos os pedidos da empresa"
|
|
1128
|
+
value={DEVICE_ORDER_VISIBILITY_COMPANY}
|
|
1129
|
+
/>
|
|
1130
|
+
</Picker>
|
|
1131
|
+
</View>
|
|
1132
|
+
{showGatewayPicker && (
|
|
1133
|
+
<View style={inlineStyle_871_18}>
|
|
1134
|
+
<Picker
|
|
1135
|
+
selectedValue={selectedGateway}
|
|
1136
|
+
onValueChange={handleGatewayChange}
|
|
1137
|
+
enabled={!isWebRuntimeDevice}
|
|
1138
|
+
mode={pickerMode}
|
|
1139
|
+
style={styles.Settings.picker}>
|
|
1140
|
+
<Picker.Item label="Infinite Pay" value="infinite-pay" />
|
|
1141
|
+
{allowCieloOption && (
|
|
1142
|
+
<Picker.Item label="Cielo" value="cielo" />
|
|
1143
|
+
)}
|
|
1144
|
+
</Picker>
|
|
1145
|
+
</View>
|
|
1146
|
+
)}
|
|
1147
|
+
|
|
1148
|
+
<TouchableOpacity
|
|
1149
|
+
onPress={handleClearTranslate}
|
|
1150
|
+
style={[
|
|
1151
|
+
globalStyles.button,
|
|
1152
|
+
{
|
|
1153
|
+
flexDirection: 'row',
|
|
1154
|
+
justifyContent: 'center',
|
|
1155
|
+
alignItems: 'center',
|
|
1156
|
+
height: 50,
|
|
1157
|
+
marginTop: 6,
|
|
1158
|
+
},
|
|
1159
|
+
]}>
|
|
1160
|
+
<Icon name="add-circle" size={24} color="#fff" />
|
|
1161
|
+
<Text style={inlineStyle_899_18}>{global.t?.t("configs", "label", "resync translations")}</Text>
|
|
1162
|
+
</TouchableOpacity>
|
|
1163
|
+
</>
|
|
1164
|
+
)}
|
|
1165
|
+
</View>
|
|
1166
|
+
</ScrollView>
|
|
1167
|
+
</SafeAreaView>
|
|
1168
|
+
);
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
export default Settings;
|