"use client";
import { useState, useMemo, useEffect } from "react";
import { useTranslation } from "@/i18n/navigation";
import type { ResourceData } from "@/app/lib/theme-data";
const PER_PAGE_MOBILE = 4;
const PER_PAGE_PC = 8;
const BREAKPOINT = 768;
function useIsPC() {
const [isPC, setIsPC] = useState(false);
useEffect(() => {
const mq = window.matchMedia(`(min-width: ${BREAKPOINT}px)`);
setIsPC(mq.matches);
const fn = () => setIsPC(mq.matches);
mq.addEventListener("change", fn);
return () => mq.removeEventListener("change", fn);
}, []);
return isPC;
}
/** 每页条数:H5=4,PC=8;总数不足则全显 */
function getPerPage(total: number, isPC: boolean): number {
const cap = isPC ? PER_PAGE_PC : PER_PAGE_MOBILE;
return total <= cap ? total : cap;
}
type ResourceNavigationProps = {
data: ResourceData;
};
export default function ResourceNavigation({ data }: ResourceNavigationProps) {
const { t } = useTranslation("community");
const isPC = useIsPC();
const firstCategoryId = data.pan.categories[0]?.id ?? "";
const [activePanCategory, setActivePanCategory] = useState(firstCategoryId);
const [booksPage, setBooksPage] = useState(0);
const [productsPage, setProductsPage] = useState(0);
const [toast, setToast] = useState(false);
const showUpdating = () => {
setToast(true);
setTimeout(() => setToast(false), 2000);
};
const activeCategory = data.pan.categories.find((c) => c.id === activePanCategory);
const booksPerPage = getPerPage(data.books.length, isPC);
const productsPerPage = getPerPage(data.products.length, isPC);
const booksTotalPages = Math.ceil(data.books.length / booksPerPage) || 1;
const productsTotalPages = Math.ceil(data.products.length / productsPerPage) || 1;
useEffect(() => {
setBooksPage((p) => Math.max(0, Math.min(p, booksTotalPages - 1)));
}, [booksTotalPages]);
useEffect(() => {
setProductsPage((p) => Math.max(0, Math.min(p, productsTotalPages - 1)));
}, [productsTotalPages]);
const paginatedBooks = useMemo(() => {
const start = booksPage * booksPerPage;
return data.books.slice(start, start + booksPerPage);
}, [data.books, booksPage, booksPerPage]);
const paginatedProducts = useMemo(() => {
const start = productsPage * productsPerPage;
return data.products.slice(start, start + productsPerPage);
}, [data.products, productsPage, productsPerPage]);
return (
{/* 图书 - 封面+书名,数量少则大封面,多则分页 */}
📚
{t("resourceSections.books")}
{data.books.length > 0 && (
({t("resourceSections.totalBooks").replace("{count}", String(data.books.length))})
)}
{paginatedBooks.map((book, i) => (
))}
{booksTotalPages > 1 && (
{booksPage + 1} / {booksTotalPages}
)}
{/* 商业数码 - 商品图+跳转电商 */}
🛒
{t("resourceSections.products")}
{data.products.length > 0 && (
({t("resourceSections.totalProducts").replace("{count}", String(data.products.length))})
)}
{paginatedProducts.map((product, i) => (
))}
{productsTotalPages > 1 && (
{productsPage + 1} / {productsTotalPages}
)}
{/* 网盘 - 分类 Tab */}
☁️
{t("resourceSections.pan")}
{data.pan.categories.map((cat) => (
))}
{toast && (
{t("updating")}
)}
);
}