fix: stick mobile footer nav to bottom

This commit is contained in:
TerryM
2026-05-28 16:19:21 +08:00
parent e0240f6217
commit 16b047ba04
3 changed files with 64 additions and 18 deletions

View File

@@ -51,6 +51,7 @@ export function Home() {
const [latestPosts, setLatestPosts] = useState<Post[]>([]);
const [popular, setPopular] = useState<PostBackedResource[]>([]);
const [popularPosts, setPopularPosts] = useState<Post[]>([]);
const [categoryUnavailableOpen, setCategoryUnavailableOpen] = useState(false);
const [err, setErr] = useState<string | null>(null);
const recRowRef = useRef<HTMLDivElement>(null);
const categoryRowRef = useRef<HTMLDivElement>(null);
@@ -66,9 +67,9 @@ export function Home() {
Promise.all([
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/latest${postQ}&limit=5`),
getJSON<{ items: Post[] }>(
`/api/posts${postQ}&sort=popular&limit=8`,
`/api/posts${postQ}&sort=popular&limit=5`,
).catch((): { items: Post[] } => ({ items: [] })),
])
.then(([c, r, l, p]) => {
@@ -206,7 +207,7 @@ export function Home() {
<div className="px-4 md:px-0">
<SectionHeader
title={t("categorySection")}
viewAllTo="/browse"
viewAllTo="/categories"
viewAllLabel={t("viewAll")}
/>
</div>
@@ -224,9 +225,11 @@ export function Home() {
className="grid w-full shrink-0 snap-start grid-cols-3 gap-2 px-4"
>
{page.map((c) => (
<div
<button
key={c.id}
className="flex h-[88px] min-w-0 cursor-default flex-col items-center justify-center gap-2 rounded-xl border border-[#27292E] bg-[#1D1E23] px-4 py-3 text-center"
type="button"
onClick={() => setCategoryUnavailableOpen(true)}
className="flex h-[88px] min-w-0 flex-col items-center justify-center gap-2 rounded-xl border border-[#27292E] bg-[#1D1E23] px-4 py-3 text-center outline-none transition hover:border-ark-gold/55 hover:bg-[#252630] focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
>
<CategoryIcon
iconKey={c.iconKey}
@@ -236,7 +239,7 @@ export function Home() {
<div className="w-full truncate text-[13px] font-medium leading-[19.5px] text-white">
{cleanCategoryDisplayName(c.name)}
</div>
</div>
</button>
))}
</div>
))}
@@ -275,9 +278,11 @@ export function Home() {
<div className="mt-7 hidden grid-cols-3 gap-3 min-[440px]:gap-3.5 md:grid md:grid-cols-5 md:gap-3 lg:grid-cols-6 xl:grid-cols-7 xl:gap-4">
{figmaOrderedCategories.map((c) => (
<div
<button
key={c.id}
className="flex h-[88px] min-w-0 cursor-default flex-col items-center justify-center gap-2 rounded-xl border border-[#27292E] bg-[#1D1E23] px-4 py-3 text-center"
type="button"
onClick={() => setCategoryUnavailableOpen(true)}
className="flex h-[88px] min-w-0 flex-col items-center justify-center gap-2 rounded-xl border border-[#27292E] bg-[#1D1E23] px-4 py-3 text-center outline-none transition hover:border-ark-gold/55 hover:bg-[#252630] focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
>
<CategoryIcon
iconKey={c.iconKey}
@@ -287,7 +292,7 @@ export function Home() {
<div className="w-full text-center text-[13px] font-medium leading-[19.5px] text-white line-clamp-2">
{cleanCategoryDisplayName(c.name)}
</div>
</div>
</button>
))}
</div>
</section>
@@ -296,7 +301,7 @@ export function Home() {
<div className="px-4 md:px-0">
<SectionHeader
title={t("officialSection")}
viewAllTo="/browse?sort=recommended"
viewAllTo="/official-recommendations"
viewAllLabel={t("viewAll")}
/>
</div>
@@ -366,7 +371,7 @@ export function Home() {
/>
</div>
<div className="flex flex-col gap-3 md:hidden">
{latestPosts.slice(0, 4).map((post) => (
{latestPosts.slice(0, 5).map((post) => (
<MessageBubble key={post.id} post={post} />
))}
</div>
@@ -392,7 +397,7 @@ export function Home() {
/>
</div>
<div className="flex flex-col gap-3 md:hidden">
{popularPosts.slice(0, 4).map((post) => (
{popularPosts.slice(0, 5).map((post) => (
<MessageBubble key={post.id} post={post} />
))}
</div>
@@ -408,6 +413,38 @@ export function Home() {
))}
</div>
</section>
{categoryUnavailableOpen ? (
<div
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/70 px-6 backdrop-blur-sm"
role="dialog"
aria-modal="true"
aria-labelledby="category-unavailable-title"
onClick={() => setCategoryUnavailableOpen(false)}
>
<div
className="w-full max-w-[320px] rounded-2xl border border-[#27292E] bg-[#1D1E23] p-5 text-center shadow-2xl"
onClick={(event) => event.stopPropagation()}
>
<div
id="category-unavailable-title"
className="text-xl font-bold text-white"
>
{t("featureUnavailable")}
</div>
<p className="mt-2 text-sm leading-6 text-[#A8A9AE]">
{t("featureUnavailableDesc")}
</p>
<button
type="button"
onClick={() => setCategoryUnavailableOpen(false)}
className="mt-5 h-10 w-full rounded-full bg-ark-gold text-sm font-semibold text-black transition hover:bg-ark-gold2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-[#1D1E23]"
>
{t("confirm")}
</button>
</div>
</div>
) : null}
</div>
);
}