Skip to content

RocketShoes é uma aplicação para adicionar tênis de diferentes modelos e em diferentes quantidades ao carrinho de compras

Notifications You must be signed in to change notification settings

vitorsemidio-dev/ignite-rocketshoes

Repository files navigation

Desafio 01 - Criando um hook de carrinho de compras

💻 Sobre o desafio

Nesse desafio, você deverá criar uma aplicação para treinar o que aprendeu até agora no ReactJS

Essa será uma aplicação onde o seu principal objetivo é criar um hook de carrinho de compras. Você terá acesso a duas páginas, um componente e um hook para implementar as funcionalidades pedidas nesse desafio:

  • Adicionar um novo produto ao carrinho;
  • Remover um produto do carrinho;
  • Alterar a quantidade de um produto no carrinho;
  • Cálculo dos preços sub-total e total do carrinho;
  • Validação de estoque;
  • Exibição de mensagens de erro;
  • Entre outros.

A seguir veremos com mais detalhes o que e como precisa ser feito 🚀

Template da aplicação

Para realizar esse desafio, criamos para você esse modelo que você deve utilizar como um template do GitHub.

O template está disponível na seguinte URL:

GitHub - rocketseat-education/ignite-template-reactjs-criando-um-hook-de-carrinho-de-compras

Dica: Caso não saiba utilizar repositórios do GitHub como template, temos um guia em nosso FAQ.

Se preparando para o desafio

Para esse desafio, além dos conceitos vistos em aula utilizaremos algumas coisa novas para deixar a nossa aplicação ainda melhor. Por isso, antes de ir diretamente para o código do desafio, explicaremos um pouquinho de:

  • Fake API com JSON Server;
  • Preservar dados do carrinho com localStorage API;
  • Mostrar erros com toastify.

Fake API com JSON Server

Assim como utilizamos o MirageJS no módulo 2 para simular uma API com os dados das transações da aplicação dtmoney, vamos utilizar o JSON Server para simular uma API que possui as informações dos produtos e do estoque.

Navegue até a pasta criada, abra no Visual Studio Code e execute os seguintes comandos no terminal:

yarn
yarn server

Em seguida, você vai ver a mensagem:

./docs/Desafio%2001%20-%20Criando%20um%20hook%20de%20carrinho%20de%20compra%20294b868df1ae430092f1fec33d8d4751/Untitled.png

Perceba que ele iniciou uma fake API com os recursos /stock e /products em localhost na porta 3333 a partir das informações do arquivo server.json localizado na raiz do seu projeto. Acessando essas rotas no seu navegador, você consegue ver o retorno das informações já em JSON:

./docs/Desafio%2001%20-%20Criando%20um%20hook%20de%20carrinho%20de%20compra%20294b868df1ae430092f1fec33d8d4751/Untitled%201.png

./docs/Desafio%2001%20-%20Criando%20um%20hook%20de%20carrinho%20de%20compra%20294b868df1ae430092f1fec33d8d4751/Untitled%202.png

Para acessar a listagem de todos os produtos e estoque, basta realizar uma requisição GET nas rotas /products e /stock respectivamente. Para acessar os dados de um único item utilize os route params, exemplo: /products/1 e /stock/1 para acessar os dados do produto e estoque do produto de id 1, respectivamente.

Dessa forma, basta consumir essas rotas da API normalmente com o axios. Caso queira estudar mais sobre o JSON Server, dê uma olhada aqui:

typicode/json-server

Preservando carrinho com localStorage API

Para preservar os dados do carrinho mesmo se fecharmos a aplicação, utilizaremos a localStorage API

Essa é uma API que nos permite persistir dados no navegador em um esquema de chave-valor (semelhante ao que temos com objetos JSON). Como essa é uma API global, você não precisa importar nada antes de usar.

Para salvar os dados, você deve utilizar o método setItem. Como primeiro argumento você deve informar o nome que você quer dar para o registro, no caso desse desafio é obrigatório utilizar o nome @RocketShoes:cart. Já o segundo argumento é o valor do registro que obrigatoriamente precisa estar no formato string. Abaixo segue um exemplo:

