Skip to content

russfraze/audiophile-ecommerce-website

Repository files navigation

Audiophile e-commerce website

Homepage

Overview

Links

  • Live Site URL: here

Available Scripts

In the project directory, you can run:

npm start

Runs the app in the development mode.
Open http://localhost:3000 to view it in your browser.

Features

Users can:

  • View the optimal layout for the app depending on their device's screen size
  • See hover states for all interactive elements on the page
  • Add/Remove products from the cart
  • Edit product quantities in the cart
  • Fill in all fields in the checkout
  • Receive form validations if fields are missed or incorrect during checkout
  • See correct checkout totals depending on the products in the cart
    • Shipping always adds $50 to the order
  • See an order confirmation modal after checking out with an order summary
  • Keep track of what's in the cart, even after refreshing the browser

Built with

  • Semantic HTML5 markup
  • CSS modules
  • Flexbox
  • CSS Grid
  • Mobile-first workflow
  • React - JS library

What I learned

Form validation

  • Reacting to lost focus
  • Handeling "was touched" state
  • Providing validation feedback
  • Managing overall form validity

Modals

  • creating modal component
  • adding modal via react portal

Cart Reducer

  • complex reducer logic

Code snippit of the ADD PRODUCT logic in the cartRecucer:

 if (action.type === 'ADD_PRODUCT') {
        const newTotalAmount = state.totalAmount + action.product.price * action.product.amount

        const existingCartProductsIndex = state.products.findIndex(product => product.id === action.product.id)
        
        const existingCartProduct = state.products[existingCartProductsIndex]
        
        let updatedProducts

        if (existingCartProduct) {
            const updatedProduct = {
                ...existingCartProduct,
                amount: existingCartProduct.amount + action.product.amount,
                total: existingCartProduct.total + action.product.price
            }
            updatedProducts = [...state.products]
            updatedProducts[existingCartProductsIndex] = updatedProduct
        } else {
            updatedProducts = state.products.concat(action.product)
        }

        return {
            products: updatedProducts,
            totalAmount: newTotalAmount
        }
    }