53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { create } from "zustand";
|
|
import { createJSONStorage, persist } from "zustand/middleware";
|
|
import type { Product } from "@/lib/headless/types";
|
|
|
|
export interface CartItem {
|
|
product: Product;
|
|
quantity: number;
|
|
variantId?: string;
|
|
}
|
|
|
|
interface CartState {
|
|
items: CartItem[];
|
|
isOpen: boolean;
|
|
openCart: () => void;
|
|
closeCart: () => void;
|
|
addItem: (product: Product, variantId?: string) => void;
|
|
removeItem: (productId: string) => void;
|
|
updateQuantity: (productId: string, quantity: number) => void;
|
|
clearCart: () => void;
|
|
}
|
|
|
|
export const useCartStore = create<CartState>()(
|
|
persist(
|
|
(set) => ({
|
|
items: [],
|
|
isOpen: false,
|
|
openCart: () => set({ isOpen: true }),
|
|
closeCart: () => set({ isOpen: false }),
|
|
addItem: (product, variantId) => set((state) => {
|
|
const existing = state.items.find((item) => item.product.id === product.id && item.variantId === variantId);
|
|
const items = existing
|
|
? state.items.map((item) => item === existing ? { ...item, quantity: item.quantity + 1 } : item)
|
|
: [...state.items, { product, quantity: 1, variantId }];
|
|
return { items, isOpen: true };
|
|
}),
|
|
removeItem: (productId) => set((state) => ({ items: state.items.filter((item) => item.product.id !== productId) })),
|
|
updateQuantity: (productId, quantity) => set((state) => ({
|
|
items: quantity <= 0
|
|
? state.items.filter((item) => item.product.id !== productId)
|
|
: state.items.map((item) => item.product.id === productId ? { ...item, quantity } : item),
|
|
})),
|
|
clearCart: () => set({ items: [] }),
|
|
}),
|
|
{
|
|
name: "ari-shopping-cart-v4",
|
|
storage: createJSONStorage(() => localStorage),
|
|
partialize: (state) => ({ items: state.items }),
|
|
},
|
|
),
|
|
);
|