198 lines
4.9 KiB
TypeScript
198 lines
4.9 KiB
TypeScript
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<ProductListResponse> {
|
|
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<ProductResponse> {
|
|
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<ProductListResponse> {
|
|
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<ProductListResponse> {
|
|
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<ProductListResponse> {
|
|
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(); |