refactor(ui): rename topbar to boardsbar and add desktop footer for board, thread, and catalog

This commit is contained in:
plebeius
2026-02-23 16:47:51 +08:00
parent a7721fc252
commit 4433834c1c
39 changed files with 672 additions and 294 deletions
@@ -34,3 +34,21 @@
font-weight: bold;
color: var(--button-desktop-text-color-hover);
}
/* Footer-style compact pagination (layout in footer-first-row.module.css) */
.footerPageLink {
padding: 2px 6px;
font-size: 12px;
text-decoration: var(--button-text-decoration);
color: var(--button-desktop-text-color);
}
.footerPageLink:hover {
color: var(--button-desktop-text-color-hover);
text-decoration: var(--button-text-decoration);
}
.footerPageCurrent {
font-weight: bold;
color: var(--button-desktop-text-color-hover);
}
@@ -1,24 +1,75 @@
import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import StyleSelector from '../style-selector/style-selector';
import footerStyles from '../footer-first-row/footer-first-row.module.css';
import styles from './board-pagination.module.css';
export interface BoardPaginationProps {
basePath: string;
currentPage: number;
totalPages: number;
/** When true, renders compact footer-style row with [1] [2] ... [10] Next Catalog + Style select */
footerStyle?: boolean;
}
const BoardPagination = ({ basePath, currentPage, totalPages }: BoardPaginationProps) => {
const BoardPagination = ({ basePath, currentPage, totalPages, footerStyle = false }: BoardPaginationProps) => {
const { t } = useTranslation();
const pageHref = (page: number) => (page === 1 ? basePath : `${basePath}/${page}`);
const prevHref = currentPage > 1 ? pageHref(currentPage - 1) : undefined;
const nextHref = currentPage < totalPages ? pageHref(currentPage + 1) : undefined;
const catalogHref = `${basePath}/catalog`;
if (totalPages <= 1) {
if (totalPages <= 1 && !footerStyle) {
return null;
}
if (footerStyle) {
const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1);
const ellipsisThreshold = 7;
const showEllipsis = totalPages > ellipsisThreshold;
const visiblePages = showEllipsis ? [1, 2, currentPage, totalPages].filter((p, i, arr) => arr.indexOf(p) === i).sort((a, b) => a - b) : pageNumbers;
return (
<div className={footerStyles.footerRow}>
<div className={footerStyles.footerLeft}>
{visiblePages.map((page, idx) => {
const isCurrent = page === currentPage;
const prevPage = visiblePages[idx - 1];
const showLeadingEllipsis = showEllipsis && prevPage !== undefined && page - prevPage > 1;
return (
<span key={page}>
{showLeadingEllipsis && <span> ... </span>}
{isCurrent ? (
<span className={styles.footerPageCurrent}>[{page}]</span>
) : (
<Link to={pageHref(page)} className={styles.footerPageLink}>
[{page}]
</Link>
)}
</span>
);
})}
{nextHref && (
<>
{' '}
<Link to={nextHref} className={styles.footerPageLink}>
{t('next')}
</Link>
</>
)}{' '}
<Link to={catalogHref} className={styles.footerPageLink}>
{t('catalog')}
</Link>
</div>
<div className={footerStyles.footerRight}>
<span className={footerStyles.styleLabel}>{t('style')}:</span>
<StyleSelector />
</div>
</div>
);
}
const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1);
return (