From 5e4d10e14fb3ed81ba29157e04ed49dab2f06114 Mon Sep 17 00:00:00 2001 From: Gian Date: Tue, 4 Jun 2024 17:56:01 -0600 Subject: [PATCH 01/10] Added date filter to patient side --- src/nutrimetas/app/GoalList.tsx | 201 ++++++++++++++++++++++++++++++-- 1 file changed, 191 insertions(+), 10 deletions(-) diff --git a/src/nutrimetas/app/GoalList.tsx b/src/nutrimetas/app/GoalList.tsx index 6d95b0a..4406ef7 100644 --- a/src/nutrimetas/app/GoalList.tsx +++ b/src/nutrimetas/app/GoalList.tsx @@ -4,9 +4,12 @@ import firestore from '@react-native-firebase/firestore'; import { useNavigation } from '@react-navigation/native'; import { useRouter } from 'expo-router'; import Icon from 'react-native-vector-icons/Ionicons'; -import { SessionContext } from '@/shared/LoginSession'; // Importa el contexto de la sesión +import { SessionContext } from '@/shared/LoginSession'; import { useGlobalSearchParams } from 'expo-router'; +import FontAwesome from '@expo/vector-icons/FontAwesome'; +import DateTimePicker from '@react-native-community/datetimepicker'; + const GoalList = () => { const router = useRouter(); const navigation = useNavigation(); @@ -15,6 +18,16 @@ const GoalList = () => { const [goals, setGoals] = useState([]); const [loading, setLoading] = useState(true); + const [showCalendar, setShowCalendar] = useState(false); + const [showPopup, setShowPopup] = useState(false); + const [selectedOption, setSelectedOption] = useState(""); + + // estados para las fechas + const [showStartDatePicker, setShowStartDatePicker] = useState(false); + const [startDate, setStartDate] = useState(new Date()); + const [showEndDatePicker, setShowEndDatePicker] = useState(false); + const [endDate, setEndDate] = useState(new Date()); + useEffect(() => { if (patientId) { const unsubscribe = firestore() @@ -27,14 +40,13 @@ const GoalList = () => { if (patientGoals.length > 0) { fetchGoalsFromFirebase(patientGoals); } else { - setLoading(false); // No hay metas, actualiza el estado de carga + setLoading(false); console.log('El paciente no tiene metas.'); } }); return () => unsubscribe(); } else { - // console.error('patientId is undefined'); setLoading(false); } }, [patientId]); @@ -43,7 +55,6 @@ const GoalList = () => { const goalsFromFirebase = []; for (const goalId of patientGoals) { - // Verificar si goalId es una cadena (ID de objetivo) if (typeof goalId.id === 'string') { const goalDoc = await firestore().collection('Goal').doc(goalId.id).get(); const goalSelectId = goalDoc.id; @@ -63,7 +74,7 @@ const GoalList = () => { } setGoals(goalsFromFirebase); - setLoading(false); // Actualiza el estado de carga + setLoading(false); }; const buildTitle = async (rubricRef: string) => { @@ -81,7 +92,7 @@ const GoalList = () => { } } catch (error) { console.error('Error fetching rubric:', error); - return 'Meta'; // O valor predeterminado + return 'Meta'; } }; @@ -105,12 +116,14 @@ const GoalList = () => { console.error('Missing data for building description'); return ''; } + let typePrefix; if (typeData.Name === 'Aumentar' || typeData.Name === 'Disminuir') { typePrefix = 'a'; } else { typePrefix = 'en'; } + const portionName = amountData.Value === 1 ? portionData.Name : portionData.Plural; return `${typeData.Name} ${actionData.Name} ${rubricData.Name} ${typePrefix} ${amountData.Value} ${portionName} ${frequencyData.Name}`; } catch (error) { @@ -128,6 +141,77 @@ const GoalList = () => { navigation.navigate('assingGoal', { sessionDocId: patientId }); }; + const handleFilterPress = () => { + console.log('Icono de filtro presionado'); + setShowPopup(true); + }; + + const handleButtonPress = (option) => { + console.log("Botón presionado:", option); + setSelectedOption(option); + setShowPopup(false); + }; + + const handleCancel = () => { + console.log('Cancelar'); + setShowPopup(false); + }; + + const handleConfirm = () => { + console.log('Confirmar'); + // Verificar las fechas + console.log('Fecha de Inicio:', startDate); + console.log('Fecha Límite:', endDate); + filterGoalsByDateRange(); + setShowPopup(false); + }; + + const handleStartDateChange = (event, selectedDate) => { + setShowStartDatePicker(false); + if (selectedDate) { + setStartDate(selectedDate); + console.log('Fecha de Inicio seleccionada:', selectedDate); + } + }; + + const handleEndDateChange = (event, selectedDate) => { + setShowEndDatePicker(false); + if (selectedDate) { + setEndDate(selectedDate); + console.log('Fecha Límite seleccionada:', selectedDate); + } + }; + + const filterGoalsByDateRange = async () => { + if (patientId) { + setLoading(true); + + // Realizar consulta para StartDate + const startGoalsQuerySnapshot = await firestore() + .collection('Goal') + .where('PatientId', '==', patientId) + .where('StartDate', '>=', startDate) + .get(); + + // Realizar consulta para Deadline + const endGoalsQuerySnapshot = await firestore() + .collection('Goal') + .where('PatientId', '==', patientId) + .where('Deadline', '<=', endDate) + .get(); + + // Combinar los resultados de ambas consultas + const startGoals = startGoalsQuerySnapshot.docs.map(doc => doc.data()); + const endGoals = endGoalsQuerySnapshot.docs.map(doc => doc.data()); + const filteredGoals = startGoals.filter(goal => { + return endGoals.some(endGoal => endGoal.id === goal.id); + }); + + setGoals(filteredGoals); + setLoading(false); + } + }; + return ( @@ -135,7 +219,54 @@ const GoalList = () => { Metas + + + + + {/* Ventana emergente */} + {showPopup && ( + + Fecha de Inicio + setShowStartDatePicker(true)}> + {startDate.toDateString()} + + + {showStartDatePicker && ( + + )} + + Fecha Límite + setShowEndDatePicker(true)}> + {endDate.toDateString()} + + + {showEndDatePicker && ( + + )} + + + Cancelar + + + Confirmar + + + )} + {loading ? ( Cargando... ) : goals.length === 0 ? ( @@ -159,7 +290,7 @@ const GoalList = () => { )} - keyExtractor={(item, index) => `${item.title}-${index}`} // Aseguramos un key único + keyExtractor={(item, index) => `${item.title}-${index}`} /> )} {role === 'professional' && ( @@ -174,11 +305,38 @@ const GoalList = () => { export default GoalList; const styles = StyleSheet.create({ + button: { + backgroundColor: '#007bff', + padding: 10, + borderRadius: 5, + marginTop: 10, + }, + buttonText: { + color: '#ffffff', + fontWeight: 'bold', + textAlign: 'center', + }, + popupContainer: { + position: 'absolute', + backgroundColor: 'white', + padding: 20, + marginTop: '20%', + borderRadius: 10, + borderWidth: 1, + borderColor: 'black', + alignItems: 'center', + justifyContent: 'center', + width: '80%', + height: '50%', + top: '25%', + left: '10%', + zIndex: 999, + }, container: { flex: 1, paddingTop: 50, paddingLeft: 20, - paddingRight: 20, // Added paddingRight for space for the tittle + paddingRight: 20, }, header: { flexDirection: 'row', @@ -189,7 +347,7 @@ const styles = StyleSheet.create({ fontSize: 28, fontWeight: 'bold', textAlign: 'left', - marginLeft: 10, // Margin on the left to separate the button from the title + marginLeft: 10, }, item: { flexDirection: 'row', @@ -200,7 +358,20 @@ const styles = StyleSheet.create({ itemImage: { width: 60, height: 60, - marginRight: 10 + marginRight: 10, + }, + filterContainer: { + position: 'absolute', + top: 0, + right: 0, + width: 30, + height: 25, + marginTop: 8, + marginRight: 8, + }, + filterImage: { + width: 30, + height: 25, }, goalDetails: { flex: 1 @@ -233,4 +404,14 @@ const styles = StyleSheet.create({ alignItems: 'center', elevation: 5, }, + datePickerStyle: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + padding: 10, + marginVertical: 10, + borderWidth: 1, + borderRadius: 5, + borderColor: 'gray', + }, }); From 02e0262641a33d62a85c6f288b3b76819d47a564 Mon Sep 17 00:00:00 2001 From: Gian Date: Wed, 5 Jun 2024 18:13:27 -0600 Subject: [PATCH 02/10] Filter functional by start date --- src/nutrimetas/app/GoalList.tsx | 116 ++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 52 deletions(-) diff --git a/src/nutrimetas/app/GoalList.tsx b/src/nutrimetas/app/GoalList.tsx index 4406ef7..4651973 100644 --- a/src/nutrimetas/app/GoalList.tsx +++ b/src/nutrimetas/app/GoalList.tsx @@ -25,8 +25,21 @@ const GoalList = () => { // estados para las fechas const [showStartDatePicker, setShowStartDatePicker] = useState(false); const [startDate, setStartDate] = useState(new Date()); - const [showEndDatePicker, setShowEndDatePicker] = useState(false); - const [endDate, setEndDate] = useState(new Date()); + + const [originalGoals, setOriginalGoals] = useState([]); + const [originalGoalsSaved, setOriginalGoalsSaved] = useState(false); // Variable para controlar si se han guardado los datos originales + + useEffect(() => { + // Guarda las metas originales solo la primera vez que se cargan + if (!originalGoalsSaved) { + setOriginalGoals(goals); + setOriginalGoalsSaved(true); + } + }, [goals, originalGoalsSaved]); + + useEffect(() => { + setOriginalGoalsSaved(false); + }, [patientId]); useEffect(() => { if (patientId) { @@ -36,7 +49,7 @@ const GoalList = () => { .onSnapshot((snapshot) => { const patientData = snapshot.data(); const patientGoals = patientData && patientData.Goals ? patientData.Goals : []; - + if (patientGoals.length > 0) { fetchGoalsFromFirebase(patientGoals); } else { @@ -57,6 +70,7 @@ const GoalList = () => { for (const goalId of patientGoals) { if (typeof goalId.id === 'string') { const goalDoc = await firestore().collection('Goal').doc(goalId.id).get(); + console.log('Datos de la meta:', goalDoc.data()); const goalSelectId = goalDoc.id; if (goalDoc.exists) { const goalData = goalDoc.data(); @@ -74,6 +88,7 @@ const GoalList = () => { } setGoals(goalsFromFirebase); + setLoading(false); }; @@ -98,8 +113,11 @@ const GoalList = () => { const fetchReferenceData = async (collection: string, docId: string) => { const doc = await firestore().collection(collection).doc(docId).get(); - return doc.exists ? doc.data() : null; + const data = doc.exists ? doc.data() : null; + console.log('Datos obtenidos de Firebase:', data); // Imprime los datos obtenidos de Firebase + return data; }; + const buildDescription = async (goalData: any) => { try { @@ -154,15 +172,25 @@ const GoalList = () => { const handleCancel = () => { console.log('Cancelar'); + // Restaurar la lista original de metas + setGoals(originalGoals); setShowPopup(false); }; const handleConfirm = () => { console.log('Confirmar'); - // Verificar las fechas - console.log('Fecha de Inicio:', startDate); - console.log('Fecha Límite:', endDate); - filterGoalsByDateRange(); + + const formattedStartDate = startDate.toISOString(); + + // Calcular la fecha final como 7 días después de la fecha de inicio + const endDate = new Date(startDate); + endDate.setDate(endDate.getDate() + 7); + const formattedEndDate = endDate.toISOString(); + + console.log('Fecha de Inicio:', formattedStartDate); + console.log('Fecha Límite:', formattedEndDate); + + filterGoalsByDateRange(startDate, endDate); setShowPopup(false); }; @@ -174,43 +202,38 @@ const GoalList = () => { } }; - const handleEndDateChange = (event, selectedDate) => { - setShowEndDatePicker(false); - if (selectedDate) { - setEndDate(selectedDate); - console.log('Fecha Límite seleccionada:', selectedDate); - } - }; + const handleReset = () => { + setShowPopup(false); // Oculta el pop-up + setGoals(originalGoals); // Restablece las metas a los valores originales + console.log(originalGoals); + } - const filterGoalsByDateRange = async () => { + const filterGoalsByDateRange = async (startDate, endDate) => { if (patientId) { setLoading(true); - - // Realizar consulta para StartDate - const startGoalsQuerySnapshot = await firestore() - .collection('Goal') - .where('PatientId', '==', patientId) - .where('StartDate', '>=', startDate) - .get(); - - // Realizar consulta para Deadline - const endGoalsQuerySnapshot = await firestore() - .collection('Goal') - .where('PatientId', '==', patientId) - .where('Deadline', '<=', endDate) - .get(); + try { + // Ajustar las fechas de inicio y fin para incluir la primera y última hora del día seleccionado + const adjustedStartDate = new Date(startDate); + adjustedStartDate.setHours(0, 0, 0, 0); // Establecer la primera hora del día + const adjustedEndDate = new Date(endDate); + adjustedEndDate.setHours(23, 59, 59, 999); // Establecer la última hora del día - // Combinar los resultados de ambas consultas - const startGoals = startGoalsQuerySnapshot.docs.map(doc => doc.data()); - const endGoals = endGoalsQuerySnapshot.docs.map(doc => doc.data()); - const filteredGoals = startGoals.filter(goal => { - return endGoals.some(endGoal => endGoal.id === goal.id); - }); + // Filtrar las metas originales por las fechas ajustadas + const filteredGoals = originalGoals.filter(goal => { + const goalStartDate = new Date(goal.StartDate.toDate()); + return goalStartDate >= adjustedStartDate && goalStartDate <= adjustedEndDate; + }); - setGoals(filteredGoals); - setLoading(false); + console.log('Metas filtradas por fecha:', filteredGoals); + setGoals(filteredGoals); + } catch (error) { + console.error("Error filtering goals:", error); + } finally { + setLoading(false); + } } }; + return ( @@ -244,26 +267,15 @@ const GoalList = () => { /> )} - Fecha Límite - setShowEndDatePicker(true)}> - {endDate.toDateString()} - - - {showEndDatePicker && ( - - )} - Cancelar Confirmar + + Reset + )} From e28757c5f6a9f245558cab6d7eb3e4b27bd9bd28 Mon Sep 17 00:00:00 2001 From: Gian Date: Thu, 6 Jun 2024 09:23:52 -0600 Subject: [PATCH 03/10] Visual changes --- src/nutrimetas/app/GoalList.tsx | 107 +++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/src/nutrimetas/app/GoalList.tsx b/src/nutrimetas/app/GoalList.tsx index 4651973..2ac0d95 100644 --- a/src/nutrimetas/app/GoalList.tsx +++ b/src/nutrimetas/app/GoalList.tsx @@ -1,5 +1,6 @@ import { StyleSheet, TouchableOpacity, FlatList, View, Text, Image } from 'react-native'; import React, { useState, useEffect, useContext } from 'react'; +import Colors from '@/constants/Colors'; import firestore from '@react-native-firebase/firestore'; import { useNavigation } from '@react-navigation/native'; import { useRouter } from 'expo-router'; @@ -28,7 +29,7 @@ const GoalList = () => { const [originalGoals, setOriginalGoals] = useState([]); const [originalGoalsSaved, setOriginalGoalsSaved] = useState(false); // Variable para controlar si se han guardado los datos originales - + const [showBackdrop, setShowBackdrop] = useState(false); //oscurece la pantalla useEffect(() => { // Guarda las metas originales solo la primera vez que se cargan if (!originalGoalsSaved) { @@ -162,6 +163,7 @@ const GoalList = () => { const handleFilterPress = () => { console.log('Icono de filtro presionado'); setShowPopup(true); + setShowBackdrop(true); }; const handleButtonPress = (option) => { @@ -172,9 +174,8 @@ const GoalList = () => { const handleCancel = () => { console.log('Cancelar'); - // Restaurar la lista original de metas - setGoals(originalGoals); setShowPopup(false); + setShowBackdrop(false); }; const handleConfirm = () => { @@ -192,6 +193,7 @@ const GoalList = () => { filterGoalsByDateRange(startDate, endDate); setShowPopup(false); + setShowBackdrop(false); }; const handleStartDateChange = (event, selectedDate) => { @@ -205,7 +207,8 @@ const GoalList = () => { const handleReset = () => { setShowPopup(false); // Oculta el pop-up setGoals(originalGoals); // Restablece las metas a los valores originales - console.log(originalGoals); + //console.log(originalGoals); + setShowBackdrop(false); } const filterGoalsByDateRange = async (startDate, endDate) => { @@ -249,11 +252,15 @@ const GoalList = () => { /> - + {showBackdrop && } {/* Ventana emergente */} {showPopup && ( + - Fecha de Inicio + + Filtros + + Fecha de Inicio setShowStartDatePicker(true)}> {startDate.toDateString()} @@ -266,15 +273,16 @@ const GoalList = () => { onChange={handleStartDateChange} /> )} - - - Cancelar - - - Confirmar - + + + Cancelar + + + Confirmar + + - Reset + Eliminar Filtros )} @@ -317,32 +325,69 @@ const GoalList = () => { export default GoalList; const styles = StyleSheet.create({ - button: { - backgroundColor: '#007bff', - padding: 10, - borderRadius: 5, - marginTop: 10, - }, - buttonText: { - color: '#ffffff', - fontWeight: 'bold', - textAlign: 'center', + backdrop: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(0, 0, 0, 0.5)', // Ajusta la opacidad según lo desees + zIndex: 998, // Asegura que esté detrás del pop-up }, popupContainer: { position: 'absolute', - backgroundColor: 'white', + flex: 1, + backgroundColor: Colors.white, padding: 20, marginTop: '20%', borderRadius: 10, borderWidth: 1, - borderColor: 'black', + borderColor: Colors.black, alignItems: 'center', justifyContent: 'center', - width: '80%', - height: '50%', - top: '25%', - left: '10%', zIndex: 999, + left: '45%', + }, + filtersHeader: { + position: 'absolute', + top: 10, + left: 10, + }, + filterTitle: { + fontSize: 18, + fontWeight: 'bold', + textAlign: 'left', + marginLeft: 10, + }, + dateTitle:{ + marginTop: 10, + marginBottom: -10, + }, + button: { + backgroundColor: Colors.lightblue, + padding: 10, + borderRadius: 5, + marginTop: 10, + + }, + buttonText: { + color: Colors.white, + fontWeight: 'bold', + textAlign: 'center', + }, + cancelButton: { + backgroundColor: Colors.red, // Puedes cambiar esto a tu color deseado + padding: 10, + borderRadius: 5, + marginTop: 10, + marginRight: 5, // Espacio adicional entre los botones + }, + confirmButton: { + backgroundColor: Colors.green, // Puedes cambiar esto a tu color deseado + padding: 10, + borderRadius: 5, + marginTop: 10, + marginLeft: 5, // Espacio adicional entre los botones }, container: { flex: 1, @@ -426,4 +471,4 @@ const styles = StyleSheet.create({ borderRadius: 5, borderColor: 'gray', }, -}); +}); \ No newline at end of file From 03b7b4803aaa29e728b86691864bdd8ae82e70b6 Mon Sep 17 00:00:00 2001 From: Gian Date: Thu, 6 Jun 2024 14:09:50 -0600 Subject: [PATCH 04/10] Cleaning code --- src/nutrimetas/app/GoalList.tsx | 66 +++++++++++---------------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/src/nutrimetas/app/GoalList.tsx b/src/nutrimetas/app/GoalList.tsx index 2ac0d95..97a53b6 100644 --- a/src/nutrimetas/app/GoalList.tsx +++ b/src/nutrimetas/app/GoalList.tsx @@ -18,31 +18,25 @@ const GoalList = () => { const { role } = useContext(SessionContext); const [goals, setGoals] = useState([]); const [loading, setLoading] = useState(true); - - const [showCalendar, setShowCalendar] = useState(false); const [showPopup, setShowPopup] = useState(false); - const [selectedOption, setSelectedOption] = useState(""); // estados para las fechas const [showStartDatePicker, setShowStartDatePicker] = useState(false); const [startDate, setStartDate] = useState(new Date()); - const [originalGoals, setOriginalGoals] = useState([]); - const [originalGoalsSaved, setOriginalGoalsSaved] = useState(false); // Variable para controlar si se han guardado los datos originales - const [showBackdrop, setShowBackdrop] = useState(false); //oscurece la pantalla + const [originalGoalsSaved, setOriginalGoalsSaved] = useState(false); + const [showBackdrop, setShowBackdrop] = useState(false); + useEffect(() => { // Guarda las metas originales solo la primera vez que se cargan - if (!originalGoalsSaved) { + if (!originalGoalsSaved && goals.length > 0) { setOriginalGoals(goals); setOriginalGoalsSaved(true); } }, [goals, originalGoalsSaved]); useEffect(() => { - setOriginalGoalsSaved(false); - }, [patientId]); - - useEffect(() => { + // Maneja la suscripción a los cambios de Patient en Firestore if (patientId) { const unsubscribe = firestore() .collection('Patient') @@ -50,7 +44,7 @@ const GoalList = () => { .onSnapshot((snapshot) => { const patientData = snapshot.data(); const patientGoals = patientData && patientData.Goals ? patientData.Goals : []; - + if (patientGoals.length > 0) { fetchGoalsFromFirebase(patientGoals); } else { @@ -58,7 +52,6 @@ const GoalList = () => { console.log('El paciente no tiene metas.'); } }); - return () => unsubscribe(); } else { setLoading(false); @@ -71,7 +64,7 @@ const GoalList = () => { for (const goalId of patientGoals) { if (typeof goalId.id === 'string') { const goalDoc = await firestore().collection('Goal').doc(goalId.id).get(); - console.log('Datos de la meta:', goalDoc.data()); + //console.log('Datos de la meta:', goalDoc.data()); const goalSelectId = goalDoc.id; if (goalDoc.exists) { const goalData = goalDoc.data(); @@ -115,7 +108,6 @@ const GoalList = () => { const fetchReferenceData = async (collection: string, docId: string) => { const doc = await firestore().collection(collection).doc(docId).get(); const data = doc.exists ? doc.data() : null; - console.log('Datos obtenidos de Firebase:', data); // Imprime los datos obtenidos de Firebase return data; }; @@ -152,7 +144,7 @@ const GoalList = () => { }; const onPressHandle = (selectedGoalId: string) => { - console.log(selectedGoalId); + //console.log(selectedGoalId); router.push({ pathname: '/GoalDetail', params: { selectedGoal: selectedGoalId } }); }; @@ -161,35 +153,24 @@ const GoalList = () => { }; const handleFilterPress = () => { - console.log('Icono de filtro presionado'); setShowPopup(true); setShowBackdrop(true); }; - const handleButtonPress = (option) => { - console.log("Botón presionado:", option); - setSelectedOption(option); - setShowPopup(false); - }; - const handleCancel = () => { - console.log('Cancelar'); setShowPopup(false); setShowBackdrop(false); }; const handleConfirm = () => { - console.log('Confirmar'); - const formattedStartDate = startDate.toISOString(); // Calcular la fecha final como 7 días después de la fecha de inicio const endDate = new Date(startDate); endDate.setDate(endDate.getDate() + 7); - const formattedEndDate = endDate.toISOString(); - + /*const formattedEndDate = endDate.toISOString(); console.log('Fecha de Inicio:', formattedStartDate); - console.log('Fecha Límite:', formattedEndDate); + console.log('Fecha Límite:', formattedEndDate); */ filterGoalsByDateRange(startDate, endDate); setShowPopup(false); @@ -200,14 +181,12 @@ const GoalList = () => { setShowStartDatePicker(false); if (selectedDate) { setStartDate(selectedDate); - console.log('Fecha de Inicio seleccionada:', selectedDate); } }; const handleReset = () => { - setShowPopup(false); // Oculta el pop-up + setShowPopup(false); setGoals(originalGoals); // Restablece las metas a los valores originales - //console.log(originalGoals); setShowBackdrop(false); } @@ -215,19 +194,17 @@ const GoalList = () => { if (patientId) { setLoading(true); try { - // Ajustar las fechas de inicio y fin para incluir la primera y última hora del día seleccionado + // Ajustar las fechas de inicio y fin para incluir la primera y última hora const adjustedStartDate = new Date(startDate); - adjustedStartDate.setHours(0, 0, 0, 0); // Establecer la primera hora del día + adjustedStartDate.setHours(0, 0, 0, 0); const adjustedEndDate = new Date(endDate); - adjustedEndDate.setHours(23, 59, 59, 999); // Establecer la última hora del día + adjustedEndDate.setHours(23, 59, 59, 999); // Filtrar las metas originales por las fechas ajustadas const filteredGoals = originalGoals.filter(goal => { const goalStartDate = new Date(goal.StartDate.toDate()); return goalStartDate >= adjustedStartDate && goalStartDate <= adjustedEndDate; }); - - console.log('Metas filtradas por fecha:', filteredGoals); setGoals(filteredGoals); } catch (error) { console.error("Error filtering goals:", error); @@ -331,8 +308,8 @@ const styles = StyleSheet.create({ left: 0, right: 0, bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.5)', // Ajusta la opacidad según lo desees - zIndex: 998, // Asegura que esté detrás del pop-up + backgroundColor: 'rgba(0, 0, 0, 0.5)', + zIndex: 998, }, popupContainer: { position: 'absolute', @@ -367,8 +344,7 @@ const styles = StyleSheet.create({ backgroundColor: Colors.lightblue, padding: 10, borderRadius: 5, - marginTop: 10, - + marginTop: 10, }, buttonText: { color: Colors.white, @@ -376,18 +352,18 @@ const styles = StyleSheet.create({ textAlign: 'center', }, cancelButton: { - backgroundColor: Colors.red, // Puedes cambiar esto a tu color deseado + backgroundColor: Colors.red, padding: 10, borderRadius: 5, marginTop: 10, - marginRight: 5, // Espacio adicional entre los botones + marginRight: 5, }, confirmButton: { - backgroundColor: Colors.green, // Puedes cambiar esto a tu color deseado + backgroundColor: Colors.green, padding: 10, borderRadius: 5, marginTop: 10, - marginLeft: 5, // Espacio adicional entre los botones + marginLeft: 5, }, container: { flex: 1, From 7f9c887c80567832f264e7a065f57cf1e9a12463 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 7 Jun 2024 17:42:06 -0600 Subject: [PATCH 05/10] Daily Goals screen and logic --- src/nutrimetas/app/DailyGoal.tsx | 266 +++++++++++++++++++++++++++++ src/nutrimetas/app/GoalList.tsx | 39 ++++- src/nutrimetas/app/_layout.tsx | 1 + src/nutrimetas/constants/Colors.ts | 3 +- src/nutrimetas/package-lock.json | 57 ++++++- src/nutrimetas/package.json | 1 + 6 files changed, 356 insertions(+), 11 deletions(-) create mode 100644 src/nutrimetas/app/DailyGoal.tsx diff --git a/src/nutrimetas/app/DailyGoal.tsx b/src/nutrimetas/app/DailyGoal.tsx new file mode 100644 index 0000000..f68e40f --- /dev/null +++ b/src/nutrimetas/app/DailyGoal.tsx @@ -0,0 +1,266 @@ +import { StyleSheet, TouchableOpacity, FlatList, View, Text, Image, TextInput } from 'react-native'; +import React, { useState, useEffect, useContext } from 'react'; +import Colors from '@/constants/Colors'; +import firestore from '@react-native-firebase/firestore'; +import { useRouter } from 'expo-router'; +import Icon from 'react-native-vector-icons/Ionicons'; +import { SessionContext } from '@/shared/LoginSession'; +import { useGlobalSearchParams } from 'expo-router'; +import { CheckBox } from 'react-native-elements'; + +const DailyGoal = () => { + const router = useRouter(); + const { patientId } = useGlobalSearchParams(); + //const { role } = useContext(SessionContext); + const [goals, setGoals] = useState([]); + const [loading, setLoading] = useState(true); + const [checkedItems, setCheckedItems] = useState({}); + const [selectedGoal, setSelectedGoal] = useState<{ [key: string]: boolean }>({}); + + useEffect(() => { + if (patientId) { + const unsubscribe = firestore() + .collection('Patient') + .doc(patientId.toString()) + .onSnapshot((snapshot) => { + const patientData = snapshot.data(); + const patientGoals = patientData && patientData.Goals ? patientData.Goals : []; + + if (patientGoals.length > 0) { + fetchGoalsFromFirebase(patientGoals); + } else { + setLoading(false); + console.log('El paciente no tiene metas.'); + } + }); + return () => unsubscribe(); + } else { + setLoading(false); + } + }, [patientId]); + + const fetchGoalsFromFirebase = async (patientGoals: any) => { + const goalsFromFirebase = []; + + for (const goalId of patientGoals) { + if (typeof goalId.id === 'string') { + const goalDoc = await firestore().collection('Goal').doc(goalId.id).get(); + const goalSelectId = goalDoc.id; + if (goalDoc.exists) { + const goalData = goalDoc.data(); + if (goalData) { + const description = await buildDailyGoal(goalData); + goalsFromFirebase.push({ ...goalData, description, goalSelectId }); + } else { + console.error('Goal data is undefined for goal ID:', goalId.id); + } + } + } else { + console.error('Invalid goal ID:', goalId); + } + } + + setGoals(goalsFromFirebase); + setLoading(false); + }; + + const fetchReferenceData = async (collection: string, docId: string) => { + const doc = await firestore().collection(collection).doc(docId).get(); + const data = doc.exists ? doc.data() : null; + return data; + }; + + const buildDailyGoal = async (goalData) => { + try { + const [rubricData, actionData, amountData, portionData/*, frequencyData*/] = await Promise.all([ + fetchReferenceData('Rubric', goalData.Rubric), + fetchReferenceData('Action', goalData.Action), + fetchReferenceData('Amount', goalData.Amount), + fetchReferenceData('Portion', goalData.Portion), + //fetchReferenceData('Frequency', goalData.Frequency), + ]); + if (!rubricData || !actionData || !amountData || !portionData /* || !frequencyData*/) { + console.error('Missing data for building description'); + return ''; + } + + let typePrefix; + if (actionData.Name.includes('consumo')) { + typePrefix = 'Consumiste'; + } else { + typePrefix = 'Realizaste'; + } + const today = 'hoy?'; + + // Elimina mayúsculas innecesarias + const rubricName = rubricData.Name.toLowerCase(); + const portionName = amountData.Value === 1 ? portionData.Name.toLowerCase() : portionData.Plural.toLowerCase(); + + // Determinar el género + let article; + if (amountData.Value === 1) { + article = portionData.Gender === 'M' ? 'un' : 'una'; + } else { + article = portionData.Gender === 'M' ? 'unos' : 'unas'; + } + + let interrogative; + if (amountData.Value !== 1) { + interrogative = portionData.Gender === 'M' ? 'Cuántos' : 'Cuántas'; + } + + // Construcción de la oración basada en la cantidad + let description; + if (amountData.Value !== 1) { + description = `${interrogative} ${portionName} de ${rubricName} consumiste ${today}`; + } else { + // Actividad fisica + description = `${typePrefix} ${article} ${rubricName} ${today}`; + } + + // Mayúscula solo para la primera letra de la oración + const result = description.charAt(0).toUpperCase() + description.slice(1); + + //console.log('Action', actionData.Name); + //console.log('Rubric', rubricData.Name); + //console.log('Amount', amountData.Value); + //console.log('Portion', portionData.Name); + //console.log('Result', result); + + return result; + } catch (error) { + console.error('Error building description:', error); + return ''; + } + }; + + const confirmDaily = () => { + router.back(); + }; + + const GoalCheckbox = (goalId: string) => { + //console.log("click ",goalId); + setSelectedGoal(prevState => ({ + ...prevState, + [goalId]: !prevState[goalId] // Cambia el estado del checkbox + })); + }; + + return ( + + + router.back()}> + + + Registro de hoy + + {loading ? ( + Cargando... + ) : goals.length === 0 ? ( + + No tiene metas pendientes. + + ) : ( + ( + + + + {item.description} + + {item.description.includes('Cuán') ? ( + + ) : ( + GoalCheckbox(item.goalSelectId)} + /> + )} + + )} + keyExtractor={(item, index) => `${item.title}-${index}`} + /> + )} + + + + + ); +} + +export default DailyGoal; + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingTop: 50, + paddingLeft: 20, + paddingRight: 20, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 10, + }, + title: { + fontSize: 28, + fontWeight: 'bold', + textAlign: 'left', + marginLeft: 10, + }, + item: { + flexDirection: 'row', + alignItems: 'center', + margin: '2%', + borderBottomWidth: 1 + }, + itemImage: { + width: 60, + height: 60, + marginRight: 10, + }, + goalDetails: { + flex: 1 + }, + confirmDailyButton: { + position: 'absolute', + bottom: 20, + right: 20, + height: 60, + borderRadius: 30, + backgroundColor: Colors.green, + justifyContent: 'center', + alignItems: 'center', + elevation: 5, + paddingHorizontal: 20, + }, + textInput: { + backgroundColor: '#f0f0f0', // Fondo gris + borderColor: 'gray' , + borderWidth: 1, + borderRadius: 5, + marginRight: 24, + padding: 5, + fontSize: 16, + width: 20, + height: 28, + textAlign: 'center' , + }, + itemDescription: { + + fontSize: 14 + }, + emptyContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center' + }, + emptyText: { + fontSize: 18, + textAlign: 'center' + }, +}); diff --git a/src/nutrimetas/app/GoalList.tsx b/src/nutrimetas/app/GoalList.tsx index 97a53b6..870503f 100644 --- a/src/nutrimetas/app/GoalList.tsx +++ b/src/nutrimetas/app/GoalList.tsx @@ -7,7 +7,7 @@ import { useRouter } from 'expo-router'; import Icon from 'react-native-vector-icons/Ionicons'; import { SessionContext } from '@/shared/LoginSession'; import { useGlobalSearchParams } from 'expo-router'; - +import { CheckBox} from 'react-native-elements'; import FontAwesome from '@expo/vector-icons/FontAwesome'; import DateTimePicker from '@react-native-community/datetimepicker'; @@ -151,7 +151,13 @@ const GoalList = () => { const handleAddGoal = () => { navigation.navigate('assingGoal', { sessionDocId: patientId }); }; - + + const handleDailyGoal = () => { + console.log('daily register'); + router.push({ pathname: '/DailyGoal', params: { patientId: patientId } }); + console.log({ pathname: '/DailyGoal', params: { sessionDocId: patientId } }); + }; + const handleFilterPress = () => { setShowPopup(true); setShowBackdrop(true); @@ -252,10 +258,10 @@ const GoalList = () => { )} - Cancelar + Salir - Confirmar + Aplicar @@ -288,13 +294,18 @@ const GoalList = () => { )} keyExtractor={(item, index) => `${item.title}-${index}`} - /> + /> )} {role === 'professional' && ( )} + {role === 'patient' && ( + + + + )} ); } @@ -308,7 +319,7 @@ const styles = StyleSheet.create({ left: 0, right: 0, bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.5)', + backgroundColor: Colors.backdrop, zIndex: 998, }, popupContainer: { @@ -432,10 +443,22 @@ const styles = StyleSheet.create({ width: 60, height: 60, borderRadius: 30, - backgroundColor: 'green', + backgroundColor: Colors.green, + justifyContent: 'center', + alignItems: 'center', + elevation: 5, + }, + registerDayButton: { + position: 'absolute', + bottom: 20, + right: 20, + height: 60, + borderRadius: 30, + backgroundColor: Colors.green, justifyContent: 'center', alignItems: 'center', elevation: 5, + paddingHorizontal: 20, }, datePickerStyle: { flexDirection: 'row', @@ -445,6 +468,6 @@ const styles = StyleSheet.create({ marginVertical: 10, borderWidth: 1, borderRadius: 5, - borderColor: 'gray', + borderColor: Colors.gray, }, }); \ No newline at end of file diff --git a/src/nutrimetas/app/_layout.tsx b/src/nutrimetas/app/_layout.tsx index f3b03c7..a851130 100644 --- a/src/nutrimetas/app/_layout.tsx +++ b/src/nutrimetas/app/_layout.tsx @@ -71,6 +71,7 @@ function RootLayoutNav() { + ); diff --git a/src/nutrimetas/constants/Colors.ts b/src/nutrimetas/constants/Colors.ts index 4955f86..697453f 100644 --- a/src/nutrimetas/constants/Colors.ts +++ b/src/nutrimetas/constants/Colors.ts @@ -28,5 +28,6 @@ export default { lightGray: '#ccc', transparent: '#ffffff00', red: '#FF0000', - black: '#000000' + black: '#000000', + backdrop: '#00000080' , }; diff --git a/src/nutrimetas/package-lock.json b/src/nutrimetas/package-lock.json index 541d0cc..fa48413 100644 --- a/src/nutrimetas/package-lock.json +++ b/src/nutrimetas/package-lock.json @@ -32,6 +32,7 @@ "react-hook-form": "^7.51.4", "react-native": "0.73.6", "react-native-element-dropdown": "^2.12.0", + "react-native-elements": "^3.4.3", "react-native-flash-message": "^0.4.2", "react-native-gifted-chat": "^2.4.0", "react-native-mask-input": "^1.2.3", @@ -7873,7 +7874,6 @@ "version": "0.70.19", "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.19.tgz", "integrity": "sha512-c6WbyCgWTBgKKMESj/8b4w+zWcZSsCforson7UdXtXMecG3MxCinYi6ihhrHVPyUrVzORsvEzK8zg32z4pK6Sg==", - "dev": true, "dependencies": { "@types/react": "*" } @@ -7882,7 +7882,6 @@ "version": "6.4.18", "resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.18.tgz", "integrity": "sha512-YGlNWb+k5laTBHd7+uZowB9DpIK3SXUneZqAiKQaj1jnJCZM0x71GDim5JCTMi4IFkhc9m8H/Gm28T5BjyivUw==", - "dev": true, "dependencies": { "@types/react": "*", "@types/react-native": "^0.70" @@ -14870,6 +14869,11 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -17061,6 +17065,35 @@ "react-native": "*" } }, + "node_modules/react-native-elements": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/react-native-elements/-/react-native-elements-3.4.3.tgz", + "integrity": "sha512-VtZc25EecPZyUBER85zFK9ZbY6kkUdcm1ZwJ9hdoGSCr1R/GFgxor4jngOcSYeMvQ+qimd5No44OVJW3rSJECA==", + "hasInstallScript": true, + "dependencies": { + "@types/react-native-vector-icons": "^6.4.6", + "color": "^3.1.2", + "deepmerge": "^4.2.2", + "hoist-non-react-statics": "^3.3.2", + "lodash.isequal": "^4.5.0", + "opencollective-postinstall": "^2.0.3", + "react-native-ratings": "8.0.4", + "react-native-size-matters": "^0.3.1" + }, + "peerDependencies": { + "react-native-safe-area-context": ">= 3.0.0", + "react-native-vector-icons": ">7.0.0" + } + }, + "node_modules/react-native-elements/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/react-native-flash-message": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/react-native-flash-message/-/react-native-flash-message-0.4.2.tgz", @@ -17221,6 +17254,18 @@ "react-native": "*" } }, + "node_modules/react-native-ratings": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-8.0.4.tgz", + "integrity": "sha512-Xczu5lskIIRD6BEdz9A0jDRpEck/SFxRqiglkXi0u67yAtI1/pcJC76P4MukCbT8K4BPVl+42w83YqXBoBRl7A==", + "dependencies": { + "lodash": "^4.17.15" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-safe-area-context": { "version": "4.8.2", "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.8.2.tgz", @@ -17255,6 +17300,14 @@ "react-native": ">=0.71.0" } }, + "node_modules/react-native-size-matters": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz", + "integrity": "sha512-mKOfBLIBFBcs9br1rlZDvxD5+mAl8Gfr5CounwJtxI6Z82rGrMO+Kgl9EIg3RMVf3G855a85YVqHJL2f5EDRlw==", + "peerDependencies": { + "react-native": "*" + } + }, "node_modules/react-native-toast-message": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.2.0.tgz", diff --git a/src/nutrimetas/package.json b/src/nutrimetas/package.json index 14b61b6..af69859 100644 --- a/src/nutrimetas/package.json +++ b/src/nutrimetas/package.json @@ -37,6 +37,7 @@ "react-hook-form": "^7.51.4", "react-native": "0.73.6", "react-native-element-dropdown": "^2.12.0", + "react-native-elements": "^3.4.3", "react-native-flash-message": "^0.4.2", "react-native-gifted-chat": "^2.4.0", "react-native-mask-input": "^1.2.3", From a7c5fe8d542928cd9cce3385a8616916a96d76a0 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 7 Jun 2024 17:47:01 -0600 Subject: [PATCH 06/10] Typo --- src/nutrimetas/app/DailyGoal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nutrimetas/app/DailyGoal.tsx b/src/nutrimetas/app/DailyGoal.tsx index f68e40f..187d757 100644 --- a/src/nutrimetas/app/DailyGoal.tsx +++ b/src/nutrimetas/app/DailyGoal.tsx @@ -239,7 +239,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 20, }, textInput: { - backgroundColor: '#f0f0f0', // Fondo gris + backgroundColor: Colors.gray, borderColor: 'gray' , borderWidth: 1, borderRadius: 5, From ccaac4c5fb35e628633bacb379e3a5eeeae3dcab Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 7 Jun 2024 17:49:01 -0600 Subject: [PATCH 07/10] Fixing color --- src/nutrimetas/app/DailyGoal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nutrimetas/app/DailyGoal.tsx b/src/nutrimetas/app/DailyGoal.tsx index 187d757..5c9d309 100644 --- a/src/nutrimetas/app/DailyGoal.tsx +++ b/src/nutrimetas/app/DailyGoal.tsx @@ -239,7 +239,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 20, }, textInput: { - backgroundColor: Colors.gray, + backgroundColor: Colors.white, // Fondo gris borderColor: 'gray' , borderWidth: 1, borderRadius: 5, From be9befaff5db2d3e514366edade8b8ab13241012 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 7 Jun 2024 17:51:57 -0600 Subject: [PATCH 08/10] Cleanup --- src/nutrimetas/app/DailyGoal.tsx | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/nutrimetas/app/DailyGoal.tsx b/src/nutrimetas/app/DailyGoal.tsx index 5c9d309..f545794 100644 --- a/src/nutrimetas/app/DailyGoal.tsx +++ b/src/nutrimetas/app/DailyGoal.tsx @@ -1,20 +1,17 @@ import { StyleSheet, TouchableOpacity, FlatList, View, Text, Image, TextInput } from 'react-native'; -import React, { useState, useEffect, useContext } from 'react'; +import React, { useState, useEffect } from 'react'; import Colors from '@/constants/Colors'; import firestore from '@react-native-firebase/firestore'; import { useRouter } from 'expo-router'; import Icon from 'react-native-vector-icons/Ionicons'; -import { SessionContext } from '@/shared/LoginSession'; import { useGlobalSearchParams } from 'expo-router'; import { CheckBox } from 'react-native-elements'; const DailyGoal = () => { const router = useRouter(); const { patientId } = useGlobalSearchParams(); - //const { role } = useContext(SessionContext); const [goals, setGoals] = useState([]); const [loading, setLoading] = useState(true); - const [checkedItems, setCheckedItems] = useState({}); const [selectedGoal, setSelectedGoal] = useState<{ [key: string]: boolean }>({}); useEffect(() => { @@ -41,7 +38,6 @@ const DailyGoal = () => { const fetchGoalsFromFirebase = async (patientGoals: any) => { const goalsFromFirebase = []; - for (const goalId of patientGoals) { if (typeof goalId.id === 'string') { const goalDoc = await firestore().collection('Goal').doc(goalId.id).get(); @@ -59,7 +55,6 @@ const DailyGoal = () => { console.error('Invalid goal ID:', goalId); } } - setGoals(goalsFromFirebase); setLoading(false); }; @@ -70,16 +65,15 @@ const DailyGoal = () => { return data; }; - const buildDailyGoal = async (goalData) => { + const buildDailyGoal = async (goalData:any) => { try { - const [rubricData, actionData, amountData, portionData/*, frequencyData*/] = await Promise.all([ + const [rubricData, actionData, amountData, portionData] = await Promise.all([ fetchReferenceData('Rubric', goalData.Rubric), fetchReferenceData('Action', goalData.Action), fetchReferenceData('Amount', goalData.Amount), fetchReferenceData('Portion', goalData.Portion), - //fetchReferenceData('Frequency', goalData.Frequency), ]); - if (!rubricData || !actionData || !amountData || !portionData /* || !frequencyData*/) { + if (!rubricData || !actionData || !amountData || !portionData) { console.error('Missing data for building description'); return ''; } @@ -117,16 +111,8 @@ const DailyGoal = () => { // Actividad fisica description = `${typePrefix} ${article} ${rubricName} ${today}`; } - // Mayúscula solo para la primera letra de la oración - const result = description.charAt(0).toUpperCase() + description.slice(1); - - //console.log('Action', actionData.Name); - //console.log('Rubric', rubricData.Name); - //console.log('Amount', amountData.Value); - //console.log('Portion', portionData.Name); - //console.log('Result', result); - + const result = description.charAt(0).toUpperCase() + description.slice(1); return result; } catch (error) { console.error('Error building description:', error); @@ -139,7 +125,6 @@ const DailyGoal = () => { }; const GoalCheckbox = (goalId: string) => { - //console.log("click ",goalId); setSelectedGoal(prevState => ({ ...prevState, [goalId]: !prevState[goalId] // Cambia el estado del checkbox @@ -239,7 +224,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 20, }, textInput: { - backgroundColor: Colors.white, // Fondo gris + backgroundColor: Colors.white, borderColor: 'gray' , borderWidth: 1, borderRadius: 5, From 2b5030c03226644c4abdb66f7dd3dd5f8b20e705 Mon Sep 17 00:00:00 2001 From: Gian Date: Fri, 7 Jun 2024 18:49:11 -0600 Subject: [PATCH 09/10] Added input restrictions --- src/nutrimetas/app/DailyGoal.tsx | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/nutrimetas/app/DailyGoal.tsx b/src/nutrimetas/app/DailyGoal.tsx index f545794..ca49148 100644 --- a/src/nutrimetas/app/DailyGoal.tsx +++ b/src/nutrimetas/app/DailyGoal.tsx @@ -13,7 +13,8 @@ const DailyGoal = () => { const [goals, setGoals] = useState([]); const [loading, setLoading] = useState(true); const [selectedGoal, setSelectedGoal] = useState<{ [key: string]: boolean }>({}); - + const [textInputValues, setTextInputValues] = useState<{ [key: string]: string }>({}); + useEffect(() => { if (patientId) { const unsubscribe = firestore() @@ -131,6 +132,17 @@ const DailyGoal = () => { })); }; + // El numero solo se admite de 0-9 + const handleTextInputChange = (goalId: string, text: string) => { + const newText = text.replace(/[^0-9]/g, ''); + if (newText.length <= 1) { + setTextInputValues(prevState => ({ + ...prevState, + [goalId]: newText, + })); + } + }; + return ( @@ -158,7 +170,13 @@ const DailyGoal = () => { {item.description} {item.description.includes('Cuán') ? ( - + handleTextInputChange(item.goalSelectId, text)} + /> ) : ( Date: Fri, 7 Jun 2024 20:25:24 -0600 Subject: [PATCH 10/10] Extra fixes for merge --- src/nutrimetas/app/(app)/(root)/_layout.tsx | 1 + src/nutrimetas/package-lock.json | 258 ++++++++------------ 2 files changed, 101 insertions(+), 158 deletions(-) diff --git a/src/nutrimetas/app/(app)/(root)/_layout.tsx b/src/nutrimetas/app/(app)/(root)/_layout.tsx index 078a2b2..4f0b942 100644 --- a/src/nutrimetas/app/(app)/(root)/_layout.tsx +++ b/src/nutrimetas/app/(app)/(root)/_layout.tsx @@ -54,6 +54,7 @@ function RootLayoutNav() { + ); diff --git a/src/nutrimetas/package-lock.json b/src/nutrimetas/package-lock.json index 283c14d..44d38f0 100644 --- a/src/nutrimetas/package-lock.json +++ b/src/nutrimetas/package-lock.json @@ -11,10 +11,11 @@ "@expo/vector-icons": "^14.0.0", "@firebase/firestore": "^4.6.1", "@hookform/resolvers": "^3.3.4", - "@react-native-community/datetimepicker": "7.7.0", - "@react-native-firebase/app": "^19.2.2", - "@react-native-firebase/auth": "^19.2.2", - "@react-native-firebase/firestore": "^19.2.2", + "@react-native-community/datetimepicker": "^8.0.0", + "@react-native-firebase/app": "^19.3.0", + "@react-native-firebase/auth": "^19.3.0", + "@react-native-firebase/firestore": "^19.3.0", + "@react-native-firebase/storage": "^19.3.0", "@react-native-vector-icons/ionicons": "^7.3.1-alpha.9", "@react-navigation/native": "^6.1.17", "@react-navigation/stack": "^6.3.29", @@ -34,9 +35,10 @@ "react-hook-form": "^7.51.4", "react-native": "0.73.6", "react-native-element-dropdown": "^2.12.0", - "react-native-elements": "^3.4.3", "react-native-flash-message": "^0.4.2", "react-native-gifted-chat": "^2.4.0", + "react-native-image-pan-zoom": "^2.1.12", + "react-native-image-picker": "^7.1.2", "react-native-mask-input": "^1.2.3", "react-native-paper": "^5.12.3", "react-native-safe-area-context": "4.8.2", @@ -44,13 +46,16 @@ "react-native-simple-toast": "^3.3.1", "react-native-toast-message": "^2.2.0", "react-native-vector-icons": "^10.1.0", + "react-native-video": "^6.1.2", "react-native-web": "~0.19.6", + "uuid": "^9.0.1", "zod": "^3.23.6" }, "devDependencies": { "@babel/core": "^7.20.0", "@types/react": "~18.2.45", "@types/react-native-vector-icons": "^6.4.18", + "@types/uuid": "^9.0.8", "jest": "^29.2.1", "jest-expo": "~50.0.4", "react-test-renderer": "18.2.0", @@ -2019,6 +2024,14 @@ "safe-json-stringify": "~1" } }, + "node_modules/@expo/bunyan/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@expo/cli": { "version": "0.17.12", "license": "MIT", @@ -3461,6 +3474,14 @@ "node": ">=12" } }, + "node_modules/@expo/rudder-sdk-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@expo/sdk-runtime-versions": { "version": "1.0.0", "license": "MIT" @@ -5663,23 +5684,33 @@ } }, "node_modules/@react-native-community/datetimepicker": { - "version": "7.7.0", - "license": "MIT", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-8.1.0.tgz", + "integrity": "sha512-7WCP4U+cOiTFOxGRb7+w2kzIDDqI0xb2D62dbF1qt8C06KmWIKcNgmzx7gfeCjzJMIDK8v+PoUECU2YZz5PvCQ==", "dependencies": { "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-windows": "*" + }, + "peerDependenciesMeta": { + "react-native-windows": { + "optional": true + } } }, "node_modules/@react-native-firebase/app": { "version": "19.3.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/app/-/app-19.3.0.tgz", + "integrity": "sha512-Y4Jlu7s7JasCcOktAN9LC+7SvMeAG04008OxtbhDK9rpatVznJqRSkMefIIwN2yBs94MWo9b61e+7v5IRMbQdw==", "dependencies": { - "opencollective-postinstall": "^2.0.3", - "superstruct": "^0.6.2" + "plist": "^3.1.0" }, "peerDependencies": { - "expo": ">=47.0.0", - "react": "*", - "react-native": "*" + "@react-native-firebase/app": "19.3.0", + "expo": ">=47.0.0" }, "peerDependenciesMeta": { "expo": { @@ -5689,7 +5720,8 @@ }, "node_modules/@react-native-firebase/auth": { "version": "19.3.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/auth/-/auth-19.3.0.tgz", + "integrity": "sha512-sccxpBAWNBg8Wmqye+SPYrvHb31mAuNYbgcuyOw19P9yxPBy/WRXwZDuJ/ctM8Nn3Caw3nCBiLTQHgMf6Zc6mw==", "dependencies": { "plist": "^3.1.0" }, @@ -5705,7 +5737,16 @@ }, "node_modules/@react-native-firebase/firestore": { "version": "19.3.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/firestore/-/firestore-19.3.0.tgz", + "integrity": "sha512-fWRtMTPfAQAtrN0I4YuGZqVW1CSnqt0+vF0NYQl4e5qGhZ6AyUUmsEd3sFlSQX7M4JHJL7iozgUSpEffOA8opw==", + "peerDependencies": { + "@react-native-firebase/app": "19.3.0" + } + }, + "node_modules/@react-native-firebase/storage": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@react-native-firebase/storage/-/storage-19.3.0.tgz", + "integrity": "sha512-ficwY+uUEDQaSlodpKLjFvF4l63EMvialF2EWpegHwPFDu8J6iJh/0pMaMZ8GijTVBfTt8QsDebC/lEhNyErLw==", "peerDependencies": { "@react-native-firebase/app": "19.3.0" } @@ -6541,8 +6582,15 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true }, "node_modules/@types/yargs": { "version": "17.0.32", @@ -9462,23 +9510,6 @@ "is-callable": "^1.1.3" } }, - "node_modules/for-in": { - "version": "1.0.2", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/form-data": { "version": "3.0.1", "license": "MIT", @@ -10235,13 +10266,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-extendable": { - "version": "0.1.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "license": "MIT", @@ -13547,24 +13571,6 @@ "version": "4.0.0", "license": "ISC" }, - "node_modules/mixin-object": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-object/node_modules/for-in": { - "version": "0.1.8", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mkdirp": { "version": "0.5.6", "license": "MIT", @@ -13935,13 +13941,6 @@ "node": ">=4" } }, - "node_modules/opencollective-postinstall": { - "version": "2.0.3", - "license": "MIT", - "bin": { - "opencollective-postinstall": "index.js" - } - }, "node_modules/ora": { "version": "5.4.1", "license": "MIT", @@ -14723,35 +14722,6 @@ "react-native": "*" } }, - "node_modules/react-native-elements": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/react-native-elements/-/react-native-elements-3.4.3.tgz", - "integrity": "sha512-VtZc25EecPZyUBER85zFK9ZbY6kkUdcm1ZwJ9hdoGSCr1R/GFgxor4jngOcSYeMvQ+qimd5No44OVJW3rSJECA==", - "hasInstallScript": true, - "dependencies": { - "@types/react-native-vector-icons": "^6.4.6", - "color": "^3.1.2", - "deepmerge": "^4.2.2", - "hoist-non-react-statics": "^3.3.2", - "lodash.isequal": "^4.5.0", - "opencollective-postinstall": "^2.0.3", - "react-native-ratings": "8.0.4", - "react-native-size-matters": "^0.3.1" - }, - "peerDependencies": { - "react-native-safe-area-context": ">= 3.0.0", - "react-native-vector-icons": ">7.0.0" - } - }, - "node_modules/react-native-elements/node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, "node_modules/react-native-flash-message": { "version": "0.4.2", "license": "MIT", @@ -14833,6 +14803,24 @@ "react": "^16.6.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-native-image-pan-zoom": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.12.tgz", + "integrity": "sha512-BF66XeP6dzuANsPmmFsJshM2Jyh/Mo1t8FsGc1L9Q9/sVP8MJULDabB1hms+eAoqgtyhMr5BuXV3E1hJ5U5H6Q==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-image-picker": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-7.1.2.tgz", + "integrity": "sha512-b5y5nP60RIPxlAXlptn2QwlIuZWCUDWa/YPUVjgHc0Ih60mRiOg1PSzf0IjHSLeOZShCpirpvSPGnDExIpTRUg==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-iphone-screen-helper": { "version": "2.1.1", "license": "MIT", @@ -14897,18 +14885,6 @@ "react-native": "*" } }, - "node_modules/react-native-ratings": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-8.0.4.tgz", - "integrity": "sha512-Xczu5lskIIRD6BEdz9A0jDRpEck/SFxRqiglkXi0u67yAtI1/pcJC76P4MukCbT8K4BPVl+42w83YqXBoBRl7A==", - "dependencies": { - "lodash": "^4.17.15" - }, - "peerDependencies": { - "react": "*", - "react-native": "*" - } - }, "node_modules/react-native-safe-area-context": { "version": "4.8.2", "license": "MIT", @@ -14940,14 +14916,6 @@ "react-native": ">=0.71.0" } }, - "node_modules/react-native-size-matters": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz", - "integrity": "sha512-mKOfBLIBFBcs9br1rlZDvxD5+mAl8Gfr5CounwJtxI6Z82rGrMO+Kgl9EIg3RMVf3G855a85YVqHJL2f5EDRlw==", - "peerDependencies": { - "react-native": "*" - } - }, "node_modules/react-native-toast-message": { "version": "2.2.0", "license": "MIT", @@ -15011,6 +14979,15 @@ "node": ">=10" } }, + "node_modules/react-native-video": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/react-native-video/-/react-native-video-6.1.2.tgz", + "integrity": "sha512-oKk4hLhcWiL+k5CRgqs+/Bvp23QrHFGx3ylawrF4OWjKRekGeHNCf2mSf7+er66ZmktMtJC0ofBTgEPq4rRG6A==", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-web": { "version": "0.19.12", "license": "MIT", @@ -16171,46 +16148,6 @@ "version": "9.2.1", "license": "MIT" }, - "node_modules/superstruct": { - "version": "0.6.2", - "license": "MIT", - "dependencies": { - "clone-deep": "^2.0.1", - "kind-of": "^6.0.1" - } - }, - "node_modules/superstruct/node_modules/clone-deep": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "for-own": "^1.0.0", - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.0", - "shallow-clone": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/superstruct/node_modules/shallow-clone": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.1", - "kind-of": "^5.0.0", - "mixin-object": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/superstruct/node_modules/shallow-clone/node_modules/kind-of": { - "version": "5.1.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/supports-color": { "version": "5.5.0", "license": "MIT", @@ -16883,8 +16820,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "license": "MIT", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -17282,4 +17224,4 @@ } } } -} +} \ No newline at end of file