195 lines
5.5 KiB
TypeScript
195 lines
5.5 KiB
TypeScript
import api, { apiStatus } from './api';
|
||
import { Product, ProductVariant } from './catalog';
|
||
|
||
// Типы данных для корзины
|
||
export interface CartItem {
|
||
id: number;
|
||
user_id: number;
|
||
variant_id: number;
|
||
quantity: number;
|
||
created_at: string;
|
||
updated_at?: string;
|
||
product_id: number;
|
||
product_name: string;
|
||
product_price: number;
|
||
product_image?: string | null;
|
||
slug: string;
|
||
variant_name: string;
|
||
total_price: number;
|
||
}
|
||
|
||
export interface Cart {
|
||
items: CartItem[];
|
||
items_count: number;
|
||
total_amount: number;
|
||
}
|
||
|
||
export interface CartItemCreate {
|
||
product_id: number;
|
||
variant_id: number;
|
||
quantity: number;
|
||
}
|
||
|
||
export interface CartItemUpdate {
|
||
quantity: number;
|
||
}
|
||
|
||
interface ApiResponse<T> {
|
||
success: boolean;
|
||
data?: T;
|
||
message?: string;
|
||
}
|
||
|
||
/**
|
||
* Создает пустую корзину для неавторизованного пользователя
|
||
* @returns Пустая корзина
|
||
*/
|
||
const createEmptyCart = (): Cart => {
|
||
return {
|
||
items: [],
|
||
items_count: 0,
|
||
total_amount: 0
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Сервис для работы с корзиной пользователя
|
||
*/
|
||
const cartService = {
|
||
/**
|
||
* Получение текущей корзины пользователя
|
||
*/
|
||
getCart: async (): Promise<Cart> => {
|
||
try {
|
||
// Если пользователь не авторизован, возвращаем пустую корзину
|
||
if (!apiStatus.isAuthenticated) {
|
||
return createEmptyCart();
|
||
}
|
||
|
||
const response = await api.get<Cart>('/cart');
|
||
return response as Cart;
|
||
} catch (error: any) {
|
||
// Обрабатываем 401 ошибку для неавторизованных запросов
|
||
if (error.response && error.response.status === 401) {
|
||
return createEmptyCart();
|
||
}
|
||
|
||
console.error('Ошибка при получении корзины:', error);
|
||
return createEmptyCart();
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Добавление товара в корзину
|
||
*/
|
||
addToCart: async (item: CartItemCreate): Promise<CartItem | null> => {
|
||
try {
|
||
// Проверяем авторизацию пользователя
|
||
if (!apiStatus.isAuthenticated) {
|
||
return null;
|
||
}
|
||
|
||
const response = await api.post<CartItem>('/cart/items', item);
|
||
|
||
return response as CartItem;
|
||
} catch (error: any) {
|
||
// Обрабатываем 401 ошибку для неавторизованных запросов
|
||
if (error.response && error.response.status === 401) {
|
||
return null;
|
||
}
|
||
|
||
console.error('Ошибка при добавлении товара в корзину:', error);
|
||
return null;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Обновление количества товара в корзине
|
||
*/
|
||
updateCartItem: async (itemId: number, data: CartItemUpdate): Promise<CartItem | null> => {
|
||
try {
|
||
// Проверяем авторизацию пользователя
|
||
if (!apiStatus.isAuthenticated) {
|
||
return null;
|
||
}
|
||
|
||
const response = await api.put<CartItem>(`/cart/items/${itemId}`, data);
|
||
|
||
return response as CartItem;
|
||
} catch (error: any) {
|
||
// Обрабатываем 401 ошибку для неавторизованных запросов
|
||
if (error.response && error.response.status === 401) {
|
||
return null;
|
||
}
|
||
|
||
console.error(`Ошибка при обновлении товара ${itemId} в корзине:`, error);
|
||
return null;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Удаление товара из корзины
|
||
*/
|
||
removeFromCart: async (itemId: number): Promise<boolean> => {
|
||
try {
|
||
// Проверяем авторизацию пользователя
|
||
if (!apiStatus.isAuthenticated) {
|
||
return false;
|
||
}
|
||
|
||
await api.delete(`/cart/items/${itemId}`);
|
||
|
||
return true;
|
||
} catch (error: any) {
|
||
// Обрабатываем 401 ошибку для неавторизованных запросов
|
||
if (error.response && error.response.status === 401) {
|
||
return false;
|
||
}
|
||
|
||
console.error(`Ошибка при удалении товара ${itemId} из корзины:`, error);
|
||
return false;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Очистка корзины
|
||
*/
|
||
clearCart: async (): Promise<boolean> => {
|
||
try {
|
||
// Проверяем авторизацию пользователя
|
||
if (!apiStatus.isAuthenticated) {
|
||
return false;
|
||
}
|
||
|
||
await api.delete('/cart/items');
|
||
|
||
return true;
|
||
} catch (error: any) {
|
||
console.error('Ошибка при очистке корзины:', error);
|
||
return false;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Проверка доступности товаров в корзине
|
||
*/
|
||
validateCart: async (): Promise<{
|
||
valid: boolean;
|
||
items?: { id: number; available: boolean; stock?: number }[];
|
||
message?: string;
|
||
}> => {
|
||
try {
|
||
const response = await api.get('/cart/validate');
|
||
return response as {
|
||
valid: boolean;
|
||
items?: { id: number; available: boolean; stock?: number }[];
|
||
message?: string;
|
||
};
|
||
} catch (error) {
|
||
console.error('Ошибка при проверке доступности товаров в корзине:', error);
|
||
return { valid: false, message: 'Не удалось проверить доступность товаров' };
|
||
}
|
||
}
|
||
};
|
||
|
||
export default cartService;
|