dressed_for_succes_store/frontend/hooks/use-cart.tsx

144 lines
3.9 KiB
TypeScript

"use client"
import { createContext, useContext, useState, useEffect, ReactNode } from "react"
import { useToast } from "@/components/ui/use-toast"
// Типы для корзины
export interface CartItem {
id: number
variant_id: number
product_id: number
name: string
price: number
image: string | object
quantity: number
size?: string
color?: string
}
interface CartContextType {
items: CartItem[]
addItem: (item: CartItem) => void
removeItem: (id: number) => void
updateQuantity: (id: number, quantity: number) => void
clearCart: () => void
itemCount: number
subtotal: number
}
// Создание контекста
const CartContext = createContext<CartContextType | undefined>(undefined)
// Провайдер контекста
export function CartProvider({ children }: { children: ReactNode }) {
const [items, setItems] = useState<CartItem[]>([])
const { toast } = useToast()
// Загрузка корзины из localStorage при инициализации
useEffect(() => {
const storedCart = localStorage.getItem("cart")
if (storedCart) {
try {
setItems(JSON.parse(storedCart))
} catch (e) {
console.error("Ошибка при загрузке корзины из localStorage:", e)
localStorage.removeItem("cart")
}
}
}, [])
// Сохранение корзины в localStorage при изменении
useEffect(() => {
localStorage.setItem("cart", JSON.stringify(items))
}, [items])
// Добавление товара в корзину
const addItem = (item: CartItem) => {
setItems(prevItems => {
// Проверяем, есть ли уже такой товар в корзине
const existingItemIndex = prevItems.findIndex(
i => i.variant_id === item.variant_id
)
// Если товар уже есть, увеличиваем количество
if (existingItemIndex > -1) {
const newItems = [...prevItems]
newItems[existingItemIndex].quantity += item.quantity
toast({
title: "Товар добавлен в корзину",
description: `${item.name} (${item.quantity} шт.)`,
})
return newItems
}
// Если товара нет, добавляем новый
toast({
title: "Товар добавлен в корзину",
description: `${item.name} (${item.quantity} шт.)`,
})
return [...prevItems, item]
})
}
// Удаление товара из корзины
const removeItem = (id: number) => {
setItems(prevItems => prevItems.filter(item => item.id !== id))
toast({
title: "Товар удален из корзины",
})
}
// Обновление количества товара
const updateQuantity = (id: number, quantity: number) => {
setItems(prevItems =>
prevItems.map(item =>
item.id === id ? { ...item, quantity } : item
)
)
}
// Очистка корзины
const clearCart = () => {
setItems([])
toast({
title: "Корзина очищена",
})
}
// Подсчет общего количества товаров
const itemCount = items.reduce((total, item) => total + item.quantity, 0)
// Подсчет общей стоимости
const subtotal = items.reduce(
(total, item) => total + item.price * item.quantity,
0
)
const value = {
items,
addItem,
removeItem,
updateQuantity,
clearCart,
itemCount,
subtotal
}
return <CartContext.Provider value={value}>{children}</CartContext.Provider>
}
// Хук для использования корзины
export function useCart() {
const context = useContext(CartContext)
if (context === undefined) {
throw new Error("useCart must be used within a CartProvider")
}
return context
}