리액트 네이티브
- 파이어 베이스로 데이터 저장하기
- 숙제라서 혼자 해보았다. 4시간 걸렸다..
export default function TodoList() {
const [todos, setTodos] = useState([]);
const [textValue, setTextValue] = useState("");
const [category, setCategory] = useState();
const [editing, setEditing] = useState();
const addText = async () => {
const id = uuidv4();
await setDoc(doc(dbService, "todos", id), {
id: id,
time: new Date(),
text: textValue,
category,
isDone: false,
isEditing: false,
});
setTextValue("");
getData();
};
const q = query(collection(dbService, "todos"), orderBy("time", "desc"));
const getData = async () => {
const querySnapshot = await getDocs(q);
const dataArray = [];
querySnapshot.forEach((doc) => {
dataArray.push(doc.data());
});
setTodos(dataArray);
};
useEffect(() => {
getData();
}, [category]);
const categoryQuery = query(collection(dbService, "category"));
const selectCategory = async (category) => {
const commentRef = doc(dbService, "category", "category");
try {
await updateDoc(commentRef, {
category,
});
setCategory(category);
} catch (error) {
console.log(error);
}
};
const initCategory = async () => {
const querySnapshot = await getDocs(categoryQuery);
const dataArray = [];
querySnapshot.forEach((doc) => {
dataArray.push(doc.data());
});
if (dataArray.length > 0) {
setCategory(dataArray[0].category);
}
};
useEffect(() => {
initCategory();
}, []);
const editingTodo = (id) => {
const commentRef = doc(dbService, "todos", id);
const selectedTodo = todos.find((todo) => todo.id === id);
updateDoc(commentRef, {
text: editing,
isEditing: !selectedTodo.isEditing,
});
getData();
};
const onChangeIsDoneHandler = (id) => {
const commentRef = doc(dbService, "todos", id);
const selectedTodo = todos.find((todo) => todo.id === id);
updateDoc(commentRef, {
isDone: !selectedTodo.isDone,
});
getData();
};
const deleteTodo = async (id) => {
try {
await deleteDoc(doc(dbService, "todos", id));
getData();
} catch (error) {
alert(error);
}
};
const onChangeIsEditingHandler = async (id) => {
const commentRef = doc(dbService, "todos", id);
const selectedTodo = todos.find((todo) => todo.id === id);
try {
await updateDoc(commentRef, {
isEditing: !selectedTodo.isEditing,
});
setEditing(selectedTodo.text);
getData();
} catch (error) {
console.log(error);
}
};
return (
<Wrap>
<ButtonWrap>
<NavigateBtn
style={{
backgroundColor: category === "JavaScript" ? "#1585f1" : "grey",
}}
onPress={() => selectCategory("JavaScript")}
>
<Text>JavaScript</Text>
</NavigateBtn>
<NavigateBtn
style={{
backgroundColor: category === "React" ? "#1585f1" : "grey",
}}
onPress={() => selectCategory("React")}
>
<Text>React</Text>
</NavigateBtn>
<NavigateBtn
style={{
backgroundColor: category === "Coding Test" ? "#1585f1" : "grey",
}}
onPress={() => selectCategory("Coding Test")}
>
<Text>Coding Test</Text>
</NavigateBtn>
</ButtonWrap>
<InputWrap>
<TodoInput
placeholder="할 일을 입력해 주세요"
value={textValue}
onChangeText={setTextValue}
onSubmitEditing={addText}
/>
</InputWrap>
<AllListWrap>
{todos.map((todo) => {
if (category === todo.category) {
return (
<ListWrap key={todo.id}>
{todo.isEditing ? (
<TextInput
value={editing}
onSubmitEditing={() => editingTodo(todo.id)}
onChangeText={setEditing}
style={{ flex: 1, backgroundColor: "white" }}
/>
) : (
<Text
style={{
textDecorationLine: todo.isDone ? "line-through" : "none",
}}
>
{todo.text}
</Text>
)}
<TDLBtnBox>
<TDLBtn onPress={() => onChangeIsDoneHandler(todo.id)}>
<FontAwesome name="check-square" size={33} color="black" />
</TDLBtn>
<TDLBtn onPress={() => onChangeIsEditingHandler(todo.id)}>
<FontAwesome name="pencil-square" size={33} color="black" />
</TDLBtn>
<TDLBtn onPress={() => deleteTodo(todo.id)}>
<FontAwesome name="trash" size={33} color="black" />
</TDLBtn>
</TDLBtnBox>
</ListWrap>
);
}
})}
</AllListWrap>
</Wrap>
);
}
const Wrap = styled.SafeAreaView`
flex: 1;
background-color: white;
`;
const ButtonWrap = styled.View`
flex: 1;
flex-direction: row;
justify-content: space-around;
align-items: center;
`;
const NavigateBtn = styled.TouchableOpacity`
width: 28%;
height: 70%;
background-color: #1585f1;
justify-content: center;
align-items: center;
`;
const InputWrap = styled.View`
/* padding: 50px; */
border-bottom: 10px;
flex: 1;
justify-content: center;
align-items: center;
border-top-width: 1px;
border-bottom-width: 1px;
`;
const TodoInput = styled.TextInput`
padding: 0 5%;
width: 90%;
height: 50%;
border-width: 1px;
`;
const AllListWrap = styled.ScrollView`
padding: 0 5%;
flex: 7;
`;
const ListWrap = styled.View`
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-left: 5%;
margin-top: 4%;
width: 100%;
height: 50px;
background-color: #d9d9d9;
`;
const TDLBtnBox = styled.View`
flex-direction: row;
justify-content: center;
align-items: center;
`;
const TDLBtn = styled.TouchableOpacity`
margin-right: 8px;
`;