localStorage.setItem('@RocketShoes:cart', cart)
💡 Caso queira enviar um valor para o registro que não esteja no formato `string`, é preciso tratá-lo (ex.: `JSON.stringify`). Isso fará com que um objeto, lista, número ou qualquer outro valor seja convertido para uma string.

Para recuperar os dados, você deve utilizar o método getItem passando como argumento do registro que, no caso desse desafio, é obrigatório utilizar como @RocketShoes:cart. Abaixo segue um exemplo:

const storagedCart = localStorage.getItem("@RocketShoes:cart");
💡 O valor retornado pelo método `getItem` é sempre no formato `string`. Caso você queira utilizar esse dado em outro formato, é preciso tratá-los (ex.: `JSON.parse`). Isso irá converter a informação ao estado original de quando foi salva com o `JSON.strigify`, seja uma lista, um objeto ou outro tipo de dado.

Caso queira estudar mais sobre a localStorage API, dê uma olhada aqui

Window.localStorage

Mostrando erros com toastify

Para mostrar os erros em tela, iremos utilizar um pacote chamado react-toastify. Ela ajuda a mostra informações temporárias e rápidas de uma forma bem bonita.

De todos os métodos, utilizaremos apenas o error e será obrigatório utilizar mensagens predefinidas para que os testes passem (veremos mais sobre isso)

Caso queira estudar mais sobre a react-toastify, dê uma olhada aqui

fkhadra/react-toastify

O que devo editar na aplicação?

Com o template já clonado, as depêndencias instaladas e a fake API rodando, você deve completar onde não possui código com o código para atingir os objetivos de cada teste. Os documentos que devem ser editados são:

components/Header/index.tsx

./docs/Desafio%2001%20-%20Criando%20um%20hook%20de%20carrinho%20de%20compra%20294b868df1ae430092f1fec33d8d4751/Untitled%203.png

Você deve receber o array cart do hook useCart e mostrar em tela a quantidade de produtos distintos adicionados ao carrinho. Dessa forma, se o carrinho possui 4 unidades do item A e 1 unidade do item B o valor a ser mostrado é 2 itens.

pages/Home/index.tsx

./docs/Desafio%2001%20-%20Criando%20um%20hook%20de%20carrinho%20de%20compra%20294b868df1ae430092f1fec33d8d4751/Untitled%204.png

Você deve renderizar os produtos buscados da fake API em tela com as informações de título, imagem, preço e quantidade adicionada ao carrinho. Por fim, é preciso implementar a funcionalidade de adicionar o produto escolhido ao carrinho ao clicar no botão ADICIONAR AO CARRINHO.

Nesse arquivo, temos três pontos importantes a serem implementados:

  • cartItemsAmount: Deve possuir as informações da quantidade de cada produto no carrinho. Sugerimos criar um objeto utilizando reduce onde a chave representa o id do produto e o valor a quantidade do produto no carrinho. Exemplo: se você possuir no carrinho um produto de id 1 e quantidade 4 e outro produto de id 2 e quantidade 3, o objeto ficaria assim:
{
	1: 4,
	2: 3
}
  • loadProducts: Deve buscar os produtos da Fake API e formatar o preço utilizando o helper utils/format
  • handleAddProduct: Deve adicionar o produto escolhido ao carrinho.

pages/Cart/index.tsx

./docs/Desafio%2001%20-%20Criando%20um%20hook%20de%20carrinho%20de%20compra%20294b868df1ae430092f1fec33d8d4751/Untitled%205.png

Você deve renderizar uma tabela com a imagem, título, preço unitário, quantidade de unidades e preço subtotal de cada produto no carrinho. Além disso, também é preciso renderizar o preço total do carrinho. Por fim, é preciso implementar as funcionalidades dos botões de decrementar, incrementar e remover o produto do carinho.

Nesse arquivo, temos cinco pontos importantes a serem implementados:

  • cartFormatted: Deve formatar o carrinho adicionando os campos priceFormatted (preço do produto) e subTotal (preço do produto multiplicado pela quantidade) ambos devidamente formatados com o utils/format.
  • total: Deve possuir a informação do valor total do carrinho devidamente formatado com o utils/format.
  • handleProductIncrement: Deve aumentar em 1 unidade a quantidade do produto escolhido ao carrinho.
  • handleProductDecrement: Deve diminuir em 1 unidade a quantidade do produto escolhido ao carrinho, onde o valor mínimo é 1 (nesse caso o botão deve estar desativado).
  • handleRemoveProduct: Deve remover o produto escolhido do carrinho.

