Seed: ecommerce template (24 files)
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import { createContext, useContext, useState, ReactNode } from "react";
|
||||
|
||||
export interface CartItem {
|
||||
id: string;
|
||||
name: string;
|
||||
price: number;
|
||||
quantity: number;
|
||||
size?: string;
|
||||
color?: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
interface CartContextType {
|
||||
items: CartItem[];
|
||||
addItem: (item: CartItem) => void;
|
||||
removeItem: (id: string) => void;
|
||||
updateQuantity: (id: string, quantity: number) => void;
|
||||
clearCart: () => void;
|
||||
total: number;
|
||||
itemCount: number;
|
||||
}
|
||||
|
||||
const CartContext = createContext<CartContextType | undefined>(undefined);
|
||||
|
||||
export function CartProvider({ children }: { children: ReactNode }) {
|
||||
const [items, setItems] = useState<CartItem[]>([
|
||||
{
|
||||
id: "leather-jacket-1",
|
||||
name: "Classic Leather Jacket",
|
||||
price: 189,
|
||||
quantity: 1,
|
||||
size: "M",
|
||||
color: "Black",
|
||||
image: "",
|
||||
},
|
||||
{
|
||||
id: "silk-dress-1",
|
||||
name: "Silk Evening Dress",
|
||||
price: 245,
|
||||
quantity: 1,
|
||||
size: "S",
|
||||
color: "Rose",
|
||||
image: "",
|
||||
},
|
||||
{
|
||||
id: "cashmere-sweater-1",
|
||||
name: "Cashmere Knit Sweater",
|
||||
price: 128,
|
||||
quantity: 2,
|
||||
size: "M",
|
||||
color: "Stone",
|
||||
image: "",
|
||||
},
|
||||
]);
|
||||
|
||||
const addItem = (newItem: CartItem) => {
|
||||
setItems((prev) => {
|
||||
const existing = prev.find(
|
||||
(i) => i.id === newItem.id && i.size === newItem.size && i.color === newItem.color
|
||||
);
|
||||
if (existing) {
|
||||
return prev.map((i) =>
|
||||
i.id === existing.id && i.size === existing.size && i.color === existing.color
|
||||
? { ...i, quantity: i.quantity + newItem.quantity }
|
||||
: i
|
||||
);
|
||||
}
|
||||
return [...prev, newItem];
|
||||
});
|
||||
};
|
||||
|
||||
const removeItem = (id: string) => {
|
||||
setItems((prev) => prev.filter((i) => i.id !== id));
|
||||
};
|
||||
|
||||
const updateQuantity = (id: string, quantity: number) => {
|
||||
if (quantity <= 0) {
|
||||
removeItem(id);
|
||||
return;
|
||||
}
|
||||
setItems((prev) => prev.map((i) => (i.id === id ? { ...i, quantity } : i)));
|
||||
};
|
||||
|
||||
const clearCart = () => setItems([]);
|
||||
|
||||
const total = items.reduce((sum, i) => sum + i.price * i.quantity, 0);
|
||||
const itemCount = items.reduce((sum, i) => sum + i.quantity, 0);
|
||||
|
||||
return (
|
||||
<CartContext.Provider value={{ items, addItem, removeItem, updateQuantity, clearCart, total, itemCount }}>
|
||||
{children}
|
||||
</CartContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useCart() {
|
||||
const context = useContext(CartContext);
|
||||
if (!context) {
|
||||
throw new Error("useCart must be used within a CartProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
Reference in New Issue
Block a user