// 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
// );
// 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);
// 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;
};
// 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]);