Untitled
unknown
plain_text
6 months ago
13 kB
3
Indexable
// import React, { useState, useCallback } from "react"; // import { // View, // Text, // FlatList, // Alert, // TouchableOpacity, // Image, // StyleSheet, // TextInput, // } from "react-native"; // import AsyncStorage from "@react-native-async-storage/async-storage"; // import { useNavigation, useFocusEffect } from "@react-navigation/native"; // import { FontAwesome, MaterialIcons } from "@expo/vector-icons"; // import IconSearch from "react-native-vector-icons/FontAwesome"; // export default function HomeScreen() { // const [expenses, setExpenses] = useState([]); // const [searchTerm, setSearchTerm] = useState(""); //search // const [noResults, setNoResults] = useState(false); //search // const [filteredExpenses, setFilteredExpenses] = useState([]); //search // const navigation = useNavigation(); // const fetchExpenses = async () => { // const storedExpenses = await AsyncStorage.getItem("expenses"); // if (storedExpenses) setExpenses(JSON.parse(storedExpenses)); // }; // useFocusEffect( // useCallback(() => { // fetchExpenses(); // }, []) // ); // const deleteExpense = async (id) => { // Alert.alert( // "Delete Expense", // "Are you sure you want to delete this expense?", // [ // { text: "Cancel", style: "cancel" }, // { // text: "OK", // onPress: async () => { // const updatedExpenses = expenses.filter((expense) => expense.id !== id); // setExpenses(updatedExpenses); // await AsyncStorage.setItem("expenses", JSON.stringify(updatedExpenses)); // }, // }, // ], // { cancelable: false } // ); // }; // const deleteAllExpenses = async () => { // Alert.alert( // "Delete All Expenses", // "Are you sure you want to delete all expenses?", // [ // { text: "Cancel", style: "cancel" }, // { // text: "OK", // onPress: async () => { // setExpenses([]); // await AsyncStorage.removeItem("expenses"); // }, // }, // ], // { cancelable: false } // ); // }; // const updateExpense = (id) => { // navigation.navigate("UpdateExpense", { expenseId: id }); // }; // const toggleFavorite = async (id) => { // const updatedExpenses = expenses.map((expense) => // expense.id === id ? { ...expense, favorite: !expense.favorite } : expense // ); // setExpenses(updatedExpenses); // await AsyncStorage.setItem("expenses", JSON.stringify(updatedExpenses)); // }; // // SEARCH // const handleSearch = () => { // // Tính toán filteredExpenses bên trong hàm // const filteredExpenses = expenses.filter((expense) => // expense.name.toLowerCase().includes(searchTerm.toLowerCase()) // ); // // Kiểm tra xem có kết quả nào hay không // if (filteredExpenses.length === 0 && searchTerm) { // setNoResults(true); // Đặt noResults thành true nếu không tìm thấy khoản chi nào // } else { // setNoResults(false); // Đặt noResults thành false nếu có kết quả // } // // Cập nhật lại filteredExpenses vào state (nếu cần thiết) // setFilteredExpenses(filteredExpenses); // }; // return ( // <View style={styles.container}> // <Image source={require("../assets/background.jpg")} style={styles.banner} /> // <View style={{ display: "flex", width: "100%", marginBottom: 10 }}> // <TextInput // style={{ // borderWidth: 1, // borderBlockColor: "black", // height: 40, // borderRadius: 10, // position: "relative", // padding: 10, // }} // placeholder="Search by name" // value={searchTerm} // onChangeText={setSearchTerm} // /> // <IconSearch // onPress={handleSearch} // name="search" // color={"blue"} // size={20} // style={{ position: "absolute", right: 35, top: 8, zIndex: 1 }} // /> // <TouchableOpacity // onPress={deleteAllExpenses} // style={{ position: "absolute", right: 10, top: 6, zIndex: 1 }} // > // <MaterialIcons name="delete" size={24} color="red" /> // </TouchableOpacity> // </View> // {noResults ? ( // <Text style={{ fontSize: 20, color: "blue", marginTop: 10 }}>No matching name found!</Text> // ) : ( // <FlatList // data={ // filteredExpenses.length > 0 // ? filteredExpenses // : expenses.sort((a, b) => new Date(b.date) - new Date(a.date)) // } // keyExtractor={(item) => item.id.toString()} // renderItem={({ item }) => ( // <View style={styles.expenseItem}> // <View> // <TouchableOpacity // onPress={() => navigation.navigate("ExpenseDetail", { expenseId: item.id })} // > // <Text>{item.name}</Text> // <Text>{item.amount}</Text> // </TouchableOpacity> // <Text>{item.date}</Text> // <Text>{item.category}</Text> // <TouchableOpacity onPress={() => toggleFavorite(item.id)}> // <FontAwesome name={item.favorite ? "heart" : "heart-o"} size={24} color="red" /> // </TouchableOpacity> // </View> // <View style={styles.buttonContainer}> // <TouchableOpacity onPress={() => updateExpense(item.id)} style={styles.iconButton}> // <MaterialIcons name="edit" size={24} color="blue" /> // </TouchableOpacity> // <TouchableOpacity onPress={() => deleteExpense(item.id)} style={styles.iconButton}> // <MaterialIcons name="delete" size={24} color="red" /> // </TouchableOpacity> // </View> // </View> // )} // /> // )} // </View> // ); // } // const styles = StyleSheet.create({ // container: { // flex: 1, // padding: 10, // backgroundColor: "#f5f5f5", // }, // banner: { // width: "100%", // height: 150, // marginBottom: 10, // }, // expenseItem: { // flexDirection: "row", // justifyContent: "space-between", // alignItems: "center", // padding: 10, // backgroundColor: "#fff", // borderRadius: 10, // marginBottom: 10, // shadowColor: "#000", // shadowOffset: { width: 0, height: 2 }, // shadowOpacity: 0.1, // shadowRadius: 5, // elevation: 3, // }, // buttonContainer: { // flexDirection: "row", // }, // iconButton: { // marginHorizontal: 5, // }, // }); //SEARCH FILTER import React, { useState, useCallback, useEffect } from "react"; import { View, Text, FlatList, Alert, TouchableOpacity, Image, StyleSheet, TextInput, } from "react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { useNavigation, useFocusEffect } from "@react-navigation/native"; import { FontAwesome, MaterialIcons } from "@expo/vector-icons"; export default function HomeScreen() { const [expenses, setExpenses] = useState([]); const [searchTerm, setSearchTerm] = useState(""); //search const [noResults, setNoResults] = useState(false); //search const [filteredExpenses, setFilteredExpenses] = useState([]); //search const navigation = useNavigation(); const fetchExpenses = async () => { const storedExpenses = await AsyncStorage.getItem("expenses"); if (storedExpenses) setExpenses(JSON.parse(storedExpenses)); }; useFocusEffect( useCallback(() => { fetchExpenses(); }, []) ); const deleteExpense = async (id) => { Alert.alert( "Delete Expense", "Are you sure you want to delete this expense?", [ { text: "Cancel", style: "cancel" }, { text: "OK", onPress: async () => { const updatedExpenses = expenses.filter((expense) => expense.id !== id); setExpenses(updatedExpenses); await AsyncStorage.setItem("expenses", JSON.stringify(updatedExpenses)); }, }, ], { cancelable: false } ); }; const deleteAllExpenses = async () => { Alert.alert( "Delete All Expenses", "Are you sure you want to delete all expenses?", [ { text: "Cancel", style: "cancel" }, { text: "OK", onPress: async () => { setExpenses([]); await AsyncStorage.removeItem("expenses"); }, }, ], { cancelable: false } ); }; const updateExpense = (id) => { navigation.navigate("UpdateExpense", { expenseId: id }); }; const toggleFavorite = async (id) => { const updatedExpenses = expenses.map((expense) => expense.id === id ? { ...expense, favorite: !expense.favorite } : expense ); setExpenses(updatedExpenses); await AsyncStorage.setItem("expenses", JSON.stringify(updatedExpenses)); }; // SEARCH const handleSearch = () => { const filteredExpenses = expenses.filter((expense) => expense.name.toLowerCase().includes(searchTerm.toLowerCase()) ); if (filteredExpenses.length === 0 && searchTerm) { setNoResults(true); } else { setNoResults(false); } setFilteredExpenses(filteredExpenses); }; // useEffect to call handleSearch when searchTerm changes useEffect(() => { handleSearch(); }, [searchTerm]); return ( <View style={styles.container}> <Image source={require("../assets/background.jpg")} style={styles.banner} /> <View style={{ display: "flex", width: "100%", marginBottom: 10 }}> <TextInput style={{ borderWidth: 1, borderBlockColor: "black", height: 40, borderRadius: 10, position: "relative", padding: 10, }} //search placeholder="Search by name" value={searchTerm} onChangeText={setSearchTerm} /> <TouchableOpacity onPress={deleteAllExpenses} style={{ position: "absolute", right: 10, top: 6, zIndex: 1 }} > <MaterialIcons name="delete" size={24} color="red" /> </TouchableOpacity> </View> {noResults ? ( <Text style={{ fontSize: 20, color: "blue", marginTop: 10 }}>No matching name found!</Text> ) : ( <FlatList data={ filteredExpenses.length > 0 ? filteredExpenses : expenses.sort(( a, b) => new Date(b.date) - new Date(a.date)) } keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => ( <View style={styles.expenseItem}> <View> <TouchableOpacity onPress={() => navigation.navigate("ExpenseDetail", { expenseId: item.id })} > <Text>{item.name}</Text> <Text>{item.amount}</Text> </TouchableOpacity> <Text>{item.date}</Text> <Text>{item.category}</Text> <TouchableOpacity onPress={() => toggleFavorite(item.id)}> <FontAwesome name={item.favorite ? "heart" : "heart-o"} size={24} color="red" /> </TouchableOpacity> </View> <View style={styles.buttonContainer}> <TouchableOpacity onPress={() => updateExpense(item.id)} style={styles.iconButton}> <MaterialIcons name="edit" size={24} color="blue" /> </TouchableOpacity> <TouchableOpacity onPress={() => deleteExpense(item.id)} style={styles.iconButton}> <MaterialIcons name="delete" size={24} color="red" /> </TouchableOpacity> </View> </View> )} /> )} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, padding: 10, backgroundColor: "#f5f5f5", }, banner: { width: "100%", height: 150, marginBottom: 10, }, expenseItem: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", padding: 10, backgroundColor: "#fff", borderRadius: 10, marginBottom: 10, shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 5, elevation: 3, }, buttonContainer: { flexDirection: "row", }, iconButton: { marginHorizontal: 5, }, });
Editor is loading...
Leave a Comment