Untitled
unknown
plain_text
a year ago
13 kB
17
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