Spaces:
Running
Running
| // src/components/ProductCard.tsx | |
| import { Product } from '@/lib/schemas'; // Importa o tipo Zod | |
| import { useCartStore } from '@/stores/useCartStore'; // Importa a "Bandeja do Cliente" (Zustand) | |
| interface ProductCardProps { | |
| product: Product; | |
| } | |
| export const ProductCard = ({ product }: ProductCardProps) => { | |
| // 1. Acessamos a função 'addItem' da store Zustand. | |
| const addItemToCart = useCartStore((state) => state.addItem); | |
| // 2. ♿ [A11y STRICT]: Acessibilidade e Semântica | |
| // O componente deve ser um link para a página de detalhes (se tivéssemos uma) | |
| // mas o botão de compra precisa ser claro para leitores de tela. | |
| const handleAddToCart = () => { | |
| addItemToCart(product); | |
| // TODO: Adicionar um feedback visual (toast) aqui para o usuário. | |
| }; | |
| return ( | |
| <div className="border rounded-lg shadow-md overflow-hidden flex flex-col justify-between p-4 bg-white"> | |
| <div className="flex justify-center h-48 mb-4"> | |
| <img | |
| src={product.image} | |
| alt={product.title} | |
| className="object-contain w-full h-full" | |
| loading="lazy" // Otimização para LCP | |
| /> | |
| </div> | |
| <div className="flex-grow"> | |
| <h2 className="text-lg font-semibold h-12 overflow-hidden mb-2">{product.title}</h2> | |
| <p className="text-xl font-bold text-gray-800 mb-2">R$ {product.price.toFixed(2)}</p> | |
| <p className="text-sm text-gray-600 line-clamp-3 mb-4">{product.description}</p> | |
| </div> | |
| <button | |
| onClick={handleAddToCart} | |
| // ♿ [A11y STRICT]: O botão deve ter um texto claro e semântica de botão. | |
| // O `aria-label` seria útil se tivéssemos apenas um ícone. | |
| className="bg-blue-600 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 transition duration-300" | |
| > | |
| Adicionar ao Carrinho | |
| </button> | |
| </div> | |
| ); | |
| }; |