fix(admin): add pagination to /admin/orders with prev/next and total counter
This commit is contained in:
@@ -65,6 +65,9 @@ export default function OrdersPage() {
|
||||
const [filterState, setFilterState] = useState('');
|
||||
const [search, setSearch] = useState('');
|
||||
const [debouncedSearch, setDebouncedSearch] = useState('');
|
||||
const [total, setTotal] = useState(0);
|
||||
const [offset, setOffset] = useState(0);
|
||||
const limit = 20;
|
||||
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => setDebouncedSearch(search), 400);
|
||||
@@ -78,14 +81,21 @@ export default function OrdersPage() {
|
||||
const data = await ordersApi.list({
|
||||
status: filterState || undefined,
|
||||
q: debouncedSearch || undefined,
|
||||
limit: 20,
|
||||
limit,
|
||||
offset,
|
||||
});
|
||||
setOrders(data.items);
|
||||
setTotal(data.total);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Error al cargar');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [filterState, debouncedSearch, offset]);
|
||||
|
||||
// Reset to first page when filters change
|
||||
useEffect(() => {
|
||||
setOffset(0);
|
||||
}, [filterState, debouncedSearch]);
|
||||
|
||||
useEffect(() => { load(); }, [load]);
|
||||
@@ -95,7 +105,7 @@ export default function OrdersPage() {
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">Pedidos</h1>
|
||||
<p className="text-sm text-gray-500 mt-0.5">{orders?.length ?? 0} pedidos</p>
|
||||
<p className="text-sm text-gray-500 mt-0.5">{total} pedidos</p>
|
||||
</div>
|
||||
|
||||
{/* Filters */}
|
||||
@@ -206,6 +216,32 @@ export default function OrdersPage() {
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
{/* Pagination footer */}
|
||||
{!loading && !error && orders && orders.length > 0 && (
|
||||
<div className="flex items-center justify-between px-4 py-3 border-t border-gray-200 bg-gray-50">
|
||||
<p className="text-xs text-gray-500">
|
||||
Mostrando {offset + 1}–{Math.min(offset + limit, total)} de {total}
|
||||
</p>
|
||||
<div className="flex gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOffset(Math.max(0, offset - limit))}
|
||||
disabled={offset === 0}
|
||||
className="px-3 py-1.5 text-xs border border-gray-300 rounded-lg disabled:opacity-40 hover:bg-white"
|
||||
>
|
||||
← Anterior
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOffset(offset + limit)}
|
||||
disabled={offset + limit >= total}
|
||||
className="px-3 py-1.5 text-xs border border-gray-300 rounded-lg disabled:opacity-40 hover:bg-white"
|
||||
>
|
||||
Siguiente →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user