{"id":21413302,"url":"https://github.com/cauandzn/rocketshoes","last_synced_at":"2026-04-11T01:54:04.772Z","repository":{"id":136253591,"uuid":"598839249","full_name":"CauanDZN/rocketshoes","owner":"CauanDZN","description":"A shoe sales React application.","archived":false,"fork":false,"pushed_at":"2023-02-07T22:52:24.000Z","size":230,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-09T04:07:24.077Z","etag":null,"topics":["javascript","json","json-server","react","reactjs","server","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CauanDZN.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-07T22:51:20.000Z","updated_at":"2023-04-12T13:03:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"8696ab82-4de7-4458-8fd7-dc62f85669f0","html_url":"https://github.com/CauanDZN/rocketshoes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CauanDZN/rocketshoes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CauanDZN%2Frocketshoes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CauanDZN%2Frocketshoes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CauanDZN%2Frocketshoes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CauanDZN%2Frocketshoes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CauanDZN","download_url":"https://codeload.github.com/CauanDZN/rocketshoes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CauanDZN%2Frocketshoes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271378680,"owners_count":24749192,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","json","json-server","react","reactjs","server","typescript"],"created_at":"2024-11-22T18:17:54.774Z","updated_at":"2026-04-11T01:53:57.467Z","avatar_url":"https://github.com/CauanDZN.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Desafio 01 - Criando um hook de carrinho de compras\n\n## 💻 Sobre o desafio\n\nNesse desafio, você deverá criar uma aplicação para treinar o que aprendeu até agora no ReactJS\n\nEssa 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:\n\n- Adicionar um novo produto ao carrinho;\n- Remover um produto do carrinho;\n- Alterar a quantidade de um produto no carrinho;\n- Cálculo dos preços sub-total e total do carrinho;\n- Validação de estoque;\n- Exibição de mensagens de erro;\n- Entre outros.\n\n## Se preparando para o desafio\n\nPara 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:\n\n- Fake API com JSON Server;\n- Preservar dados do carrinho com localStorage API;\n- Mostrar erros com toastify.\n\n### Fake API com JSON Server\n\nAssim como utilizamos o MirageJS no módulo 2 para simular uma API com os dados das transações da aplicação dt.money, vamos utilizar o JSON Server para simular uma API que possui as informações dos produtos e do estoque. \n\nNavegue até a pasta criada, abra no Visual Studio Code e execute os seguintes comandos no terminal:\n\n```bash\nyarn\nyarn server\n```\nDessa forma, basta consumir essas rotas da API normalmente com o axios. \n\n### Preservando carrinho com localStorage API\n\nPara preservar os dados do carrinho mesmo se fecharmos a aplicação, utilizaremos a **localStorage API**\n\nEssa é 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. \n\nPara 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:\n\n```bash\nlocalStorage.setItem('@RocketShoes:cart', cart)\n```\n\nCaso 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.\n\nPara 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:\n\n```jsx\nconst storagedCart = localStorage.getItem('@RocketShoes:cart');\n```\n\nO 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.\n\n### Mostrando erros com toastify\n\nPara mostrar os erros em tela, iremos utilizar um lib chamada **react-toastify**. Ela ajuda a mostra informações temporárias e rápidas de uma forma bem bonita.\n\nDe todos os métodos, utilizaremos apenas o `error` e será obrigatório utilizar mensagens predefinidas para que os testes passem (veremos mais sobre isso)\n\n## O que devo editar na aplicação?\n\nCom o template já clonado, as depêndencias instaladas e a [fake API rodando](https://www.notion.so/Desafio-01-Criando-um-hook-de-carrinho-de-compras-5769216778794019a83f544e79167b12), 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:\n\n- [src/components/Header/index.tsx](https://github.com/rocketseat-education/ignite-template-reactjs-criando-um-hook-de-carrinho-de-compras/blob/main/src/components/Header/index.tsx);\n- [src/pages/Home/index.tsx](https://github.com/rocketseat-education/ignite-template-reactjs-criando-um-hook-de-carrinho-de-compras/blob/main/src/pages/Home/index.tsx)\n- [src/pages/Cart/index.tsx](https://github.com/rocketseat-education/ignite-template-reactjs-criando-um-hook-de-carrinho-de-compras/blob/main/src/pages/Cart/index.tsx);\n- [src/hooks/useCart.tsx](https://github.com/rocketseat-education/ignite-template-reactjs-criando-um-hook-de-carrinho-de-compras/blob/main/src/hooks/useCart.tsx).\n\n### components/Header/index.tsx\n\nVocê 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`.\n\n### pages/Home/index.tsx\n\nVocê 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`.\n\nNesse arquivo, temos três pontos importantes a serem implementados:\n\n- **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:\n\n```jsx\n{\n\t1: 4,\n\t2: 3\n}\n```\n\n- **loadProducts:** Deve buscar os produtos da Fake API e formatar o preço utilizando o helper `utils/format`\n- **handleAddProduct:** Deve adicionar o produto escolhido ao carrinho.\n\n### pages/Cart/index.tsx\n\nVocê deve renderizar uma tabela com a imagem, título, preço unitário, quantidade de unidades e preço subtotal de cada produto o 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.\n\nNesse arquivo, temos cinco pontos importantes a serem implementados:\n\n- **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`.\n- **total:** Deve possuir a informação do valor total do carrinho devidamente formatado com o `utils/format`.\n- **handleProductIncrement:** Deve aumentar em 1 unidade a quantidade do produto escolhido ao carrinho.\n- **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).\n- **handleRemoveProduct:** Deve remover o produto escolhido do carrinho.\n\n### hooks/useCart.tsx\n\nApesar 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:\n\n- hook `useCart`;\n- context `CartProvider`;\n- manipular `localStorage`;\n- exibir `toasts`.\n\nEntão é aqui que você vai implementar as funcionalidades que serão utilizadas pelo restante do app. Os principais pontos são:\n\n- **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.\n- **addProduct:** Deve adicionar um produto ao carrinho. Porém, é preciso verificar algumas coisas:\n    - O valor atualizado do carrinho deve ser perpetuado no **localStorage** utilizando o método `setItem`.\n    - Caso o produto já exista no carrinho, não se deve adicionar um novo produto repetido, apenas incrementar em 1 unidade a quantidade;\n    - 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:\n\n    ```jsx\n    toast.error('Quantidade solicitada fora de estoque');\n    ```\n\n    - 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:\n\n    ```jsx\n    toast.error('Erro na adição do produto');\n    ```\n\n- **removeProduct:** Deve remover um produto do carrinho. Porém, é preciso verificar algumas coisas:\n    - O valor atualizado do carrinho deve ser perpetuado no **localStorage** utilizando o método `setItem`.\n    - 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:\n\n    ```jsx\n    toast.error('Erro na remoção do produto');\n    ```\n\n- **updateProductAmount:** Deve atualizar a quantidade de um produto no carrinho. Porém, é preciso verificar algumas coisas:\n    - O valor atualizado do carrinho deve ser perpetuado no **localStorage** utilizando o método `setItem`.\n    - Se a quantidade do produto for menor ou igual a zero, sair da função **updateProductAmount** instantaneamente.\n    - 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:\n\n    ```jsx\n    toast.error('Quantidade solicitada fora de estoque');\n    ```\n\n    - 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:\n\n    ```jsx\n    toast.error('Erro na alteração de quantidade do produto');\n    ```\n\n## Especificação dos testes\n\nEm cada teste, tem uma breve descrição no que sua aplicação deve cumprir para que o teste passe.\n\nCaso 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)**\n\nPara esse desafio, temos os seguintes testes:\n\n[Teste components/Header/index.tsx](https://www.notion.so/Teste-components-Header-index-tsx-4c2e827e1b1246e9bbb4c63e6c4e7972)\n\n[Testes pages/Home/index.tsx](https://www.notion.so/Testes-pages-Home-index-tsx-8c9b60a771684f60baf9b9c4de5aa8a9)\n\n[Testes pages/Cart/index.tsx](https://www.notion.so/Testes-pages-Cart-index-tsx-20a8e0aa574b4a8a8a8a6462bc769094)\n\n[Testes hooks/useCart.tsx](https://www.notion.so/Testes-hooks-useCart-tsx-ee1a6dd59bf74599aa8cc518bcda4a17)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcauandzn%2Frocketshoes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcauandzn%2Frocketshoes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcauandzn%2Frocketshoes/lists"}