├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── img │ ├── pokecoin.png │ ├── pokestore-fire.PNG │ ├── pokestore-grass.PNG │ ├── pokeball-fire.svg │ └── pokeball-grass.svg ├── manifest.json └── index.html ├── src ├── services │ └── api.js ├── index.js ├── components │ ├── Search │ │ ├── index.js │ │ └── styles.css │ ├── ItemCart │ │ ├── styles.css │ │ └── index.js │ ├── Cards │ │ ├── styles.css │ │ └── index.js │ ├── Card │ │ ├── index.js │ │ └── styles.css │ ├── Header │ │ ├── styles.css │ │ └── index.js │ └── Cart │ │ ├── index.js │ │ └── styles.css ├── styles.css └── App.js ├── .gitignore ├── package.json └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saranascimento/desafio-loja-pokemon/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saranascimento/desafio-loja-pokemon/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saranascimento/desafio-loja-pokemon/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/img/pokecoin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saranascimento/desafio-loja-pokemon/HEAD/public/img/pokecoin.png -------------------------------------------------------------------------------- /public/img/pokestore-fire.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saranascimento/desafio-loja-pokemon/HEAD/public/img/pokestore-fire.PNG -------------------------------------------------------------------------------- /public/img/pokestore-grass.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saranascimento/desafio-loja-pokemon/HEAD/public/img/pokestore-grass.PNG -------------------------------------------------------------------------------- /src/services/api.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const api = axios.create({ 4 | baseURL: 'https://pokeapi.co/api/v2/' 5 | 6 | }); 7 | 8 | export default api -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | ReactDOM.render( 6 | 7 | 8 | , 9 | document.getElementById('root') 10 | ); 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/components/Search/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './styles.css' 4 | 5 | const Search = ({filterUpdate}) => { 6 | 7 | return ( 8 | filterUpdate(event.target.value.toLowerCase())} 10 | type="text" 11 | id="search" 12 | placeholder="Buscar Pokemon..." 13 | 14 | /> 15 | ) 16 | } 17 | 18 | export default Search; -------------------------------------------------------------------------------- /src/components/ItemCart/styles.css: -------------------------------------------------------------------------------- 1 | .item { 2 | display: grid; 3 | grid-template-columns: 60px 1fr 65px; 4 | width: 100%; 5 | align-items: center; 6 | justify-items: flex-start; 7 | padding: 8px 0; 8 | font-size: 18px; 9 | } 10 | 11 | .item:nth-child(2n+1) { 12 | background-color: whitesmoke; 13 | } 14 | 15 | .item_pokemon-image { 16 | width: 50px; 17 | margin-left: 4px; 18 | } 19 | 20 | .item_pokemon-name { 21 | font-size: 14px; 22 | } 23 | 24 | .price { 25 | display: flex; 26 | align-items: center; 27 | justify-content: center; 28 | } -------------------------------------------------------------------------------- /src/components/Search/styles.css: -------------------------------------------------------------------------------- 1 | #search { 2 | width: 80%; 3 | font-size: 16px; 4 | padding: 12px 20px 12px 40px; 5 | border: 1px solid #ddd; 6 | border-radius: 4px; 7 | background: #ffffff url(https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Vector_search_icon.svg/111px-Vector_search_icon.svg.png) no-repeat; 8 | background-size: 20px; 9 | background-position: 1.8% 50%; 10 | 11 | } 12 | 13 | @media only screen and (max-width: 700px) { 14 | .logo-wrapper p { 15 | display: none; 16 | } 17 | 18 | #search { 19 | width: 85%; 20 | } 21 | } -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/components/Cards/styles.css: -------------------------------------------------------------------------------- 1 | .pokemon-list { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fit, minmax(225px, 1fr)); 4 | grid-gap: 20px; 5 | padding-inline-start: 0; 6 | align-items: center; 7 | justify-items: center; 8 | max-width: 800px; 9 | margin: 0 20px; 10 | } 11 | 12 | .store{ 13 | margin-bottom: 35px; 14 | display: flex; 15 | justify-content: center; 16 | } 17 | 18 | @media only screen and (max-width: 700px) { 19 | .store{ 20 | flex-direction: column-reverse; 21 | align-items: center; 22 | } 23 | 24 | .pokemon-list{ 25 | max-width: initial; 26 | } 27 | } -------------------------------------------------------------------------------- /src/components/ItemCart/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './styles.css' 3 | 4 | const ItemCart = ({pokemon}) => { 5 | return ( 6 |
7 | image pokemon 8 | {pokemon.name}{` (x${pokemon.amount})`} 9 |
10 | image of pokecoin 11 | {pokemon.price * pokemon.amount} 12 |
13 |
14 | ) 15 | } 16 | 17 | export default ItemCart -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pokemon-store", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.11.0", 7 | "@testing-library/jest-dom": "^4.2.4", 8 | "@testing-library/react": "^9.3.2", 9 | "@testing-library/user-event": "^7.1.2", 10 | "axios": "^0.19.2", 11 | "react": "^16.13.1", 12 | "react-dom": "^16.13.1", 13 | "react-icons": "^3.10.0", 14 | "react-scripts": "3.4.1" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start" 18 | 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Ranchers&family=Press+Start+2P&family=Roboto:wght@400;700&family=Trade+Winds&display=swap'); 2 | 3 | :root { 4 | --primary-grass-color: #447e65; 5 | --secondary-grass-color: #DEFDE0; 6 | 7 | --primary-fire-color: #c24d4d; 8 | --secondary-fire-color:#FDDFDF; 9 | 10 | --dark-color: #696969; 11 | --light-color: #f5f5f5; 12 | 13 | } 14 | 15 | 16 | * { 17 | margin: 0; 18 | padding: 0; 19 | outline: 0; 20 | box-sizing: border-box; 21 | } 22 | 23 | body { 24 | background-color: var(--light-color); 25 | color: var(--dark-color); 26 | display: flex; 27 | justify-content: center; 28 | font-family: 'Roboto', sans-serif; 29 | } 30 | 31 | .container { 32 | max-width: 1024px; 33 | margin: 0 auto; 34 | } 35 | 36 | #root { 37 | width: 100%; 38 | } 39 | 40 | .pokemon-price-image { 41 | width: 24px; 42 | margin-right: 4px; 43 | 44 | } 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/components/Card/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './styles.css' 4 | 5 | const Card = ({id, type, image, name, price, setPokemonSelected,}) => { 6 | 7 | return ( 8 | 9 |
10 |
11 | {type} 12 |
13 | {name} 14 |
15 | image of pokecoin 16 | {price} 17 |
18 | 19 |
20 |
21 |
22 | ) 23 | } 24 | 25 | export default Card -------------------------------------------------------------------------------- /src/components/Header/styles.css: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | height: 100px; 4 | font-size: 18px; 5 | font-weight: bold; 6 | color: white; 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | margin-bottom: 20px; 11 | } 12 | 13 | .header-fire { 14 | background-color: var(--primary-fire-color); 15 | } 16 | 17 | .header-grass { 18 | background-color: var(--primary-grass-color); 19 | } 20 | 21 | .box-header { 22 | display: flex; 23 | align-items: center; 24 | justify-content: space-between; 25 | width: 100%; 26 | padding: 0 20px; 27 | } 28 | 29 | .logo-wrapper { 30 | display: flex; 31 | align-items: center; 32 | justify-content: center; 33 | } 34 | 35 | .logo-wrapper img { 36 | width: 35px; 37 | margin: 4px; 38 | } 39 | 40 | .logo-wrapper p { 41 | font-size: 1.4em; 42 | } 43 | 44 | @media only screen and (max-width: 700px) { 45 | .logo-wrapper p { 46 | display: none; 47 | } 48 | } 49 | 50 | .btn-header-cart { 51 | background: transparent; 52 | color: white; 53 | border: none; 54 | font-size: 28px; 55 | display: flex; 56 | justify-content: center; 57 | align-items: center; 58 | } 59 | 60 | .btn-header-cart span{ 61 | margin-left: 8px; 62 | font-size: 16px; 63 | } 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/components/Cards/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | 4 | import Card from '../Card' 5 | 6 | import "./styles.css" 7 | 8 | export default class Cards extends Component { 9 | 10 | 11 | getIdFromURL = (url) => { 12 | let id = parseInt(url.split("/")[6]) 13 | 14 | return id 15 | } 16 | 17 | 18 | render() { 19 | let {pokemonList, type, setPokemonSelected, filterPokemon} = this.props 20 | 21 | return ( 22 |
23 | 24 | {pokemonList.slice(0,32) 25 | .filter(pokemon => { 26 | return pokemon.pokemon.name.indexOf(filterPokemon) >= 0 27 | }) 28 | .map((pokemon, index) => ( 29 | 38 | 39 | ))} 40 |
41 | 42 | ) 43 | } 44 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Desafio - PokeStore 2 | 3 | 4 | ### Instalação das dependências do projeto: 5 | Agora, para ver a aplicação funcionando em sua máquina você precisa seguir os seguintes passos: 6 | 7 | ```sh 8 | $ yarn install 9 | ou 10 | $ npm install 11 | ``` 12 | 13 | ### Para executar o projeto: 14 | 15 | ```sh 16 | $ npm start 17 | ou 18 | $ yarn start 19 | ``` 20 | 21 | Para começar a comprar seus pokemon (Sim, o plural de Pokemon é Pokemon, haha) você pode acessar a PokeStore dos Pokemon de fogo clicando [aqui](https://desafio-pokestore.netlify.app/fire) , ou clicar [aqui](https://desafio-pokestore.netlify.app/grass) para a loja dos Pokemon do tipo Grama. 22 | 23 | ### Links dos temas: 24 | 25 | -- Para acessar a PokeStore de Fogo: http://localhost:3000/fire 26 | -- Para acessar a PokeStore de Grama: http://localhost:3000/grass 27 | 28 | ### Tecnologias: 29 | 30 | - **React / JavaScript** 31 | 32 | ### Screenshots do Projeto: 33 | -PokeStore de fogo 34 | ![PokeStore de fogo](./public/img/pokestore-fire.PNG) 35 | 36 | -PokeStore de Grama 37 | ![PokeStore da grama](./public/img/pokestore-grass.PNG) 38 | 39 | ### Funcionalidades do projeto: 40 | 41 | * Catálogo de produtos 42 | * Carrinho lateral 43 | * Resumo do carrinho 44 | * 2 lojas com estilos e tipos diferentes de Pokémon 45 | * Barra de busca para filtrar os Pokémon 46 | * Botão de finalizar compra, reiniciando o processo de compra 47 | * Modal de obrigado ao finalizar compra 48 | 49 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | PokeStore 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/components/Header/index.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | 3 | import {FaShoppingCart} from 'react-icons/fa' 4 | import { ClickAwayListener } from '@material-ui/core'; 5 | 6 | import Cart from '../Cart' 7 | import Search from '../Search' 8 | 9 | import "./styles.css" 10 | 11 | const Header = ({pokemonSelected, type, resetCart, filterUpdate}) => { 12 | 13 | const [open, setOpen] = React.useState(false); 14 | 15 | const handleClick = () => { 16 | setOpen((prev) => !prev); 17 | }; 18 | 19 | const handleClickAway = () => { 20 | setOpen(false); 21 | }; 22 | 23 | return ( 24 |
25 |
26 |
27 | Pokebola 28 |

PokeStore

29 |
30 | 31 | 34 | 35 | 36 |
37 |
38 | 42 |
43 | {open ? ( 44 | 45 | 51 | 52 | ) : null} 53 |
54 |
55 |
56 |
57 | ) 58 | }; 59 | 60 | 61 | 62 | export default Header; -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component }from 'react'; 2 | import api from '../src/services/api' 3 | 4 | import "./styles.css" 5 | 6 | import Header from './components/Header'; 7 | import Cards from './components/Cards'; 8 | import Cart from './components/Cart'; 9 | 10 | 11 | 12 | export default class App extends Component { 13 | 14 | constructor(props) { 15 | super(props) 16 | this.state = { 17 | pokemonList: [], 18 | pokemonSelected: [], 19 | type: "", 20 | filterPokemon: "", 21 | }; 22 | 23 | this.filterUpdate = this.filterUpdate.bind(this); 24 | } 25 | 26 | componentDidMount() { 27 | this.loadPokemons(); 28 | }; 29 | 30 | getPokemonThemeFromUrl = () => { 31 | return window.location.pathname.split("/")[1] === "fire" ? "fire" : "grass" 32 | } 33 | 34 | loadPokemons = async () => { 35 | let pokemonType = this.getPokemonThemeFromUrl() 36 | const response = await api.get(`type/${pokemonType}`) 37 | this.setState({ pokemonList: response.data.pokemon, type: response.data.name}) 38 | }; 39 | 40 | resetCart = () => { 41 | return this.setState({pokemonSelected: []}) 42 | } 43 | 44 | setPokemonSelected = (image, name, price) => { 45 | 46 | const found = this.state.pokemonSelected.findIndex(pokemon => pokemon.name === name ) 47 | 48 | if(found === -1) { 49 | return this.setState({pokemonSelected: [...this.state.pokemonSelected, {image, name, price, amount: 1 }]}) 50 | } 51 | 52 | let pokemonsSelectedList = [...this.state.pokemonSelected] 53 | 54 | pokemonsSelectedList[found].amount += 1 55 | 56 | this.setState({pokemonSelected: pokemonsSelectedList}) 57 | 58 | 59 | } 60 | 61 | filterUpdate(value) { 62 | this.setState({ 63 | filterPokemon: value 64 | }) 65 | } 66 | 67 | render () { 68 | const { pokemonList, type, pokemonSelected, filterPokemon } = this.state 69 | 70 | return ( 71 |
72 |
78 |
79 | 85 | 91 |
92 | 93 |
94 | ) 95 | 96 | } 97 | 98 | } 99 | 100 | 101 | -------------------------------------------------------------------------------- /public/img/pokeball-fire.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 24 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /public/img/pokeball-grass.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 24 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/components/Card/styles.css: -------------------------------------------------------------------------------- 1 | .card { 2 | width: 225px; 3 | height: 320px; 4 | background-color: white; 5 | border: 1px solid #DDD; 6 | border-radius: 5px; 7 | padding: 4px; 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | box-shadow: 1px 1px 7px 2px #ddd; 12 | transition: transform .2s; 13 | } 14 | 15 | 16 | .card-grass:hover { 17 | transform: scale(1.1); 18 | box-shadow: 0px 0px 4px 0px var(--primary-grass-color); 19 | } 20 | 21 | .card-fire:hover { 22 | transform: scale(1.1); 23 | box-shadow: 0px 0px 4px 0px var(--primary-fire-color); 24 | } 25 | 26 | .card figure{ 27 | width: 100%; 28 | height: 100%; 29 | display: flex; 30 | justify-content: center; 31 | flex-direction: column; 32 | align-items: center; 33 | position: relative; 34 | } 35 | 36 | .figure-card-fire { 37 | background-color: var(--secondary-fire-color); 38 | } 39 | 40 | .figure-card-grass { 41 | 42 | background-color: var(--secondary-grass-color); 43 | } 44 | 45 | .card figure::after { 46 | content: ""; 47 | display: block; 48 | width: 70%; 49 | height: 50%; 50 | border-radius: 100%; 51 | background-color: #fff; 52 | opacity: .7; 53 | position: absolute; 54 | top: 8%; 55 | left: 13%; 56 | } 57 | 58 | .card_pokemon-button { 59 | height: 36px; 60 | border-radius: 5px; 61 | background: none; 62 | margin-top: 10px; 63 | font-weight: bold; 64 | font-size: 14px; 65 | text-decoration: none; 66 | display: flex; 67 | justify-content: center; 68 | align-items: center; 69 | transition: all 0.2s; 70 | width: 100%; 71 | text-transform: uppercase; 72 | font-family: 'Roboto', sans-serif; 73 | } 74 | 75 | .card-btn-fire { 76 | border: 2px solid var(--primary-fire-color); 77 | color: var(--primary-fire-color); 78 | } 79 | 80 | .card-btn-grass { 81 | border: 2px solid var(--primary-grass-color); 82 | color: var(--primary-grass-color); 83 | } 84 | 85 | .card-btn-fire:hover { 86 | background: var(--primary-fire-color); 87 | color: white; 88 | } 89 | 90 | .card-btn-grass:hover { 91 | background: var(--primary-grass-color); 92 | color: white; 93 | } 94 | 95 | .card figure .card_pokemon-image { 96 | width: 70%; 97 | height: 50%; 98 | z-index: 1; 99 | } 100 | 101 | .card figure figcaption { 102 | display: flex; 103 | justify-content: center; 104 | align-items: center; 105 | flex-direction: column; 106 | width: 90%; 107 | } 108 | 109 | .card .card_pokemon-name { 110 | margin-top: 8px; 111 | margin-bottom: 8px; 112 | font-size: 1.3em; 113 | color: #696969; 114 | font-family: 'Roboto', sans-serif; 115 | } 116 | 117 | .card .card_pokemon-price-wrapper { 118 | display: flex; 119 | justify-content: center; 120 | align-items: center; 121 | } 122 | 123 | .card .card_pokemon-price { 124 | color: #a64b54; 125 | font-family: 'Press Start 2P', cursive; 126 | font-size: 14px; 127 | } 128 | 129 | @media only screen and (max-width: 700px) { 130 | 131 | 132 | .card-btn-fire { 133 | color: #fff; 134 | background: var(--primary-fire-color) ; 135 | } 136 | 137 | .card-btn-grass { 138 | color: #fff; 139 | background: var(--primary-grass-color) ; 140 | } 141 | 142 | .card-grass, 143 | .card-grass:hover{ 144 | transform: scale(1); 145 | box-shadow: 0px 0px 4px 0px var(--primary-grass-color); 146 | } 147 | 148 | .card-fire, 149 | .card-fire:hover{ 150 | transform: scale(1); 151 | box-shadow: 0px 0px 4px 0px var(--primary-fire-color); 152 | } 153 | 154 | } -------------------------------------------------------------------------------- /src/components/Cart/index.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import Modal from '@material-ui/core/Modal'; 3 | import Backdrop from '@material-ui/core/Backdrop'; 4 | import Fade from '@material-ui/core/Fade'; 5 | 6 | import {FaCheck} from 'react-icons/fa' 7 | 8 | import ItemCart from '../ItemCart' 9 | import './styles.css' 10 | 11 | const Cart = ({pokemonSelected, type, resetCart, filterUpdate}) => { 12 | 13 | let [active, changeActive ] = useState(false) 14 | 15 | const updateActive = (active) => { 16 | if(window.matchMedia('(max-width: 600px)').matches) { 17 | changeActive(!active) 18 | } 19 | } 20 | 21 | const handleOpen = () => { 22 | filterUpdate("") 23 | resetCart() 24 | setOpen(true); 25 | }; 26 | 27 | const handleClose = () => { 28 | setOpen(false); 29 | }; 30 | 31 | const [open, setOpen] = useState(false); 32 | 33 | return ( 34 |
updateActive(active)}> 35 |
36 |

