import { API_CONFIG } from '../constants/Config'; const API_URL = API_CONFIG.BASE_URL; export interface ProductResponse { productId: number; productName: string; description: string; price: number; stockQuantity: number; imageUrl: string; categoryId: number; categoryName: string; createdAt: string; updatedAt: string; } export interface ProductListResponse { products: ProductResponse[]; currentPage: number; totalItems: number; totalPages: number; hasNext: boolean; hasPrevious: boolean; } class ProductService { /** * Lấy danh sách tất cả sản phẩm */ async getAllProducts( page: number = 0, size: number = 10, sortBy: string = 'productId', sortDir: 'asc' | 'desc' = 'asc' ): Promise { try { const params = new URLSearchParams({ page: page.toString(), size: size.toString(), sortBy, sortDir, }); const url = `${API_URL}/products?${params}`; console.log('Fetching products from:', url); const response = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, }); if (!response.ok) { let errorMessage = `Failed to fetch products: ${response.status} ${response.statusText}`; try { const errorData = await response.json(); errorMessage = errorData.message || errorData.error || errorMessage; } catch { // If response is not JSON, use the status text const text = await response.text().catch(() => ''); errorMessage = text || errorMessage; } console.error('API Error:', { status: response.status, statusText: response.statusText, url, }); throw new Error(errorMessage); } const data = await response.json(); return data; } catch (error) { if (error instanceof TypeError && error.message.includes('fetch')) { console.error('Network error - API may be unreachable:', error); throw new Error('Không thể kết nối đến server. Vui lòng kiểm tra kết nối mạng.'); } console.error('Error fetching products:', error); throw error; } } /** * Lấy chi tiết sản phẩm theo ID */ async getProductById(id: number): Promise { try { const response = await fetch(`${API_URL}/products/${id}`); if (!response.ok) { throw new Error('Product not found'); } return await response.json(); } catch (error) { console.error('Error fetching product:', error); throw error; } } /** * Lấy sản phẩm theo category */ async getProductsByCategory( categoryId: number, page: number = 0, size: number = 10, sortBy: string = 'productId', sortDir: 'asc' | 'desc' = 'asc' ): Promise { try { const params = new URLSearchParams({ page: page.toString(), size: size.toString(), sortBy, sortDir, }); const response = await fetch(`${API_URL}/products/category/${categoryId}?${params}`); if (!response.ok) { throw new Error('Failed to fetch products by category'); } return await response.json(); } catch (error) { console.error('Error fetching products by category:', error); throw error; } } /** * Tìm kiếm sản phẩm */ async searchProducts( keyword: string, page: number = 0, size: number = 10, sortBy: string = 'productId', sortDir: 'asc' | 'desc' = 'asc' ): Promise { try { const params = new URLSearchParams({ keyword, page: page.toString(), size: size.toString(), sortBy, sortDir, }); const response = await fetch(`${API_URL}/products/search?${params}`); if (!response.ok) { throw new Error('Failed to search products'); } return await response.json(); } catch (error) { console.error('Error searching products:', error); throw error; } } /** * Lấy sản phẩm còn hàng */ async getAvailableProducts( page: number = 0, size: number = 10, sortBy: string = 'productId', sortDir: 'asc' | 'desc' = 'asc' ): Promise { try { const params = new URLSearchParams({ page: page.toString(), size: size.toString(), sortBy, sortDir, }); const response = await fetch(`${API_URL}/products/available?${params}`); if (!response.ok) { throw new Error('Failed to fetch available products'); } return await response.json(); } catch (error) { console.error('Error fetching available products:', error); throw error; } } } export default new ProductService();