diff --git a/app/src/pages/CategoryPage.jsx b/app/src/pages/CategoryPage.jsx new file mode 100644 index 0000000..cf831dc --- /dev/null +++ b/app/src/pages/CategoryPage.jsx @@ -0,0 +1,62 @@ +import { useState, useEffect } from 'react'; +import { TeknavData } from '../../teknav-data.js'; +import { useNav, EmptyState } from '../../teknav-ui.jsx'; +import { LazyDiagram } from '../../src/components/lazy-diagram.jsx'; +import { ArticleRow } from '../../teknav-articles.jsx'; +import { contentApi } from '../../src/lib/content-api.js'; + +export function CategoryPage({ slug }) { + const { navigate } = useNav(); + const [cat, setCat] = useState(() => TeknavData.categories.find(c => c.slug === slug)); + const [articles, setArticles] = useState(() => contentApi.fallbackArticles().filter(a => a.category === slug)); + + useEffect(() => { + let cancelled = false; + setCat(TeknavData.categories.find(c => c.slug === slug)); + setArticles(contentApi.fallbackArticles().filter(a => a.category === slug)); + Promise.all([ + contentApi.getCategory(slug).catch(() => null), + contentApi.listArticles({ category: slug, limit: 100 }).catch(() => null), + ]).then(([category, result]) => { + if (cancelled) return; + if (category) setCat({ ...(TeknavData.categories.find(c => c.slug === slug) ?? {}), ...category, id: category.slug }); + if (result?.items) setArticles(result.items); + }); + return () => { cancelled = true; }; + }, [slug]); + + if (!cat) return ; + + return ( +
+
+
+
+
دسته‌بندی
+

{cat.name}

+

{cat.description}

+
+ {[['تعداد مقاله', cat.articleCount], ['نویسنده فعال', cat.authorCount], ['میانگین زمان مطالعه', cat.avgReadTime + ' دقیقه']].map(([l, v]) => ( +
+
{v}
+
{l}
+
+ ))} +
+
+
+ +
+
+
+ +
+

مقاله‌های {cat.name} ({articles.length})

+ {articles.length === 0 ? : ( + articles.map((a, i) => ) + )} +
+ +
+ ); +}