2024.03.21 TIL - 트러블슈팅(유저가 그린그림 가져오기 로직변경, 좋아요 로직변경)

Innes·2024년 3월 21일
0

TIL(Today I Learned)

목록 보기
97/147
post-thumbnail

유저가 그린 그림 가져오는 로직 변경

  • 기존 : users테이블의 drawings_array에서 id배열 가지고와서(인자로 받음), 그 id들과 일치하는 url들을 posts에서 가져오기
// api
// painter의 다른 그림들 url 가져오기
export const getDrawingUrls = async (drawingIds: number[]) => {
  const response = await supabase
    .from("posts")
    .select("drawing_url")
    .in("drawing_id", drawingIds)
    .then(({ data: postsData, error }) => {
      if (error) throw error;
      const drawingUrls = postsData.map((post) => post.drawing_url);
      return drawingUrls;
    });
  return response;
};
// 컴포넌트

  // 기존 - 그림id의 배열을 props로 받아와서 url을 찾고 아래에서 뿌려준다.
  // 유저가 그린 그림url 배열
  const {
    data: drawingUrls,
    isLoading,
    isError,
  } = useQuery({
    queryKey: ["drawingUrls"],
    queryFn: () => getDrawingUrls(drawingIds),
  });

  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (isError) {
    return <div>Error</div>;
  }
// Painter.tsx 컴포넌트 - 그림id 배열 만들기

