| 'use client'; |
|
|
| import { create } from 'zustand'; |
| import { persist } from 'zustand/middleware'; |
| import { CartItem, Product, OrderType } from '@/types/database'; |
| import { generateId } from '@/lib/utils'; |
|
|
| interface CartStore { |
| items: CartItem[]; |
| restaurantId: string | null; |
| restaurantName: string | null; |
| orderType: OrderType; |
| tableNumber: string | null; |
| customerName: string; |
| customerPhone: string; |
| customerEmail: string; |
| deliveryAddress: string; |
| notes: string; |
|
|
| addItem: (product: Product, quantity: number, options?: Record<string, string | string[]>, notes?: string) => void; |
| removeItem: (itemId: string) => void; |
| updateQuantity: (itemId: string, quantity: number) => void; |
| clearCart: () => void; |
| setOrderType: (type: OrderType) => void; |
| setTableNumber: (number: string | null) => void; |
| setRestaurant: (id: string, name: string) => void; |
| setCustomerName: (name: string) => void; |
| setCustomerPhone: (phone: string) => void; |
| setCustomerEmail: (email: string) => void; |
| setDeliveryAddress: (address: string) => void; |
| setNotes: (notes: string) => void; |
| getSubtotal: () => number; |
| getTax: () => number; |
| getTotal: () => number; |
| getItemCount: () => number; |
| } |
|
|
| export const useCartStore = create<CartStore>()( |
| persist( |
| (set, get) => ({ |
| items: [], |
| restaurantId: null, |
| restaurantName: null, |
| orderType: 'dine_in', |
| tableNumber: null, |
| customerName: '', |
| customerPhone: '', |
| customerEmail: '', |
| deliveryAddress: '', |
| notes: '', |
|
|
| addItem: (product, quantity, options = {}, notes = '') => { |
| const total = product.price * quantity; |
| const newItem: CartItem = { |
| id: generateId(), |
| product, |
| quantity, |
| options, |
| notes, |
| total, |
| }; |
| set((state) => ({ items: [...state.items, newItem] })); |
| }, |
|
|
| removeItem: (itemId) => { |
| set((state) => ({ items: state.items.filter((i) => i.id !== itemId) })); |
| }, |
|
|
| updateQuantity: (itemId, quantity) => { |
| if (quantity <= 0) { |
| get().removeItem(itemId); |
| return; |
| } |
| set((state) => ({ |
| items: state.items.map((item) => |
| item.id === itemId |
| ? { ...item, quantity, total: item.product.price * quantity } |
| : item |
| ), |
| })); |
| }, |
|
|
| clearCart: () => { |
| set({ items: [], notes: '' }); |
| }, |
|
|
| setOrderType: (type) => set({ orderType: type }), |
| setTableNumber: (number) => set({ tableNumber: number }), |
| setRestaurant: (id, name) => set({ restaurantId: id, restaurantName: name }), |
| setCustomerName: (name) => set({ customerName: name }), |
| setCustomerPhone: (phone) => set({ customerPhone: phone }), |
| setCustomerEmail: (email) => set({ customerEmail: email }), |
| setDeliveryAddress: (address) => set({ deliveryAddress: address }), |
| setNotes: (notes) => set({ notes }), |
|
|
| getSubtotal: () => { |
| return get().items.reduce((sum, item) => sum + item.total, 0); |
| }, |
|
|
| getTax: () => { |
| return get().getSubtotal() * 0.08; |
| }, |
|
|
| getTotal: () => { |
| return get().getSubtotal() + get().getTax(); |
| }, |
|
|
| getItemCount: () => { |
| return get().items.reduce((sum, item) => sum + item.quantity, 0); |
| }, |
| }), |
| { |
| name: 'scanmenu-cart', |
| } |
| ) |
| ); |
|
|