E-Commerce-Module/frontend/src/hooks/apiHooks.js

309 lines
No EOL
8.2 KiB
JavaScript

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import productService, { productAdminService } from '@services/productService';
import authService from '@services/authService';
import cartService from '@services/cartService';
import { useAuth, useCart, useNotification } from './reduxHooks';
import apiClient from '@services/api';
import Clarity from '@microsoft/clarity';
// Product hooks
export const useProducts = (params) => {
return useQuery({
queryKey: ['products', params],
queryFn: () => productService.getAllProducts(params),
});
};
export const useProduct = (id) => {
return useQuery({
queryKey: ['product', id],
queryFn: () => productService.getProductById(id),
enabled: !!id,
});
};
export const useCategories = () => {
return useQuery({
queryKey: ['categories'],
queryFn: () => productService.getAllCategories(),
});
};
export const useTags = () => {
return useQuery({
queryKey: ['tags'],
queryFn: () => productService.getAllTags(),
});
};
export const useProductsByCategory = (categoryName) => {
return useQuery({
queryKey: ['products', 'category', categoryName],
queryFn: () => productService.getProductsByCategory(categoryName),
enabled: !!categoryName,
});
};
// Admin product hooks
export const useCreateProduct = () => {
const queryClient = useQueryClient();
const notification = useNotification();
return useMutation({
mutationFn: (productData) => productAdminService.createProduct(productData),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['products'] });
notification.showNotification('Product created successfully', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to create product',
'error'
);
},
});
};
export const useUpdateProduct = () => {
const queryClient = useQueryClient();
const notification = useNotification();
return useMutation({
mutationFn: ({ id, productData }) => productAdminService.updateProduct(id, productData),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ['products'] });
queryClient.invalidateQueries({ queryKey: ['product', variables.id] });
notification.showNotification('Product updated successfully', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to update product',
'error'
);
},
});
};
export const useDeleteProduct = () => {
const queryClient = useQueryClient();
const notification = useNotification();
return useMutation({
mutationFn: (id) => productAdminService.deleteProduct(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['products'] });
notification.showNotification('Product deleted successfully', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to delete product',
'error'
);
},
});
};
// Auth hooks
export const useRegister = () => {
const notification = useNotification();
return useMutation({
mutationFn: (userData) => authService.register(userData),
onSuccess: () => {
notification.showNotification('Registration successful', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Registration failed',
'error'
);
},
});
};
export const useRequestLoginCode = () => {
const notification = useNotification();
return useMutation({
mutationFn: (email) => authService.requestLoginCode(email),
onSuccess: () => {
notification.showNotification('Login code sent to your email', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to send login code',
'error'
);
},
});
};
export const useVerifyCode = () => {
const { login } = useAuth();
const notification = useNotification();
return useMutation({
mutationFn: (verifyData) => authService.verifyCode(verifyData),
onSuccess: (data) => {
login(data.userId, data.apiKey, data.isAdmin, data.email, data?.firstName, data?.lastName);
notification.showNotification('Login successful', 'success');
Clarity.identify(data.userId, data.apiKey);
},
onError: (error) => {
notification.showNotification(
error.message || 'Invalid verification code',
'error'
);
},
});
};
export const useLogout = () => {
const { logout, user } = useAuth();
const notification = useNotification();
return useMutation({
mutationFn: () => authService.logout(user?.id),
onSuccess: () => {
logout();
notification.showNotification('Logged out successfully', 'success');
},
onError: () => {
// Force logout even if API call fails
logout();
},
});
};
// Cart hooks
export const useGetCart = (userId) => {
const { updateCart } = useCart();
return useQuery({
queryKey: ['cart', userId],
queryFn: () => cartService.getCart(userId),
enabled: !!userId,
onSuccess: (data) => {
updateCart(data);
},
});
};
export const useAddToCart = () => {
const queryClient = useQueryClient();
const { updateCart } = useCart();
const notification = useNotification();
return useMutation({
mutationFn: (cartItemData) => cartService.addToCart(cartItemData),
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: ['cart'] });
updateCart(data);
notification.showNotification('Item added to cart', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to add item to cart',
'error'
);
},
});
};
export const useUpdateCartItem = () => {
const queryClient = useQueryClient();
const { updateCart } = useCart();
const notification = useNotification();
return useMutation({
mutationFn: (updateData) => cartService.updateCartItem(updateData),
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: ['cart'] });
updateCart(data);
notification.showNotification('Cart updated', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to update cart',
'error'
);
},
});
};
export const useClearCart = () => {
const queryClient = useQueryClient();
const { clearCart } = useCart();
const notification = useNotification();
return useMutation({
mutationFn: (userId) => cartService.clearCart(userId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['cart'] });
clearCart();
notification.showNotification('Cart cleared', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Failed to clear cart',
'error'
);
},
});
};
export const useCheckout = () => {
const queryClient = useQueryClient();
const { clearCart } = useCart();
const notification = useNotification();
return useMutation({
mutationFn: (checkoutData) => cartService.checkout(checkoutData),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['cart'] });
clearCart();
notification.showNotification('Order placed successfully', 'success');
},
onError: (error) => {
notification.showNotification(
error.message || 'Checkout failed',
'error'
);
},
});
};
/**
* Hook for fetching user's orders
*/
export const useUserOrders = () => {
const { user } = useAuth();
return useQuery({
queryKey: ['user-orders', user],
queryFn: async () => {
const response = await apiClient.get('/user/orders');
return response.data;
},
enabled: !!user,
staleTime: 60000 // 1 minute
});
};
/**
* Hook for fetching a single user order by ID
* @param {string} id - Order ID
*/
export const useUserOrder = (id) => {
const { user } = useAuth();
return useQuery({
queryKey: ['user-order', id],
queryFn: async () => {
const response = await apiClient.get(`/user/orders/${id}`);
return response.data;
},
enabled: !!id && !!user
});
};