├── .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 |
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 |
--------------------------------------------------------------------------------