const Painter = ({ post, id }: PostProps) => {
  // 그림 작성자 nickname, profile_img, 그린 그림들 가져오기
  const {
    data: painterInfoArray,
    isLoading,
    isError,
  } = useQuery({
    queryKey: ["painterInfo"],
    queryFn: () => getPainterInfo(post.painter_email),
  });

  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (isError || !Array.isArray(painterInfoArray)) {
    return <div>Error</div>;
  }

  const painterInfo = painterInfoArray[0];
  // console.log("painterInfoArray", painterInfoArray);

  // 기존 - 유저가 그린 그림id 배열(현재 보고있는 그림의 id는 제외)
  // const drawingIds = painterInfo.drawings_array.filter(
  //   (drawingId: number) => drawingId !== id
  // );
  • 변경 후 : posts에서 그림주인 email과 일치하는 drawing_url들을 가져오기
// api
// posts테이블에서 일치하는 email의 그림 url들을 배열로 반환하기
export const getDrawingUrls = async (email: string) => {
  const { data: urlArray, error } = await supabase
    .from("posts")
    .select("drawing_url")
    .eq("painter_email", email);
  if (error) {
    throw error;
  }
  const urls = urlArray.map((urlObj) => urlObj.drawing_url);
  return urls;
};
// 컴포넌트
  // 변경후 - posts테이블에서 post.painter_email과 일치하는 그림 url들을 가져와서 배열로 저장, 아래에서 뿌려주기
  const email = post.painter_email;
  const {
    data: drawingUrls,
    isLoading,
    isError,
  } = useQuery({
    queryKey: ["drawingUrls"],
    queryFn: () => getDrawingUrls(email),
  });

  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (isError) {
    return <div>Error</div>;
  }

  console.log("drawingUrls", drawingUrls);

좋아요 로직 수정

  • 기존 : users테이블에서 likes_array로 좋아요한 그림id를 배열로 관리
// api

// 좋아요 클릭시 로그인한 user의 likes_array에 그림id 추가하기
export const insertDrawingId = async (email: string, drawingId: number) => {
  // email을 사용하여 해당 사용자 찾기 - users 반환값은 배열 안의 객체
  const { data: users, error } = await supabase
    .from("users")
    .select()
    .eq("email", email);

  if (error) {
    console.error("Error fetching user:", error.message);
    return;
  }

  // 해당 사용자의 likes_array에 drawingId 추가하기
  const selectedUser = users[0];
  const updatedBookmarksArray = [...selectedUser.likes_array, drawingId];

  // 수정한 배열을 해당 유저의 likes_array에 업데이트하기
  const { error: updateError } = await supabase
    .from("users")
    .update({ likes_array: updatedBookmarksArray })
    .eq("email", email);

  if (updateError) {
    console.error("Error updating user drawings array:", updateError.message);
    return;
  }
};


// 유저의 likes_array 가져오기
export const getLikesArray = async (email: string) => {
  console.log("email", email);
  const { data, error } = await supabase
    .from("users")
    .select("likes_array")
    .eq("email", email);
  if (error) {
    console.error(error);
  }

  return data;
};
  • 변경 : likes라는 조인 테이블을 따로 만들어서 좋아요한 유저 email(id여도 됨), 그림id (편의상 이 프로젝트에서는 그림 url도 추가함) 추가해서 관리하기
// api

// likes에서 email, drawing_id 존재하는지 확인 - 유저가 좋아요 했는지 확인하기
export const isCheckLikeState = async (drawingId: number) => {
  // current loggedIn user의 email 가져오기
  const { data: user, error: userError } = await supabase.auth.getUser();
  if (userError) {
    throw userError;
  }
  const email = user.user.email;

  // likes테이블에서 email, drawingId 모두 일치하는값 있는지 확인하기
  const { data: like, error } = await supabase
    .from("likes")
    .select()
    .eq("user_email", email)
    .eq("drawing_id", drawingId);

  if (error) {
    throw error;
  }

  return like.length > 0;
};

// 좋아요! - likes테이블에 email, id, url 추가하기
export const insertLike = async (id: number, url: string) => {
  // current loggedIn user의 email 가져오기
  const { data: user, error: userError } = await supabase.auth.getUser();
  if (userError) {
    throw userError;
  }
  const email = user.user.email;

  // likes 테이블에 insert
  const { data, error } = await supabase.from("likes").insert([
    {
      user_email: email,
      drawing_id: id,
      drawing_url: url,
    },
  ]);
  if (error) {
    throw error;
  }
  return data;
};

// 좋아요 취소 - likes 테이블에서 그림id가 같은 열 삭제
export const deleteLike = async (id: number) => {
  const { data, error } = await supabase
    .from("likes")
    .delete()
    .eq("drawing_id", id)
    .select();
  if (error) {
    throw error;
  }
  return data;
};

화면 렌더링시 이미 좋아요한 그림인지 체크하기

  • 화면 렌더링시 이미 좋아요했던 그림이면 좋아요 하트 색을 채워놓으려고 좋아요 상태를 체크하는 로직을 짰는데 로그아웃상태일 땐 하트가 아닌 Error가 떴다.
    -> 로그인 상태인 경우에만 좋아요상태를 확인하도록 로직 변경

  • 기존

  // 화면 렌더링시 : 현재 유저가 이 그림을 좋아요한 상태인지 확인하기 
  // 좋아요 상태이면 isLike -> true(하트 색 채워놓기)
  const [isLike, setIsLike] = useState(false);

  const {
    data: checkLikeState,
    isLoading: checkLikeLoading,
    isError: checkLikeError,
  } = useQuery({
    queryKey: ["checkLike"],
    queryFn: async () => {
      const response = await isCheckLikeState(id);
      response && setIsLike(true);
      return response;
    },
  });

  if (checkLikeLoading) {
    return <div>Loading...</div>;
  }
  if (checkLikeError) {
    return <div>Error</div>;
  }
  • 변경 후
  const [isLike, setIsLike] = useState(false);
  // zustand로 전역관리중인 로그인상태 가져오기
  const isLoggedIn = useAuthStore((state) => state.isLoggedIn);

// 로그인상태 변경될때마다 실행
// 로그인상태이면 - 현재 그림이 user가 좋아요했던 그림인지 확인하기
useEffect(() => {
    if (isLoggedIn) {
      const fetchData = async () => {
        try {
          const response = await isCheckLikeState(id);
          // 하트 색채우기 구별(response가 boolean값임)
          setIsLike(response);
        } catch (error) {
          console.error(error);
        }
      };
      fetchData();
    }
  }, [id, isLoggedIn]);
profile
꾸준히 성장하는 우상향 개발자

0개의 댓글