From 43e7807034db67652bada00eee17a425d332b3f3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 13 Jul 2025 15:58:47 +0900 Subject: refactor(frontend): extract ArticleItem from ArticleList --- frontend/src/components/ArticleItem.tsx | 86 +++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 frontend/src/components/ArticleItem.tsx (limited to 'frontend/src/components/ArticleItem.tsx') diff --git a/frontend/src/components/ArticleItem.tsx b/frontend/src/components/ArticleItem.tsx new file mode 100644 index 0000000..e5a506f --- /dev/null +++ b/frontend/src/components/ArticleItem.tsx @@ -0,0 +1,86 @@ +import { faCheck, faCircle } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useMutation } from "urql"; +import type { + GetReadArticlesQuery, + GetUnreadArticlesQuery, +} from "../graphql/generated/graphql"; +import { + MarkArticleReadDocument, + MarkArticleUnreadDocument, +} from "../graphql/generated/graphql"; + +type Article = NonNullable< + | GetUnreadArticlesQuery["unreadArticles"] + | GetReadArticlesQuery["readArticles"] +>[0]; + +interface Props { + article: Article; + showReadStatus?: boolean; +} + +export function ArticleItem({ article, showReadStatus = true }: Props) { + const [, markArticleRead] = useMutation(MarkArticleReadDocument); + const [, markArticleUnread] = useMutation(MarkArticleUnreadDocument); + + const handleToggleRead = async ( + articleId: string, + isCurrentlyRead: boolean, + ) => { + if (isCurrentlyRead) { + await markArticleUnread({ id: articleId }); + } else { + await markArticleRead({ id: articleId }); + } + }; + + const handleArticleClick = async (article: Article) => { + // Open article in new tab and mark as read if it's unread + window.open(article.url, "_blank", "noreferrer"); + if (!article.isRead) { + await markArticleRead({ id: article.id }); + } + }; + + return ( +
+ {showReadStatus && ( + + )} +
+ +
+
+ ); +} -- cgit v1.2.3-70-g09d2