Untitled

 avatar
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