Feito com Node, v20.12.2.
- Lista de Produtos: Exibir uma lista de produtos com nome, imagem, preço e categoria.
- Filtros: Implementar filtros por busca de nome, categoria e faixa de preço.
- Detalhes do Produto: Ao clicar em um produto, exibir seus detalhes (nome, descrição, preço, imagem e categoria).
- Carrinho de Compras: Permitir adicionar e remover produtos do carrinho.
- Checkout: Implementar um processo de checkout simples.
- Responsividade: A aplicação deve ser totalmente responsiva.
- Next.js: Utilize as funcionalidades de roteamento e geração de páginas estáticas do Next.js.
- Estilização: Utilize TailwindCSS ou CSS Modules.
- Testes: Implementação de testes unitários e/ou de integração.
- SSR: Implementação de Server Components.
-
pnpm i
, para instalar as dependências. -
pnpm dev
, para iniciar o servidor de desenvolvimento.
pnpm build
.
pnpm build
, então pnpm start
.
pnpm test
.
- React
- Next.js
- TypeScript
- ESLint/Prettier
- TailwindCSS
- shadcn
- React Hook Form
- Zod
- Vitest
- Sonner
- pnpm
Foi uma experiência enriquecedora e repleto de desafios, expondo oportunidades para experimentar com diferentes features do React e Next.js para solucionar vários problemas.
React 19 e Next.js 15 foram usados, devido às suas melhorias de performance e experiência de desenvolvimento. Embora ainda estejam em sua versão RC (Release Candidate), ambos se provaram estáveis o suficiente para uso neste projeto. Porém, algumas funcionalidades não foram utilizadas, pois não estão bem documentadas atualmente.
TailwindCSS e shadcn foram escolhidos para acelerar o desenvolvimento, garantindo consistência e facilitando a criação de interfaces com alta qualidade.
shadcn, em particular, fornece uma estilização padrão fácil de extender e alto nível de controle sobre seus componentes. Sua integração com a Radix UI fornece várias soluções em relação à acessibilidade, influenciando positivamente várias métricas chave.
React Hook Form é fácil de usar e fornece muitas otimizações importantes ao lidar com uma quantidade maior de campos.
Zod fornece validação de schemas, útil na validação de formulário ou variáveis de ambiente. O mesmo também executa durante o runtime, permitindo um type checking mais forte que o TypeScript em certos cenários.
Vitest possui uma API muita semelhante ao Jest, ao mesmo tempo em que fornece um ganho significativo de performance. A integração com a Testing Library permite acesso à uma camada mais profunda de testes, enquanto user-event permite simular o disparo de eventos no lado cliente.
pnpm é um gerenciador de pacotes rápido e estável. Também é eficiente, reutilizando os pacotes já presentes em sua máquina, a qual é uma vantagem considerável sobre o Bun, dependendo do cenário.
Patterns como SOLID, Composition e Custom Hooks foram ferramentas indispensáveis na construção do projeto, facilitando a separação de responsabilidades, reutilização de código e manutenção de cada componente.
Os componentes foram abstraídos de forma a permitir uma maior separação entre as camadas de lógica e visual, semelhante à pattern de Dumb e Smart Components, porém um cuidado maior foi empregado para evitar excesso de abstrações, a qual poderia potencialmente poderia dificultar a navegação pelo projeto.
Um aspecto importante a mencionar é que há uma ligeira diferença entre o peso da fonte renderizada no Figma e o browser: https://forum.figma.com/t/why-does-a-font-weight-in-figma-seem-lighter-than-the-same-weight-in-the-browser/2207; assim, não é possível garantir 100% de paridade com o layout fornecido, pois cada dispositivo processa fontes e propriedades relacionadas de uma forma diferente.
Obs.: o erro "Warning: Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." exibido no console ocorre devido à remoção de forwardRef e definição de "ref" como um prop comum. Isso não afeta o funcionamento dos componentes no shadcn.
Obs. 2: Boilerplate gerado via Progenitor: https://github.com/sidneifjr/Progenitor
└── 📁ecommerce-schoen
└── .eslintrc.json
└── .gitignore
└── .prettierrc
└── components.json
└── next-env.d.ts
└── next.config.mjs
└── package.json
└── pnpm-lock.yaml
└── postcss.config.mjs
└── 📁public
└── vercel.svg
└── README.md
└── 📁src
└── 📁app
└── 📁cart
└── page.tsx
└── favicon.ico
└── globals.css
└── layout.tsx
└── loading.tsx
└── page.tsx
└── 📁products
└── 📁[slug]
└── page.tsx
└── 📁assets
└── loader.svg
└── logo.svg
└── order-fulfilled.svg
└── pix.svg
└── product-image.png
└── 📁products
└── botas.png
└── chinelos.png
└── chuteira.png
└── hero-image.png
└── product-1.png
└── product-2.png
└── product-3.png
└── sandalia.png
└── sapatenis.png
└── tenis.png
└── 📁components
└── 📁cart
└── cart-details.tsx
└── 📁cart-list
└── cart-list-item-buttons.tsx
└── index.tsx
└── 📁cart-modal
└── cart-modal-form-default.tsx
└── cart-modal-form-fulfilled.tsx
└── index.tsx
└── input-field.tsx
└── header.tsx
└── hero.tsx
└── loader.tsx
└── no-products-found.tsx
└── 📁product
└── index.tsx
└── product-carousel-thumb.tsx
└── product-carousel.tsx
└── product-info.tsx
└── 📁product-list
└── index.tsx
└── product-list-heading.tsx
└── product-list-item.tsx
└── product-list-side-menu.tsx
└── slider.tsx
└── 📁typography
└── h1.tsx
└── h2.tsx
└── h3.tsx
└── h4.tsx
└── large.tsx
└── lead.tsx
└── paragraph.tsx
└── small.tsx
└── 📁ui
└── aspect-ratio.tsx
└── button.tsx
└── card.tsx
└── carousel.tsx
└── dialog.tsx
└── input.tsx
└── label.tsx
└── navigation-menu.tsx
└── sonner.tsx
└── 📁contexts
└── cart-context.tsx
└── 📁data
└── product-list.tsx
└── 📁hooks
└── useCarousel.ts
└── useCart.ts
└── useFilterProducts.ts
└── useFindProduct.ts
└── useModal.ts
└── useShowPassword.ts
└── 📁lib
└── utils.ts
└── 📁tests
└── header.test.tsx
└── hero.test.tsx
└── no-products-found.test.tsx
└── 📁types
└── index.ts
└── 📁utils
└── capitalizeFirstLetter.ts
└── formatCurrency.ts
└── handleAccentedCharacters.ts
└── tailwind.config.ts
└── 📁test
└── vitest.setup.ts
└── tsconfig.json
└── vitest.config.ts
- Testes unitários mais extensivos.
- Testes e2e, para validar Server Components (conforme recomendado pelos docs do Next.js).
- Refatorar useFilterProducts.
- Limpar itens do carrinho, ao finalizar o fluxo;