hooks/useCart.tsx

Apesar de não retornar diretamente nenhuma renderização de elementos na interface como os outros arquivos, esse é o coração do desafio. Ele é responsável por:

  • hook useCart;
  • context CartProvider;
  • manipular localStorage;
  • exibir toasts.

Então é aqui que você vai implementar as funcionalidades que serão utilizadas pelo restante do app. Os principais pontos são:

  • cart: Deve verificar se existe algum registro com o valor @RocketShoes:cart e retornar esse valor caso existir. Caso contrário, retornar um array vazio.
  • addProduct: Deve adicionar um produto ao carrinho. Porém, é preciso verificar algumas coisas:
    • O valor atualizado do carrinho deve ser perpetuado no localStorage utilizando o método setItem.
    • Caso o produto já exista no carrinho, não se deve adicionar um novo produto repetido, apenas incrementar em 1 unidade a quantidade;
    • Verificar se existe no estoque a quantidade desejada do produto. Caso contrário, utilizar o método error da react-toastify com a seguinte mensagem:
    toast.error("Quantidade solicitada fora de estoque");
    • Capturar utilizando trycatch os erros que ocorrerem ao longo do método e, no catch, utilizar o método error da react-toastify com a seguinte mensagem:
    toast.error("Erro na adição do produto");
  • removeProduct: Deve remover um produto do carrinho. Porém, é preciso verificar algumas coisas:
    • O valor atualizado do carrinho deve ser perpetuado no localStorage utilizando o método setItem.
    • Capturar utilizando trycatch os erros que ocorrerem ao longo do método e, no catch, utilizar o método error da react-toastify com a seguinte mensagem:
    toast.error("Erro na remoção do produto");
  • updateProductAmount: Deve atualizar a quantidade de um produto no carrinho. Porém, é preciso verificar algumas coisas:
    • O valor atualizado do carrinho deve ser perpetuado no localStorage utilizando o método setItem.
    • Se a quantidade do produto for menor ou igual a zero, sair da função updateProductAmount instantaneamente.
    • Verificar se existe no estoque a quantidade desejada do produto. Caso contrário, utilizar o método error da react-toastify com a seguinte mensagem:
    toast.error("Quantidade solicitada fora de estoque");
    • Capturar utilizando trycatch os erros que ocorrerem ao longo do método e, no catch, utilizar o método error da react-toastify com a seguinte mensagem:
    toast.error("Erro na alteração de quantidade do produto");

Especificação dos testes

Em cada teste, tem uma breve descrição no que sua aplicação deve cumprir para que o teste passe.

💡 Caso você tenha dúvidas quanto ao que são os testes, e como interpretá-los, dê uma olhada em **[nosso FAQ](https://www.notion.so/FAQ-Desafios-ddd8fcdf2339436a816a0d9e45767664)**

Para esse desafio, temos os seguintes testes:

Teste components/Header/index.tsx

Testes pages/Home/index.tsx

Testes pages/Cart/index.tsx

Testes hooks/useCart.tsx

Como deve ficar a aplicação ao final?

Está com dúvidas (ou curioso 👀) para ver como deve ficar a aplicação ao final do desafio? Deixamos abaixo um vídeo mostrando as principais funcionalidades que você deve implementar para te ajudar (ou matar sua curiosidade 👀).

📅 Entrega

Esse desafio deve ser entregue a partir da plataforma da Rocketseat. Envie o link do repositório que você fez suas alterações. Após concluir o desafio, além de ter mandado o código para o GitHub, fazer um post no Linkedin é uma boa forma de demonstrar seus conhecimentos e esforços para evoluir na sua carreira para oportunidades futuras.

Solução do desafio

Caso você queira ver como resolver o desafio, fizemos um vídeo explicando o passo a passo para cumprir com todos os requisitos da aplicação:

https://youtu.be/NTeUIfUtKWw

Feito com 💜 por Rocketseat 👋 Participe da nossa comunidade aberta!

About

RocketShoes é uma aplicação para adicionar tênis de diferentes modelos e em diferentes quantidades ao carrinho de compras

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published