├── .gitignore ├── package.json ├── index.css ├── README.md ├── index.html ├── pizzaCalculator.js ├── pizzaCalculator.spec.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codingclub2022aula2", 3 | "version": "1.0.0", 4 | "description": "## Aula", 5 | "main": "index.js", 6 | "dependencies": { 7 | "browser-sync": "^2.27.7", 8 | "jest": "^27.5.1", 9 | "node-static": "^0.7.11" 10 | }, 11 | "devDependencies": {}, 12 | "scripts": { 13 | "start": "browser-sync start -s -f . --no-notify --host $LOCAL_IP --port 9000", 14 | "test": "jest" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/drFabio/coding-club-pizza-calculator.git" 19 | }, 20 | "author": "", 21 | "license": "ISC", 22 | "bugs": { 23 | "url": "https://github.com/drFabio/coding-club-pizza-calculator/issues" 24 | }, 25 | "homepage": "https://github.com/drFabio/coding-club-pizza-calculator#readme" 26 | } 27 | -------------------------------------------------------------------------------- /index.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Opa tudo bom? 3 | * Tomei a liberdade de anotar o código: 4 | * 🧐 = Pode ignorar se quiser, é sofisticado 5 | * 😄 = Informação 6 | * 👀 = dica importante para lição de casa 7 | */ 8 | 9 | /** 10 | * 😄 = Esse nome, sem nenhum sinal correpsonde as tags HTML 11 | */ 12 | label { 13 | font-weight: bold; 14 | color: red; 15 | border-bottom: 1px solid black; 16 | margin-bottom: 0.5rem; 17 | } 18 | /** 19 | * 😄 = Esse nome, [entre chaves] corresponde à atributos 20 | */ 21 | label[for="flavors"] { 22 | color: green; 23 | } 24 | 25 | h3 { 26 | color: blue; 27 | } 28 | /** 29 | * 😄 = Isso ilustra o box-model, estamos com width, border e padding. 30 | Cheque no editor como isso se parece 31 | */ 32 | form { 33 | /** 34 | * 😄 = A gente pode mudar como o tamanho é contado. 35 | Mudando o box-sizing 36 | */ 37 | box-sizing: border-box; 38 | width: 400px; 39 | padding: 2rem; 40 | border: 1px solid black; 41 | margin: 1rem; 42 | } 43 | /** 44 | * 😄 = .classe é como pegamos coias com a clase após o ponto. Veja no Html onde está formContent 45 | */ 46 | .formContent { 47 | /** 48 | * 😄 = Uma cor só para ajudar à debuggar 49 | */ 50 | background-color: hotpink; 51 | margin-bottom: 2rem; 52 | display: flex; 53 | flex-direction: column; 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introducão à HTML, CSS ,JS e gerenciamento de layouts 2 | 3 | Como rodar esse código: 4 | 5 | 1. Abra um console (ctrl+ shift+p no windows cmd+shift+p no mac) , digite "Create new terminal" 6 | 2. Uma janela vai se abrir, digite "npm i" 7 | 3. digite "npm run start" 8 | 4. Abra o navegador em localhost:3000 9 | 10 | ## Aula 11 | 12 | Calculadora de pizza, utilizando-se de HTML, CSS e Javascript 13 | 14 | - Uma forma de selecionar os sabores; 15 | - Uma forma de dizer quanto de cada sabor nós queremos; 16 | - A calculadora deve dizer quantas pizzas precisamos 17 | 18 | Ex: Marguerita 2X, Calabresa 1X, Lombo 3X. 19 | 20 | Resultado possível 1: 21 | Meio marguerita, Meio Lombo 22 | Inteira de calabresa 23 | 24 | Resultado possível 2: 25 | Meio marguerita, Meio Calabresa 26 | Inteira Lombo 27 | 28 | ## Nota 29 | 30 | HTML- Estrutura 31 | CSS - Decoracao 32 | JS - Comportamento 33 | 34 | ## Tarefas 35 | 36 | 1. Adicione o preco individual de pizzas no resumo de pizzas, por exemplo: "3 margheritas por 27 € (9 cada)" 37 | 2. Adicione um novo sabor de pizzas (Nota: Vamos ter que adicionar no cardápio E NO HTML) 38 | 3. Bônus: Descubra como limpar a quantidade ao clickar no botão Add. 39 | a. Exemplo, Usuário colocou 4 fatias de margherita 40 | b. Ao clickar em add o valor que no momento permanece como 4 iria para 0 41 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |

Resumo de fatias

12 | 13 | 14 |
15 |
16 | 17 | 18 |
19 |
20 | 21 | 26 |
27 | 28 | 29 |
30 | 31 |
32 |

