88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
"use client"
|
|
|
|
import { createContext, useContext, useState, useEffect, type ReactNode } from "react"
|
|
|
|
interface CartItem {
|
|
id: number
|
|
title: string
|
|
price: number
|
|
quantity: number
|
|
coverImage?: string
|
|
}
|
|
|
|
interface CartContextType {
|
|
cart: CartItem[]
|
|
addToCart: (item: CartItem) => void
|
|
updateQuantity: (id: number, quantity: number) => void
|
|
removeFromCart: (id: number) => void
|
|
clearCart: () => void
|
|
}
|
|
|
|
const CartContext = createContext<CartContextType | undefined>(undefined)
|
|
|
|
export function CartProvider({ children }: { children: ReactNode }) {
|
|
const [cart, setCart] = useState<CartItem[]>([])
|
|
|
|
useEffect(() => {
|
|
// 从本地存储中恢复购物车状态
|
|
const storedCart = localStorage.getItem("cart")
|
|
if (storedCart) {
|
|
try {
|
|
setCart(JSON.parse(storedCart))
|
|
} catch (error) {
|
|
console.error("Failed to parse stored cart", error)
|
|
localStorage.removeItem("cart")
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
// 当购物车变化时,更新本地存储
|
|
useEffect(() => {
|
|
localStorage.setItem("cart", JSON.stringify(cart))
|
|
}, [cart])
|
|
|
|
const addToCart = (item: CartItem) => {
|
|
setCart((prevCart) => {
|
|
const existingItemIndex = prevCart.findIndex((cartItem) => cartItem.id === item.id)
|
|
|
|
if (existingItemIndex >= 0) {
|
|
// 如果商品已存在,增加数量
|
|
const updatedCart = [...prevCart]
|
|
updatedCart[existingItemIndex].quantity += item.quantity
|
|
return updatedCart
|
|
} else {
|
|
// 否则添加新商品
|
|
return [...prevCart, item]
|
|
}
|
|
})
|
|
}
|
|
|
|
const updateQuantity = (id: number, quantity: number) => {
|
|
setCart((prevCart) =>
|
|
prevCart.map((item) => (item.id === id ? { ...item, quantity: Math.max(1, quantity) } : item)),
|
|
)
|
|
}
|
|
|
|
const removeFromCart = (id: number) => {
|
|
setCart((prevCart) => prevCart.filter((item) => item.id !== id))
|
|
}
|
|
|
|
const clearCart = () => {
|
|
setCart([])
|
|
}
|
|
|
|
return (
|
|
<CartContext.Provider value={{ cart, addToCart, updateQuantity, removeFromCart, clearCart }}>
|
|
{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
|
|
}
|