Carrinho

37 |
38 |
39 | {pokemonSelected.map((pokemon) => ( 40 | 41 | 44 | ))} 45 |
46 |
47 |
48 |
49 | {pokemonSelected.reduce((totalPrice, pokemon) => { 50 | return totalPrice + pokemon.amount 51 | },0)} Pokemon 52 |
53 |
54 |

Total:

55 |
56 | image of pokecoin 57 | {pokemonSelected.reduce((totalPrice, pokemon) => { 58 | return totalPrice + Number(pokemon.price * pokemon.amount) 59 | },0)} 60 |
61 |
62 |
63 | 64 | 65 |
66 | 67 | 79 | 80 |
81 |
82 | 83 |

Obrigado!!!

84 |

Você recebeu de volta

85 | 86 | image of pokecoin 87 | 88 | {Number(Math.random() * 1000).toFixed(0)} 89 | 90 |
91 |
92 |
93 |
94 | 95 |
96 | 97 | ) 98 | }; 99 | 100 | export default Cart; -------------------------------------------------------------------------------- /src/components/Cart/styles.css: -------------------------------------------------------------------------------- 1 | .cart { 2 | color: var(--dark-color); 3 | width: 15em; 4 | max-height: 22em; 5 | background-color: white; 6 | display: flex; 7 | align-items: center; 8 | flex-direction: column; 9 | font-size: 1.5em; 10 | border: 2px solid #ddd; 11 | } 12 | 13 | .cart-wrapper { 14 | display: none; 15 | } 16 | 17 | .store .active-cart{ 18 | height: 450px; 19 | } 20 | 21 | @media only screen and (max-width: 700px) { 22 | .cart { 23 | align-items: center; 24 | flex-direction: column; 25 | border: 2px solid #ddd; 26 | margin-bottom: 40px; 27 | overflow: hidden; 28 | height: 80px; 29 | } 30 | 31 | .cart-body{ 32 | min-height: 100px; 33 | } 34 | 35 | } 36 | 37 | .cart-wrapper { 38 | position: relative; 39 | z-index: 2; 40 | } 41 | 42 | .cart-header { 43 | width: 100%; 44 | display: flex; 45 | justify-content: center; 46 | align-items: center; 47 | box-shadow: 1px 1px 5px #ccccccd9; 48 | margin-bottom: 4px; 49 | } 50 | 51 | .cart-header h1 { 52 | padding: 20px 8px; 53 | font-size: 32px; 54 | } 55 | 56 | .cart-body { 57 | width: 100%; 58 | max-height: 400px; 59 | overflow: auto; 60 | padding: 8px; 61 | } 62 | 63 | .cart-footer { 64 | width: 100%; 65 | display: inherit; 66 | flex-direction: column; 67 | margin-top: auto; 68 | padding: 8px; 69 | } 70 | 71 | .total-price { 72 | margin: 9px 0; 73 | display: flex; 74 | align-items: center; 75 | justify-content: space-between; 76 | } 77 | 78 | .total-price p { 79 | font-weight: 700; 80 | } 81 | 82 | .item_total-price { 83 | font-size: 18px; 84 | padding: 20px 0; 85 | border-top: 1px solid #ccc; 86 | border-bottom: 1px solid #ccc; 87 | margin-bottom: 8px; 88 | display: flex; 89 | justify-content: space-between; 90 | flex-direction: column; 91 | } 92 | 93 | .item_cart-button { 94 | width: 50%; 95 | padding: 8px; 96 | border: 1px solid #ccc; 97 | border-radius: 4px; 98 | margin: 20px auto; 99 | color: ghostwhite; 100 | font-weight: 700; 101 | font-size: 16px; 102 | cursor: pointer; 103 | } 104 | 105 | .btn-cart-fire { 106 | background-color: var(--primary-fire-color); 107 | } 108 | 109 | .btn-cart-grass { 110 | background-color: var(--primary-grass-color); 111 | } 112 | 113 | .btn-cart-grass:hover { 114 | background-color: #459674; 115 | } 116 | 117 | .btn-cart-fire:hover { 118 | background-color: #d83f3f 119 | } 120 | 121 | .modal { 122 | display: flex; 123 | align-items: center; 124 | justify-content: center; 125 | } 126 | 127 | .card-modal { 128 | width: 30%; 129 | height: 35%; 130 | display: flex; 131 | justify-content: center; 132 | align-items: center; 133 | flex-direction: column; 134 | padding: 2px 4px 3px; 135 | border-radius: 8px; 136 | } 137 | 138 | @media only screen and (max-width: 760px) { 139 | .card-modal { 140 | width: 80%; 141 | font-size: 1em; 142 | } 143 | } 144 | 145 | .card-modal-grass { 146 | background-color: var(--primary-grass-color); 147 | border: 2px solid green; 148 | box-shadow: 0px 0px 8px 3px var(--dark-color); 149 | } 150 | 151 | .card-modal-fire { 152 | background-color: var(--primary-fire-color); 153 | border: 2px solid #c33535; 154 | box-shadow: 0px 0px 8px 3px var(--dark-color); 155 | } 156 | 157 | .box-modal { 158 | width: 85%; 159 | height: 80%; 160 | display: flex; 161 | justify-content: center; 162 | align-items: center; 163 | flex-direction: column; 164 | border-radius: 4px; 165 | } 166 | 167 | .box-modal svg { 168 | font-size: 2em; 169 | } 170 | 171 | .box-modal-grass { 172 | background: var(--secondary-grass-color); 173 | } 174 | 175 | .box-modal-fire { 176 | 177 | background: var(--secondary-fire-color); 178 | } 179 | 180 | .card-modal h1 { 181 | font-size: 2.5em; 182 | } 183 | 184 | .card-modal p { 185 | font-size: 1.3em; 186 | padding: 8px; 187 | font-weight: 400; 188 | } 189 | 190 | .card-modal span { 191 | display: flex; 192 | justify-content: center; 193 | align-items: center; 194 | } 195 | 196 | 197 | --------------------------------------------------------------------------------