72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import React, { createContext, useState, useContext, ReactNode } from 'react';
|
|
|
|
export type CartItem = {
|
|
id: string;
|
|
name: string;
|
|
quantity: number;
|
|
price: number;
|
|
image: string;
|
|
};
|
|
|
|
type CartState = {
|
|
items: CartItem[];
|
|
total: number;
|
|
};
|
|
|
|
type CartContextType = {
|
|
cart: CartState;
|
|
addItem: (item: CartItem) => void;
|
|
clearCart: () => void;
|
|
updateQuantity: (id: string, quantity: number) => void;
|
|
};
|
|
|
|
const CartContext = createContext<CartContextType | undefined>(undefined);
|
|
|
|
export const CartProvider = ({ children }: { children: ReactNode }) => {
|
|
const [cart, setCart] = useState<CartState>({ items: [], total: 0 });
|
|
|
|
const addItem = (item: CartItem) => {
|
|
setCart(prev => {
|
|
const existing = prev.items.find(i => i.id === item.id);
|
|
let updatedItems;
|
|
|
|
if (existing) {
|
|
updatedItems = prev.items.map(i =>
|
|
i.id === item.id ? { ...i, quantity: i.quantity + item.quantity } : i
|
|
);
|
|
} else {
|
|
updatedItems = [...prev.items, item];
|
|
}
|
|
|
|
const updatedTotal = updatedItems.reduce((sum, i) => sum + i.quantity * i.price, 0);
|
|
return { items: updatedItems, total: updatedTotal };
|
|
});
|
|
};
|
|
|
|
const clearCart = () => setCart({ items: [], total: 0 });
|
|
|
|
const updateQuantity = (id: string, quantity: number) => {
|
|
setCart(prev => {
|
|
const updatedItems = prev.items.map(item =>
|
|
item.id === id ? { ...item, quantity } : item
|
|
);
|
|
const updatedTotal = updatedItems.reduce((sum, i) => sum + i.quantity * i.price, 0);
|
|
return { items: updatedItems, total: updatedTotal };
|
|
});
|
|
};
|
|
|
|
return (
|
|
<CartContext.Provider value={{ cart, addItem, clearCart, updateQuantity }}>
|
|
{children}
|
|
</CartContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useCart = () => {
|
|
const context = useContext(CartContext);
|
|
if (!context) {
|
|
throw new Error('useCart must be used within a CartProvider');
|
|
}
|
|
return context;
|
|
};
|