Spaces:
Running
Running
| // src/stores/useCartStore.ts | |
| import { create } from 'zustand'; | |
| import { persist } from 'zustand/middleware'; | |
| import { CartItem, Product } from '@/lib/schemas'; // Importamos os tipos do Zod | |
| // Define o formato do estado do nosso carrinho | |
| interface CartState { | |
| items: CartItem[]; // A lista de itens no carrinho | |
| addItem: (product: Product) => void; // Ação: Adicionar item | |
| removeItem: (productId: number) => void; // Ação: Remover item | |
| clearCart: () => void; // Ação: Limpar carrinho | |
| calculateTotal: () => number; // Ação: Calcular total | |
| } | |
| // 🎯 [DECISÃO ARQUITETURAL]: Usamos o middleware `persist` para salvar o estado | |
| // no `localStorage` do navegador. Isso garante que o carrinho não seja perdido | |
| // quando o usuário recarregar a página ou navegar para outras rotas. | |
| export const useCartStore = create<CartState>()( | |
| persist( | |
| (set, get) => ({ | |
| // Estado inicial do carrinho | |
| items: [], | |
| // --- Ações --- | |
| // Adicionar um produto ao carrinho | |
| addItem: (product) => { | |
| set((state) => { | |
| // 1. Verificamos se o produto já está no carrinho | |
| const existingItemIndex = state.items.findIndex( | |
| (item) => item.product.id === product.id | |
| ); | |
| if (existingItemIndex > -1) { | |
| // Se o produto já existe, incrementamos a quantidade | |
| const newItems = [...state.items]; | |
| newItems[existingItemIndex] = { | |
| ...newItems[existingItemIndex], | |
| quantity: newItems[existingItemIndex].quantity + 1, | |
| }; | |
| return { items: newItems }; | |
| } else { | |
| // Se o produto é novo, adicionamos ele com quantidade 1 | |
| const newItem: CartItem = { product, quantity: 1 }; | |
| return { items: [...state.items, newItem] }; | |
| } | |
| }); | |
| }, | |
| // Remover um produto do carrinho (diminui a quantidade ou remove se for 1) | |
| removeItem: (productId) => { | |
| set((state) => ({ | |
| items: state.items | |
| .map((item) => { | |
| if (item.product.id === productId) { | |
| // Diminui a quantidade, mas nunca abaixo de 0 | |
| return { ...item, quantity: item.quantity - 1 }; | |
| } | |
| return item; | |
| }) | |
| // Filtra o array para remover itens com quantidade 0 | |
| .filter((item) => item.quantity > 0), | |
| })); | |
| }, | |
| // Limpar todos os itens do carrinho | |
| clearCart: () => set({ items: [] }), | |
| // Calcular o valor total do carrinho | |
| calculateTotal: () => { | |
| return get().items.reduce( | |
| (total, item) => total + item.product.price * item.quantity, | |
| 0 | |
| ); | |
| }, | |
| }), | |
| { | |
| name: 'ecommerce-cart-storage', // Nome da chave no localStorage | |
| } | |
| ) | |
| ); |