2
respostas

[Projeto] Minha solução

Antes mesmo de assistir o segundo vídeo quebrei a cabeça para resolver sozinho. Tive que pesquisar bastante e usei IA para sugerir como fazer o que eu desejava e, depois, para entender os conceitos da linguagem que estão por trás dela.

Em primeiro lugar, sequer cogitei usar o HTML como fonte de informação, uma vez que ele pode ser alterado diretamente no browser, o que ofereceria uma boa oportunidade de fraude. Além disso, separar o produto do valor por split() não funcionaria caso houvesse um produto como um "mouse-pad", por exemplo.

Pesquisando descobri que informações, como a lista dos produtos disponíveis e seus preços, vem de um back-end (o que quer que isso seja) e por isso resolvi colocar como constante no programa, e não no HTML. A IA me ensinou a usar dicionários, o que facilitou muito a minha vida.

Daí veio a ideia de representar o carrinho também como uma lista. Isso foi mais complicado mas, por acidente, usar também um dicionário. Como é um exemplo, iniciei com o que estava na imagem inicial.

Ao invés de ficar somando e subtraindo o total (sei lá, fiquei com medo de me confundir), criei uma função que soma o carrinho todo e resulta o total.

Daí, mostrar o carrinho e total ficou uma coisa sempre certa. O que estiver nas variáveis, estará na tela, evitando o bug que os professores corrigiram durante a construção.

Quando comecei a adicionar coisas no carrinho percebi que não fazia sentido deixar o mesmo item mais de uma vez como na solução dos professores, e sim mudar as quantidades. Como estou trabalhando com as variáveis, deu bastante trabalho, mas funcionou.

Mas e tirar os itens do carrinhos? Descobri que o meu programa (assim como os dos professores) aceita números negativos. E daí, digitando números negativos o programa ajusta sozinho o valor do item e o total.

Mas e quando chega a zero? E se baixar de zero ? Fiz mais uma modificação para retirar o item do carrinho se a quantidade for menor do que 1.

Daí tive que lidar com a ausência de preenchimento de quantidade. Descobri o que é NaN, e decidi que se o usuário deixar a quantidade em branco, o item do carrinho é removido. Poderia fazer diferente. Foi uma escolha.

No fim meu programa ficou muito mais complicado do que o do exemplo mas com as seguintes vantagens em relação ao exemplo dos professores:

  • Funciona com produtos com hífen ("-") no nome
  • Não usa o HTML como fonte de informação - o que é uma péssima prática
  • Foca apenas no controle do carrinho sem ter que preocupar com a soma, que é calculada a partir do carrinho
  • Evita que um mesmo produto entre duas vezes no carrinho
  • Permite, ainda de que um modo improvisado, a retirada de quantidades e mesmo de itens do carrinho

O código não cabe aqui. Vou ver como posto

2 respostas
// Produtos disponiveis - Conteúdo estático	nesse exemplo, 
// os produtos estão disponíveis em um array, mas poderiam ser carregados 
// de um banco de dados, de um arquivo JSON, de uma API, etc.

var products = [
    { name: "Fone de ouvido", price: 100 },
    { name: "Celular", price: 1300 },
    { name: "Oculus VR", price: 5000 }
]
 
// Carrinho com vários produtos e quantidade de cada um. Cada produto aparece apenas uma vez no carrinho,
// e deve ter uma quantidade maior ou igual a 1
var cart = [
    { product: products[1], quantity: 1}
]

// Função que calcula o valor total do carrinho
function getTotal(cart) {
    return cart.reduce((total, item) => total + item.product.price * item.quantity, 0)
}

// Função que adiciona um produto ao carrinho com uma quntidade passada por parametro
// Se o produto já estiver no carrinho, a quantidade é incrementada
// Caso ele não esteja, inclua.
// Como a quantidade pode ser negativa, caso a quantidade resultante do incremento
// for menor ou igual a zero, o produto é retirado do carrinho
//
// Parâmetros:  idProduto - nesse exemplo o indice do produto em products
//              quantidade - quantidade a adicionar
function addToCart(idProduto, quantidade) {
    var item = cart.find(item => item.product === products[idProduto])
    if (item) {
        item.quantity += quantidade
        if (item.quantity <= 0) {
            cart = cart.filter(i => i !== item)
        }
    } else {
        cart.push({ product: products[idProduto], quantity: quantidade })
    }
}

function removeProdutoDoCarrinho(idProduto) {
    produto = products[idProduto];
    cart = cart.filter(item => item.product !== produto)
}

function clearCart() {
    cart = [];
}

//////////////////////////////////////////////////////////////////////////////////////////////

// Até aqui as funções mexem apenas com o carrinho e produtos, sem interferir com a página HTML.
// A partir desse ponto estão as funções que interagem com a página HTML.


