@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.
Files changed (51) hide show
  1. package/README.md +831 -47
  2. package/dist/entrypoints/queue/printImage.subscriber.js +3 -3
  3. package/dist/entrypoints/ui/AppShell.d.ts +61 -0
  4. package/dist/entrypoints/ui/AppShell.js +72 -11
  5. package/dist/entrypoints/ui/common_provider.d.ts +6 -1
  6. package/dist/entrypoints/ui/common_provider.js +45 -1
  7. package/dist/entrypoints/ui/domain_switcher.js +5 -4
  8. package/dist/entrypoints/ui/theme.d.ts +8 -7
  9. package/dist/entrypoints/ui/theme.js +8 -7
  10. package/dist/index.d.ts +0 -1
  11. package/dist/index.js +0 -1
  12. package/dist/infrastructure/ui/ToastHost.d.ts +6 -1
  13. package/dist/infrastructure/ui/ToastHost.js +18 -9
  14. package/dist/services/printer.service.d.ts +6 -0
  15. package/dist/services/printer.service.js +36 -3
  16. package/dist/ui/components/atoms/DebugBanner.js +4 -8
  17. package/dist/ui/components/atoms/PrinterIcon.d.ts +4 -0
  18. package/dist/ui/components/atoms/PrinterIcon.js +4 -0
  19. package/dist/ui/components/atoms/index.d.ts +1 -0
  20. package/dist/ui/components/atoms/index.js +1 -0
  21. package/dist/ui/components/molecules/BluetoothDeviceSelectorModal.js +16 -10
  22. package/dist/ui/components/molecules/DeadLetterErrorBlock.js +3 -2
  23. package/dist/ui/components/molecules/EventTimelineItem.js +31 -33
  24. package/dist/ui/components/molecules/GeoPermissionCard.d.ts +8 -0
  25. package/dist/ui/components/molecules/GeoPermissionCard.js +21 -0
  26. package/dist/ui/components/molecules/ProcessToast.d.ts +7 -4
  27. package/dist/ui/components/molecules/ProcessToast.js +45 -44
  28. package/dist/ui/components/molecules/ProcessToastProvider.js +1 -1
  29. package/dist/ui/components/molecules/TimeZoneSelector.d.ts +7 -0
  30. package/dist/ui/components/molecules/TimeZoneSelector.js +19 -0
  31. package/dist/ui/components/molecules/TimeZoneSelectorModal.d.ts +9 -0
  32. package/dist/ui/components/molecules/TimeZoneSelectorModal.js +61 -0
  33. package/dist/ui/components/molecules/index.d.ts +4 -0
  34. package/dist/ui/components/molecules/index.js +3 -0
  35. package/dist/ui/components/molecules/timezone.d.ts +4 -0
  36. package/dist/ui/components/molecules/timezone.js +1 -0
  37. package/dist/ui/components/organisms/BluetoothPrinterSelector.d.ts +3 -1
  38. package/dist/ui/components/organisms/BluetoothPrinterSelector.js +29 -9
  39. package/dist/ui/components/organisms/DatabaseInfoRow.js +1 -1
  40. package/dist/ui/components/organisms/DeadLetterQueueRow.js +3 -3
  41. package/dist/ui/components/organisms/EventRow.js +15 -15
  42. package/dist/ui/components/organisms/InjectableWebView.js +20 -10
  43. package/dist/ui/components/organisms/TableInfoInfoRow.js +1 -1
  44. package/dist/ui/screens/database/database.json_detail.js +3 -3
  45. package/dist/ui/screens/database/database.list.js +4 -5
  46. package/dist/ui/screens/database/database.table_rows.js +1 -2
  47. package/dist/ui/screens/dead_letter_queue/dead_letter_queue.list.js +4 -5
  48. package/dist/ui/screens/events/events.list.js +4 -5
  49. package/package.json +9 -5
  50. package/dist/ui/layouts/router_layouts.d.ts +0 -17
  51. 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
- Toast.show({
41
- type: "info",
42
- text1: "Limpiando caché...",
43
- text2: "Descargando cliente fresco",
44
- visibilityTime: 2000,
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 (_jsx(SafeAreaView, { className: "flex-1", edges: ["top", "bottom"], style: { backgroundColor }, 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, renderLoading: renderLoading ||
160
- (() => _jsx(WebViewLoadingIndicator, { backgroundColor: backgroundColor })), scalesPageToFit: true, sharedCookiesEnabled: true, source: { uri: url }, startInLoadingState: true, style: { flex: 1, backgroundColor } }) }));
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-white 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-gray-500", ellipsizeMode: "tail", numberOfLines: 2, variant: "bodySmall", children: jsonString })] }) }));
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 { theme } from "@sincpro/mobile-ui/theme";
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: EVariantScreenHeader.FLAT_HEADER, children: _jsx(FormViewV2.Header.Actions, { children: _jsxs(Typography.Text, { className: "text-gray-500", 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 () => {
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 navigate = useNavigate();
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 = () => navigate(-1);
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: EVariantScreenHeader.FLAT_HEADER }), _jsx(ListViewV2.Content, { children: (table) => (_jsx(DatabaseInfoRow, { item: {
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: EVariantScreenHeader.FLAT_HEADER, children: _jsx(ListViewV2.Header.Search, {}) }), _jsx(ListViewV2.Content, { children: (item) => (_jsx(TableInfoRow, { item: { data: safeJsonStringify(item) }, onPress: () => selectRowJson(safeJsonStringify(item), item.index) })) })] }));
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 navigate = useNavigate();
8
+ const navigation = useNavigation();
10
9
  const { enrichedEvents, isLoading, loadEvents, retryEvent } = useDeadLetterQueue();
11
10
  useEffect(() => {
12
11
  loadEvents();
13
12
  }, [loadEvents]);
14
- const onBack = () => navigate(-1);
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: EVariantScreenHeader.FLAT_HEADER }), _jsx(ListViewV2.Content, { children: (event) => (_jsx(DeadLetterQueueRow, { item: event, onRetry: async (evt) => {
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 navigate = useNavigate();
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 = () => navigate(-1);
21
- return (_jsxs(ListViewV2.Root, { description: "Eventos registrados", isLoading: isLoading, items: pagedEvents, name: "Eventos", onBack: onBack, onRefresh: loadEvents, children: [_jsx(ListViewV2.Header, { variant: EVariantScreenHeader.FLAT_HEADER, 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) => {
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.1.1",
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-router-native": ">=6",
62
- "@sincpro/mobile-ui": "^0.2.1"
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-router-native": "^6.30.0",
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.2.1"
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 };