"use client";
import { useState, useMemo, useSyncExternalStore } from "react";
import { useTranslation } from "@/app/digital/i18n/navigation";
import type { ResourceData } from "@/app/digital/lib/theme-data";
const PER_PAGE_MOBILE = 4;
const PER_PAGE_PC = 8;
const BREAKPOINT = 768;
function useIsPC() {
return useSyncExternalStore(
(callback) => {
if (typeof window === "undefined") return () => {};
const mq = window.matchMedia(`(min-width: ${BREAKPOINT}px)`);
const fn = () => callback();
mq.addEventListener("change", fn);
return () => mq.removeEventListener("change", fn);
},
() =>
typeof window !== "undefined" &&
window.matchMedia(`(min-width: ${BREAKPOINT}px)`).matches,
() => false
);
}
/** 每页条数: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;
const safeBooksPage = Math.max(0, Math.min(booksPage, booksTotalPages - 1));
const safeProductsPage = Math.max(0, Math.min(productsPage, productsTotalPages - 1));
const paginatedBooks = useMemo(() => {
const start = safeBooksPage * booksPerPage;
return data.books.slice(start, start + booksPerPage);
}, [data.books, safeBooksPage, booksPerPage]);
const paginatedProducts = useMemo(() => {
const start = safeProductsPage * productsPerPage;
return data.products.slice(start, start + productsPerPage);
}, [data.products, safeProductsPage, productsPerPage]);
return (
{/* 图书 - 封面+书名,数量少则大封面,多则分页 */}
📚
{t("resourceSections.books")}
{data.books.length > 0 && (
({t("resourceSections.totalBooks").replace("{count}", String(data.books.length))})
)}
{paginatedBooks.map((book, i) => (
))}
{booksTotalPages > 1 && (
{safeBooksPage + 1} / {booksTotalPages}
)}
{/* 商业数码 - 商品图+跳转电商 */}
🛒
{t("resourceSections.products")}
{data.products.length > 0 && (
({t("resourceSections.totalProducts").replace("{count}", String(data.products.length))})
)}
{paginatedProducts.map((product, i) => (
))}
{productsTotalPages > 1 && (
{safeProductsPage + 1} / {productsTotalPages}
)}
{/* 网盘 - 分类 Tab */}
☁️
{t("resourceSections.pan")}
{data.pan.categories.map((cat) => (
))}
{toast && (
{t("updating")}
)}
);
}