Skip to content

Commit

Permalink
Feat: 심화 기능 구현, 좋아요 기능 최적화
Browse files Browse the repository at this point in the history
  • Loading branch information
yoyobar committed Sep 10, 2024
1 parent ee795db commit b1e5346
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 26 deletions.
4 changes: 4 additions & 0 deletions src/api/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,7 @@ export const articleRePost = (
};
return axiosInstance.patch(`/article/update/${article_id}/`, requestForm);
};

export const likeList = () => {
return axiosInstance.get(`/article/list/like/`);
};
16 changes: 8 additions & 8 deletions src/common/content/ContentFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ import { twMerge as tw } from "tailwind-merge";
import { motion } from "framer-motion";
import { axiosInstance } from "../../api/axios";
import { FaHeart } from "react-icons/fa";
import { useArticleStore } from "../../config/store";
import { articleApi } from "../../api";
import { AxiosError } from "axios";
import { useLikeStore } from "../../config/store";
import { articleApi } from "../../api";
interface ContentFooterProps {
articleId: number;
like_count: number;
view_count: number;
commentsCount: number;
commentsCountClick: (num: number) => void;
like: boolean;
onAlert: (text: string) => void;
}

Expand All @@ -24,13 +23,12 @@ const ContentFooter = ({
view_count,
commentsCount,
commentsCountClick,
like,
onAlert,
}: ContentFooterProps) => {
const [hoverIndex, setHoverIndex] = useState<number | null>(null);
const [currentLikeCount, setCurrentLikeCount] = useState<number>(like_count);
const [currentViewCount] = useState<number>(view_count);
const { initArticle } = useArticleStore();
const { likeData, initLike } = useLikeStore();

const handleMouseEnter = (i: number) => {
setHoverIndex(i);
Expand All @@ -40,11 +38,13 @@ const ContentFooter = ({
setHoverIndex(null);
};

const nowLike = likeData?.find((item) => item.article_id === articleId);

const handleAddLike = async () => {
try {
const commentResponse = await axiosInstance.post(`/article/${articleId}/like/`);
const articleResponse = await articleApi.articleList();
initArticle(articleResponse.data);
const likeResponse = await articleApi.likeList();
initLike(likeResponse.data);

if (commentResponse.status === 200) {
const { like_count, message } = commentResponse.data;
Expand Down Expand Up @@ -73,7 +73,7 @@ const ContentFooter = ({

const data = [
{ icon: FaMessage, text: "댓글", count: commentsCount, onClick: () => commentsCountClick(articleId) },
{ icon: FaHeart, like: like, text: "좋아요", count: currentLikeCount, onClick: handleAddLike },
{ icon: FaHeart, like: nowLike?.like, text: "좋아요", count: currentLikeCount, onClick: handleAddLike },
{ icon: PiCursorClickFill, text: "조회수", count: currentViewCount },
];

Expand Down
8 changes: 4 additions & 4 deletions src/common/header/HeaderInfoLogged.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useLocation, useNavigate } from "react-router-dom";
import ProfileImage from "../profile/ProfileImage";
import { useArticleStore, useUserStore } from "../../config/store";
import { useLikeStore, useUserStore } from "../../config/store";
import Button from "../button/Button";
import { accountApi, articleApi, authApi, notificationApi } from "../../api";
import { useCallback, useEffect, useState } from "react";
Expand Down Expand Up @@ -54,7 +54,7 @@ const HeaderInfoLogged = () => {
const [isAdmin, setIsAdmin] = useState(false);
const location = useLocation();
const queryClient = useQueryClient();
const { initArticle } = useArticleStore();
const { initLike } = useLikeStore();

const openDetailModal = (article_id: number, notification_id: number) => {
setSelectedArticleId(article_id);
Expand Down Expand Up @@ -83,8 +83,8 @@ const HeaderInfoLogged = () => {

const handleLogout = async () => {
await authApi.userLogout();
const articleResponse = await articleApi.articleList();
initArticle(articleResponse.data);
const likeResponse = await articleApi.likeList();
initLike(likeResponse.data);
window.location.reload();
};

Expand Down
9 changes: 5 additions & 4 deletions src/common/modal/ModalLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import ButtonLogin from "../button/ButtonLogin";
import { articleApi, authApi } from "../../api";
import { useGoogleLogin } from "@react-oauth/google";
import { useNavigate } from "react-router-dom";
import { useArticleStore, useAuthStore } from "../../config/store";
import { useAuthStore, useLikeStore } from "../../config/store";

const ModalLogin = ({ onClose, isOpen, parent }: ModalProps) => {
const modalRef = useRef<HTMLDivElement>(null);
const nav = useNavigate();
const { setStatus } = useAuthStore();
const { initArticle } = useArticleStore();
const { initLike } = useLikeStore();
useEffect(() => {
const parentElement = document.querySelector("." + parent);
const headerElement = document.querySelector(".header");
Expand Down Expand Up @@ -60,8 +60,9 @@ const ModalLogin = ({ onClose, isOpen, parent }: ModalProps) => {
await authApi.userGoogleAccessTokenReceiver(token);
setStatus(true);
onClose();
const articleResponse = await articleApi.articleList();
initArticle(articleResponse.data);

const likeResponse = await articleApi.likeList();
initLike(likeResponse.data);
} catch (error) {
console.error("login failed", error);
}
Expand Down
16 changes: 14 additions & 2 deletions src/config/store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export const useUserStore = create<UserStore>((set) => ({
status: true,
exp: 0,
verified: false,
like: false,
},
otherUser: {
articles: [],
Expand All @@ -50,7 +49,6 @@ export const useUserStore = create<UserStore>((set) => ({
status: false,
exp: 0,
verified: true,
like: false,
},
initUser: (form: UserData) => set(() => ({ user: form })),
initOtherUser: (form: UserData) => set(() => ({ otherUser: form })),
Expand Down Expand Up @@ -83,6 +81,20 @@ export const useArticleStore = create<ArticleStore>((set) => ({
setTag: (tag: number) => set(() => ({ selectTag: tag })),
}));

interface Like {
like: boolean;
article_id: number;
}
interface LikeStore {
likeData: Like[] | null;
initLike: (form: Like[]) => void;
}

export const useLikeStore = create<LikeStore>((set) => ({
likeData: null,
initLike: (form: Like[]) => set(() => ({ likeData: form })),
}));

interface Image {
src: string[] | null;
id: string[] | null;
Expand Down
1 change: 0 additions & 1 deletion src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export interface AllArticle {
updated_at: string;
images: AllImages[];
like_count: number;
like: boolean;
tags: AllTags[];
thumbnail_image: string;
title: string;
Expand Down
12 changes: 9 additions & 3 deletions src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ProfileImage from "../common/profile/ProfileImage";
import Topic from "../common/topic/Topic";
import TrendingComment from "../common/trending/TrendingComment";
import TrendingContent from "../common/trending/TrendingContent";
import { useArticleStore, useUserStore } from "../config/store";
import { useArticleStore, useLikeStore, useUserStore } from "../config/store";
import { articleApi } from "../api";
import SkeletonContent from "../common/skeleton/SkeletonContent";
import Content from "../common/content/Content";
Expand All @@ -29,6 +29,7 @@ const HomePage = () => {
const [filterArticle, setFilterArticle] = useState<AllArticle[] | null>(null);
const navigate = useNavigate();
const location = useLocation();
const { initLike } = useLikeStore();
const articleIdFromURL = new URLSearchParams(location.search).get("article");
const searchFormURL = new URLSearchParams(location.search).get("search");
const editorFormURL = new URLSearchParams(location.search).get("editor");
Expand All @@ -38,6 +39,11 @@ const HomePage = () => {
initArticle(articleResponse.data);
}, [initArticle]);

const initLikes = useCallback(async () => {
const likeResponse = await articleApi.likeList();
initLike(likeResponse.data);
}, [initLike]);

const [isAlert, setIsAlert] = useState(false);
const [alertText, setAlertText] = useState<null | string>(null);

Expand Down Expand Up @@ -92,8 +98,9 @@ const HomePage = () => {
useEffect(() => {
if (!searchFormURL) {
initArticles();
initLikes();
}
}, [initArticles, searchFormURL]);
}, [initArticles, initLikes, searchFormURL]);

// 필터링을 위한 useMemo
const filteredArticles = useMemo(() => {
Expand Down Expand Up @@ -183,7 +190,6 @@ const HomePage = () => {
view_count={article.view_count}
like_count={article.like_count}
articleId={article.article_id}
like={article.like}
onAlert={alertHandler}
/>
</div>
Expand Down
9 changes: 5 additions & 4 deletions src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AxiosError } from "axios";
import { AnimatePresence, motion } from "framer-motion";
import { IoWarning } from "react-icons/io5";
import { articleApi } from "../api";
import { useArticleStore } from "../config/store";
import { useLikeStore } from "../config/store";

interface LoginData {
id: string;
Expand All @@ -32,7 +32,7 @@ const LoginPage = () => {
const navigate = useNavigate();
const [isAlert, setIsAlert] = useState(false);
const [alertMsg, setAlertMsg] = useState<null | string>(null);
const { initArticle } = useArticleStore();
const { initLike } = useLikeStore();

const alertHandler = (text: string) => {
setIsAlert(true);
Expand All @@ -44,8 +44,9 @@ const LoginPage = () => {
setIsSubmit(true);
try {
const response = await userLogin({ username: id, password: password });
const articleResponse = await articleApi.articleList();
initArticle(articleResponse.data);
const likeResponse = await articleApi.likeList();
initLike(likeResponse.data);

if (response.status === 200) {
setIsSubmit(false);
navigate("/");
Expand Down

0 comments on commit b1e5346

Please sign in to comment.