Files
project_it207_client/hooks/useWishlist.ts
2025-11-19 14:34:05 +07:00

150 lines
4.5 KiB
TypeScript

import { useState, useCallback, useEffect } from 'react';
import { wishlistApi, WishlistProduct } from '../services/wishlistApi ';
interface UseWishlistState {
wishlists: WishlistProduct[];
loading: boolean;
error: string | null;
totalElements: number;
totalPages: number;
currentPage: number;
wishlistCount: number;
}
export const useWishlist = () => {
const [state, setState] = useState<UseWishlistState>({
wishlists: [],
loading: false,
error: null,
totalElements: 0,
totalPages: 0,
currentPage: 0,
wishlistCount: 0,
});
/**
* Lấy danh sách ưu thích
*/
const fetchWishlists = useCallback(
async (page: number = 0, size: number = 10, sortBy: string = 'createdAt') => {
setState((prev) => ({ ...prev, loading: true, error: null }));
try {
const response = await wishlistApi.getWishlists(page, size, sortBy);
if (response.success && response.data) {
// Map API response đến format chính xác
const wishlists = (response.data.wishlists || []).map((item: any) => ({
id: item.wishlistId || item.id,
wishlistId: item.wishlistId || item.id,
productId: item.productId,
productName: item.productName,
productImage: item.productImage,
price: item.price,
description: item.description,
addedAt: item.addedAt,
}));
setState((prev) => ({
...prev,
wishlists: response.data?.wishlists || [],
totalElements: response.data?.totalElements ?? 0,
totalPages: response.data?.totalPages ?? 0,
currentPage: response.data?.currentPage ?? 0,
loading: false,
}));
} else {
throw new Error(response.message || 'Không thể lấy danh sách ưu thích');
}
} catch (error) {
setState((prev) => ({
...prev,
error: error instanceof Error ? error.message : 'Lỗi không xác định',
loading: false,
}));
}
},
[]
);
/**
* Thêm sản phẩm vào ưu thích
*/
const addToWishlist = useCallback(async (productId: number) => {
try {
const response = await wishlistApi.addToWishlist(productId);
if (response.success && response.data) {
setState((prev) => ({
...prev,
wishlists: [response.data!, ...prev.wishlists],
totalElements: prev.totalElements + 1,
wishlistCount: prev.wishlistCount + 1,
}));
return { success: true, message: response.message };
} else {
throw new Error(response.message || 'Không thể thêm vào ưu thích');
}
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Lỗi không xác định';
setState((prev) => ({ ...prev, error: errorMessage }));
return { success: false, message: errorMessage };
}
}, []);
/**
* Xóa sản phẩm khỏi ưu thích
*/
const removeFromWishlist = useCallback(async (productId: number) => {
try {
const response = await wishlistApi.removeFromWishlist(productId);
if (response.success) {
setState((prev) => ({
...prev,
wishlists: prev.wishlists.filter((w) => w.productId !== productId),
totalElements: Math.max(0, prev.totalElements - 1),
wishlistCount: Math.max(0, prev.wishlistCount - 1),
}));
return { success: true, message: response.message };
} else {
throw new Error(response.message || 'Không thể xóa khỏi ưu thích');
}
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Lỗi không xác định';
setState((prev) => ({ ...prev, error: errorMessage }));
return { success: false, message: errorMessage };
}
}, []);
/**
* Lấy số lượng ưu thích
*/
const fetchWishlistCount = useCallback(async () => {
try {
const response = await wishlistApi.getWishlistCount();
if (response.success && response.data !== undefined) {
setState((prev) => ({
...prev,
wishlistCount: response.data!,
}));
}
} catch (error) {
console.error('Error fetching wishlist count:', error);
}
}, []);
/**
* Xóa lỗi
*/
const clearError = useCallback(() => {
setState((prev) => ({ ...prev, error: null }));
}, []);
return {
...state,
fetchWishlists,
addToWishlist,
removeFromWishlist,
fetchWishlistCount,
clearError,
};
};