Files
HKSingleParty/03_source/cms_backend/src/app/api/pagination/route.ts
louiscklaw b7cd25b614 build ok,
2025-06-15 11:28:24 +08:00

77 lines
2.6 KiB
TypeScript

import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
// ----------------------------------------------------------------------
export const runtime = 'edge';
const DEFAULT_PAGE = 1;
const DEFAULT_PER_PAGE = 10;
const TOTAL_PRODUCTS = 50;
const _products = Array.from({ length: TOTAL_PRODUCTS }, (_, index) => ({
id: `id-${index + 1}`,
name: `product-${index + 1}`,
category: (index % 2 && 'Accessories') || (index % 3 && 'Shoes') || 'Clothing',
}));
type Products = typeof _products;
/** **************************************
* Products with pagination and filters
*************************************** */
export async function GET(req: NextRequest) {
const { searchParams } = req.nextUrl;
const pageParam = searchParams.get('page') ?? `${DEFAULT_PAGE}`;
const perPageParam = searchParams.get('perPage') ?? `${DEFAULT_PER_PAGE}`;
const page = parseInt(pageParam, 10);
const perPage = parseInt(perPageParam, 10);
const searchQuery = searchParams.get('search')?.trim().toLowerCase() ?? '';
const category = searchParams.get('category')?.trim() ?? '';
try {
const filteredProducts = filterProducts(_products, searchQuery, category);
const paginatedProducts = paginateProducts(filteredProducts, page, perPage);
const totalPages = Math.ceil(filteredProducts.length / perPage);
const totalItems = filteredProducts.length;
logger('[Product] filtered-products', filteredProducts.length);
return response(
{
products: paginatedProducts,
totalPages,
totalItems,
categoryOptions: Array.from(new Set(_products.map(({ category: c_category }) => c_category))), // Remove duplicate categories
},
STATUS.OK
);
} catch (error) {
return handleError('Pagination - Get list of products', error);
}
}
// ----------------------------------------------------------------------
function paginateProducts(products: Products, page: number, perPage: number) {
const startIndex = (page - 1) * perPage;
const endIndex = startIndex + perPage;
return products.slice(startIndex, endIndex);
}
function filterProducts(products: Products, searchQuery: string, category: string) {
return products.filter(({ id, name, category: prodCategory }) => {
// Accept search by id or name
const matchesSearch = searchQuery ? id.includes(searchQuery) || name.toLowerCase().includes(searchQuery) : true;
const matchesCategory = category ? prodCategory === category : true;
return matchesSearch && matchesCategory;
});
}