// A função mostraCarrinho() é responsável por exibir apenas o carrinho na tela.

function mostraCarrinho() {
    var listaProdutos = document.getElementById('lista-produtos')
    listaProdutos.innerHTML = ''
    var produtoElemento = document.createElement('section')
        produtoElemento.className = 'carrinho__produtos__produto'
    cart.forEach(item => {
           produtoElemento.innerHTML += `
            <section class="carrinho__produtos__produto">
                <span class="texto-azul">${item.quantity}x</span> ${item.product.name} <span class="texto-azul">R$${item.product.price * item.quantity}</span>
            </section>
        `
    })
    listaProdutos.appendChild(produtoElemento)
}

// Função mostraTotal() é responsável por exibir apenas o valor total do carrinho na tela.
function mostraTotal() {
    var valorTotal = document.getElementById('valor-total')
    valorTotal.innerHTML = `R$${getTotal(cart)}`
}

// Função limpar() é responsável por limpar o carrinho.
function limpar() {
    clearCart();
    atualizaCarrinhoNaTela();
}

// Função atualizaCarrinhoNaTela() é responsável por atualizar o carrinho na tela e o total.
function atualizaCarrinhoNaTela() {
    mostraCarrinho();
    mostraTotal();
}

// Função adicionar() que atende ao botão adicionar funciona do seguinte modo
// 1) Pega o produto em tela no html <select class="produto-input" name="produto" id="produto">
// 2) Pega a quantidade (número inteiro) do html <input class="quantidade-input" id="quantidade" type="number" placeholder="100">
// 3) Se a quantidade não está em branco, chama addToCart.
function adicionar() {
    var produtoSelect = document.getElementById('produto')
    var quantidadeInput = document.getElementById('quantidade')
    var idProduto = produtoSelect.selectedIndex;
    var quantidade = parseInt(quantidadeInput.value)
    
    // Trata o caso de quantidade vazia ou não numérica, removendo o carrinho. 
    // Escolhi fazer assim. Podia ser diferente
    if (!isNaN(quantidade) && quantidade !== 0) {
        addToCart(idProduto, quantidade)
    } else {
        removeProdutoDoCarrinho(idProduto);
    }
    atualizaCarrinhoNaTela();
}

// 
// Esse é o código que é executado quando a página é carregada.
//
mostraCarrinho();
mostraTotal();

Oi, Flavio! Tudo bem?

Sobre sua última dúvida, você apresentou um ótimo exemplo de pensamento crítico e evolução no projeto, buscando alternativas para melhorar funcionalidades e evitar problemas potenciais, como duplicidade de itens no carrinho ou cálculos incorretos.

Para facilitar sua postagem no fórum, você pode simplificar o compartilhamento de código dividindo-o em arquivos ou trechos menores. Assim, fica mais fácil para outros alunos revisarem e darem feedback. Veja como organizar:

1. Módulo de Produtos e Carrinho:

// Definição dos produtos disponíveis
const products = [
    { name: "Mouse", price: 50 },
    { name: "Teclado", price: 100 },
    { name: "Monitor", price: 800 },
];

// Definição do carrinho
let cart = [];

// Função para calcular o total do carrinho
function calculateTotal(cart) {
    return cart.reduce((sum, item) => sum + item.product.price * item.quantity, 0);
}

// Adicionar ou atualizar itens no carrinho
function addToCart(productId, quantity) {
    const product = products[productId];
    const item = cart.find((i) => i.product === product);

    if (item) {
        item.quantity += quantity;
        if (item.quantity <= 0) {
            cart = cart.filter((i) => i !== item);
        }
    } else if (quantity > 0) {
        cart.push({ product, quantity });
    }
}

// Remover um item do carrinho
function removeFromCart(productId) {
    cart = cart.filter((item) => item.product !== products[productId]);
}

// Limpar o carrinho
function clearCart() {
    cart = [];
}

2. Funções para Atualização do HTML:

// Atualizar a exibição do carrinho
function updateCartDisplay() {
    const cartContainer = document.getElementById("cart-items");
    cartContainer.innerHTML = cart.map((item) =>
        `<div>${item.quantity}x ${item.product.name} - R$${item.product.price * item.quantity}</div>`
    ).join("");
    document.getElementById("cart-total").textContent = `Total: R$${calculateTotal(cart)}`;
}

// Adicionar produto ao clicar no botão
function handleAddProduct() {
    const productId = document.getElementById("product-select").value;
    const quantity = parseInt(document.getElementById("quantity").value, 10) || 0;
    addToCart(productId, quantity);
    updateCartDisplay();
}

Com isso, seu código estará modularizado e mais fácil de entender e manter. Basta incluir no HTML as funções de evento como handleAddProduct nos botões para interagir com o carrinho.

Fico à disposição. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.