feat: link nav to home sections
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { ChevronRight } from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { getJSON, itemsOrEmpty, type Category } from "../../api";
|
||||
import { CategoryIcon } from "../../components/CategoryIcon";
|
||||
@@ -44,10 +44,13 @@ function figmaCategoryRank(category: Category): number {
|
||||
|
||||
export function Home() {
|
||||
const { t, lang } = useI18n();
|
||||
const { hash } = useLocation();
|
||||
const [cats, setCats] = useState<Category[]>([]);
|
||||
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);
|
||||
@@ -64,8 +67,11 @@ 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`,
|
||||
).catch((): { items: Post[] } => ({ items: [] })),
|
||||
])
|
||||
.then(([c, r, l]) => {
|
||||
.then(([c, r, l, p]) => {
|
||||
setCats(itemsOrEmpty(c));
|
||||
setRec(
|
||||
itemsOrEmpty(r.items).map((post) =>
|
||||
@@ -79,6 +85,13 @@ export function Home() {
|
||||
postToResource(post, lang, itemsOrEmpty(c)),
|
||||
),
|
||||
);
|
||||
const popularItems = itemsOrEmpty<Post>(p.items);
|
||||
setPopularPosts(popularItems);
|
||||
setPopular(
|
||||
popularItems.map((post) =>
|
||||
postToResource(post, lang, itemsOrEmpty(c)),
|
||||
),
|
||||
);
|
||||
})
|
||||
.catch((e) => setErr(String(e)));
|
||||
}, [lang]);
|
||||
@@ -152,7 +165,18 @@ export function Home() {
|
||||
recRowRef.current?.scrollBy({ left: dir * 280, behavior: "smooth" });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!hash) return;
|
||||
const id = hash.slice(1);
|
||||
if (!id) return;
|
||||
const frame = window.requestAnimationFrame(() => {
|
||||
document.getElementById(id)?.scrollIntoView({ block: "start" });
|
||||
});
|
||||
return () => window.cancelAnimationFrame(frame);
|
||||
}, [hash, cats.length, rec.length, latest.length, popular.length]);
|
||||
|
||||
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,
|
||||
@@ -356,7 +380,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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user