teste / src /stores /useCartStore.ts
adriano2005's picture
Create src/stores/useCartStore.ts
b5d475e verified
// 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
}
)
);