// src/screens/VaccinationScreen.js import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, ScrollView, TextInput, TouchableOpacity, Alert, Modal, FlatList, } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import DateTimePicker from '@react-native-community/datetimepicker'; import { executeQuery } from '../database'; // Lista de vacunas comunes const COMMON_VACCINES = [ 'Fiebre Aftosa', 'Brucelosis', 'Carbón', 'Leptospirosis', 'Clostridiales', 'Rabia', 'IBR', 'DVB', 'Parainfluenza', 'Rinotraqueítis', ]; // Lista de responsables const RESPONSABLES = ['Juan', 'Pedro', 'Carlos', 'Miguel', 'Papá', 'Tú']; export default function VaccinationScreen({ navigation }) { const [animalId, setAnimalId] = useState(''); const [vaccineName, setVaccineName] = useState(''); const [date, setDate] = useState(new Date()); const [nextDate, setNextDate] = useState(new Date()); const [responsable, setResponsable] = useState(''); const [observations, setObservations] = useState(''); // Estados para modales const [showDatePicker, setShowDatePicker] = useState(false); const [datePickerFor, setDatePickerFor] = useState(''); // 'date' o 'nextDate' const [showVaccineModal, setShowVaccineModal] = useState(false); const [showAnimalModal, setShowAnimalModal] = useState(false); const [showResponsableModal, setShowResponsableModal] = useState(false); // Lista de animales para búsqueda const [animals, setAnimals] = useState([]); const [filteredAnimals, setFilteredAnimals] = useState([]); // Cargar animales al iniciar useEffect(() => { loadAnimals(); }, []); const loadAnimals = async () => { try { const result = await executeQuery( 'SELECT id, nombre, categoria FROM animales WHERE activo = 1 ORDER BY id' ); const animalsList = []; for (let i = 0; i < result.rows.length; i++) { animalsList.push(result.rows.item(i)); } setAnimals(animalsList); setFilteredAnimals(animalsList); } catch (error) { console.error('Error cargando animales:', error); } }; const handleSearchAnimal = (text) => { setAnimalId(text); if (text.length > 0) { const filtered = animals.filter(animal => animal.id.toLowerCase().includes(text.toLowerCase()) || (animal.nombre && animal.nombre.toLowerCase().includes(text.toLowerCase())) ); setFilteredAnimals(filtered); } else { setFilteredAnimals(animals); } }; const handleDateChange = (event, selectedDate) => { setShowDatePicker(false); if (selectedDate) { if (datePickerFor === 'date') { setDate(selectedDate); } else { setNextDate(selectedDate); } } }; const formatDate = (dateObj) => { return dateObj.toISOString().split('T')[0]; }; const handleSave = async () => { // Validaciones if (!animalId.trim()) { Alert.alert('Error', 'Por favor ingrese el número o lote del animal'); return; } if (!vaccineName.trim()) { Alert.alert('Error', 'Por favor seleccione una vacuna'); return; } const vaccinationData = { id: `vac_${Date.now()}`, animal_id: animalId.toUpperCase(), tipo_evento: 'VACUNACION', producto: vaccineName, fecha_aplicacion: formatDate(date), fecha_proxima: formatDate(nextDate), responsable: responsable || 'No especificado', observaciones: observations, }; try { // Guardar en eventos_sanitarios await executeQuery( `INSERT INTO eventos_sanitarios (id, animal_id, tipo_evento, producto, fecha_aplicacion, fecha_proxima, responsable, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [ vaccinationData.id, vaccinationData.animal_id, vaccinationData.tipo_evento, vaccinationData.producto, vaccinationData.fecha_aplicacion, vaccinationData.fecha_proxima, vaccinationData.responsable, vaccinationData.observaciones, ] ); // Crear alerta para próxima vacunación si hay fecha próxima if (vaccinationData.fecha_proxima) { const alertId = `alert_${Date.now()}`; await executeQuery( `INSERT INTO alertas_pendientes (id, tipo, animal_id, descripcion, fecha_vencimiento, prioridad) VALUES (?, ?, ?, ?, ?, ?)`, [ alertId, 'VACUNACION', vaccinationData.animal_id, `Próxima dosis: ${vaccinationData.producto}`, vaccinationData.fecha_proxima, 2, ] ); } Alert.alert( '¡Éxito!', `Vacunación registrada correctamente para ${vaccinationData.animal_id}`, [ { text: 'Registrar otra', onPress: () => { setAnimalId(''); setVaccineName(''); setObservations(''); }, }, { text: 'Volver al inicio', onPress: () => navigation.navigate('Home'), }, ] ); } catch (error) { console.error('Error guardando vacunación:', error); Alert.alert('Error', 'No se pudo guardar la vacunación'); } }; const renderAnimalItem = ({ item }) => ( { setAnimalId(item.nombre ? `${item.id} - ${item.nombre}` : item.id); setShowAnimalModal(false); }} > {item.id} {item.nombre && ( {item.nombre} )} {item.categoria} ); return ( {/* Campo: Animal/Lote */} Animal o Lote * setShowAnimalModal(true)} > Presione para buscar animal existente o escriba nuevo {/* Campo: Vacuna */} Vacuna * setShowVaccineModal(true)} > {/* Campo: Fecha de aplicación */} Fecha de aplicación { setDatePickerFor('date'); setShowDatePicker(true); }} > {/* Campo: Próxima fecha */} Próxima dosis (opcional) { setDatePickerFor('nextDate'); setShowDatePicker(true); }} > El sistema creará una alerta automática {/* Campo: Responsable */} Responsable setShowResponsableModal(true)} > {/* Campo: Observaciones */} Observaciones {/* Botones de acción */} navigation.goBack()} > CANCELAR GUARDAR VACUNACIÓN {/* Recordatorio */} Este registro quedará guardado en el dispositivo. No se requiere internet. {/* Modal: Seleccionar animal */} Seleccionar Animal setShowAnimalModal(false)}> item.id} style={styles.animalList} /> { setShowAnimalModal(false); // Habilitar edición directa // (necesitarías un estado adicional para esto) }} > Escribir manualmente {/* Modal: Seleccionar vacuna */} Seleccionar Vacuna setShowVaccineModal(false)}> ( { setVaccineName(item); setShowVaccineModal(false); }} > {item} )} keyExtractor={(item) => item} /> { setShowVaccineModal(false); // Aquí podrías activar un TextInput manual }} > Escribir manualmente {/* Modal: Seleccionar responsable */} Seleccionar Responsable setShowResponsableModal(false)}> ( { setResponsable(item); setShowResponsableModal(false); }} > {item} )} keyExtractor={(item) => item} /> { setShowResponsableModal(false); // Activar TextInput manual }} > Escribir manualmente {/* Date Picker */} {showDatePicker && ( )} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F5F5F5', }, form: { padding: 16, }, field: { marginBottom: 20, }, label: { fontSize: 16, fontWeight: '600', color: '#333', marginBottom: 8, }, input: { backgroundColor: 'white', borderWidth: 1, borderColor: '#DDD', borderRadius: 8, paddingHorizontal: 12, paddingVertical: 12, fontSize: 16, flex: 1, }, inputWithIcon: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'white', borderWidth: 1, borderColor: '#DDD', borderRadius: 8, paddingHorizontal: 12, }, textArea: { minHeight: 80, textAlignVertical: 'top', }, helperText: { fontSize: 12, color: '#666', marginTop: 4, fontStyle: 'italic', }, buttonContainer: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 24, marginBottom: 16, }, cancelButton: { flex: 1, backgroundColor: '#F5F5F5', borderWidth: 1, borderColor: '#DDD', borderRadius: 8, paddingVertical: 14, alignItems: 'center', marginRight: 8, }, cancelButtonText: { color: '#666', fontWeight: '600', fontSize: 16, }, saveButton: { flex: 2, backgroundColor: '#4CAF50', borderRadius: 8, paddingVertical: 14, alignItems: 'center', flexDirection: 'row', justifyContent: 'center', marginLeft: 8, }, saveButtonText: { color: 'white', fontWeight: 'bold', fontSize: 16, marginLeft: 8, }, reminderBox: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#E8F5E9', padding: 12, borderRadius: 8, marginTop: 16, }, reminderText: { flex: 1, fontSize: 14, color: '#2E7D32', marginLeft: 12, }, // Estilos para modales modalContainer: { flex: 1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'flex-end', }, modalContent: { backgroundColor: 'white', borderTopLeftRadius: 20, borderTopRightRadius: 20, maxHeight: '80%', }, modalHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 16, borderBottomWidth: 1, borderBottomColor: '#EEE', }, modalTitle: { fontSize: 18, fontWeight: 'bold', color: '#333', }, searchInput: { backgroundColor: '#F5F5F5', marginHorizontal: 16, marginVertical: 12, padding: 12, borderRadius: 8, fontSize: 16, }, animalList: { maxHeight: 300, }, animalItem: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, borderBottomWidth: 1, borderBottomColor: '#EEE', }, animalInfo: { marginLeft: 12, }, animalId: { fontSize: 16, fontWeight: '600', color: '#333', }, animalName: { fontSize: 14, color: '#666', }, animalCategory: { fontSize: 12, color: '#999', }, vaccineItem: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 14, borderBottomWidth: 1, borderBottomColor: '#EEE', }, vaccineItemText: { fontSize: 16, marginLeft: 12, color: '#333', }, responsableItem: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 14, borderBottomWidth: 1, borderBottomColor: '#EEE', }, responsableItemText: { fontSize: 16, marginLeft: 12, color: '#333', }, useTextButton: { padding: 16, alignItems: 'center', borderTopWidth: 1, borderTopColor: '#EEE', }, useTextButtonText: { color: '#2196F3', fontSize: 16, fontWeight: '600', }, });