Files
homaroma/apps/ssr/src/store/cartStore.ts
T
2026-06-03 08:39:12 +07:00

79 lines
2.3 KiB
TypeScript

import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { CartItem } from '@irelax/types';
interface CartState {
items: CartItem[];
isCartOpen: boolean;
addToCart: (item: Omit<CartItem, 'cartItemId'>) => void;
removeFromCart: (cartItemId: string) => void;
updateQuantity: (cartItemId: string, quantity: number) => void;
clearCart: () => void;
toggleCart: (isOpen?: boolean) => void;
getCartTotal: () => number;
getCartCount: () => number;
}
export const useCartStore = create<CartState>()(
persist(
(set, get) => ({
items: [],
isCartOpen: false,
addToCart: (item) => set((state) => {
// Build a unique ID for the item. If variantId exists, use it. Otherwise, use productId.
const exactIdMatch = state.items.find(i =>
i.productId === item.productId && i.variantId === item.variantId
);
if (exactIdMatch) {
// Increment quantity if exact match exists
return {
items: state.items.map(i =>
i.cartItemId === exactIdMatch.cartItemId
? { ...i, quantity: i.quantity + item.quantity }
: i
),
isCartOpen: true
};
}
// Add new item with a generated cartItemId
const cartItemId = crypto.randomUUID();
return {
items: [...state.items, { ...item, cartItemId }],
isCartOpen: true
};
}),
removeFromCart: (cartItemId) => set((state) => ({
items: state.items.filter(i => i.cartItemId !== cartItemId)
})),
updateQuantity: (cartItemId, quantity) => set((state) => ({
items: state.items.map(i =>
i.cartItemId === cartItemId ? { ...i, quantity: Math.max(1, quantity) } : i
)
})),
clearCart: () => set({ items: [] }),
toggleCart: (isOpen) => set((state) => ({
isCartOpen: isOpen !== undefined ? isOpen : !state.isCartOpen
})),
getCartTotal: () => {
return get().items.reduce((total, item) => total + (item.price * item.quantity), 0);
},
getCartCount: () => {
return get().items.reduce((count, item) => count + item.quantity, 0);
}
}),
{
name: 'irelax-cart-storage',
partialize: (state) => ({ items: state.items }), // Only persist items, not UI state
}
)
);