new_react_frontend #9
@@ -1,10 +1,78 @@
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { View, FlatList, StyleSheet, Text } from 'react-native';
|
||||
import { SearchBar } from '../../components/SearchBar';
|
||||
import { MedicineCard } from '../../components/MedicineCard';
|
||||
import { LoadingSpinner } from '../../components/LoadingSpinner';
|
||||
import { useDebounce } from '../../hooks/useDebounce';
|
||||
import { searchMedicines } from '../../services/medicines';
|
||||
import { colors, spacing } from '../../constants/theme';
|
||||
import { Medicine } from '../../types';
|
||||
import { config } from '../../constants/config';
|
||||
|
||||
export default function HomeScreen() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [results, setResults] = useState<Medicine[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const debouncedQuery = useDebounce(query, config.SEARCH_DEBOUNCE_MS);
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedQuery.length < 2) {
|
||||
setResults([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchResults = async () => {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const data = await searchMedicines(debouncedQuery);
|
||||
setResults(data);
|
||||
} catch (err) {
|
||||
setError('Error al buscar medicamentos');
|
||||
console.error(err);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchResults();
|
||||
}, [debouncedQuery]);
|
||||
|
||||
const handleSearch = (searchQuery: string) => {
|
||||
setQuery(searchQuery);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>FarmaFinder</Text>
|
||||
<Text style={styles.subtitle}>Busca medicamentos</Text>
|
||||
<SearchBar
|
||||
onSearch={handleSearch}
|
||||
value={query}
|
||||
onChangeText={setQuery}
|
||||
/>
|
||||
|
||||
{isLoading && <LoadingSpinner message="Buscando medicamentos..." />}
|
||||
|
||||
{error && (
|
||||
<View style={styles.errorContainer}>
|
||||
<Text style={styles.errorText}>{error}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{!isLoading && !error && results.length === 0 && query.length >= 2 && (
|
||||
<View style={styles.emptyContainer}>
|
||||
<Text style={styles.emptyText}>No se encontraron medicamentos</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<FlatList
|
||||
data={results}
|
||||
keyExtractor={(item) => item.nregistro}
|
||||
renderItem={({ item }) => <MedicineCard medicine={item} />}
|
||||
contentContainerStyle={styles.list}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -12,18 +80,27 @@ export default function HomeScreen() {
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
list: {
|
||||
paddingBottom: spacing.xl,
|
||||
},
|
||||
errorContainer: {
|
||||
padding: spacing.md,
|
||||
marginHorizontal: spacing.md,
|
||||
backgroundColor: '#F8D7DA',
|
||||
borderRadius: 8,
|
||||
},
|
||||
errorText: {
|
||||
color: '#721C24',
|
||||
textAlign: 'center',
|
||||
},
|
||||
emptyContainer: {
|
||||
padding: spacing.xl,
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F2F2F7',
|
||||
},
|
||||
title: {
|
||||
fontSize: 28,
|
||||
fontWeight: 'bold',
|
||||
color: '#1C1C1E',
|
||||
},
|
||||
subtitle: {
|
||||
emptyText: {
|
||||
color: colors.textSecondary,
|
||||
fontSize: 16,
|
||||
color: '#8E8E93',
|
||||
marginTop: 8,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user