2026-01-14 17:31:59 +07:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import { useEffect, useState, useCallback } from 'react';
|
|
|
|
|
import {
|
2026-01-15 17:30:04 +07:00
|
|
|
getCartItems,
|
2026-01-14 17:31:59 +07:00
|
|
|
addProductToCart,
|
|
|
|
|
removeProductFromCart,
|
|
|
|
|
clearCart,
|
2026-01-15 17:30:04 +07:00
|
|
|
increaseQuantity,
|
|
|
|
|
decreaseQuantity,
|
|
|
|
|
updateQuantity,
|
|
|
|
|
getProductQuantity,
|
|
|
|
|
isProductInCart,
|
|
|
|
|
CART_CHANGE_EVENT,
|
|
|
|
|
type CartItem,
|
2026-01-14 17:31:59 +07:00
|
|
|
} from '../services/cart';
|
|
|
|
|
|
|
|
|
|
export function useCart() {
|
2026-01-15 17:30:04 +07:00
|
|
|
const [cartItems, setCartItems] = useState<CartItem[] | null>(null);
|
2026-01-14 17:31:59 +07:00
|
|
|
|
|
|
|
|
// Load cart lần đầu
|
|
|
|
|
useEffect(() => {
|
2026-01-15 17:30:04 +07:00
|
|
|
setCartItems(getCartItems());
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
// Listen to cart changes from ANY source
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const handleCartChange = () => {
|
|
|
|
|
setCartItems(getCartItems());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Listen to custom event
|
|
|
|
|
window.addEventListener(CART_CHANGE_EVENT, handleCartChange);
|
|
|
|
|
|
|
|
|
|
// Also listen to storage event (for changes from other tabs)
|
|
|
|
|
window.addEventListener('storage', (e) => {
|
|
|
|
|
if (e.key === 'cart_products') {
|
|
|
|
|
handleCartChange();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener(CART_CHANGE_EVENT, handleCartChange);
|
|
|
|
|
window.removeEventListener('storage', handleCartChange);
|
|
|
|
|
};
|
2026-01-14 17:31:59 +07:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const refresh = useCallback(() => {
|
2026-01-15 17:30:04 +07:00
|
|
|
setCartItems(getCartItems());
|
2026-01-14 17:31:59 +07:00
|
|
|
}, []);
|
|
|
|
|
|
2026-01-15 17:30:04 +07:00
|
|
|
const addToCart = useCallback((productId: number, quantity: number = 1) => {
|
|
|
|
|
const result = addProductToCart(productId, quantity);
|
|
|
|
|
// Không cần refresh() nữa vì event listener sẽ tự động update
|
|
|
|
|
return result;
|
|
|
|
|
}, []);
|
2026-01-14 17:31:59 +07:00
|
|
|
|
|
|
|
|
const removeFromCart = useCallback((productId: number) => {
|
|
|
|
|
removeProductFromCart(productId);
|
2026-01-15 17:30:04 +07:00
|
|
|
// Không cần refresh()
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const increase = useCallback((productId: number, amount: number = 1) => {
|
|
|
|
|
const success = increaseQuantity(productId, amount);
|
|
|
|
|
// Không cần refresh()
|
|
|
|
|
return success;
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const decrease = useCallback((productId: number, amount: number = 1) => {
|
|
|
|
|
const success = decreaseQuantity(productId, amount);
|
|
|
|
|
if (!success) {
|
|
|
|
|
console.log('Số lượng tối thiểu: 1');
|
|
|
|
|
}
|
|
|
|
|
// Không cần refresh()
|
|
|
|
|
return success;
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const updateQty = useCallback((productId: number, cartQuantity: number) => {
|
|
|
|
|
const success = updateQuantity(productId, cartQuantity);
|
|
|
|
|
if (!success) {
|
|
|
|
|
console.log('Số lượng phải lớn hơn hoặc bằng 1');
|
|
|
|
|
}
|
|
|
|
|
// Không cần refresh()
|
|
|
|
|
return success;
|
|
|
|
|
}, []);
|
2026-01-14 17:31:59 +07:00
|
|
|
|
|
|
|
|
const clear = useCallback(() => {
|
|
|
|
|
clearCart();
|
2026-01-15 17:30:04 +07:00
|
|
|
// Không cần setCartItems([]) nữa, event sẽ tự động update
|
2026-01-14 17:31:59 +07:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const isInCart = useCallback(
|
2026-01-15 17:30:04 +07:00
|
|
|
(productId: number) => cartItems?.some(item => item.id === productId) ?? false,
|
|
|
|
|
[cartItems]
|
2026-01-14 17:31:59 +07:00
|
|
|
);
|
|
|
|
|
|
2026-01-15 17:30:04 +07:00
|
|
|
const getQuantity = useCallback(
|
|
|
|
|
(productId: number) => {
|
|
|
|
|
return cartItems?.find(item => item.id === productId)?.cartQuantity ?? 0;
|
|
|
|
|
},
|
|
|
|
|
[cartItems]
|
|
|
|
|
);
|
2026-01-14 17:31:59 +07:00
|
|
|
|
2026-01-15 17:30:04 +07:00
|
|
|
const totalItems = cartItems?.reduce((sum, item) => sum + item.cartQuantity, 0) ?? 0;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
cartItems: cartItems ?? [],
|
|
|
|
|
cartCount: cartItems?.length ?? 0,
|
|
|
|
|
totalItems,
|
|
|
|
|
loading: cartItems === null,
|
2026-01-14 17:31:59 +07:00
|
|
|
addToCart,
|
|
|
|
|
removeFromCart,
|
2026-01-15 17:30:04 +07:00
|
|
|
increaseQuantity: increase,
|
|
|
|
|
decreaseQuantity: decrease,
|
|
|
|
|
updateQuantity: updateQty,
|
2026-01-14 17:31:59 +07:00
|
|
|
clear,
|
|
|
|
|
isInCart,
|
2026-01-15 17:30:04 +07:00
|
|
|
getQuantity,
|
|
|
|
|
refresh,
|
2026-01-14 17:31:59 +07:00
|
|
|
};
|
2026-01-15 17:30:04 +07:00
|
|
|
}
|