diff --git a/frontend/components/article/ArticleMeta.tsx b/frontend/components/article/ArticleMeta.tsx index 450795e86..f51ed9a49 100644 --- a/frontend/components/article/ArticleMeta.tsx +++ b/frontend/components/article/ArticleMeta.tsx @@ -1,10 +1,48 @@ import React from "react"; +import Router from "next/router"; +import useSWR, { trigger } from "swr"; import ArticleActions from "./ArticleActions"; import CustomImage from "../common/CustomImage"; import CustomLink from "../common/CustomLink"; +import ArticleAPI from "../../lib/api/article"; +import checkLogin from "../../lib/utils/checkLogin"; +import { SERVER_BASE_URL } from "../../lib/utils/constant"; +import storage from "../../lib/utils/storage"; + +const BOOKMARKED_CLASS = "btn btn-sm btn-primary"; +const NOT_BOOKMARKED_CLASS = "btn btn-sm btn-outline-primary"; const ArticleMeta = ({ article }) => { + const { data: currentUser } = useSWR("user", storage); + const isLoggedIn = checkLogin(currentUser); + + const [bookmarked, setBookmarked] = React.useState(article?.bookmarked || false); + + React.useEffect(() => { + setBookmarked(article?.bookmarked || false); + }, [article?.bookmarked]); + + const handleBookmark = async () => { + if (!isLoggedIn) { + Router.push(`/user/login`); + return; + } + + try { + if (bookmarked) { + setBookmarked(false); + await ArticleAPI.unbookmark(article.slug, currentUser?.token); + } else { + setBookmarked(true); + await ArticleAPI.bookmark(article.slug, currentUser?.token); + } + trigger(`${SERVER_BASE_URL}/articles/${article.slug}`); + } catch (error) { + setBookmarked(bookmarked); + } + }; + if (!article) return; return ( @@ -30,6 +68,14 @@ const ArticleMeta = ({ article }) => { + + ); }; diff --git a/frontend/components/article/ArticlePreview.tsx b/frontend/components/article/ArticlePreview.tsx index 266853203..818da69fc 100644 --- a/frontend/components/article/ArticlePreview.tsx +++ b/frontend/components/article/ArticlePreview.tsx @@ -8,11 +8,14 @@ import CustomLink from "../common/CustomLink"; import CustomImage from "../common/CustomImage"; import { usePageDispatch } from "../../lib/context/PageContext"; import checkLogin from "../../lib/utils/checkLogin"; +import ArticleAPI from "../../lib/api/article"; import { SERVER_BASE_URL } from "../../lib/utils/constant"; import storage from "../../lib/utils/storage"; const FAVORITED_CLASS = "btn btn-sm btn-primary"; const NOT_FAVORITED_CLASS = "btn btn-sm btn-outline-primary"; +const BOOKMARKED_CLASS = "btn btn-sm btn-primary"; +const NOT_BOOKMARKED_CLASS = "btn btn-sm btn-outline-primary"; const ArticlePreview = ({ article }) => { const setPage = usePageDispatch(); @@ -24,6 +27,31 @@ const ArticlePreview = ({ article }) => { const { data: currentUser } = useSWR("user", storage); const isLoggedIn = checkLogin(currentUser); + const handleClickBookmark = async (slug) => { + if (!isLoggedIn) { + Router.push(`/user/login`); + return; + } + + setPreview({ + ...preview, + bookmarked: !preview.bookmarked, + }); + + try { + if (preview.bookmarked) { + await ArticleAPI.unbookmark(slug, currentUser?.token); + } else { + await ArticleAPI.bookmark(slug, currentUser?.token); + } + } catch (error) { + setPreview({ + ...preview, + bookmarked: preview.bookmarked, + }); + } + }; + const handleClickFavorite = async (slug) => { if (!isLoggedIn) { Router.push(`/user/login`); @@ -96,6 +124,15 @@ const ArticlePreview = ({ article }) => {
+