feat: 分页组件统一封装 + 移动端无限滚动

- 新增 PaginationBar 组件,支持 isDark / loading / 页码导航 / 每页大小切换
- 重写 pay/orders/page.tsx 使用 PaginationBar,summary 来自 API groupBy 全量统计
- admin/page.tsx 替换内联分页 UI 为 PaginationBar
- MobileOrderList 支持无限滚动:IntersectionObserver 哨兵 + hasMore/loadingMore props
- pay/page.tsx 新增 loadMoreOrders(append 模式),初始化/刷新时重置分页状态
This commit is contained in:
erio
2026-03-01 20:12:32 +08:00
parent 292c14b882
commit b4eebb0b1b
5 changed files with 251 additions and 194 deletions

View File

@@ -4,6 +4,7 @@ import { useSearchParams } from 'next/navigation';
import { useState, useEffect, useCallback, Suspense } from 'react';
import OrderTable from '@/components/admin/OrderTable';
import OrderDetail from '@/components/admin/OrderDetail';
import PaginationBar from '@/components/PaginationBar';
interface AdminOrder {
id: string;
@@ -198,60 +199,15 @@ function AdminContent() {
)}
</div>
{/* Pagination */}
<div className="mt-4 flex flex-wrap items-center justify-between gap-3 text-sm text-gray-500">
<div className="flex items-center gap-2">
<span> {total} </span>
{[20, 50, 100].map((s) => (
<button
key={s}
onClick={() => { setPageSize(s); setPage(1); }}
className={`rounded border px-2.5 py-1 text-xs font-medium transition-colors ${
pageSize === s
? 'border-blue-500 bg-blue-50 text-blue-700'
: 'border-gray-300 text-gray-600 hover:bg-gray-100'
}`}
>
{s}
</button>
))}
</div>
{totalPages > 1 && (
<div className="flex items-center gap-1.5">
<button
onClick={() => setPage(1)}
disabled={page <= 1}
className="rounded border px-2.5 py-1 disabled:opacity-40 hover:bg-gray-100"
>
««
</button>
<button
onClick={() => setPage((p) => Math.max(1, p - 1))}
disabled={page <= 1}
className="rounded border px-3 py-1 disabled:opacity-40 hover:bg-gray-100"
>
</button>
<span className="px-3 py-1">
{page} / {totalPages}
</span>
<button
onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
disabled={page >= totalPages}
className="rounded border px-3 py-1 disabled:opacity-40 hover:bg-gray-100"
>
</button>
<button
onClick={() => setPage(totalPages)}
disabled={page >= totalPages}
className="rounded border px-2.5 py-1 disabled:opacity-40 hover:bg-gray-100"
>
»»
</button>
</div>
)}
</div>
<PaginationBar
page={page}
totalPages={totalPages}
total={total}
pageSize={pageSize}
loading={loading}
onPageChange={(p) => setPage(p)}
onPageSizeChange={(s) => { setPageSize(s); setPage(1); }}
/>
{/* Order Detail */}
{detailOrder && <OrderDetail order={detailOrder} onClose={() => setDetailOrder(null)} />}