import { ArticleDataType } from "@/types/article"; import { ProductDataType } from "@/types/products"; const BASE_URL = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:5000"; type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; type QueryValue = string | number | boolean | null | undefined; type QueryParams = Record; interface RequestOptions { method?: HttpMethod; params?: QueryParams; body?: TBody; signal?: AbortSignal; cache?: RequestCache; next?: NextFetchRequestConfig; } export interface ListParams extends QueryParams { limit?: number; // THÊM limit page?: number; offset?: number; q?: string; // tuỳ chọn (search) sort?: string; categoryId?: number | string; } function buildURL(path: string, params?: QueryParams) { const url = new URL(path, BASE_URL); if (params) { for (const [k, v] of Object.entries(params)) { if (Array.isArray(v)) { v.forEach((vv) => { if (vv !== undefined && vv !== null) url.searchParams.append(k, String(vv)); }); } else if (v !== undefined && v !== null) { url.searchParams.set(k, String(v)); } } } return url.toString(); } async function apiRequest( endpoint: string, options: RequestOptions = {} ): Promise { const { method = "GET", params, body, signal, cache = "no-store", next, } = options; const url = buildURL(endpoint, params); const res = await fetch(url, { method, headers: { "Content-Type": "application/json" }, body: body && method !== "GET" ? JSON.stringify(body) : undefined, signal, cache, next, }); if (!res.ok) { const msg = await res.text().catch(() => res.statusText); throw new Error(`API ${method} ${endpoint} failed: ${res.status} ${msg}`); } return res.json() as Promise; } // API cho bài viết export const fetchListArticles = (params?: ListParams) => apiRequest<{ list: ArticleDataType[]; total?: number }>("/article", { params, }); // GET /articleDetails?path=:slug export const fetchArticleDetail = (slug: string) => apiRequest("/articleDetails", { params: { path: slug }, }); // API cho công việc export const fetchListProduct = (params?: ListParams) => apiRequest<{ list: ProductDataType[]; total?: number }>("/product", { params, }); export const fetchProductDetail = (slug: string) => apiRequest("/productDetails", { params: { path: slug }, }); export const fetchProductsByCategoryId = ( categoryId: number | string, params?: Omit ) => fetchListProduct({ ...params, categoryId, });