웹개발/PRJ

[React] Weekly to do list 만들기 2

쌀쌀 2024. 1. 19. 19:25

목표

 

firebase를 이용한 투두리스트 CRUD 기능 구현하기

 

구현

 

1. firebase 사이트에서 cloud storage를 생성한 후  firebase.js 파일을 만들어서 아래와 같이 작성합니다.

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
import { getFirestore } from "firebase/firestore";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
 //작성하셈
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
const db = getFirestore(app);

export default db;

 

2. useFirestore이라는 훅을 만들어 CRUD에 필요한 기능들을 추가합니다.

 

import { useState, useEffect } from "react";
import {
  collection,
  addDoc,
  getDocs,
  deleteDoc,
  updateDoc,
  doc,
  query,
  where,
  orderBy,
} from "firebase/firestore";
import db from "../firebaseconfig"; // Firebase 설정 파일 경로에 맞게 수정

const useFirestore = (collectionName, selectedDate) => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const querySnapshot = await getDocs(
          query(
            collection(db, collectionName),
            where("date", "==", selectedDate),
            orderBy("index")
          )
        );
        const documents = querySnapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));
        // Filter documents based on the selectedDate
        const filteredData = documents.filter((item) => {
          // Assuming your data has a 'date' property
          return item.date === selectedDate;
        });
        setData(filteredData);
        setLoading(false);
        console.log("Data fetched successfully");
      } catch (error) {
        console.error("Error fetching data: ", error);
      }
    };

    fetchData();
  }, [collectionName, selectedDate]);

  const addDocument = async (document) => {
    try {
      const docRef = await addDoc(collection(db, collectionName), document);
      console.log("Document added with ID: ", docRef.id);
      return docRef.id;
    } catch (error) {
      console.error("Error adding document: ", error);
    }
  };

  const deleteDocument = async (docId) => {
    try {
      const docRef = doc(db, collectionName, docId);
      await deleteDoc(docRef);
      console.log("Document deleted successfully");
    } catch (error) {
      console.error("Error deleting document: ", error);
    }
  };

  const updateDocument = async (docId, updatedFields) => {
    try {
      const docRef = doc(collection(db, collectionName), docId);
      await updateDoc(docRef, updatedFields);
      console.log("Document updated successfully");
    } catch (error) {
      console.error("Error updating document: ", error);
    }
  };

  const getCollectionData = async (selectedDate) => {
    try {
      // 특정 날짜에 해당하는 데이터만 가져오기 위한 쿼리 작성
      const querySnapshot = await getDocs(
        query(
          collection(db, collectionName),
          where("date", "==", selectedDate),
          orderBy("index")
        )
      );

      const documents = querySnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));

      console.log("Documents loaded successfully:", documents);
      setData(documents);
      return documents;
    } catch (error) {
      console.error("Error loading documents: ", error);
    } finally {
      setLoading(false);
    }
  };

  return {
    data,
    loading,
    addDocument,
    deleteDocument,
    getCollectionData,
    updateDocument,
  };
};

export default useFirestore;

 

fetch부터 add, delete, update,get 까지 모든 함수를 선언한 뒤 export 합니다

 

3. 이제 useForestore를 Todolist 파일에서 가져와서 씁니다.

 

// ToDoList.jsx


// useFirestore에서 export한 함수나 스테이트 가져오기
  const {
    data,
    loading,
    addDocument,
    deleteDocument,
    updateDocument,
    getCollectionData,
  } = useFirestore("todolist", selectedDate.toLocaleDateString("ko-KR"));
  
    const deleteTodo = (id) => {
    const newTodos = todos.filter((todo) => todo.id !== id);
    setTodos(newTodos);

    deleteDocument(id);
  };
  
  //수정 및 삭제 기능 추가 
  
  const finishEditing = async (id, value) => {
    value.isEditing = !value.isEditing;
    // console.log(value);
    setNextIndex(nextIndex + 1);
    if (!value.isAdded) {
    //처음 등록되는 리스트의 경우엔 스토어에 저장해준 뒤 저장된 결과 값을 가져옵니다.
      value.isAdded = true;
      value.index = nextIndex;
      try {
        const newTodoId = await addDocument(value);
        await getCollectionData(selectedDate.toLocaleDateString("ko-KR"));
        const addedTodo = data.find((todo) => todo.id === newTodoId);
        if (addedTodo) {
          setTodos([...todos, addedTodo]);
        }
      } catch (error) {
        console.log("error");
      }
      //이미 등록돼 수정이 필요한 경우엔 업데이트를 합니다.
    } else {
      updateDocument(id, { value: value.value });
    }
  };

 

완성본

 

이제 스타일을 만져봐야 하는데요. 요즘 핫하다는 tailwind-css를 써보려고 합니다. 완성되면 돌아오겠습니다.