ScanMenu / src /stores /cart-store.ts
HamzaAri's picture
🚀 Deploy ScanMenu - Production-ready SaaS web app for digital restaurant menus & QR ordering
e1ef9fc verified
Raw
History Blame Contribute Delete
3.41 kB
'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',
}
)
);