aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/ArticleList.tsx
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-07-13 15:58:47 +0900
committernsfisis <nsfisis@gmail.com>2025-07-13 15:58:47 +0900
commit43e7807034db67652bada00eee17a425d332b3f3 (patch)
treeef6a8b1271154011690cdb15406c52bd2f699df8 /frontend/src/components/ArticleList.tsx
parent4082bdf34beda81815a41c8ce71086bed1c401cf (diff)
downloadfeedaka-43e7807034db67652bada00eee17a425d332b3f3.tar.gz
feedaka-43e7807034db67652bada00eee17a425d332b3f3.tar.zst
feedaka-43e7807034db67652bada00eee17a425d332b3f3.zip
refactor(frontend): extract ArticleItem from ArticleList
Diffstat (limited to 'frontend/src/components/ArticleList.tsx')
-rw-r--r--frontend/src/components/ArticleList.tsx82
1 files changed, 5 insertions, 77 deletions
diff --git a/frontend/src/components/ArticleList.tsx b/frontend/src/components/ArticleList.tsx
index ee7b187..5d508c5 100644
--- a/frontend/src/components/ArticleList.tsx
+++ b/frontend/src/components/ArticleList.tsx
@@ -1,18 +1,8 @@
-import {
- faCheck,
- faCircle,
- faExternalLinkAlt,
-} 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";
+import { ArticleItem } from "./ArticleItem";
interface Props {
articles: NonNullable<
@@ -23,28 +13,6 @@ interface Props {
}
export function ArticleList({ articles, 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: (typeof articles)[0]) => {
- // Open article in new tab and mark as read if it's unread
- window.open(article.url, "_blank");
- if (!article.isRead) {
- await markArticleRead({ id: article.id });
- }
- };
-
if (articles.length === 0) {
return (
<div className="p-4 text-center text-gray-500">No articles found.</div>
@@ -83,51 +51,11 @@ export function ArticleList({ articles, showReadStatus = true }: Props) {
</h3>
<div className="space-y-1">
{feedArticles.map((article) => (
- <div
+ <ArticleItem
key={article.id}
- className={`group flex items-center gap-3 rounded-lg border p-3 hover:bg-gray-50 ${
- article.isRead
- ? "border-gray-200 bg-white"
- : "border-blue-200 bg-blue-50"
- }`}
- >
- {showReadStatus && (
- <button
- type="button"
- onClick={() => handleToggleRead(article.id, article.isRead)}
- className={`flex-shrink-0 rounded p-1 transition-colors ${
- article.isRead
- ? "text-gray-400 hover:text-gray-600"
- : "text-blue-600 hover:text-blue-700"
- }`}
- title={article.isRead ? "Mark as unread" : "Mark as read"}
- >
- <FontAwesomeIcon
- icon={article.isRead ? faCheck : faCircle}
- className="w-4 h-4"
- />
- </button>
- )}
- <div className="flex-1 min-w-0">
- <button
- type="button"
- onClick={() => handleArticleClick(article)}
- className={`text-left w-full group-hover:text-blue-600 transition-colors ${
- article.isRead
- ? "text-gray-700"
- : "text-gray-900 font-medium"
- }`}
- >
- <div className="flex items-center gap-2">
- <span className="truncate">{article.title}</span>
- <FontAwesomeIcon
- icon={faExternalLinkAlt}
- className="w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0"
- />
- </div>
- </button>
- </div>
- </div>
+ article={article}
+ showReadStatus={showReadStatus}
+ />
))}
</div>
</div>