import { useState } from "react"; import type { components } from "../api/generated"; import { ArticleItem } from "./ArticleItem"; type Article = components["schemas"]["Article"]; interface Props { articles: Article[]; isReadView?: boolean; isSingleFeed?: boolean; hasNextPage?: boolean; loadingMore?: boolean; onLoadMore?: () => void; } export function ArticleList({ articles, isReadView, isSingleFeed, hasNextPage, loadingMore, onLoadMore, }: Props) { const [hiddenArticleIds, setHiddenArticleIds] = useState>( new Set(), ); const handleArticleReadChange = (articleId: string, isRead: boolean) => { if (isReadView !== isRead) { setHiddenArticleIds((prev) => new Set(prev).add(articleId)); } }; const visibleArticles = articles.filter( (article) => !hiddenArticleIds.has(article.id), ); if (visibleArticles.length === 0) { return (

No articles found.

); } if (isSingleFeed) { return (
{visibleArticles.map((article) => ( ))}
); } // Group articles by feed const articlesByFeed = visibleArticles.reduce( (acc, article) => { const feedId = article.feed.id; if (!acc[feedId]) { acc[feedId] = { feed: article.feed, articles: [], }; } acc[feedId].articles.push(article); return acc; }, {} as Record< string, { feed: { id: string; title: string }; articles: Article[] } >, ); return (
{Object.values(articlesByFeed).map(({ feed, articles: feedArticles }) => (

{feed.title} {feedArticles.length} article {feedArticles.length !== 1 ? "s" : ""}

{feedArticles.map((article) => ( ))}
))}
); } function LoadMoreButton({ hasNextPage, loadingMore, onLoadMore, }: { hasNextPage?: boolean; loadingMore?: boolean; onLoadMore?: () => void; }) { if (!hasNextPage || !onLoadMore) return null; return (
); }