Total em preco

33 |

34 |

Resumo de pizzas

35 | 36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /pizzaCalculator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 😄 = A lógica principal da nossa calculadora de pizzas 3 | * 4 | * @todo Na próxima etapa precisamos receber uma lista de fatias, nao só um número 5 | */ 6 | function calculateNumberOfPizzas(pizzaMenu, peopleOrders, costs = {}) { 7 | const slicesMap = {}; 8 | /** 9 | * 😄 = Essa é a taxa fixa do entregador 10 | */ 11 | const deliveryCost = costs.deliveryCost || 0; 12 | 13 | const inHousePrice = costs.inHousePrice || 0; 14 | 15 | /** 16 | * 🧐 = É um loop de todos os menus 17 | */ 18 | for (const currentOrder of peopleOrders) { 19 | const currentFlavor = currentOrder.flavor; 20 | const slices = currentOrder.quantity; 21 | if (!slicesMap[currentFlavor]) { 22 | slicesMap[currentFlavor] = 0; 23 | } 24 | slicesMap[currentFlavor] += slices; 25 | } 26 | const bill = {}; 27 | /** 28 | * 🧐 = Uma outra forma de fazer um loop , dessa vez em um 29 | * dicionário 30 | */ 31 | Object.keys(slicesMap).forEach((flavor) => { 32 | const sumOfSlices = slicesMap[flavor]; 33 | const numberOfPizzas = Math.ceil(sumOfSlices / 8); 34 | bill[flavor] = ( 35 | numberOfPizzas * pizzaMenu[flavor].price * (1 + inHousePrice) + 36 | deliveryCost 37 | ).toFixed(2); 38 | }); 39 | return bill; 40 | } 41 | 42 | /** 43 | * 🧐 = Uma diferenca do navegador e do servidor. 44 | * O servidor lida com módulos de forma diferente por padrão 45 | */ 46 | module.exports = { 47 | calculateNumberOfPizzas, 48 | }; 49 | -------------------------------------------------------------------------------- /pizzaCalculator.spec.js: -------------------------------------------------------------------------------- 1 | const { calculateNumberOfPizzas } = require("./pizzaCalculator"); 2 | 3 | /** 4 | * 😄 = Esse é o início do nosso TDD 5 | */ 6 | describe(`Pizza Calculator`, () => { 7 | /** 8 | * 😄 =Isso é um mapa ou dicionario. 9 | * chave = valor. 10 | * Chave = margherita, Valor { name: "Margherita", price: 9 } 11 | * Com isso, chave name , valor "Margherita" 12 | */ 13 | const menu = { 14 | margherita: { name: "Margherita", price: 9 }, 15 | mushroomAndHam: { name: "Regina", price: 11 }, 16 | veggie: { name: "Vegetariana", price: 13 }, 17 | }; 18 | const orders = [ 19 | { 20 | flavor: "margherita", 21 | quantity: 2, 22 | }, 23 | { 24 | flavor: "margherita", 25 | quantity: 3, 26 | }, 27 | { 28 | flavor: "mushroomAndHam", 29 | quantity: 5, 30 | }, 31 | { 32 | flavor: "margherita", 33 | quantity: 7, 34 | }, 35 | ]; 36 | it(`Calculates based on the orders and menu`, () => { 37 | expect(calculateNumberOfPizzas(menu, orders)).toEqual({ 38 | margherita: (Math.ceil(12 / 8) * menu.margherita.price).toFixed(2), 39 | mushroomAndHam: (Math.ceil(5 / 8) * menu.mushroomAndHam.price).toFixed(2), 40 | }); 41 | }); 42 | it(`Calculates the pizza with a percentage of price when in house`, () => { 43 | expect( 44 | calculateNumberOfPizzas(menu, orders, { inHousePrice: 0.1 }) 45 | ).toEqual({ 46 | margherita: (Math.ceil(12 / 8) * menu.margherita.price * 1.1).toFixed(2), 47 | mushroomAndHam: ( 48 | Math.ceil(5 / 8) * 49 | menu.mushroomAndHam.price * 50 | 1.1 51 | ).toFixed(2), 52 | }); 53 | expect( 54 | calculateNumberOfPizzas(menu, orders, { inHousePrice: 0.15 }) 55 | ).toEqual({ 56 | margherita: (Math.ceil(12 / 8) * menu.margherita.price * 1.15).toFixed(2), 57 | mushroomAndHam: ( 58 | Math.ceil(5 / 8) * 59 | menu.mushroomAndHam.price * 60 | 1.15 61 | ).toFixed(2), 62 | }); 63 | }); 64 | it.only(`Calculates the pizza the final price with a delivery cost`, () => { 65 | const deliveryCost = 2.3; 66 | const margheritaPrice = Math.ceil(12 / 8) * menu.margherita.price + 2.3; 67 | const mushroomAndHamPrice = 68 | Math.ceil(5 / 8) * menu.mushroomAndHam.price + 2.3; 69 | expect( 70 | calculateNumberOfPizzas(menu, orders, { deliveryCost: 2.3 }) 71 | ).toEqual({ 72 | margherita: margheritaPrice.toFixed(2), 73 | mushroomAndHam: mushroomAndHamPrice.toFixed(2), 74 | total: (deliveryCost + margheritaPrice + mushroomAndHamPrice).toFixed(2), 75 | }); 76 | }); 77 | }); 78 | 79 | /** 80 | * ÁREA DE NOTAS EM GERAL 81 | */ 82 | /** 83 | * 😄 = Isso é uma arrow function. 84 | */ 85 | // () => {} 86 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Opa tudo bom? 3 | * Tomei a liberdade de anotar o código: 4 | * 🧐 = Pode ignorar se quiser, é sofisticado 5 | * 😄 = Informação 6 | * 👀 = dica importante para lição de casa 7 | */ 8 | 9 | /** 10 | * 😄 = Aqui é onde a memória do sistema fica, 11 | * Pense nisso como a conta 12 | */ 13 | const orderState = { 14 | total: 0, 15 | flavorQuantityMap: {}, 16 | }; 17 | /** 18 | * 😄 = Esse é nosso carápio 19 | */ 20 | const flavorMap = { 21 | margherita: { name: "Margherita", price: 9 }, 22 | mushroomAndHam: { name: "Regina", price: 11 }, 23 | veggie: { name: "Vegetariana", price: 13 }, 24 | }; 25 | 26 | /** 27 | * 😄 = Quando o botao de adicionar é clicado isso é o que acontece 28 | */ 29 | function handlePizzaForm(event) { 30 | /** 31 | * 🧐 = pausa a submissao do formulario para alguma página 32 | * permitindo que a gente modifique. 33 | * 34 | */ 35 | event.preventDefault(); 36 | /** 37 | * 🧐 = Constrói um formulário que eu possa manipular 38 | */ 39 | const formData = new FormData(event.target); 40 | 41 | /** 42 | * 😄 = Para inspecionar o que está acontecendo, 43 | * Lembre-se que no console do navegador tudo que é escrito aqui 44 | * Vai aparecer lá 45 | */ 46 | console.log(`===============================`); 47 | console.log({ 48 | flavor: formData.get("flavors"), 49 | flavorQuantity: formData.get("flavorQuantity"), 50 | }); 51 | console.log(`===============================`); 52 | 53 | /** 54 | * 😄 = Com o valor do formulário que é texto, a gente transforma para número 55 | * Isso é o campo cujo o name é flavorQuantity. 56 | * Tente achá-lo no html 57 | */ 58 | const quantity = parseInt(formData.get("flavorQuantity")) || 1; 59 | /** 60 | * 😄 = Isso é o campo cujo o name é flavors. 61 | * Tente achá-lo no html 62 | */ 63 | const flavor = formData.get("flavors"); 64 | 65 | /** 66 | * 😄 = Acha o elemento cujo á propriedade id é sliceList 67 | * Tente achá-lo no html 68 | */ 69 | const targetList = document.querySelector("#sliceList"); 70 | /** 71 | * 😄 = Cria dinamicamente uma tag
  • 72 | * Para cada pedido de sabor nós vamos precisar de uma nova 73 | */ 74 | const listItem = document.createElement("li"); 75 | /** 76 | * 😄 = Coloca o valor do texto da tag para ser algo como 77 | * 10 margherita 78 | */ 79 | listItem.innerText = quantity + " " + flavorMap[flavor].name + " "; 80 | /** 81 | * 😄 = Efetivamente adiciona a nova tag
  • . 82 | * Pense nisso como preparar um prato na cozinha e finalmente entregar ele À mesa 83 | * se nunca chamássemos appendChild o conteúdo nunca apareceria na tela 84 | */ 85 | targetList.appendChild(listItem); 86 | 87 | /** 88 | * 🧐 = Invoca a funcao updateSlice, nao se preocupe com isso por hora 89 | */ 90 | updateSlice(flavor, quantity); 91 | /** 92 | * 🧐 = Invoca a funcao updateSummary, nao se preocupe com isso por hora 93 | */ 94 | updateSummary(); 95 | } 96 | /** 97 | * Gerencia o estado do pedido 98 | * @param {*} flavor 99 | * @param {*} quantity 100 | */ 101 | function updateSlice(flavor, quantity) { 102 | /** 103 | * 🧐 = pegamos o valor flavorQuantityMap, não se preocupe mto com isso por hora 104 | */ 105 | const { flavorQuantityMap } = orderState; 106 | 107 | /** 108 | * 😄 = Caso o valor não exista iniciamos com 0 109 | */ 110 | if (!flavorQuantityMap[flavor]) { 111 | flavorQuantityMap[flavor] = 0; 112 | } 113 | 114 | /** 115 | * 😄 = Somamos o valor que tinhamos com o que foi recém adicionao 116 | */ 117 | flavorQuantityMap[flavor] += quantity; 118 | /** 119 | * 🧐 = Loopa por todos os valore para atualizar o total 120 | * Não se preocupe mto com isso por hora 121 | */ 122 | orderState.total = Object.entries(flavorQuantityMap).reduce( 123 | (previousSum, [key, quantity]) => { 124 | /** 125 | * 👀 = Essa parte é a quantidade de pizzas 126 | * A gente parece precisar utilizar isso com frequencia 127 | */ 128 | const quantityOfPizzas = Math.ceil(quantity / 8); 129 | return previousSum + quantityOfPizzas * flavorMap[key].price; 130 | }, 131 | 0 132 | ); 133 | 134 | /** 135 | * 😄 = É sempre bom ver o que está acontecendo na "cabeca" da máquina. 136 | * Lembre-se de checar o console com frequencia 137 | **/ 138 | console.log(`~~~~~~~~~~~~~ Order state atual ~~~~~~~~~~~~~`); 139 | console.log(JSON.stringify(orderState)); 140 | console.log(`~~~~~~~~~~~~~~~~~~~~~~~~~~`); 141 | } 142 | 143 | /** 144 | * Atualiza o resumo de pizzas 145 | */ 146 | function updateSummary() { 147 | /** 148 | * 😄 = Adiciona o valor total com o euro grudado no elemento cujo id é total 149 | * Tente achá-lo no html 150 | */ 151 | document.getElementById("total").innerText = orderState.total + " €"; 152 | 153 | /** 154 | * 😄 = Procura o elemento com id de slicesSummary. 155 | * Tente achá-lo no HTML 156 | */ 157 | const targetList = document.getElementById("slicesSummary"); 158 | /** 159 | * 😄 = Limpa o sumário anterior, remove todo o conteúdo 160 | */ 161 | targetList.innerHTML = ""; 162 | 163 | /** 164 | * 🧐 = Loopa por todos os valore para a 165 | * Não se preocupe mto com isso por hora 166 | */ 167 | Object.entries(orderState.flavorQuantityMap).forEach(([flavor, quantity]) => { 168 | /** 169 | * 😄 = à partir daqui estou em um unico pedaco de pizza 170 | */ 171 | 172 | /** 173 | * 😄 = Da pizza atual, lemos o valor do preco no "cardápio" 174 | */ 175 | const priceOfCurrentFlavor = flavorMap[flavor].price; 176 | /** 177 | * 😄 = Da pizza atual, lemos o valor do nome da pizaa no "cardápio" 178 | */ 179 | const nameOfCurrentFlavor = flavorMap[flavor].name; 180 | 181 | /** 182 | * 😄 = Calculamos dado o número de fatias quantas pizzas precisaríamos 183 | */ 184 | const quantityOfPizzas = Math.ceil(quantity / 8); 185 | 186 | /** 187 | * 😄 = Cheque esses valores no console. 188 | * Um texto parecido deve aparecer para cada sabor 189 | */ 190 | console.log("-----------------------"); 191 | console.log("Preco do pedaco atual " + priceOfCurrentFlavor); 192 | console.log("Nome do pedaco atual " + nameOfCurrentFlavor); 193 | console.log("Quantidade de pedacos " + quantity); 194 | console.log("Quantidade de pizzas " + quantityOfPizzas); 195 | 196 | /** 197 | * 😄 = Cria-se um novo list item (li) 198 | */ 199 | const listItem = document.createElement("li"); 200 | 201 | /** 202 | * 😄 = "Colocamos o valor como 2 margheritas por 20 €" 203 | * Por exemplo 204 | */ 205 | listItem.innerText = 206 | quantityOfPizzas + 207 | " " + 208 | nameOfCurrentFlavor + 209 | " por " + 210 | priceOfCurrentFlavor * quantityOfPizzas + 211 | " €"; 212 | 213 | /** 214 | * 😄 = Addicionamos a lista de forma à imprimir na tela 215 | */ 216 | targetList.appendChild(listItem); 217 | }); 218 | } 219 | --------------------------------------------------------------------------------