스파르타코딩클럽 내일배움캠프 TIL45

한재창·2023년 1월 2일
0

리액트 네이티브

  • 파이어 베이스로 데이터 저장하기
  • 숙제라서 혼자 해보았다. 4시간 걸렸다..
export default function TodoList() {
  const [todos, setTodos] = useState([]);
  const [textValue, setTextValue] = useState("");
  const [category, setCategory] = useState();
  const [editing, setEditing] = useState();

  // firebase에 데이터 추가하기
  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();
  };

  // firebase에서 데이터 가져오기
  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]);

  // firebase에서 리로드시 마지막 카테고리 데이터 가져오기
  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();
  }, []);

  // firebase에서 데이터 수정하기
  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();
  };

  // fisebase에서 완료, 취소하기
  const onChangeIsDoneHandler = (id) => {
    const commentRef = doc(dbService, "todos", id);
    const selectedTodo = todos.find((todo) => todo.id === id);
    updateDoc(commentRef, {
      isDone: !selectedTodo.isDone,
    });
    getData();
  };

  // firebase에서 데이터 삭제하기
  const deleteTodo = async (id) => {
    try {
      await deleteDoc(doc(dbService, "todos", id));
      getData();
    } catch (error) {
      alert(error);
    }
  };

  // firebase에서 수정 버튼 함수
  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에서 사용하는 함수의 매개변수에 value값이 들어가도록 만들어졌다.
          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;
`;
profile
취준 개발자

0개의 댓글