@sincpro/mobile 0.1.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +831 -47
- package/dist/entrypoints/queue/printImage.subscriber.js +3 -3
- package/dist/entrypoints/ui/AppShell.d.ts +61 -0
- package/dist/entrypoints/ui/AppShell.js +72 -11
- package/dist/entrypoints/ui/common_provider.d.ts +6 -1
- package/dist/entrypoints/ui/common_provider.js +45 -1
- package/dist/entrypoints/ui/domain_switcher.js +5 -4
- package/dist/entrypoints/ui/theme.d.ts +8 -7
- package/dist/entrypoints/ui/theme.js +8 -7
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infrastructure/ui/ToastHost.d.ts +6 -1
- package/dist/infrastructure/ui/ToastHost.js +18 -9
- package/dist/services/printer.service.d.ts +6 -0
- package/dist/services/printer.service.js +36 -3
- package/dist/ui/components/atoms/DebugBanner.js +4 -8
- package/dist/ui/components/atoms/PrinterIcon.d.ts +4 -0
- package/dist/ui/components/atoms/PrinterIcon.js +4 -0
- package/dist/ui/components/atoms/index.d.ts +1 -0
- package/dist/ui/components/atoms/index.js +1 -0
- package/dist/ui/components/molecules/BluetoothDeviceSelectorModal.js +16 -10
- package/dist/ui/components/molecules/DeadLetterErrorBlock.js +3 -2
- package/dist/ui/components/molecules/EventTimelineItem.js +31 -33
- package/dist/ui/components/molecules/GeoPermissionCard.d.ts +8 -0
- package/dist/ui/components/molecules/GeoPermissionCard.js +21 -0
- package/dist/ui/components/molecules/ProcessToast.d.ts +7 -4
- package/dist/ui/components/molecules/ProcessToast.js +45 -44
- package/dist/ui/components/molecules/ProcessToastProvider.js +1 -1
- package/dist/ui/components/molecules/TimeZoneSelector.d.ts +7 -0
- package/dist/ui/components/molecules/TimeZoneSelector.js +19 -0
- package/dist/ui/components/molecules/TimeZoneSelectorModal.d.ts +9 -0
- package/dist/ui/components/molecules/TimeZoneSelectorModal.js +61 -0
- package/dist/ui/components/molecules/index.d.ts +4 -0
- package/dist/ui/components/molecules/index.js +3 -0
- package/dist/ui/components/molecules/timezone.d.ts +4 -0
- package/dist/ui/components/molecules/timezone.js +1 -0
- package/dist/ui/components/organisms/BluetoothPrinterSelector.d.ts +3 -1
- package/dist/ui/components/organisms/BluetoothPrinterSelector.js +29 -9
- package/dist/ui/components/organisms/DatabaseInfoRow.js +1 -1
- package/dist/ui/components/organisms/DeadLetterQueueRow.js +3 -3
- package/dist/ui/components/organisms/EventRow.js +15 -15
- package/dist/ui/components/organisms/InjectableWebView.js +20 -10
- package/dist/ui/components/organisms/TableInfoInfoRow.js +1 -1
- package/dist/ui/screens/database/database.json_detail.js +3 -3
- package/dist/ui/screens/database/database.list.js +4 -5
- package/dist/ui/screens/database/database.table_rows.js +1 -2
- package/dist/ui/screens/dead_letter_queue/dead_letter_queue.list.js +4 -5
- package/dist/ui/screens/events/events.list.js +4 -5
- package/package.json +9 -5
- package/dist/ui/layouts/router_layouts.d.ts +0 -17
- package/dist/ui/layouts/router_layouts.js +0 -20
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { jsx as _jsx } from "nativewind/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
2
|
import { loggerUseCases } from "../../../infrastructure/logger";
|
|
3
3
|
import { webViewService } from "../../../services/webview.service";
|
|
4
|
+
import { useToast } from "@sincpro/mobile-ui/Feedback";
|
|
4
5
|
import Spinner from "@sincpro/mobile-ui/Feedback/Feedback.Spinner";
|
|
6
|
+
import { useBottomInset } from "@sincpro/mobile-ui/layouts/BottomInset";
|
|
5
7
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
6
8
|
import { BackHandler, StyleSheet, View } from "react-native";
|
|
7
9
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
8
|
-
import Toast from "react-native-toast-message";
|
|
9
10
|
import WebView from "react-native-webview";
|
|
10
11
|
function WebViewControls({ canGoBack: _canGoBack, canGoForward: _canGoForward, onGoBack: _onGoBack, onGoForward: _onGoForward, onReload: _onReload, }) {
|
|
11
12
|
return _jsx(View, {});
|
|
@@ -14,6 +15,7 @@ function WebViewLoadingIndicator({ backgroundColor }) {
|
|
|
14
15
|
return (_jsx(View, { style: [StyleSheet.absoluteFillObject, styles.loading, { backgroundColor }], children: _jsx(Spinner, { size: "large", text: "Cargando p\u00E1gina..." }) }));
|
|
15
16
|
}
|
|
16
17
|
function useWebView() {
|
|
18
|
+
const toast = useToast();
|
|
17
19
|
const webViewRef = useRef(null);
|
|
18
20
|
const [canGoBack, setCanGoBack] = useState(false);
|
|
19
21
|
const [retryCount, setRetryCount] = useState(0);
|
|
@@ -37,11 +39,11 @@ function useWebView() {
|
|
|
37
39
|
const hardRefresh = useCallback(() => {
|
|
38
40
|
if (webViewRef.current) {
|
|
39
41
|
loggerUseCases.info("Hard refresh: Clearing cache and reloading");
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
toast.show({
|
|
43
|
+
variant: "info",
|
|
44
|
+
title: "Limpiando caché...",
|
|
45
|
+
message: "Descargando cliente fresco",
|
|
46
|
+
duration: 2000,
|
|
45
47
|
});
|
|
46
48
|
if (webViewRef.current.clearCache) {
|
|
47
49
|
webViewRef.current.clearCache(true);
|
|
@@ -52,7 +54,7 @@ function useWebView() {
|
|
|
52
54
|
}
|
|
53
55
|
}, 300);
|
|
54
56
|
}
|
|
55
|
-
}, []);
|
|
57
|
+
}, [toast]);
|
|
56
58
|
useEffect(() => {
|
|
57
59
|
const backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
|
|
58
60
|
if (canGoBack) {
|
|
@@ -88,7 +90,9 @@ function useWebView() {
|
|
|
88
90
|
}
|
|
89
91
|
function InjectableWebView({ url, scripts, injectedJavaScript, onMessage, onNavigationChange, onLoadStart, onLoadEnd, onError, renderLoading, backgroundColor = "#f8f8f8", reloadKey, hardRefreshKey, maxRetries = 2, useDefaultCache = true, }) {
|
|
90
92
|
const { webViewRef, handleNavigationStateChange, retryCount, setRetryCount, reload, hardRefresh, errorTimeoutRef, loadingTimeoutRef, isLoadingRef, } = useWebView();
|
|
93
|
+
const bottomInset = useBottomInset();
|
|
91
94
|
const finalScript = webViewService.combineScripts(scripts, injectedJavaScript);
|
|
95
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
92
96
|
function handleMessage(event) {
|
|
93
97
|
onMessage?.(event);
|
|
94
98
|
}
|
|
@@ -98,6 +102,7 @@ function InjectableWebView({ url, scripts, injectedJavaScript, onMessage, onNavi
|
|
|
98
102
|
}
|
|
99
103
|
function handleLoadStart() {
|
|
100
104
|
isLoadingRef.current = true;
|
|
105
|
+
setIsLoading(true);
|
|
101
106
|
if (loadingTimeoutRef.current) {
|
|
102
107
|
clearTimeout(loadingTimeoutRef.current);
|
|
103
108
|
}
|
|
@@ -111,6 +116,7 @@ function InjectableWebView({ url, scripts, injectedJavaScript, onMessage, onNavi
|
|
|
111
116
|
}
|
|
112
117
|
function handleLoadEnd() {
|
|
113
118
|
isLoadingRef.current = false;
|
|
119
|
+
setIsLoading(false);
|
|
114
120
|
if (loadingTimeoutRef.current) {
|
|
115
121
|
clearTimeout(loadingTimeoutRef.current);
|
|
116
122
|
loadingTimeoutRef.current = null;
|
|
@@ -156,8 +162,12 @@ function InjectableWebView({ url, scripts, injectedJavaScript, onMessage, onNavi
|
|
|
156
162
|
}
|
|
157
163
|
}, [hardRefreshKey, hardRefresh]);
|
|
158
164
|
const cacheMode = useDefaultCache ? "LOAD_DEFAULT" : "LOAD_NO_CACHE";
|
|
159
|
-
return (
|
|
160
|
-
|
|
165
|
+
return (
|
|
166
|
+
// Outer full-bleed container: under edge-to-edge (SDK 54+ / targetSdk 36) the window
|
|
167
|
+
// draws behind the transparent system bars. The loading overlay lives here (NOT inside
|
|
168
|
+
// the inset SafeAreaView) so it covers the whole screen and also shows on reload/refresh.
|
|
169
|
+
_jsxs(View, { style: { flex: 1, backgroundColor }, children: [_jsx(SafeAreaView, { className: "flex-1", edges: ["bottom"], style: { backgroundColor, marginBottom: bottomInset }, children: _jsx(WebView, { allowsBackForwardNavigationGestures: true, cacheEnabled: true, cacheMode: cacheMode, domStorageEnabled: true, injectedJavaScript: finalScript, javaScriptEnabled: true, mixedContentMode: "compatibility", onError: handleError, onLoadEnd: handleLoadEnd, onLoadStart: handleLoadStart, onMessage: handleMessage, onNavigationStateChange: handleNavigationStateChangeInternal, ref: webViewRef, scalesPageToFit: true, sharedCookiesEnabled: true, source: { uri: url }, style: { flex: 1, backgroundColor } }) }), isLoading &&
|
|
170
|
+
(renderLoading ? (renderLoading()) : (_jsx(WebViewLoadingIndicator, { backgroundColor: backgroundColor })))] }));
|
|
161
171
|
}
|
|
162
172
|
const styles = StyleSheet.create({
|
|
163
173
|
loading: {
|
|
@@ -14,6 +14,6 @@ function TableInfoRow({ item, onPress }) {
|
|
|
14
14
|
messageId += `[${parsedData.uuid})]`;
|
|
15
15
|
}
|
|
16
16
|
const jsonString = safeJsonStringify(parsedData);
|
|
17
|
-
return (_jsx(TouchableOpacity, { activeOpacity: 0.7, className: "bg-
|
|
17
|
+
return (_jsx(TouchableOpacity, { activeOpacity: 0.7, className: "bg-bg-card p-4 rounded-xl my-2 shadow-sm", onPress: onPress, children: _jsxs(View, { children: [_jsx(Typography.Text, { className: "mb-2", variant: "caption", children: parsedData.name || "Sin Nombre" }), _jsx(Typography.Text, { numberOfLines: 1, semibold: true, variant: "body", children: messageId || "Sin Identificador" }), parsedData.status && (_jsxs(Typography.Text, { variant: "label", children: ["Estado: ", parsedData.status] })), _jsx(Typography.Text, { className: "text-text-secondary", ellipsizeMode: "tail", numberOfLines: 2, variant: "bodySmall", children: jsonString })] }) }));
|
|
18
18
|
}
|
|
19
19
|
export default TableInfoRow;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "nativewind/jsx-runtime";
|
|
2
2
|
import { Display } from "@sincpro/mobile-ui/Display";
|
|
3
3
|
import { Form } from "@sincpro/mobile-ui/Form";
|
|
4
|
-
import {
|
|
4
|
+
import { useTheme } from "@sincpro/mobile-ui/theme";
|
|
5
5
|
import { Typography } from "@sincpro/mobile-ui/Typography";
|
|
6
6
|
import { FormViewV2 } from "@sincpro/mobile-ui/views/FormViewV2";
|
|
7
7
|
import JsonPreview from "@sincpro/mobile-ui/widgets/JSONViewer";
|
|
8
|
-
import { EVariantScreenHeader } from "@sincpro/mobile-ui/widgets/ScreenHeader";
|
|
9
8
|
import * as Clipboard from "expo-clipboard";
|
|
10
9
|
import { View } from "react-native";
|
|
11
10
|
import { useDatabase } from "./database.context";
|
|
12
11
|
const Button = Form.Button;
|
|
13
12
|
const Icon = Display.Icon;
|
|
14
13
|
function JsonDetailView() {
|
|
14
|
+
const theme = useTheme();
|
|
15
15
|
const { selectedTable, selectedRowJson, goBackFromJson, currentRowIndex, filteredData, hasNextRow, hasPreviousRow, goToNextRow, goToPreviousRow, } = useDatabase();
|
|
16
|
-
return (_jsxs(FormViewV2.Root, { description: `JSON VIEWER - ${selectedTable}`, isLoading: false, item: { json: selectedRowJson }, name: "Detalles", onBack: goBackFromJson, children: [_jsx(FormViewV2.Header, { variant:
|
|
16
|
+
return (_jsxs(FormViewV2.Root, { description: `JSON VIEWER - ${selectedTable}`, isLoading: false, item: { json: selectedRowJson }, name: "Detalles", onBack: goBackFromJson, children: [_jsx(FormViewV2.Header, { variant: "default", children: _jsx(FormViewV2.Header.Actions, { children: _jsxs(Typography.Text, { className: "text-text-secondary", variant: "bodySmall", children: [currentRowIndex + 1, " de ", filteredData.length] }) }) }), _jsx(FormViewV2.Content, { children: _jsx(JsonPreview, { selectedJson: selectedRowJson }) }), _jsx(FormViewV2.Footer, { children: _jsxs(View, { className: "flex-row items-center justify-between gap-3", children: [_jsx(Button, { className: "flex-none min-w-[50px]", disabled: !hasPreviousRow, icon: _jsx(Icon, { color: hasPreviousRow ? theme.secondary : theme.text.tertiary, name: "chevron-left", size: 24, type: "feather" }), onPress: goToPreviousRow, title: "", variant: "secondary" }), _jsx(Button, { className: "flex-1", onPress: async () => {
|
|
17
17
|
await Clipboard.setStringAsync(selectedRowJson);
|
|
18
18
|
}, title: "Copiar JSON", variant: "primary" }), _jsx(Button, { className: "flex-none min-w-[50px]", disabled: !hasNextRow, icon: _jsx(Icon, { color: hasNextRow ? theme.secondary : theme.text.tertiary, name: "chevron-right", size: 24, type: "feather" }), onPress: goToNextRow, title: "", variant: "secondary" })] }) })] }));
|
|
19
19
|
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { useNavigation } from "@react-navigation/native";
|
|
2
3
|
import DatabaseInfoRow from "../../../ui/components/organisms/DatabaseInfoRow";
|
|
3
4
|
import { ListViewV2 } from "@sincpro/mobile-ui/views/ListViewV2";
|
|
4
|
-
import { EVariantScreenHeader } from "@sincpro/mobile-ui/widgets/ScreenHeader";
|
|
5
5
|
import { useEffect } from "react";
|
|
6
|
-
import { useNavigate } from "react-router-native";
|
|
7
6
|
import { DatabaseProvider, EDatabaseView, useDatabase } from "./database.context";
|
|
8
7
|
import JsonDetailView from "./database.json_detail";
|
|
9
8
|
import TableRowsView from "./database.table_rows";
|
|
10
9
|
function TablesView() {
|
|
11
|
-
const
|
|
10
|
+
const navigation = useNavigation();
|
|
12
11
|
const { loadTables, isLoading, tables, selectTable } = useDatabase();
|
|
13
12
|
useEffect(() => {
|
|
14
13
|
void loadTables();
|
|
15
14
|
}, [loadTables]);
|
|
16
|
-
const onBack = () =>
|
|
15
|
+
const onBack = () => navigation.goBack();
|
|
17
16
|
return (_jsxs(ListViewV2.Root, { isLoading: isLoading, items: tables, name: "Lista de tablas", onBack: onBack, onPressItem: async (table) => {
|
|
18
17
|
await selectTable(table.name);
|
|
19
|
-
}, children: [_jsx(ListViewV2.Header, { variant:
|
|
18
|
+
}, children: [_jsx(ListViewV2.Header, { variant: "default" }), _jsx(ListViewV2.Content, { children: (table) => (_jsx(DatabaseInfoRow, { item: {
|
|
20
19
|
name: table.displayName || table.name,
|
|
21
20
|
description: "Tabla de base de datos",
|
|
22
21
|
tableName: table.name,
|
|
@@ -2,10 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
|
2
2
|
import { safeJsonStringify } from "../../../tools/utils/serializer";
|
|
3
3
|
import TableInfoRow from "../../../ui/components/organisms/TableInfoInfoRow";
|
|
4
4
|
import { ListViewV2 } from "@sincpro/mobile-ui/views/ListViewV2";
|
|
5
|
-
import { EVariantScreenHeader } from "@sincpro/mobile-ui/widgets/ScreenHeader";
|
|
6
5
|
import { useDatabase } from "./database.context";
|
|
7
6
|
function TableRowsView() {
|
|
8
7
|
const { isLoading, filteredData, selectedTable, goBackFromRows, selectRowJson, setSearchQuery, } = useDatabase();
|
|
9
|
-
return (_jsxs(ListViewV2.Root, { isLoading: isLoading, items: filteredData, name: `Datos - ${selectedTable}`, onBack: goBackFromRows, onPressItem: (item) => selectRowJson(safeJsonStringify(item), item.index), onSearch: setSearchQuery, children: [_jsx(ListViewV2.Header, { variant:
|
|
8
|
+
return (_jsxs(ListViewV2.Root, { isLoading: isLoading, items: filteredData, name: `Datos - ${selectedTable}`, onBack: goBackFromRows, onPressItem: (item) => selectRowJson(safeJsonStringify(item), item.index), onSearch: setSearchQuery, children: [_jsx(ListViewV2.Header, { variant: "default", children: _jsx(ListViewV2.Header.Search, {}) }), _jsx(ListViewV2.Content, { children: (item) => (_jsx(TableInfoRow, { item: { data: safeJsonStringify(item) }, onPress: () => selectRowJson(safeJsonStringify(item), item.index) })) })] }));
|
|
10
9
|
}
|
|
11
10
|
export default TableRowsView;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { useNavigation } from "@react-navigation/native";
|
|
2
3
|
import DeadLetterQueueRow from "../../../ui/components/organisms/DeadLetterQueueRow";
|
|
3
4
|
import { ListViewV2 } from "@sincpro/mobile-ui/views/ListViewV2";
|
|
4
|
-
import { EVariantScreenHeader } from "@sincpro/mobile-ui/widgets/ScreenHeader";
|
|
5
5
|
import { useEffect } from "react";
|
|
6
|
-
import { useNavigate } from "react-router-native";
|
|
7
6
|
import { DeadLetterQueueProvider, useDeadLetterQueue } from "./dead_letter_queue.context";
|
|
8
7
|
function DeadLetterQueueScreenComponent() {
|
|
9
|
-
const
|
|
8
|
+
const navigation = useNavigation();
|
|
10
9
|
const { enrichedEvents, isLoading, loadEvents, retryEvent } = useDeadLetterQueue();
|
|
11
10
|
useEffect(() => {
|
|
12
11
|
loadEvents();
|
|
13
12
|
}, [loadEvents]);
|
|
14
|
-
const onBack = () =>
|
|
15
|
-
return (_jsxs(ListViewV2.Root, { description: "Eventos que no pudieron ser procesados", isLoading: isLoading, items: enrichedEvents, name: "Eventos fallidos", onBack: onBack, onRefresh: loadEvents, children: [_jsx(ListViewV2.Header, { variant:
|
|
13
|
+
const onBack = () => navigation.goBack();
|
|
14
|
+
return (_jsxs(ListViewV2.Root, { description: "Eventos que no pudieron ser procesados", isLoading: isLoading, items: enrichedEvents, name: "Eventos fallidos", onBack: onBack, onRefresh: loadEvents, children: [_jsx(ListViewV2.Header, { variant: "default" }), _jsx(ListViewV2.Content, { children: (event) => (_jsx(DeadLetterQueueRow, { item: event, onRetry: async (evt) => {
|
|
16
15
|
await retryEvent(evt);
|
|
17
16
|
setTimeout(() => {
|
|
18
17
|
void loadEvents();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
|
|
2
|
+
import { useNavigation } from "@react-navigation/native";
|
|
2
3
|
import EventRow from "../../../ui/components/organisms/EventRow";
|
|
3
4
|
import { ListViewV2 } from "@sincpro/mobile-ui/views/ListViewV2";
|
|
4
|
-
import { EVariantScreenHeader } from "@sincpro/mobile-ui/widgets/ScreenHeader";
|
|
5
5
|
import { useEffect } from "react";
|
|
6
|
-
import { useNavigate } from "react-router-native";
|
|
7
6
|
import { EventsProvider, useEvents } from "./events.context";
|
|
8
7
|
const FILTER_OPTIONS = [
|
|
9
8
|
{ label: "Todos", value: "ALL" },
|
|
@@ -12,13 +11,13 @@ const FILTER_OPTIONS = [
|
|
|
12
11
|
{ label: "Pendientes", value: "PENDING" },
|
|
13
12
|
];
|
|
14
13
|
function EventsScreenComponent() {
|
|
15
|
-
const
|
|
14
|
+
const navigation = useNavigation();
|
|
16
15
|
const { pagedEvents, isLoading, loadEvents, retryEvent, filter, setFilter } = useEvents();
|
|
17
16
|
useEffect(() => {
|
|
18
17
|
void loadEvents();
|
|
19
18
|
}, [loadEvents]);
|
|
20
|
-
const onBack = () =>
|
|
21
|
-
return (_jsxs(ListViewV2.Root, { description: "Eventos registrados", isLoading: isLoading, items: pagedEvents, name: "Eventos", onBack: onBack, onRefresh: loadEvents, children: [_jsx(ListViewV2.Header, { variant:
|
|
19
|
+
const onBack = () => navigation.goBack();
|
|
20
|
+
return (_jsxs(ListViewV2.Root, { description: "Eventos registrados", isLoading: isLoading, items: pagedEvents, name: "Eventos", onBack: onBack, onRefresh: loadEvents, children: [_jsx(ListViewV2.Header, { variant: "default", children: _jsx(ListViewV2.Header.Filters, { children: _jsx(ListViewV2.Header.Filters.Chips, { children: FILTER_OPTIONS.map((option) => (_jsx(ListViewV2.Header.Filters.Chip, { active: filter === option.value, label: option.label, onPress: () => setFilter(option.value) }, option.value))) }) }) }), _jsx(ListViewV2.Content, { children: (event) => (_jsx(EventRow, { item: event, onRetry: async (evt) => {
|
|
22
21
|
await retryEvent(evt);
|
|
23
22
|
} })) })] }));
|
|
24
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sincpro/mobile",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Sincpro Mobile framework core: offline-first infra (DB, queue/events, cron), DDD patterns, adapters, AppShell and module-driven composition for React Native",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -58,8 +58,10 @@
|
|
|
58
58
|
"react-native-toast-message": "*",
|
|
59
59
|
"react-native-view-shot": "*",
|
|
60
60
|
"react-native-webview": "*",
|
|
61
|
-
"react-
|
|
62
|
-
"@
|
|
61
|
+
"@react-navigation/native": ">=7",
|
|
62
|
+
"@react-navigation/native-stack": ">=7",
|
|
63
|
+
"react-native-screens": "*",
|
|
64
|
+
"@sincpro/mobile-ui": "^0.7.1"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@types/big.js": "^6.2.2",
|
|
@@ -96,10 +98,12 @@
|
|
|
96
98
|
"react-native-toast-message": "^2.3.3",
|
|
97
99
|
"react-native-view-shot": "^4.0.3",
|
|
98
100
|
"react-native-webview": "13.15.0",
|
|
99
|
-
"react-
|
|
101
|
+
"@react-navigation/native": "^7.0.0",
|
|
102
|
+
"@react-navigation/native-stack": "^7.0.0",
|
|
103
|
+
"react-native-screens": "~4.25.2",
|
|
100
104
|
"tsc-alias": "^1.8.17",
|
|
101
105
|
"typescript": "~5.9.2",
|
|
102
|
-
"@sincpro/mobile-ui": "^0.
|
|
106
|
+
"@sincpro/mobile-ui": "^0.7.1"
|
|
103
107
|
},
|
|
104
108
|
"exports": {
|
|
105
109
|
".": "./dist/index.js",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import UITabNavigatorLayout from "@sincpro/mobile-ui/layouts/TabNavigatorLayout";
|
|
2
|
-
import type { ComponentProps, ReactElement } from "react";
|
|
3
|
-
type UITabProps = ComponentProps<typeof UITabNavigatorLayout>;
|
|
4
|
-
/**
|
|
5
|
-
* Layouts conectados a react-router. El design system (@sincpro/mobile-ui) trae
|
|
6
|
-
* las versiones presentacionales (sin router); aquí el core —que sí posee el
|
|
7
|
-
* router— les inyecta location/navigate/Outlet para usarse como layout routes.
|
|
8
|
-
*/
|
|
9
|
-
declare function TabNavigatorLayout(props: Omit<UITabProps, "content" | "currentPath" | "onTabPress">): ReactElement;
|
|
10
|
-
declare namespace TabNavigatorLayout {
|
|
11
|
-
var Tabs: ({ children: tabsChildren }: {
|
|
12
|
-
children?: import("react").ReactNode;
|
|
13
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
var Tab: (_props: import("@sincpro/mobile-ui/layouts/TabNavigatorLayout").TabProps) => null;
|
|
15
|
-
}
|
|
16
|
-
declare function PlainLayout(): ReactElement;
|
|
17
|
-
export { PlainLayout, TabNavigatorLayout };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "nativewind/jsx-runtime";
|
|
2
|
-
import UIPlainLayout from "@sincpro/mobile-ui/layouts/PlainLayout";
|
|
3
|
-
import UITabNavigatorLayout from "@sincpro/mobile-ui/layouts/TabNavigatorLayout";
|
|
4
|
-
import { Outlet, useLocation, useNavigate } from "react-router-native";
|
|
5
|
-
/**
|
|
6
|
-
* Layouts conectados a react-router. El design system (@sincpro/mobile-ui) trae
|
|
7
|
-
* las versiones presentacionales (sin router); aquí el core —que sí posee el
|
|
8
|
-
* router— les inyecta location/navigate/Outlet para usarse como layout routes.
|
|
9
|
-
*/
|
|
10
|
-
function TabNavigatorLayout(props) {
|
|
11
|
-
const location = useLocation();
|
|
12
|
-
const navigate = useNavigate();
|
|
13
|
-
return (_jsx(UITabNavigatorLayout, { ...props, content: _jsx(Outlet, {}), currentPath: location.pathname, onTabPress: (path) => navigate(path) }));
|
|
14
|
-
}
|
|
15
|
-
TabNavigatorLayout.Tabs = UITabNavigatorLayout.Tabs;
|
|
16
|
-
TabNavigatorLayout.Tab = UITabNavigatorLayout.Tab;
|
|
17
|
-
function PlainLayout() {
|
|
18
|
-
return (_jsx(UIPlainLayout, { children: _jsx(Outlet, {}) }));
|
|
19
|
-
}
|
|
20
|
-
export { PlainLayout, TabNavigatorLayout };
|