@controleonline/ui-common 1.2.70 → 1.2.75
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/actions/workers/manager/action.yml +147 -0
- package/.github/actions/workers/qa/action.yml +44 -0
- package/.github/actions/workers/security/action.yml +44 -0
- package/.github/actions/workers/technical-documenter/action.yml +51 -0
- package/.github/workflows/manager-worker.yml +168 -0
- package/.github/workflows/publish-npm.yml +45 -0
- package/.gitmodules +3 -0
- package/AGENTS.md +6 -0
- package/README.md +14 -0
- package/package.json +32 -28
- package/src/api/fetch.js +1 -1
- package/src/api/index.js +328 -58
- package/src/react/components/AddImportModal.js +95 -111
- package/src/react/components/AnimatedModal.js +171 -0
- package/src/react/components/AnimatedModal.styles.js +21 -0
- package/src/react/components/AppTypeSwitcher.js +164 -0
- package/src/react/components/AppTypeSwitcher.styles.js +109 -0
- package/src/react/components/BackgroundRuntimeBridge.js +5 -4
- package/src/react/components/BottomNavigationBar.config.js +211 -231
- package/src/react/components/BottomNavigationBar.js +86 -31
- package/src/react/components/BottomNavigationBar.styles.js +118 -110
- package/src/react/components/CategoryForm.js +52 -35
- package/src/react/components/DefaultProvider.native.js +194 -156
- package/src/react/components/DefaultProvider.web.js +188 -112
- package/src/react/components/DeliveryPushBridge.native.js +2 -2
- package/src/react/components/DeviceAlertSoundService.js +3 -3
- package/src/react/components/KioskModeBridge.js +2 -2
- package/src/react/components/LauncherModeBridge.js +2 -2
- package/src/react/components/ManagerPushBridge.native.js +2 -2
- package/src/react/components/NetworkPrinterPreviewModal.js +249 -0
- package/src/react/components/NetworkPrinterPreviewModal.styles.js +159 -0
- package/src/react/components/RemoteCheckoutService.js +28 -20
- package/src/react/components/RuntimeBottomNavigationBar.js +146 -119
- package/src/react/components/RuntimeInfoFooter.js +137 -45
- package/src/react/components/RuntimeInfoFooter.styles.js +3 -0
- package/src/react/components/StateStore.js +258 -0
- package/src/react/components/UnifiedPaymentBar.js +7 -4
- package/src/react/components/UserAvatar.js +160 -0
- package/src/react/components/WebsocketListener.native.js +11 -11
- package/src/react/components/integrations/IntegrationHero/index.js +48 -0
- package/src/react/components/integrations/IntegrationHero/styles.js +57 -0
- package/src/react/components/integrations/IntegrationTabs/index.js +89 -0
- package/src/react/components/integrations/IntegrationTabs/styles.js +44 -0
- package/src/react/config/deviceConfigBootstrap.js +71 -30
- package/src/react/css/orders.js +72 -0
- package/src/react/pages/Connections.js +229 -0
- package/src/react/pages/Connections.styles.js +222 -0
- package/src/react/pages/DeviceDetailPage.js +2814 -0
- package/src/react/pages/DeviceDetailPage.styles.js +308 -0
- package/src/react/pages/Devices/currentDevice.js +194 -0
- package/src/react/pages/Devices/deviceTypes/DeviceGroupCard.js +257 -0
- package/src/react/pages/Devices/deviceTypes/all.js +23 -0
- package/src/react/pages/Devices/deviceTypes/device.js +25 -0
- package/src/react/pages/Devices/deviceTypes/deviceListHelpers.js +178 -0
- package/src/react/pages/Devices/deviceTypes/display.js +26 -0
- package/src/react/pages/Devices/deviceTypes/index.js +145 -0
- package/src/react/pages/Devices/deviceTypes/ipCamera.js +35 -0
- package/src/react/pages/Devices/deviceTypes/pdv.js +88 -0
- package/src/react/pages/Devices/deviceTypes/printer.js +37 -0
- package/src/react/pages/Devices/deviceTypes/shared.js +453 -0
- package/src/react/pages/Devices/deviceTypes/useDeviceNetworkConnectivity.js +145 -0
- package/src/react/pages/Devices.js +183 -0
- package/src/react/pages/Devices.styles.js +353 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99CatalogTab.js +219 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99OverviewTab.js +134 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99PreviewModal.js +173 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99ProductCard.js +1 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99QuickWalletModal.js +181 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99SettingsTab.js +306 -0
- package/src/react/pages/Food99IntegrationPage/components/Food99StoreTab.js +417 -0
- package/src/react/pages/Food99IntegrationPage/index.js +1530 -0
- package/src/react/pages/Food99IntegrationPage/styles.js +792 -0
- package/src/react/pages/Food99IntegrationPage/utils.js +155 -0
- package/src/react/pages/Food99IntegrationPage.js +1 -0
- package/src/react/pages/Food99IntegrationPage.styles.js +1 -0
- package/src/react/pages/GenericLogPage.js +42 -167
- package/src/react/pages/IFoodIntegrationPage/components/IFoodCatalogTab.js +8 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodOperationsTab.js +420 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodOverviewTab.js +118 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodPreviewModal.js +103 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodProductCard.js +1 -0
- package/src/react/pages/IFoodIntegrationPage/components/IFoodStoreTab.js +150 -0
- package/src/react/pages/IFoodIntegrationPage/index.js +1298 -0
- package/src/react/pages/IFoodIntegrationPage/styles.js +764 -0
- package/src/react/pages/IFoodIntegrationPage/utils.js +91 -0
- package/src/react/pages/IFoodIntegrationPage.js +1 -0
- package/src/react/pages/IFoodIntegrationPage.styles.js +1 -0
- package/src/react/pages/Imports.js +214 -166
- package/src/react/pages/IntegrationConfigPage.js +744 -0
- package/src/react/pages/IntegrationConfigPage.styles.js +269 -0
- package/src/react/pages/Integrations.js +299 -0
- package/src/react/pages/Integrations.styles.js +130 -0
- package/src/react/pages/ManagerOrderNotificationsPage.js +642 -0
- package/src/react/pages/MarketplaceIntegrationPage/components/MarketplaceProductCard.js +205 -0
- package/src/react/pages/MarketplaceIntegrationPage/components/RemoteMarketplaceMenuTab.js +335 -0
- package/src/react/pages/MarketplaceIntegrationPage/index.js +60 -0
- package/src/react/pages/MarketplaceIntegrationPage/utils.js +137 -0
- package/src/react/pages/MercadoLivreIntegrationPage.js +538 -0
- package/src/react/pages/PrinterDeviceDetailPage.js +1916 -0
- package/src/react/pages/PrinterDeviceDetailPage.styles.js +223 -0
- package/src/react/pages/PrinterDeviceFormPage.js +521 -0
- package/src/react/pages/PrinterDeviceFormPage.styles.js +159 -0
- package/src/react/pages/SettingsPage/PaymentTypesByWalletTab.js +484 -454
- package/src/react/pages/SettingsPage/index.js +1266 -1167
- package/src/react/pages/WhatsAppConnectionPage.js +459 -0
- package/src/react/pages/WhatsAppConnectionPage.styles.js +284 -0
- package/src/react/pages/integrationsCatalog.js +399 -0
- package/src/react/print/providers/local.js +1 -1
- package/src/react/router/publicRoutes.js +25 -0
- package/src/react/services/Cielo/Checkout.js +39 -0
- package/src/react/services/Cielo/Cielo.js +193 -0
- package/src/react/services/Cielo/Print.js +7 -0
- package/src/react/services/InfinitePay/Checkout.js +33 -0
- package/src/react/services/InfinitePay/InfinitePay.js +24 -0
- package/src/react/{utils → services}/paymentGatewayExecution.js +91 -91
- package/src/react/styles/global.js +115 -0
- package/src/react/utils/categoryContexts.js +46 -0
- package/src/react/utils/entityDisplay.js +222 -217
- package/src/react/utils/fileUrl.js +201 -16
- package/src/react/utils/integrationPage.js +16 -0
- package/src/react/utils/menuNavigation.js +31 -0
- package/src/react/utils/orderIdentity.js +277 -0
- package/src/react/utils/remotePayment.js +115 -61
- package/src/react/utils/runtimeFooter.js +40 -22
- package/src/react/utils/runtimeLanguage.js +50 -9
- package/src/react/utils/runtimeMenu.js +190 -98
- package/src/react/utils/runtimeZoom.js +43 -0
- package/src/react/utils/shopConfig.js +72 -34
- package/src/react/utils/shopFranchises.js +182 -23
- package/src/react/utils/socketRuntimePipeline.js +14 -14
- package/src/react/utils/storeColumns.js +23 -4
- package/src/react/utils/userAvatar.js +104 -0
- package/src/store/categories/index.js +48 -20
- package/src/store/configs/index.js +2 -2
- package/src/store/device_config/index.js +62 -21
- package/src/store/entity_log/index.js +22 -1
- package/src/store/imports/customActions.js +51 -0
- package/src/store/imports/index.js +89 -88
- package/src/store/status/index.js +11 -11
- package/src/store/themes/index.js +22 -0
- package/src/store/timezones/index.js +3 -1
- package/src/tests/browser/manager/connections.spec.js +143 -0
- package/src/tests/browser/manager/devices-current.spec.js +343 -0
- package/src/tests/browser/manager/mercado-livre-integration.spec.js +268 -0
- package/src/tests/react/api/deviceHeaders.test.js +114 -0
- package/src/tests/react/api/loadSmokeIndex.test.js +75 -0
- package/src/tests/react/components/AddImportModal.test.js +166 -0
- package/src/tests/react/components/BottomNavigationBar.config.test.js +20 -0
- package/src/tests/react/components/UserAvatar.test.js +52 -0
- package/src/tests/react/config/deviceConfigBootstrap.test.js +47 -0
- package/src/tests/react/pages/DevicePickerStyles.test.js +47 -0
- package/src/tests/react/pages/Devices/deviceListHelpers.test.js +39 -0
- package/src/tests/react/pages/DevicesCurrentDevice.test.js +198 -0
- package/src/tests/react/pages/connectionsHelpers.test.js +34 -0
- package/src/tests/react/pages/mercadoLivreIntegrationPageContract.test.mjs +16 -0
- package/src/tests/react/print/localPrintProvider.test.js +1 -1
- package/src/tests/react/services/Cielo.test.js +190 -0
- package/src/tests/react/store/categoriesOrdering.test.js +26 -0
- package/src/tests/react/utils/appDomain.test.js +62 -0
- package/src/tests/react/utils/entityDisplay.test.js +2 -2
- package/src/tests/react/utils/fileUrl.test.js +62 -0
- package/src/tests/react/utils/formatter.test.mjs +33 -0
- package/src/tests/react/utils/importStatus.test.js +2 -2
- package/src/tests/react/utils/orderIdentity.test.js +139 -0
- package/src/tests/react/utils/remotePayment.test.js +62 -0
- package/src/tests/react/utils/runtimeFooter.test.js +32 -9
- package/src/tests/react/utils/runtimeLanguage.test.js +80 -10
- package/src/tests/react/utils/runtimeMenu.test.js +195 -111
- package/src/tests/react/utils/runtimeZoom.test.js +38 -0
- package/src/tests/react/utils/shopConfig.test.js +75 -0
- package/src/tests/react/utils/shopFranchises.test.js +122 -12
- package/src/tests/react/utils/translate.discovery.test.mjs +170 -0
- package/src/tests/react/utils/translate.test.helpers.mjs +152 -0
- package/src/tests/react/utils/translate.test.mjs +252 -396
- package/src/tests/react/utils/userAvatar.test.js +63 -0
- package/src/utils/appDomain.js +15 -4
- package/src/utils/formatter.js +122 -16
- package/src/utils/integrationConfigs.js +1 -0
- package/src/utils/translate.js +277 -398
- package/src/utils/translateDiscovery.js +96 -0
- package/src/utils/translateNormalize.js +33 -0
- package/src/utils/translatePending.js +92 -0
- package/src/utils/translateStorage.js +142 -0
- package/.github/agents/developer.agent.md +0 -30
- package/.github/agents/devops.agent.md +0 -30
- package/.github/agents/qa.agent.md +0 -30
- package/.github/agents/security.agent.md +0 -30
- package/.github/workflows/npmjs.yml +0 -35
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React, {useEffect, useRef, useState} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Animated,
|
|
4
|
+
Dimensions,
|
|
5
|
+
Keyboard,
|
|
6
|
+
KeyboardAvoidingView,
|
|
7
|
+
Modal,
|
|
8
|
+
Platform,
|
|
9
|
+
StyleSheet,
|
|
10
|
+
Text,
|
|
11
|
+
} from 'react-native';
|
|
12
|
+
import {GestureHandlerRootView} from 'react-native-gesture-handler';
|
|
13
|
+
import {toast, Toasts} from '@backpackapp-io/react-native-toast';
|
|
14
|
+
import styles from './AnimatedModal.styles';
|
|
15
|
+
import {
|
|
16
|
+
TOAST_EXTRA_INSETS,
|
|
17
|
+
TOAST_MODAL_COUNT_KEY,
|
|
18
|
+
TOAST_PROVIDER_KEYS,
|
|
19
|
+
} from './toastConfig';
|
|
20
|
+
|
|
21
|
+
const {height: SCREEN_HEIGHT} = Dimensions.get('window');
|
|
22
|
+
|
|
23
|
+
const incrementModalToastDepth = () => {
|
|
24
|
+
const currentDepth = Number(global?.[TOAST_MODAL_COUNT_KEY] || 0);
|
|
25
|
+
global[TOAST_MODAL_COUNT_KEY] = currentDepth + 1;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const decrementModalToastDepth = () => {
|
|
29
|
+
const currentDepth = Number(global?.[TOAST_MODAL_COUNT_KEY] || 0);
|
|
30
|
+
global[TOAST_MODAL_COUNT_KEY] = Math.max(0, currentDepth - 1);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Modal com overlay aparecendo na hora e apenas o conteúdo subindo de baixo.
|
|
35
|
+
*/
|
|
36
|
+
export default function AnimatedModal({
|
|
37
|
+
visible,
|
|
38
|
+
onRequestClose,
|
|
39
|
+
children,
|
|
40
|
+
style,
|
|
41
|
+
}) {
|
|
42
|
+
const [showing, setShowing] = useState(visible);
|
|
43
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
44
|
+
const overlayOpacity = useRef(new Animated.Value(0)).current;
|
|
45
|
+
const slideY = useRef(new Animated.Value(SCREEN_HEIGHT)).current;
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (visible) {
|
|
49
|
+
setShowing(true);
|
|
50
|
+
slideY.setValue(SCREEN_HEIGHT);
|
|
51
|
+
overlayOpacity.setValue(0);
|
|
52
|
+
|
|
53
|
+
Animated.parallel([
|
|
54
|
+
Animated.spring(slideY, {
|
|
55
|
+
toValue: 0,
|
|
56
|
+
damping: 24,
|
|
57
|
+
stiffness: 300,
|
|
58
|
+
useNativeDriver: true,
|
|
59
|
+
}),
|
|
60
|
+
Animated.timing(overlayOpacity, {
|
|
61
|
+
toValue: 1,
|
|
62
|
+
duration: 300,
|
|
63
|
+
useNativeDriver: true,
|
|
64
|
+
}),
|
|
65
|
+
]).start();
|
|
66
|
+
}
|
|
67
|
+
}, [visible, overlayOpacity, slideY]);
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (!visible && showing) {
|
|
71
|
+
Animated.parallel([
|
|
72
|
+
Animated.timing(overlayOpacity, {
|
|
73
|
+
toValue: 0,
|
|
74
|
+
duration: 150,
|
|
75
|
+
useNativeDriver: true,
|
|
76
|
+
}),
|
|
77
|
+
Animated.timing(slideY, {
|
|
78
|
+
toValue: SCREEN_HEIGHT,
|
|
79
|
+
duration: 200,
|
|
80
|
+
useNativeDriver: true,
|
|
81
|
+
}),
|
|
82
|
+
]).start(() => {
|
|
83
|
+
setShowing(false);
|
|
84
|
+
setKeyboardHeight(0);
|
|
85
|
+
onRequestClose?.();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}, [visible, showing, overlayOpacity, slideY, onRequestClose]);
|
|
89
|
+
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (Platform.OS !== 'android') {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const showSub = Keyboard.addListener('keyboardDidShow', event => {
|
|
96
|
+
setKeyboardHeight(event?.endCoordinates?.height || 0);
|
|
97
|
+
});
|
|
98
|
+
const hideSub = Keyboard.addListener('keyboardDidHide', () => {
|
|
99
|
+
setKeyboardHeight(0);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return () => {
|
|
103
|
+
showSub.remove();
|
|
104
|
+
hideSub.remove();
|
|
105
|
+
};
|
|
106
|
+
}, []);
|
|
107
|
+
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!visible) {
|
|
110
|
+
setKeyboardHeight(0);
|
|
111
|
+
}
|
|
112
|
+
}, [visible]);
|
|
113
|
+
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (!showing) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
incrementModalToastDepth();
|
|
120
|
+
return () => {
|
|
121
|
+
decrementModalToastDepth();
|
|
122
|
+
};
|
|
123
|
+
}, [showing]);
|
|
124
|
+
|
|
125
|
+
const overlayStyle = [
|
|
126
|
+
styles.overlay,
|
|
127
|
+
style,
|
|
128
|
+
Platform.OS === 'android' ? {paddingBottom: keyboardHeight} : null,
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
const normalizedChildren = React.Children.toArray(children).map(child => {
|
|
132
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
133
|
+
const text = String(child).trim();
|
|
134
|
+
if (!text || text === '.') return null;
|
|
135
|
+
return <Text>{text}</Text>;
|
|
136
|
+
}
|
|
137
|
+
return child;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<Modal
|
|
142
|
+
visible={showing}
|
|
143
|
+
animationType="none"
|
|
144
|
+
transparent
|
|
145
|
+
statusBarTranslucent
|
|
146
|
+
onRequestClose={onRequestClose}>
|
|
147
|
+
<GestureHandlerRootView style={styles.gestureRoot}>
|
|
148
|
+
<KeyboardAvoidingView
|
|
149
|
+
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
|
150
|
+
style={overlayStyle}>
|
|
151
|
+
<Animated.View
|
|
152
|
+
style={[
|
|
153
|
+
StyleSheet.absoluteFillObject,
|
|
154
|
+
styles.overlayBg,
|
|
155
|
+
{opacity: overlayOpacity},
|
|
156
|
+
]}
|
|
157
|
+
/>
|
|
158
|
+
<Animated.View
|
|
159
|
+
style={[styles.content, {transform: [{translateY: slideY}]}]}>
|
|
160
|
+
{normalizedChildren}
|
|
161
|
+
</Animated.View>
|
|
162
|
+
<Toasts
|
|
163
|
+
providerKey={TOAST_PROVIDER_KEYS.MODAL}
|
|
164
|
+
extraInsets={TOAST_EXTRA_INSETS}
|
|
165
|
+
onToastPress={currentToast => toast.dismiss(currentToast.id)}
|
|
166
|
+
/>
|
|
167
|
+
</KeyboardAvoidingView>
|
|
168
|
+
</GestureHandlerRootView>
|
|
169
|
+
</Modal>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {StyleSheet} from 'react-native';
|
|
2
|
+
|
|
3
|
+
const styles = StyleSheet.create({
|
|
4
|
+
gestureRoot: {
|
|
5
|
+
flex: 1,
|
|
6
|
+
},
|
|
7
|
+
overlay: {
|
|
8
|
+
flex: 1,
|
|
9
|
+
justifyContent: 'flex-end',
|
|
10
|
+
},
|
|
11
|
+
overlayBg: {
|
|
12
|
+
backgroundColor: 'rgba(15, 23, 42, 0.4)',
|
|
13
|
+
},
|
|
14
|
+
content: {
|
|
15
|
+
width: '100%',
|
|
16
|
+
flex: 1,
|
|
17
|
+
justifyContent: 'flex-end',
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export default styles;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React, {useMemo, useState} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Modal,
|
|
4
|
+
Platform,
|
|
5
|
+
ScrollView,
|
|
6
|
+
Text,
|
|
7
|
+
TextInput,
|
|
8
|
+
TouchableOpacity,
|
|
9
|
+
View,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import Icon from 'react-native-vector-icons/Feather';
|
|
12
|
+
import {
|
|
13
|
+
app_type,
|
|
14
|
+
app_type_base,
|
|
15
|
+
app_type_options,
|
|
16
|
+
clear_app_type,
|
|
17
|
+
normalize_app_type,
|
|
18
|
+
set_app_type,
|
|
19
|
+
} from '@appType';
|
|
20
|
+
import styles from './AppTypeSwitcher.styles';
|
|
21
|
+
|
|
22
|
+
const reloadApp = () => {
|
|
23
|
+
if (typeof window !== 'undefined' && typeof window.location?.reload === 'function') {
|
|
24
|
+
window.location.reload();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function AppTypeOptionsModal({visible, currentAppType, onClose, onSelect}) {
|
|
29
|
+
const [query, setQuery] = useState('');
|
|
30
|
+
|
|
31
|
+
const filteredOptions = useMemo(() => {
|
|
32
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
33
|
+
if (!normalizedQuery) {
|
|
34
|
+
return app_type_options;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return app_type_options.filter(option =>
|
|
38
|
+
option.toLowerCase().includes(normalizedQuery),
|
|
39
|
+
);
|
|
40
|
+
}, [query]);
|
|
41
|
+
|
|
42
|
+
if (!visible) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Modal visible transparent animationType="fade" onRequestClose={onClose}>
|
|
48
|
+
<View style={styles.modalOverlay}>
|
|
49
|
+
<View style={styles.modalPanel}>
|
|
50
|
+
<View style={styles.modalHeader}>
|
|
51
|
+
<Text style={styles.modalTitle}>Selecionar tipo de app</Text>
|
|
52
|
+
<TouchableOpacity
|
|
53
|
+
accessibilityRole="button"
|
|
54
|
+
accessibilityLabel="Fechar seletor"
|
|
55
|
+
style={styles.closeButton}
|
|
56
|
+
onPress={onClose}
|
|
57
|
+
>
|
|
58
|
+
<Icon name="x" size={18} color="#334155" />
|
|
59
|
+
</TouchableOpacity>
|
|
60
|
+
</View>
|
|
61
|
+
<TextInput
|
|
62
|
+
style={styles.modalSearch}
|
|
63
|
+
value={query}
|
|
64
|
+
onChangeText={setQuery}
|
|
65
|
+
placeholder="Filtrar"
|
|
66
|
+
placeholderTextColor="#94A3B8"
|
|
67
|
+
/>
|
|
68
|
+
<ScrollView contentContainerStyle={styles.optionList}>
|
|
69
|
+
{filteredOptions.map(option => {
|
|
70
|
+
const selected = option === currentAppType;
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<TouchableOpacity
|
|
74
|
+
key={option}
|
|
75
|
+
accessibilityRole="button"
|
|
76
|
+
accessibilityLabel={option}
|
|
77
|
+
style={[styles.optionRow, selected && styles.optionRowActive]}
|
|
78
|
+
onPress={() => onSelect(option)}
|
|
79
|
+
>
|
|
80
|
+
<Text style={[styles.optionText, selected && styles.optionTextActive]}>
|
|
81
|
+
{option}
|
|
82
|
+
</Text>
|
|
83
|
+
{selected && <Text style={styles.optionHint}>Visão atual</Text>}
|
|
84
|
+
</TouchableOpacity>
|
|
85
|
+
);
|
|
86
|
+
})}
|
|
87
|
+
</ScrollView>
|
|
88
|
+
</View>
|
|
89
|
+
</View>
|
|
90
|
+
</Modal>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const AppTypeSwitcher = () => {
|
|
95
|
+
const buildAppType = normalize_app_type(app_type_base);
|
|
96
|
+
const currentAppType = normalize_app_type(app_type);
|
|
97
|
+
const [selectorOpen, setSelectorOpen] = useState(false);
|
|
98
|
+
|
|
99
|
+
if (Platform.OS !== 'web' || buildAppType !== 'ADMIN') {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const handleSelect = appType => {
|
|
104
|
+
const normalizedAppType = normalize_app_type(appType);
|
|
105
|
+
if (!normalizedAppType || normalizedAppType === currentAppType) {
|
|
106
|
+
setSelectorOpen(false);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (normalizedAppType === buildAppType) {
|
|
111
|
+
clear_app_type();
|
|
112
|
+
} else {
|
|
113
|
+
set_app_type(normalizedAppType);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
setSelectorOpen(false);
|
|
117
|
+
reloadApp();
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const handleReset = () => {
|
|
121
|
+
clear_app_type();
|
|
122
|
+
setSelectorOpen(false);
|
|
123
|
+
reloadApp();
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<>
|
|
128
|
+
<View style={styles.container}>
|
|
129
|
+
<Text style={styles.label}>Tipo de app</Text>
|
|
130
|
+
<TouchableOpacity
|
|
131
|
+
accessibilityRole="button"
|
|
132
|
+
accessibilityLabel="Selecionar tipo de app"
|
|
133
|
+
activeOpacity={0.82}
|
|
134
|
+
style={styles.button}
|
|
135
|
+
onPress={() => setSelectorOpen(true)}
|
|
136
|
+
>
|
|
137
|
+
<Text style={styles.buttonText}>{currentAppType}</Text>
|
|
138
|
+
<Icon name="chevron-down" size={16} color="#334155" />
|
|
139
|
+
</TouchableOpacity>
|
|
140
|
+
|
|
141
|
+
{currentAppType !== buildAppType && (
|
|
142
|
+
<TouchableOpacity
|
|
143
|
+
accessibilityRole="button"
|
|
144
|
+
accessibilityLabel="Voltar para ADMIN"
|
|
145
|
+
activeOpacity={0.82}
|
|
146
|
+
style={styles.resetButton}
|
|
147
|
+
onPress={handleReset}
|
|
148
|
+
>
|
|
149
|
+
<Text style={styles.resetText}>Voltar para ADMIN</Text>
|
|
150
|
+
</TouchableOpacity>
|
|
151
|
+
)}
|
|
152
|
+
</View>
|
|
153
|
+
|
|
154
|
+
<AppTypeOptionsModal
|
|
155
|
+
visible={selectorOpen}
|
|
156
|
+
currentAppType={currentAppType}
|
|
157
|
+
onClose={() => setSelectorOpen(false)}
|
|
158
|
+
onSelect={handleSelect}
|
|
159
|
+
/>
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export default AppTypeSwitcher;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {StyleSheet} from 'react-native';
|
|
2
|
+
|
|
3
|
+
export default StyleSheet.create({
|
|
4
|
+
container: {
|
|
5
|
+
alignItems: 'flex-end',
|
|
6
|
+
gap: 6,
|
|
7
|
+
},
|
|
8
|
+
label: {
|
|
9
|
+
color: '#64748B',
|
|
10
|
+
fontSize: 11,
|
|
11
|
+
fontWeight: '800',
|
|
12
|
+
letterSpacing: 0.2,
|
|
13
|
+
},
|
|
14
|
+
button: {
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
backgroundColor: '#FFFFFF',
|
|
17
|
+
borderColor: '#D8E0EA',
|
|
18
|
+
borderRadius: 999,
|
|
19
|
+
borderWidth: 1,
|
|
20
|
+
flexDirection: 'row',
|
|
21
|
+
gap: 8,
|
|
22
|
+
justifyContent: 'space-between',
|
|
23
|
+
minWidth: 164,
|
|
24
|
+
paddingHorizontal: 12,
|
|
25
|
+
paddingVertical: 8,
|
|
26
|
+
},
|
|
27
|
+
buttonText: {
|
|
28
|
+
color: '#0F172A',
|
|
29
|
+
fontSize: 13,
|
|
30
|
+
fontWeight: '800',
|
|
31
|
+
},
|
|
32
|
+
resetButton: {
|
|
33
|
+
paddingHorizontal: 2,
|
|
34
|
+
paddingVertical: 2,
|
|
35
|
+
},
|
|
36
|
+
resetText: {
|
|
37
|
+
color: '#1D4ED8',
|
|
38
|
+
fontSize: 11,
|
|
39
|
+
fontWeight: '800',
|
|
40
|
+
},
|
|
41
|
+
modalOverlay: {
|
|
42
|
+
flex: 1,
|
|
43
|
+
backgroundColor: 'rgba(15, 23, 42, 0.46)',
|
|
44
|
+
justifyContent: 'center',
|
|
45
|
+
padding: 16,
|
|
46
|
+
},
|
|
47
|
+
modalPanel: {
|
|
48
|
+
backgroundColor: '#FFFFFF',
|
|
49
|
+
borderRadius: 18,
|
|
50
|
+
maxHeight: '80%',
|
|
51
|
+
overflow: 'hidden',
|
|
52
|
+
},
|
|
53
|
+
modalHeader: {
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
borderBottomColor: '#E2E8F0',
|
|
56
|
+
borderBottomWidth: 1,
|
|
57
|
+
flexDirection: 'row',
|
|
58
|
+
justifyContent: 'space-between',
|
|
59
|
+
paddingHorizontal: 16,
|
|
60
|
+
paddingVertical: 14,
|
|
61
|
+
},
|
|
62
|
+
modalTitle: {
|
|
63
|
+
color: '#0F172A',
|
|
64
|
+
fontSize: 16,
|
|
65
|
+
fontWeight: '800',
|
|
66
|
+
},
|
|
67
|
+
closeButton: {
|
|
68
|
+
alignItems: 'center',
|
|
69
|
+
borderRadius: 16,
|
|
70
|
+
height: 32,
|
|
71
|
+
justifyContent: 'center',
|
|
72
|
+
width: 32,
|
|
73
|
+
},
|
|
74
|
+
modalSearch: {
|
|
75
|
+
backgroundColor: '#F8FAFC',
|
|
76
|
+
borderBottomColor: '#E2E8F0',
|
|
77
|
+
borderBottomWidth: 1,
|
|
78
|
+
color: '#0F172A',
|
|
79
|
+
fontSize: 13,
|
|
80
|
+
fontWeight: '700',
|
|
81
|
+
minHeight: 42,
|
|
82
|
+
paddingHorizontal: 16,
|
|
83
|
+
paddingVertical: 10,
|
|
84
|
+
},
|
|
85
|
+
optionList: {
|
|
86
|
+
paddingVertical: 8,
|
|
87
|
+
},
|
|
88
|
+
optionRow: {
|
|
89
|
+
paddingHorizontal: 16,
|
|
90
|
+
paddingVertical: 12,
|
|
91
|
+
},
|
|
92
|
+
optionRowActive: {
|
|
93
|
+
backgroundColor: '#EFF6FF',
|
|
94
|
+
},
|
|
95
|
+
optionText: {
|
|
96
|
+
color: '#334155',
|
|
97
|
+
fontSize: 14,
|
|
98
|
+
fontWeight: '800',
|
|
99
|
+
},
|
|
100
|
+
optionTextActive: {
|
|
101
|
+
color: '#1D4ED8',
|
|
102
|
+
},
|
|
103
|
+
optionHint: {
|
|
104
|
+
color: '#64748B',
|
|
105
|
+
fontSize: 11,
|
|
106
|
+
fontWeight: '600',
|
|
107
|
+
marginTop: 2,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, {useEffect, useMemo, useRef} from 'react';
|
|
2
2
|
import {NativeModules} from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import {app_type} from '@appType';
|
|
4
|
+
import { env as APP_ENV } from '@env';
|
|
4
5
|
import {useStore} from '@store';
|
|
5
6
|
import DeviceInfo from 'react-native-device-info';
|
|
6
7
|
import {resolveAppDomain} from '@controleonline/ui-common/src/utils/appDomain';
|
|
@@ -61,7 +62,7 @@ const BackgroundRuntimeBridge = () => {
|
|
|
61
62
|
|
|
62
63
|
const bundleId = safeTrim(DeviceInfo.getBundleId());
|
|
63
64
|
const runtimeAppKey =
|
|
64
|
-
bundleId || safeTrim(
|
|
65
|
+
bundleId || safeTrim(app_type).toUpperCase() || 'app';
|
|
65
66
|
const runtimeDeviceId = normalizeDeviceId(runtimeDevice?.id);
|
|
66
67
|
const runtimeDeviceType = normalizeDeviceType(
|
|
67
68
|
runtimeDeviceConfig?.type ||
|
|
@@ -70,7 +71,7 @@ const BackgroundRuntimeBridge = () => {
|
|
|
70
71
|
);
|
|
71
72
|
const currentCompanyId = safeTrim(currentCompany?.id);
|
|
72
73
|
const sessionToken = readSessionToken();
|
|
73
|
-
const isManagerRuntime = isManagerAppType(
|
|
74
|
+
const isManagerRuntime = isManagerAppType(app_type);
|
|
74
75
|
const managerOrderNotificationPreferences =
|
|
75
76
|
resolveManagerOrderNotificationPreferences(user);
|
|
76
77
|
const userAlertSoundUrl = safeTrim(
|
|
@@ -162,7 +163,7 @@ const BackgroundRuntimeBridge = () => {
|
|
|
162
163
|
companyAlias: safeTrim(currentCompany?.alias || currentCompany?.name),
|
|
163
164
|
companyId: currentCompanyId,
|
|
164
165
|
appDomain: safeTrim(resolveAppDomain(APP_ENV.DOMAIN)),
|
|
165
|
-
appType: safeTrim(
|
|
166
|
+
appType: safeTrim(app_type).toUpperCase(),
|
|
166
167
|
backgroundEnabled: true,
|
|
167
168
|
deviceId: runtimeDeviceId,
|
|
168
169
|
deviceType: runtimeDeviceType,
|