feat: add popular resources home section

This commit is contained in:
TerryM
2026-05-28 15:35:56 +08:00
parent 0e98428f64
commit 4b497380ee

View File

@@ -26,6 +26,8 @@ export function Home() {
const [rec, setRec] = useState<PostBackedResource[]>([]);
const [latest, setLatest] = useState<PostBackedResource[]>([]);
const [latestPosts, setLatestPosts] = useState<Post[]>([]);
const [popular, setPopular] = useState<PostBackedResource[]>([]);
const [popularPosts, setPopularPosts] = useState<Post[]>([]);
const [err, setErr] = useState<string | null>(null);
const recRowRef = useRef<HTMLDivElement>(null);
const categoryRowRef = useRef<HTMLDivElement>(null);
@@ -42,8 +44,9 @@ export function Home() {
getJSON<Category[]>(`/api/categories${catQ}`),
getJSON<{ items: Post[] }>(`/api/posts/recommended${postQ}&limit=12`),
getJSON<{ items: Post[] }>(`/api/posts/latest${postQ}&limit=8`),
getJSON<{ items: Post[] }>(`/api/posts${postQ}&sort=popular&limit=8`),
])
.then(([c, r, l]) => {
.then(([c, r, l, p]) => {
setCats(itemsOrEmpty(c));
setRec(
itemsOrEmpty(r.items).map((post) =>
@@ -57,6 +60,13 @@ export function Home() {
postToResource(post, lang, itemsOrEmpty(c)),
),
);
const popularItems = itemsOrEmpty(p.items);
setPopularPosts(popularItems);
setPopular(
popularItems.map((post) =>
postToResource(post, lang, itemsOrEmpty(c)),
),
);
})
.catch((e) => setErr(String(e)));
}, [lang]);
@@ -127,6 +137,7 @@ export function Home() {
};
const latestPlaceholderCount = Math.max(0, 5 - latest.length);
const popularPlaceholderCount = Math.max(0, 5 - popular.length);
const recommendedDotCount = Math.max(1, Math.min(4, rec.length || 4));
const activeRecommendedDot = Math.min(
recommendedDotCount - 1,
@@ -340,7 +351,31 @@ export function Home() {
</div>
</section>
<span id="popular" className="block scroll-mt-24" aria-hidden="true" />
<section id="popular" className="scroll-mt-24">
<div className="px-4 md:px-0">
<SectionHeader
title={t("popularSection")}
viewAllTo="/browse?sort=popular"
viewAllLabel={t("viewAll")}
/>
</div>
<div className="flex flex-col gap-3 md:hidden">
{popularPosts.slice(0, 4).map((post) => (
<MessageBubble key={post.id} post={post} />
))}
</div>
<div className="mt-7 hidden gap-3 min-[576px]:grid-cols-2 md:grid md:gap-4 lg:grid-cols-3 xl:grid-cols-5">
{popular.map((r) => (
<LatestUpdateRow key={r.id} r={r} iconKey={iconKeyForResource(r)} />
))}
{Array.from({ length: popularPlaceholderCount }).map((_, index) => (
<ComingSoonLatestUpdateRow
key={`popular-coming-soon-${index}`}
index={popular.length + index}
/>
))}
</div>
</section>
</div>
);
}