From b96f2f676a7055d5bfb5b01839110da44f07f830 Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Sat, 17 May 2025 18:17:20 -0400 Subject: [PATCH 1/9] Creating new tabBar and doing fixes --- src/app/(delivery-tabs)/_layout.tsx | 29 +--- src/app/(delivery-tabs)/deliverySupport.tsx | 6 - src/app/(tabs)/_layout.tsx | 20 +-- src/app/(tabs)/support.tsx | 7 - src/app/_layout.tsx | 50 +++---- src/components/TabBar.tsx | 140 ++++++++++++++++++ src/components/TabBarButton.tsx | 94 ++++++++++++ src/constants/icon.tsx | 22 +++ src/screens/ActiveOrdersScreen.tsx | 2 +- src/screens/CartListScreen.tsx | 1 + src/screens/DirectionChangeScreen.tsx | 2 +- src/screens/DirectionCreateScreen.tsx | 2 +- src/screens/DirectionScreen.tsx | 2 +- .../LoggedInPasswordRecoveryScreen.tsx | 1 - src/screens/MenuScreen.tsx | 1 - src/screens/OrderDetailScreen.tsx | 2 +- src/screens/OrdersScreen.tsx | 2 +- src/screens/PasswordChangeScreen.tsx | 2 +- src/screens/ProfileScreen.tsx | 2 +- src/screens/SelectLocationScreen.tsx | 25 +++- .../delivery/DeliveryHistoryScreen.tsx | 4 + src/screens/delivery/DeliveryHomeScreen.tsx | 4 + .../delivery/DeliverySupportScreen.tsx | 21 --- src/screens/tab/BranchesScreen.tsx | 4 + src/screens/tab/CategoriesScreen.tsx | 4 + src/screens/tab/HomeScreen.tsx | 4 + src/screens/tab/OffersScreen.tsx | 4 + src/screens/tab/SupportScreen.tsx | 21 --- src/styles/theme.ts | 4 + 29 files changed, 338 insertions(+), 144 deletions(-) delete mode 100644 src/app/(delivery-tabs)/deliverySupport.tsx delete mode 100644 src/app/(tabs)/support.tsx create mode 100644 src/components/TabBar.tsx create mode 100644 src/components/TabBarButton.tsx create mode 100644 src/constants/icon.tsx delete mode 100644 src/screens/delivery/DeliverySupportScreen.tsx delete mode 100644 src/screens/tab/SupportScreen.tsx diff --git a/src/app/(delivery-tabs)/_layout.tsx b/src/app/(delivery-tabs)/_layout.tsx index 9e1243f..14b1f43 100644 --- a/src/app/(delivery-tabs)/_layout.tsx +++ b/src/app/(delivery-tabs)/_layout.tsx @@ -3,25 +3,17 @@ import { Tabs } from 'expo-router'; import { View, StyleSheet } from 'react-native'; import { Colors } from '../../styles/theme'; import PoppinsText from '../../components/PoppinsText'; -import { - HomeIcon, - ClockIcon, - LifebuoyIcon, -} from 'react-native-heroicons/outline'; +import { HomeIcon, ClockIcon } from 'react-native-heroicons/outline'; import TopBarDelivery from '../../components/TopBarDelivery'; import { AlertProvider } from '../../components/AlertProvider'; // Importar el AlertProvider +import { TabBar } from '../../components/TabBar'; export default function DeliveryTabLayout() { return ( - + }> - ( - - Soporte - - ), - headerShown: false, - title: 'Soporte', - tabBarIcon: () => ( - - ), - }} - /> diff --git a/src/app/(delivery-tabs)/deliverySupport.tsx b/src/app/(delivery-tabs)/deliverySupport.tsx deleted file mode 100644 index fae268e..0000000 --- a/src/app/(delivery-tabs)/deliverySupport.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import DeliverySupportScreen from '../../screens/delivery/DeliverySupportScreen'; - -export default function DeliverySupport() { - return ; -} diff --git a/src/app/(tabs)/_layout.tsx b/src/app/(tabs)/_layout.tsx index ae1c79b..27b9f64 100644 --- a/src/app/(tabs)/_layout.tsx +++ b/src/app/(tabs)/_layout.tsx @@ -3,22 +3,21 @@ import { ListBulletIcon, MapPinIcon, TagIcon, - LifebuoyIcon, } from 'react-native-heroicons/outline'; import { Tabs } from 'expo-router'; import { Colors } from '../../styles/theme'; import PoppinsText from '../../components/PoppinsText'; import { View, StyleSheet } from 'react-native'; import TopBar from '../../components/TopBar'; +import { TabBar } from '../../components/TabBar'; export default function TabLayout() { return ( } // Siempre renderiza la TabBar screenOptions={{ - tabBarActiveTintColor: Colors.primary, - tabBarStyle: { backgroundColor: Colors.secondaryWhite }, tabBarHideOnKeyboard: true, tabBarVisibilityAnimationConfig: { show: { @@ -93,21 +92,6 @@ export default function TabLayout() { ), }} /> - ( - - Soporte - - ), - title: 'Soporte', - headerShown: false, - tabBarIcon: () => ( - - ), - }} - /> ); diff --git a/src/app/(tabs)/support.tsx b/src/app/(tabs)/support.tsx deleted file mode 100644 index 600e4de..0000000 --- a/src/app/(tabs)/support.tsx +++ /dev/null @@ -1,7 +0,0 @@ -// app/(tabs)/support.tsx -import React from 'react'; -import SupportScreen from '../../screens/tab/SupportScreen'; - -export default function TabsHome() { - return ; -} diff --git a/src/app/_layout.tsx b/src/app/_layout.tsx index a9c0b94..7fe2879 100644 --- a/src/app/_layout.tsx +++ b/src/app/_layout.tsx @@ -55,6 +55,10 @@ export default function RootLayout() { ({ headerBackVisible: false, + headerStyle: { + backgroundColor: Colors.bgColor, // Color específico para esta pantalla + }, + headerShadowVisible: false, headerLeft: () => navigation.canGoBack() ? ( - + - + - - - - + + + + ({ headerTitle: '', - headerTransparent: true, headerLeft: undefined, headerRight: () => ( navigation.goBack()}> @@ -149,10 +137,7 @@ export default function RootLayout() { ), })} /> - + diff --git a/src/components/TabBar.tsx b/src/components/TabBar.tsx new file mode 100644 index 0000000..c34528f --- /dev/null +++ b/src/components/TabBar.tsx @@ -0,0 +1,140 @@ +import { View, StyleSheet, LayoutChangeEvent } from 'react-native'; +import { BottomTabBarProps } from '@react-navigation/bottom-tabs'; +import { Colors } from '../styles/theme'; +import { useState } from 'react'; +import TabBarButton from './TabBarButton'; +import Animated, { + useAnimatedStyle, + useSharedValue, + withTiming, +} from 'react-native-reanimated'; + +export function TabBar({ state, descriptors, navigation }: BottomTabBarProps) { + const currentRoute = state.routes[state.index].name; + + // Oculta la TabBar en pantallas específicas + const hiddenRoutes = ['menu', 'cart']; // Agrega aquí las rutas donde no quieres mostrar la TabBar + if (hiddenRoutes.includes(currentRoute)) { + return null; // No renderiza la TabBar + } + + const [dimensions, setDimensions] = useState({ width: 10, height: 20 }); + + const buttonWidth = dimensions.width / state.routes.length; + + const onTabBarLayout = (e: LayoutChangeEvent) => { + setDimensions({ + width: e.nativeEvent.layout.width, + height: e.nativeEvent.layout.height, + }); + }; + + const tabPositionX = useSharedValue(0); + + const animatedStyle = useAnimatedStyle(() => ({ + transform: [ + { + translateX: tabPositionX.value + 16, + }, + ], + })); + + return ( + + + {state.routes.map((route, index) => { + const { options } = descriptors[route.key]; + const label = + options.tabBarLabel !== undefined + ? options.tabBarLabel + : options.title !== undefined + ? options.title + : route.name; + + const isFocused = state.index === index; + + const onPress = () => { + tabPositionX.value = withTiming(buttonWidth * index, { + duration: 350, + }); + + const event = navigation.emit({ + type: 'tabPress', + target: route.key, + canPreventDefault: true, + }); + + if (!isFocused && !event.defaultPrevented) { + navigation.navigate(route.name, route.params); + } + }; + + const onLongPress = () => { + navigation.emit({ + type: 'tabLongPress', + target: route.key, + }); + }; + + return ( + + label({ + ...props, + position: props.position as 'beside-icon' | 'below-icon', + }) + : label + } + /> + ); + })} + + ); +} + +const styles = StyleSheet.create({ + tabBar: { + position: 'absolute', + flexDirection: 'row', + bottom: 0, + justifyContent: 'space-between', + alignItems: 'center', + borderColor: Colors.gray_100, + borderTopWidth: 1, + backgroundColor: Colors.menuWhite, + paddingVertical: 6, + shadowColor: '#000', + shadowOffset: { + width: 0, + height: 10, + }, + shadowOpacity: 0.1, + shadowRadius: 10, + }, + // tabBarItem: { + // flex: 1, + // justifyContent: 'center', + // alignItems: 'center', + // }, +}); diff --git a/src/components/TabBarButton.tsx b/src/components/TabBarButton.tsx new file mode 100644 index 0000000..d11c631 --- /dev/null +++ b/src/components/TabBarButton.tsx @@ -0,0 +1,94 @@ +import { Pressable, StyleSheet, GestureResponderEvent } from 'react-native'; +import Animated from 'react-native-reanimated'; +import React, { useEffect } from 'react'; +import { icon } from '../constants/icon'; +import { + interpolate, + useAnimatedStyle, + useSharedValue, + withSpring, +} from 'react-native-reanimated'; +import { Colors } from '../styles/theme'; + +const TabBarButton = ({ + onPress, + onLongPress, + isFocused, + routeName, + label, +}: { + onPress: (event: GestureResponderEvent) => void; + onLongPress: (event: GestureResponderEvent) => void; + isFocused: boolean; + routeName: keyof typeof icon; + color: string; + label: + | string + | ((args: { + focused: boolean; + color: string; + position: string; + children: string; + }) => React.ReactNode); +}) => { + const scale = useSharedValue(0); + + useEffect(() => { + scale.value = withSpring( + typeof isFocused === 'boolean' ? (isFocused ? 1 : 0) : isFocused, + { duration: 350 }, + ); + }, [scale, isFocused]); + + const animatedIconStyle = useAnimatedStyle(() => { + const scaleValue = interpolate(scale.value, [0, 1], [1, 1.2]); + + const top = interpolate(scale.value, [0, 1], [0, 9]); + return { + transform: [{ scale: scaleValue }], + top, + }; + }); + + const animatedTextStyle = useAnimatedStyle(() => { + const opacity = interpolate(scale.value, [0, 1], [1, 0]); + return { + opacity, + }; + }); + return ( + + + {icon[routeName]({ + color: isFocused ? Colors.menuWhite : Colors.primary, + })} + + + + {typeof label === 'function' + ? label({ + focused: isFocused, + color: isFocused ? Colors.primary : Colors.primary, + position: 'beside-icon', + children: '', + }) + : label} + + + ); +}; + +export default TabBarButton; + +const styles = StyleSheet.create({ + tabBarItem: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + paddingVertical: 6, + }, +}); diff --git a/src/constants/icon.tsx b/src/constants/icon.tsx new file mode 100644 index 0000000..45386e5 --- /dev/null +++ b/src/constants/icon.tsx @@ -0,0 +1,22 @@ +import { Feather } from '@expo/vector-icons'; +import type { ComponentProps } from 'react'; + +type FeatherIconProps = Omit, 'name'>; + +export const icon = { + index: (props: FeatherIconProps) => ( + + ), + categories: (props: FeatherIconProps) => ( + + ), + branches: (props: FeatherIconProps) => ( + + ), + offers: (props: FeatherIconProps) => ( + + ), + deliveryHistory: (props: FeatherIconProps) => ( + + ), +}; diff --git a/src/screens/ActiveOrdersScreen.tsx b/src/screens/ActiveOrdersScreen.tsx index 51bd3eb..a5fc103 100644 --- a/src/screens/ActiveOrdersScreen.tsx +++ b/src/screens/ActiveOrdersScreen.tsx @@ -171,6 +171,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, }, alertContainer: { position: 'absolute', @@ -183,7 +184,6 @@ const styles = StyleSheet.create({ }, orderHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, orderInfo: { diff --git a/src/screens/CartListScreen.tsx b/src/screens/CartListScreen.tsx index c2151aa..b5a6f51 100644 --- a/src/screens/CartListScreen.tsx +++ b/src/screens/CartListScreen.tsx @@ -153,6 +153,7 @@ const styles = StyleSheet.create({ flex: 1, backgroundColor: Colors.bgColor, padding: 16, + paddingTop: -16, }, header: { fontSize: FontSizes.h5.size, diff --git a/src/screens/DirectionChangeScreen.tsx b/src/screens/DirectionChangeScreen.tsx index 26ebc2b..df541bd 100644 --- a/src/screens/DirectionChangeScreen.tsx +++ b/src/screens/DirectionChangeScreen.tsx @@ -251,6 +251,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, }, alertContainer: { position: 'absolute', @@ -263,7 +264,6 @@ const styles = StyleSheet.create({ }, addressHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, addressImage: { diff --git a/src/screens/DirectionCreateScreen.tsx b/src/screens/DirectionCreateScreen.tsx index 35f3ca8..8488348 100644 --- a/src/screens/DirectionCreateScreen.tsx +++ b/src/screens/DirectionCreateScreen.tsx @@ -207,6 +207,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, }, alertContainer: { position: 'absolute', @@ -219,7 +220,6 @@ const styles = StyleSheet.create({ }, addressHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, addressInfo: { diff --git a/src/screens/DirectionScreen.tsx b/src/screens/DirectionScreen.tsx index 8653b6b..998c23c 100644 --- a/src/screens/DirectionScreen.tsx +++ b/src/screens/DirectionScreen.tsx @@ -191,6 +191,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, }, alertContainer: { position: 'absolute', @@ -203,7 +204,6 @@ const styles = StyleSheet.create({ }, directionHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, directionInfo: { diff --git a/src/screens/LoggedInPasswordRecoveryScreen.tsx b/src/screens/LoggedInPasswordRecoveryScreen.tsx index e2b2096..880e6f5 100644 --- a/src/screens/LoggedInPasswordRecoveryScreen.tsx +++ b/src/screens/LoggedInPasswordRecoveryScreen.tsx @@ -296,7 +296,6 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, justifyContent: 'flex-start', - paddingTop: 56, paddingHorizontal: 20, }, stepsWrapper: { diff --git a/src/screens/MenuScreen.tsx b/src/screens/MenuScreen.tsx index a7bc1ab..761691f 100644 --- a/src/screens/MenuScreen.tsx +++ b/src/screens/MenuScreen.tsx @@ -214,7 +214,6 @@ const styles = StyleSheet.create({ }, menuContent: { flex: 1, - marginTop: 40, paddingHorizontal: 10, justifyContent: 'space-between', }, diff --git a/src/screens/OrderDetailScreen.tsx b/src/screens/OrderDetailScreen.tsx index 2a4d39b..6dddebc 100644 --- a/src/screens/OrderDetailScreen.tsx +++ b/src/screens/OrderDetailScreen.tsx @@ -234,6 +234,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, paddingBottom: 0, }, alertContainer: { @@ -253,7 +254,6 @@ const styles = StyleSheet.create({ }, orderHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, orderImage: { diff --git a/src/screens/OrdersScreen.tsx b/src/screens/OrdersScreen.tsx index d7dfa26..73a5600 100644 --- a/src/screens/OrdersScreen.tsx +++ b/src/screens/OrdersScreen.tsx @@ -197,6 +197,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, }, alertContainer: { position: 'absolute', @@ -209,7 +210,6 @@ const styles = StyleSheet.create({ }, orderHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, orderInfo: { diff --git a/src/screens/PasswordChangeScreen.tsx b/src/screens/PasswordChangeScreen.tsx index 595e918..9e35277 100644 --- a/src/screens/PasswordChangeScreen.tsx +++ b/src/screens/PasswordChangeScreen.tsx @@ -207,7 +207,7 @@ const styles = StyleSheet.create({ backgroundColor: Colors.bgColor, justifyContent: 'flex-start', alignItems: 'center', - paddingTop: 100, + paddingTop: 32, paddingHorizontal: 20, }, alertContainer: { diff --git a/src/screens/ProfileScreen.tsx b/src/screens/ProfileScreen.tsx index ee10956..1e60176 100644 --- a/src/screens/ProfileScreen.tsx +++ b/src/screens/ProfileScreen.tsx @@ -311,6 +311,7 @@ const styles = StyleSheet.create({ flexGrow: 1, backgroundColor: Colors.bgColor, padding: 20, + paddingTop: -20, }, alertContainer: { position: 'absolute', @@ -323,7 +324,6 @@ const styles = StyleSheet.create({ }, profileHeader: { alignItems: 'center', - marginTop: 30, marginBottom: 15, }, profileImage: { diff --git a/src/screens/SelectLocationScreen.tsx b/src/screens/SelectLocationScreen.tsx index a85b204..dfa43b3 100644 --- a/src/screens/SelectLocationScreen.tsx +++ b/src/screens/SelectLocationScreen.tsx @@ -1,5 +1,11 @@ import React, { useState, useRef, useEffect } from 'react'; -import { StyleSheet, View, TextInput, Alert } from 'react-native'; +import { + StyleSheet, + View, + TextInput, + Alert, + TouchableOpacity, +} from 'react-native'; import MapView, { PROVIDER_GOOGLE, Region } from 'react-native-maps'; // Importa el tipo Region import * as Location from 'expo-location'; import { useRouter } from 'expo-router'; @@ -8,10 +14,14 @@ import { MapPinIcon } from 'react-native-heroicons/solid'; import { Colors, FontSizes } from '../styles/theme'; import PoppinsText from '../components/PoppinsText'; import { Config } from '../config'; +import { ChevronLeftIcon } from 'react-native-heroicons/outline'; +import { useNavigation } from '@react-navigation/native'; const SelectLocationScreen = () => { console.log('Clave de API utilizada:', Config.googleMapsApiKey); + const navigation = useNavigation(); + const [selectedLocation, setSelectedLocation] = useState<{ latitude: number; longitude: number; @@ -129,6 +139,15 @@ const SelectLocationScreen = () => { {/* Header con input para mostrar la dirección */} + + + { /> )) )} + ); @@ -172,6 +173,9 @@ const styles = StyleSheet.create({ padding: 16, marginHorizontal: 4, }, + height: { + height: 64, + }, title: { fontSize: FontSizes.h5.size, lineHeight: FontSizes.h5.lineHeight, diff --git a/src/screens/delivery/DeliveryHomeScreen.tsx b/src/screens/delivery/DeliveryHomeScreen.tsx index 3f63b72..43e9d0f 100644 --- a/src/screens/delivery/DeliveryHomeScreen.tsx +++ b/src/screens/delivery/DeliveryHomeScreen.tsx @@ -205,6 +205,7 @@ export default function DeliveryHomeScreen() { /> )) )} + {/* Popup de confirmación para descartar orden */} @@ -233,6 +234,9 @@ const styles = StyleSheet.create({ padding: 16, marginHorizontal: 4, }, + height: { + height: 64, + }, title: { fontSize: FontSizes.h5.size, lineHeight: FontSizes.h5.lineHeight, diff --git a/src/screens/delivery/DeliverySupportScreen.tsx b/src/screens/delivery/DeliverySupportScreen.tsx deleted file mode 100644 index 5b841c7..0000000 --- a/src/screens/delivery/DeliverySupportScreen.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { View, StyleSheet } from 'react-native'; -import PoppinsText from '../../components/PoppinsText'; -import { Colors } from '../../styles/theme'; - -export default function SupportScreen() { - return ( - - Pantalla Soporte - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: Colors.bgColor, - }, -}); diff --git a/src/screens/tab/BranchesScreen.tsx b/src/screens/tab/BranchesScreen.tsx index f74e03d..9d70be8 100644 --- a/src/screens/tab/BranchesScreen.tsx +++ b/src/screens/tab/BranchesScreen.tsx @@ -144,6 +144,7 @@ export default function BranchesScreen() { + ); } @@ -155,6 +156,9 @@ const styles = StyleSheet.create({ padding: 16, paddingTop: -16, }, + height: { + height: 64, + }, title: { fontSize: FontSizes.s1.size, lineHeight: FontSizes.s1.lineHeight, diff --git a/src/screens/tab/CategoriesScreen.tsx b/src/screens/tab/CategoriesScreen.tsx index f446b72..7f5517f 100644 --- a/src/screens/tab/CategoriesScreen.tsx +++ b/src/screens/tab/CategoriesScreen.tsx @@ -80,6 +80,7 @@ export default function CategoriesScreen() { showsVerticalScrollIndicator={true} alwaysBounceVertical={true} /> + ); } @@ -89,6 +90,9 @@ const styles = StyleSheet.create({ backgroundColor: Colors.bgColor, flex: 1, }, + height: { + height: 64, + }, alertContainer: { position: 'absolute', width: 326, diff --git a/src/screens/tab/HomeScreen.tsx b/src/screens/tab/HomeScreen.tsx index ad91bf1..8d1e2de 100644 --- a/src/screens/tab/HomeScreen.tsx +++ b/src/screens/tab/HomeScreen.tsx @@ -216,6 +216,7 @@ export default function HomeScreen() { )} + Pantalla Ofertas + ); } @@ -18,4 +19,7 @@ const styles = StyleSheet.create({ alignItems: 'center', backgroundColor: Colors.bgColor, }, + height: { + height: 64, + }, }); diff --git a/src/screens/tab/SupportScreen.tsx b/src/screens/tab/SupportScreen.tsx deleted file mode 100644 index ee0cf25..0000000 --- a/src/screens/tab/SupportScreen.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { View, StyleSheet } from 'react-native'; -import PoppinsText from '../../components/PoppinsText'; -import { Colors } from '../../styles/theme'; - -export default function SupportScreen() { - return ( - - Pantalla Ofertas - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: Colors.bgColor, - }, -}); diff --git a/src/styles/theme.ts b/src/styles/theme.ts index 22a60be..c41121f 100644 --- a/src/styles/theme.ts +++ b/src/styles/theme.ts @@ -36,6 +36,10 @@ export const Colors = { gray_100: '#E7E7E6', gray_500: '#6E6D6C', + tertiary_600: '#247D74', + tertiary_500: '#319B8F', + tertiary_400: '#4AB7A8', + secondary_300: '#8BEAB3', primary_300: '#A2BEEE', From 2d1347e590939b948213a5573cbcfb820ef2a536 Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Sun, 18 May 2025 18:37:06 -0400 Subject: [PATCH 2/9] Fixing some errors that appeared in delivery details --- src/components/DeliveryMap.tsx | 96 +++++++++---- src/screens/delivery/DeliveryDetailScreen.tsx | 135 +++++++++++------- 2 files changed, 151 insertions(+), 80 deletions(-) diff --git a/src/components/DeliveryMap.tsx b/src/components/DeliveryMap.tsx index c987c23..fa3e7e4 100644 --- a/src/components/DeliveryMap.tsx +++ b/src/components/DeliveryMap.tsx @@ -1,8 +1,9 @@ import React, { useEffect, useState } from 'react'; import MapView, { Marker, Polyline } from 'react-native-maps'; -import { StyleSheet, View, Alert } from 'react-native'; +import { StyleSheet, View, Alert, ActivityIndicator } from 'react-native'; import * as Location from 'expo-location'; import { Config } from '../config'; +import { Colors } from '../styles/theme'; interface DeliveryMapProps { deliveryState: number; @@ -25,6 +26,7 @@ const DeliveryMap: React.FC = ({ const [customerRouteCoordinates, setCustomerRouteCoordinates] = useState< { latitude: number; longitude: number }[] >([]); + const [isLoading, setIsLoading] = useState(true); // Estado de carga // Solicitar permisos y obtener la ubicación del delivery useEffect(() => { @@ -48,15 +50,6 @@ const DeliveryMap: React.FC = ({ latitude: location.coords.latitude, longitude: location.coords.longitude, }); - - // Obtener la ruta desde la ubicación del delivery hasta la sucursal - fetchRoute( - location.coords.latitude, - location.coords.longitude, - branchLocation.latitude, - branchLocation.longitude, - setRouteCoordinates, - ); } catch (error) { console.error('Error al obtener la ubicación del delivery:', error); Alert.alert( @@ -96,11 +89,30 @@ const DeliveryMap: React.FC = ({ } }; + // Obtener la ruta hacia la sucursal + useEffect(() => { + if ( + deliveryLocation && + branchLocation.latitude !== 0 && + branchLocation.longitude !== 0 + ) { + fetchRoute( + deliveryLocation.latitude, + deliveryLocation.longitude, + branchLocation.latitude, + branchLocation.longitude, + setRouteCoordinates, + ); + } + }, [deliveryLocation, branchLocation]); + // Obtener la ruta hacia el cliente cuando el estado sea el correspondiente useEffect(() => { if ( - deliveryState >= 3 && // Estado "Ir a destino de entrega" o posterior - deliveryLocation + deliveryState >= 3 && + deliveryLocation && + customerLocation.latitude !== 0 && + customerLocation.longitude !== 0 ) { fetchRoute( deliveryLocation.latitude, @@ -113,7 +125,20 @@ const DeliveryMap: React.FC = ({ // Limpiar la ruta hacia la sucursal setRouteCoordinates([]); } - }, [deliveryState, deliveryLocation]); + }, [deliveryState, deliveryLocation, customerLocation]); + + // Verificar si todos los datos necesarios están disponibles + useEffect(() => { + if ( + deliveryLocation && + branchLocation.latitude !== 0 && + branchLocation.longitude !== 0 && + customerLocation.latitude !== 0 && + customerLocation.longitude !== 0 + ) { + setIsLoading(false); // Finalizar la carga cuando todos los datos estén disponibles + } + }, [deliveryLocation, branchLocation, customerLocation]); // Decodificar la polyline de Google Maps const decodePolyline = (encoded: string) => { @@ -154,13 +179,22 @@ const DeliveryMap: React.FC = ({ return points; }; + if (isLoading) { + // Mostrar un indicador de carga mientras se obtienen los datos + return ( + + + + ); + } + return ( = ({ )} {/* Mostrar la ubicación de la sucursal */} - + {branchLocation.latitude !== 0 && branchLocation.longitude !== 0 && ( + + )} {/* Mostrar la ubicación del cliente */} - + {customerLocation.latitude !== 0 && + customerLocation.longitude !== 0 && ( + + )} {/* Mostrar la ruta hacia la sucursal */} {routeCoordinates.length > 0 && ( @@ -197,7 +236,7 @@ const DeliveryMap: React.FC = ({ /> )} - {/* Mostrar la ruta hacia el cliente solo si el estado es el correspondiente */} + {/* Mostrar la ruta hacia el cliente */} {deliveryState >= 3 && customerRouteCoordinates.length > 0 && ( { const [order, setOrder] = useState( undefined, ); + const [isOrderDetailsLoading, setIsOrderDetailsLoading] = useState(true); + const [isFetchingOrder, setIsFetchingOrder] = useState(false); // Nuevo estado de carga para fetchOrder + const [branchNames, setBranchNames] = useState< + Record + >({}); + const [deliveryStateBadge, setDeliveryStateBadge] = useState(0); + const router = useRouter(); + + useEffect(() => { + const fetchOrderDetails = async () => { + try { + if (!orderDetails) { + const details = await DeliveryService.getOrderDetails(id as string); + dispatch(setOrderDetails({ id: id as string, details })); + } + } catch (error) { + console.error('Error al obtener los detalles del pedido:', error); + } finally { + setIsOrderDetailsLoading(false); + } + }; + + fetchOrderDetails(); + }, [id, orderDetails, dispatch]); + + useEffect(() => { + const fetchBranches = async () => { + try { + const branches = await BranchService.findAll({ page: 1, limit: 100 }); + const branchMap = branches.results.reduce( + ( + acc: Record< + string, + { name: string; latitude: number; longitude: number } + >, + branch, + ) => { + acc[branch.id] = { + name: branch.name, + latitude: branch.latitude, + longitude: branch.longitude, + }; + return acc; + }, + {}, + ); + + setBranchNames(branchMap); + } catch (error) { + console.error('Error al obtener las sucursales:', error); + } finally { + setIsFetchingOrder(false); + } + }; + + if (orderDetails) { + fetchBranches(); + } + }, [orderDetails]); + useEffect(() => { const fetchOrder = async () => { + setIsFetchingOrder(true); // Iniciar el indicador de carga + let timerId: NodeJS.Timeout | null = null; // Identificador del temporizador + try { if (!orderDetails) { - console.error( - 'No se encontraron detalles de la orden de tipo delivery.', - ); + // Agregar un temporizador de 2 segundos antes de mostrar el error + timerId = setTimeout(() => { + if (!orderDetails) { + console.error( + 'No se encontraron detalles de la orden de tipo delivery.', + ); + } + }, 2000); return; } - const orderId = orderDetails.orderId; // Extraer el ID de la orden + const orderId = orderDetails.orderId; console.log('ID de la orden:', orderId); - const order = await UserService.getOrder(orderId); // Usar el ID de la orden + const order = await UserService.getOrder(orderId); if (order.success) { - console.log('Datos del pedido:', order.data); // Log para verificar los datos + console.log('Datos del pedido:', order.data); setOrder(order.data); } else { console.error('Error al obtener el pedido:', order.error); @@ -65,7 +133,10 @@ const DeliveryDetailScreen: React.FC = () => { } catch (error) { console.error('Error en fetchOrder:', error); } finally { - setLoading(false); + setIsFetchingOrder(false); // Finalizar el indicador de carga + if (timerId) { + clearTimeout(timerId); // Cancelar el temporizador si los datos están disponibles + } } }; @@ -76,13 +147,6 @@ const DeliveryDetailScreen: React.FC = () => { (state: RootState) => state.delivery.deliveryState[id as string] || 0, ); - const [branchNames, setBranchNames] = useState< - Record - >({}); - const [loading, setLoading] = useState(true); - const [deliveryStateBadge, setDeliveryStateBadge] = useState(0); - const router = useRouter(); - // Estados para las alertas const [showAlert, setShowAlert] = useState(false); const [alertType, setAlertType] = useState<'success' | 'error' | 'info'>( @@ -115,45 +179,6 @@ const DeliveryDetailScreen: React.FC = () => { longitude: orderDetails?.address?.longitude || 0, }; - useEffect(() => { - const fetchOrderDetails = async () => { - if (!orderDetails) { - const details = await DeliveryService.getOrderDetails(id as string); - dispatch(setOrderDetails({ id: id as string, details })); - } - - try { - // Obtener todas las sucursales y mapear sus nombres y coordenadas - const branches = await BranchService.findAll({ page: 1, limit: 100 }); - const branchMap = branches.results.reduce( - ( - acc: Record< - string, - { name: string; latitude: number; longitude: number } - >, - branch, - ) => { - acc[branch.id] = { - name: branch.name, - latitude: branch.latitude, - longitude: branch.longitude, - }; - return acc; - }, - {}, - ); - - setBranchNames(branchMap); - } catch (error) { - console.error('Error al obtener los detalles del pedido:', error); - } finally { - setLoading(false); - } - }; - - fetchOrderDetails(); - }, [id, orderDetails, dispatch]); - const handleNextState = async () => { try { if (deliveryState === buttonStates.length - 1) { @@ -242,11 +267,13 @@ const DeliveryDetailScreen: React.FC = () => { } }; - if (loading) { + if (isOrderDetailsLoading || isFetchingOrder) { + // Mostrar un indicador de carga mientras se obtienen los detalles del pedido o la orden return ; } if (!orderDetails) { + // Mostrar un mensaje de error si no se encuentran los detalles del pedido return ( From 8632ed578fae0c3bdc5528b6ca9b80763e8689ac Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Sun, 18 May 2025 20:15:41 -0400 Subject: [PATCH 3/9] Adapting proper estimated time to order delivery cards --- src/components/OrderCard.tsx | 12 +- src/screens/delivery/DeliveryHomeScreen.tsx | 151 ++++++++++++++++---- 2 files changed, 129 insertions(+), 34 deletions(-) diff --git a/src/components/OrderCard.tsx b/src/components/OrderCard.tsx index ca4451b..67d196c 100644 --- a/src/components/OrderCard.tsx +++ b/src/components/OrderCard.tsx @@ -59,7 +59,7 @@ const OrderCard: React.FC = ({ {/* Details */} - + {address} @@ -73,7 +73,7 @@ const OrderCard: React.FC = ({ - Hora de entrega: {estimatedTime} + Tiempo estimado: {estimatedTime} @@ -135,18 +135,18 @@ const styles = StyleSheet.create({ color: Colors.primary, marginBottom: 8, }, - details: { - marginBottom: 4, - }, detailRow: { flexDirection: 'row', alignItems: 'center', - marginBottom: 8, + marginBottom: 10, }, detailText: { fontSize: FontSizes.b3.size, color: Colors.textMain, marginLeft: 8, + flexWrap: 'wrap', + maxWidth: '90%', + textAlign: 'left', }, button: { marginBottom: 8, diff --git a/src/screens/delivery/DeliveryHomeScreen.tsx b/src/screens/delivery/DeliveryHomeScreen.tsx index 43e9d0f..4136972 100644 --- a/src/screens/delivery/DeliveryHomeScreen.tsx +++ b/src/screens/delivery/DeliveryHomeScreen.tsx @@ -17,17 +17,63 @@ import { DeliveryService } from '../../services/delivery'; import { BranchService } from '../../services/branches'; import { OrderDeliveryDetailedResponse, - BranchResponse, OrderDeliveryStatus, } from '@pharmatech/sdk'; import { useAlert } from '../../components/AlertProvider'; // Importar el hook useAlert +import * as Location from 'expo-location'; // Importar Location para obtener la ubicación actual +import { Config } from '../../config'; // Importar la configuración de la API de Google Maps + +// Definir el tipo para un leg de la API de Google Maps Directions +interface GoogleMapsLeg { + duration: { + value: number; // Duración en segundos + }; +} + +const calculateTravelTime = async ( + origin: { latitude: number; longitude: number }, + destination: { latitude: number; longitude: number }, +): Promise => { + try { + const response = await fetch( + `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.latitude},${origin.longitude}&destination=${destination.latitude},${destination.longitude}&key=${Config.googleMapsApiKey}`, + ); + const data = await response.json(); + + if (data.routes && data.routes.length > 0) { + // Extraer el tiempo estimado en segundos + const durationInSeconds = data.routes[0].legs.reduce( + (total: number, leg: GoogleMapsLeg) => total + leg.duration.value, + 0, + ); + + // Convertir a minutos + return Math.ceil(durationInSeconds / 60); + } else { + console.error('No se pudo calcular el tiempo estimado.'); + return 0; + } + } catch (error) { + console.error('Error al calcular el tiempo estimado:', error); + return 0; + } +}; + +// Extender el tipo OrderDeliveryDetailedResponse +type ExtendedOrderDeliveryDetailedResponse = OrderDeliveryDetailedResponse & { + formattedEstimatedTime: string; // Nueva propiedad para el tiempo formateado +}; export default function DeliveryHomeScreen() { const router = useRouter(); const { showAlert } = useAlert(); - const [orders, setOrders] = useState([]); - const [branchNames, setBranchNames] = useState>({}); + const [orders, setOrders] = useState( + [], + ); + const [branchNames, setBranchNames] = useState< + Record + >({}); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [selectedOrder, setSelectedOrder] = @@ -44,30 +90,85 @@ export default function DeliveryHomeScreen() { const payload = JSON.parse(atob(jwt.split('.')[1])); const employeeId = payload.sub; + // Obtener las órdenes asignadas const response = await DeliveryService.getAssignedOrders(employeeId); - const detailedOrders = await Promise.all( - response.results.map(async (order) => { - const details = await DeliveryService.getOrderDetails(order.id); - return details; - }), - ); - - const branchIds = [ - ...new Set(detailedOrders.map((order) => order.branchId)), - ]; + // Obtener las sucursales const branches = await BranchService.findAll({ page: 1, limit: 100 }); const branchMap = branches.results.reduce( - (acc: Record, branch: BranchResponse) => { - if (branchIds.includes(branch.id)) { - acc[branch.id] = branch.name; - } + ( + acc: Record< + string, + { name: string; latitude: number; longitude: number } + >, + branch, + ) => { + acc[branch.id] = { + name: branch.name, + latitude: branch.latitude, + longitude: branch.longitude, + }; return acc; }, {}, ); - setBranchNames(branchMap); + + // Procesar las órdenes con cálculo de tiempo estimado + const detailedOrders: ExtendedOrderDeliveryDetailedResponse[] = + await Promise.all( + response.results.map(async (order) => { + const details = await DeliveryService.getOrderDetails(order.id); + + // Obtener la ubicación actual del repartidor + const location = await Location.getCurrentPositionAsync({}); + const deliveryLocation = { + latitude: location.coords.latitude, + longitude: location.coords.longitude, + }; + + // Obtener la ubicación de la sucursal + const branchLocation = { + latitude: branchMap[details.branchId]?.latitude || 0, + longitude: branchMap[details.branchId]?.longitude || 0, + }; + + // Obtener la ubicación del cliente + const customerLocation = { + latitude: details.address.latitude, + longitude: details.address.longitude, + }; + + // Calcular tiempos de viaje + const timeToBranch = await calculateTravelTime( + deliveryLocation, + branchLocation, + ); + const timeToCustomer = await calculateTravelTime( + branchLocation, + customerLocation, + ); + + // Tiempo total estimado en minutos + const totalEstimatedTime = timeToBranch + timeToCustomer; + + // Formatear el tiempo estimado + const formattedEstimatedTime = + totalEstimatedTime < 60 + ? `${totalEstimatedTime} minutos` + : `${Math.floor(totalEstimatedTime / 60)} horas ${ + totalEstimatedTime % 60 + } minutos`; + + // Retornar la orden con el tiempo estimado formateado + return { + ...details, + estimatedTime: new Date(), // Mantener el tipo original como Date + formattedEstimatedTime, // Asignar el tiempo formateado + }; + }), + ); + setOrders(detailedOrders); } catch (error) { console.error('Error al obtener las órdenes asignadas:', error); @@ -127,14 +228,6 @@ export default function DeliveryHomeScreen() { setSelectedOrder(null); }; - const formatTime = (isoDate: string | Date): string => { - const date = typeof isoDate === 'string' ? new Date(isoDate) : isoDate; - return date.toLocaleTimeString('es-VE', { - hour: '2-digit', - minute: '2-digit', - }); - }; - const calculateElapsedTime = (createdAt: string): string => { const now = new Date(); const createdDate = new Date(createdAt); @@ -186,8 +279,10 @@ export default function DeliveryHomeScreen() { orderCode={order.orderId.split('-')[0]} // Mostrar solo los primeros 8 caracteres orderType="pedido" address={order.address?.adress || 'Dirección no disponible'} - branch={branchNames[order.branchId] || 'Sucursal no disponible'} - estimatedTime={formatTime(order.estimatedTime)} // Pasar directamente la cadena ISO + branch={ + branchNames[order.branchId]?.name || 'Sucursal no disponible' + } + estimatedTime={order.formattedEstimatedTime} // Mostrar el tiempo estimado elapsedTime={calculateElapsedTime(order.createdAt)} deliveryStatus={ order.deliveryStatus as From a2db7355a63d55246a580c23836f0184839366ca Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Wed, 21 May 2025 13:19:02 -0400 Subject: [PATCH 4/9] Updating to latest sdk version --- package-lock.json | 8 ++++---- package.json | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95c5fb0..ac7f9d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.2.0", "dependencies": { "@expo-google-fonts/poppins": "^0.2.3", - "@pharmatech/sdk": "^0.4.11", + "@pharmatech/sdk": "^0.4.19", "@ptomasroos/react-native-multi-slider": "^2.2.2", "@react-native-community/slider": "^4.5.6", "@reduxjs/toolkit": "^2.6.1", @@ -3592,9 +3592,9 @@ } }, "node_modules/@pharmatech/sdk": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/@pharmatech/sdk/-/sdk-0.4.11.tgz", - "integrity": "sha512-iJChZa3uTsQrz6kLZJfnwrBTZOe2o6azPlwk/ByiMxA5V7UlPfVp8sDz4EIppYbBl2+uM4sLMGnQmiWatKEECA==", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/@pharmatech/sdk/-/sdk-0.4.19.tgz", + "integrity": "sha512-ZiYsoiVRtDjxs5eDqtUAZrEsUWMEZ9+q5XpSOSHt+gTcZLBzntIOO21ZyAm6ONXyRO6EORsOy2vlnnOv87Cs0g==", "license": "MIT", "dependencies": { "axios": "^1.8.1" diff --git a/package.json b/package.json index 62c765a..bd58b0d 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,14 @@ }, "dependencies": { "@expo-google-fonts/poppins": "^0.2.3", - "@pharmatech/sdk": "^0.4.11", + "@pharmatech/sdk": "^0.4.19", "@ptomasroos/react-native-multi-slider": "^2.2.2", "@react-native-community/slider": "^4.5.6", "@reduxjs/toolkit": "^2.6.1", "date-fns": "^4.1.0", "expo": "~52.0.37", "expo-constants": "~17.0.7", + "expo-dev-client": "~5.0.20", "expo-font": "~13.0.4", "expo-image-picker": "~16.0.6", "expo-linking": "~7.0.5", @@ -51,8 +52,7 @@ "react-native-svg": "^15.11.2", "react-redux": "^9.2.0", "socket.io-client": "^4.8.1", - "tailwindcss": "^3.4.17", - "expo-dev-client": "~5.0.20" + "tailwindcss": "^3.4.17" }, "devDependencies": { "@babel/core": "^7.25.2", From 82411e0d4621fd7790d2343262acac98cd4e16c4 Mon Sep 17 00:00:00 2001 From: miglesiasDev <1001.28391672.ucla@gmail.com> Date: Sat, 24 May 2025 16:44:57 -0400 Subject: [PATCH 5/9] Adding expanded view of maps in delivery flow --- src/components/DeliveryMap.tsx | 26 +-- src/components/HistoryMap.tsx | 16 +- src/components/HistoryOrderCard.tsx | 9 +- src/screens/delivery/DeliveryDetailScreen.tsx | 176 +++++++++++++----- .../delivery/DeliveryHistoryDetailScreen.tsx | 94 ++++++++-- .../delivery/DeliveryHistoryScreen.tsx | 13 +- 6 files changed, 235 insertions(+), 99 deletions(-) diff --git a/src/components/DeliveryMap.tsx b/src/components/DeliveryMap.tsx index fa3e7e4..3546f1c 100644 --- a/src/components/DeliveryMap.tsx +++ b/src/components/DeliveryMap.tsx @@ -1,6 +1,12 @@ import React, { useEffect, useState } from 'react'; import MapView, { Marker, Polyline } from 'react-native-maps'; -import { StyleSheet, View, Alert, ActivityIndicator } from 'react-native'; +import { + StyleSheet, + View, + Alert, + ActivityIndicator, + ViewStyle, +} from 'react-native'; import * as Location from 'expo-location'; import { Config } from '../config'; import { Colors } from '../styles/theme'; @@ -9,12 +15,14 @@ interface DeliveryMapProps { deliveryState: number; branchLocation: { latitude: number; longitude: number }; customerLocation: { latitude: number; longitude: number }; + style?: ViewStyle; // Permitir estilos personalizados } const DeliveryMap: React.FC = ({ deliveryState, branchLocation, customerLocation, + style, // Recibir el estilo como prop }) => { const [deliveryLocation, setDeliveryLocation] = useState<{ latitude: number; @@ -182,16 +190,16 @@ const DeliveryMap: React.FC = ({ if (isLoading) { // Mostrar un indicador de carga mientras se obtienen los datos return ( - + ); } return ( - + = ({ const styles = StyleSheet.create({ container: { - height: 300, - borderRadius: 16, - overflow: 'hidden', - marginBottom: 16, - }, - map: { - flex: 1, + flex: 1, // Permitir que el mapa ocupe todo el espacio disponible }, loadingContainer: { - height: 300, + flex: 1, // Asegura que el indicador de carga ocupe todo el espacio disponible justifyContent: 'center', alignItems: 'center', }, diff --git a/src/components/HistoryMap.tsx b/src/components/HistoryMap.tsx index 7a0b0d7..ba62402 100644 --- a/src/components/HistoryMap.tsx +++ b/src/components/HistoryMap.tsx @@ -1,18 +1,20 @@ import React, { useEffect, useState } from 'react'; import MapView, { Marker, Polyline } from 'react-native-maps'; -import { StyleSheet, View, Alert } from 'react-native'; +import { StyleSheet, View, Alert, ViewStyle } from 'react-native'; import { Config } from '../config'; interface HistoryMapProps { deliveryLocation: { latitude: number; longitude: number }; branchLocation: { latitude: number; longitude: number }; customerLocation: { latitude: number; longitude: number }; + style?: ViewStyle; // Permitir estilos personalizados } const HistoryMap: React.FC = ({ deliveryLocation, branchLocation, customerLocation, + style, // Recibir el estilo como prop }) => { const [routeToBranch, setRouteToBranch] = useState< { latitude: number; longitude: number }[] @@ -118,9 +120,9 @@ const HistoryMap: React.FC = ({ }; return ( - + = ({ const styles = StyleSheet.create({ container: { - height: 300, - borderRadius: 16, - overflow: 'hidden', - marginBottom: 16, - }, - map: { - flex: 1, + flex: 1, // Permitir que el mapa ocupe todo el espacio disponible }, }); diff --git a/src/components/HistoryOrderCard.tsx b/src/components/HistoryOrderCard.tsx index e52e37e..e70d09c 100644 --- a/src/components/HistoryOrderCard.tsx +++ b/src/components/HistoryOrderCard.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { View, StyleSheet } from 'react-native'; import { MapPinIcon, - ClockIcon, + CalendarDaysIcon, BuildingStorefrontIcon, } from 'react-native-heroicons/outline'; import { CheckCircleIcon } from 'react-native-heroicons/solid'; @@ -84,9 +84,9 @@ const HistoryOrderCard: React.FC = ({ - + - Tiempo de entrega: {estimatedTime} + Fecha de entrega: {estimatedTime} @@ -151,6 +151,9 @@ const styles = StyleSheet.create({ fontSize: FontSizes.b3.size, color: Colors.textMain, marginLeft: 8, + flexWrap: 'wrap', // Permite que el texto se ajuste en varias líneas + maxWidth: '90%', // Limita el ancho del texto al 90% del contenedor + textAlign: 'left', }, button: { marginBottom: 8, diff --git a/src/screens/delivery/DeliveryDetailScreen.tsx b/src/screens/delivery/DeliveryDetailScreen.tsx index ac5d5f5..0e0b25e 100644 --- a/src/screens/delivery/DeliveryDetailScreen.tsx +++ b/src/screens/delivery/DeliveryDetailScreen.tsx @@ -5,6 +5,8 @@ import { ScrollView, ActivityIndicator, Image, + Modal, + TouchableOpacity, } from 'react-native'; import { useLocalSearchParams, useRouter } from 'expo-router'; import { @@ -12,6 +14,7 @@ import { BuildingStorefrontIcon, MapPinIcon, PhoneIcon, + XMarkIcon, } from 'react-native-heroicons/solid'; import Badge from '../../components/Badge'; import PoppinsText from '../../components/PoppinsText'; @@ -48,6 +51,43 @@ const DeliveryDetailScreen: React.FC = () => { >({}); const [deliveryStateBadge, setDeliveryStateBadge] = useState(0); const router = useRouter(); + const [isMapModalVisible, setIsMapModalVisible] = useState(false); + + const branchLocation = { + latitude: branchNames[orderDetails?.branchId ?? '']?.latitude || 0, + longitude: branchNames[orderDetails?.branchId ?? '']?.longitude || 0, + }; + + const customerLocation = { + latitude: orderDetails?.address?.latitude || 0, + longitude: orderDetails?.address?.longitude || 0, + }; + + const deliveryState = useSelector( + (state: RootState) => state.delivery.deliveryState[id as string] || 0, + ); + + // Estados para las alertas + const [showAlert, setShowAlert] = useState(false); + const [alertType, setAlertType] = useState<'success' | 'error' | 'info'>( + 'info', + ); + const [alertMessage, setAlertMessage] = useState(''); + + const deliveryStates = [ + 'Buscando pedido en sucursal de origen', + 'Haciendo entrega del pedido', + ]; + + const buttonStates = [ + 'Comenzar entrega', + 'Llegué a la sucursal', + 'Ya tengo los productos del pedido', + 'Ir a destino de entrega', + 'Ya hice la entrega', + ]; + + const [showConfirmationPopup, setShowConfirmationPopup] = useState(false); useEffect(() => { const fetchOrderDetails = async () => { @@ -143,41 +183,21 @@ const DeliveryDetailScreen: React.FC = () => { fetchOrder(); }, [orderDetails]); - const deliveryState = useSelector( - (state: RootState) => state.delivery.deliveryState[id as string] || 0, - ); - - // Estados para las alertas - const [showAlert, setShowAlert] = useState(false); - const [alertType, setAlertType] = useState<'success' | 'error' | 'info'>( - 'info', - ); - const [alertMessage, setAlertMessage] = useState(''); - - const deliveryStates = [ - 'Buscando pedido en sucursal de origen', - 'Haciendo entrega del pedido', - ]; - - const buttonStates = [ - 'Comenzar entrega', - 'Llegué a la sucursal', - 'Ya tengo los productos del pedido', - 'Ir a destino de entrega', - 'Ya hice la entrega', - ]; - - const [showConfirmationPopup, setShowConfirmationPopup] = useState(false); - - const branchLocation = { - latitude: branchNames[orderDetails?.branchId ?? '']?.latitude || 0, - longitude: branchNames[orderDetails?.branchId ?? '']?.longitude || 0, - }; + // Mostrar un indicador de carga mientras se obtienen los detalles del pedido o la orden + if (isOrderDetailsLoading || isFetchingOrder) { + return ; + } - const customerLocation = { - latitude: orderDetails?.address?.latitude || 0, - longitude: orderDetails?.address?.longitude || 0, - }; + if (!orderDetails) { + // Mostrar un mensaje de error si no se encuentran los detalles del pedido + return ( + + + No se encontraron datos del pedido. + + + ); + } const handleNextState = async () => { try { @@ -267,22 +287,6 @@ const DeliveryDetailScreen: React.FC = () => { } }; - if (isOrderDetailsLoading || isFetchingOrder) { - // Mostrar un indicador de carga mientras se obtienen los detalles del pedido o la orden - return ; - } - - if (!orderDetails) { - // Mostrar un mensaje de error si no se encuentran los detalles del pedido - return ( - - - No se encontraron datos del pedido. - - - ); - } - return ( {/* Mostrar alertas */} @@ -407,6 +411,15 @@ const DeliveryDetailScreen: React.FC = () => { deliveryState={deliveryState} branchLocation={branchLocation} customerLocation={customerLocation} + style={{ height: 300, marginBottom: 16 }} + /> + +