2026-03-06 09:05:31 -05:00

85 lines
2.5 KiB
TypeScript

import { create } from 'zustand'
import { persist } from 'zustand/middleware'
export interface CartItem {
menuItemId: string
name: string
price: number
quantity: number
specialRequest?: string
}
interface CartStore {
restaurantId: string | null
restaurantName: string | null
restaurantSlug: string | null
items: CartItem[]
addItem: (restaurantId: string, restaurantName: string, restaurantSlug: string, item: Omit<CartItem, 'quantity'>) => void
removeItem: (menuItemId: string) => void
updateQuantity: (menuItemId: string, quantity: number) => void
clearCart: () => void
// Computed
subtotal: () => number
itemCount: () => number
deliveryFee: number
}
export const useCart = create<CartStore>()(
persist(
(set, get) => ({
restaurantId: null,
restaurantName: null,
restaurantSlug: null,
items: [],
deliveryFee: 5.00,
addItem: (restaurantId, restaurantName, restaurantSlug, item) => {
// Coerce price to number (PostgreSQL returns DECIMAL as string)
item = { ...item, price: Number(item.price) }
const { restaurantId: currentRestId, items } = get()
// Switching restaurant — clear cart first
if (currentRestId && currentRestId !== restaurantId) {
set({ restaurantId, restaurantName, restaurantSlug, items: [{ ...item, quantity: 1 }] })
return
}
const existing = items.find((i) => i.menuItemId === item.menuItemId)
if (existing) {
set({
items: items.map((i) =>
i.menuItemId === item.menuItemId ? { ...i, quantity: i.quantity + 1 } : i,
),
})
} else {
set({
restaurantId,
restaurantName,
restaurantSlug,
items: [...items, { ...item, quantity: 1 }],
})
}
},
removeItem: (menuItemId) =>
set({ items: get().items.filter((i) => i.menuItemId !== menuItemId) }),
updateQuantity: (menuItemId, quantity) => {
if (quantity <= 0) {
get().removeItem(menuItemId)
return
}
set({ items: get().items.map((i) => (i.menuItemId === menuItemId ? { ...i, quantity } : i)) })
},
clearCart: () => set({ restaurantId: null, restaurantName: null, restaurantSlug: null, items: [] }),
subtotal: () => get().items.reduce((sum, i) => sum + Number(i.price) * i.quantity, 0),
itemCount: () => get().items.reduce((sum, i) => sum + i.quantity, 0),
}),
{ name: 'vibe-cart' },
),
)