JSFiddle - React, Tailwind, and code Playground

by Laura Kishimoto

HTML

<!DOCTYPE html>
<html>
<head>
  <title>javascript</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="css/style.css"/>
</head>
<body>

<div class="product-details product">
	<div class="product-img">
		<img id="product-img" src="https://res.cloudinary.com/lautsprecher-teufel/image/upload/c_fill,f_auto,h_200,q_auto,w_300/v1/products/BOOMSTER_GO/boomster-go-main-black-1300x1300x72.jpg" alt="Night Black BOOMSTER Go" class="product-details__image" />
	</div>
  <h1 class="product-details-name">BOOMSTER Go</h1>
	<div id="price" class="price product-details-price"></div>
	<div class="pagination"></div>
  <button id="button" class="button">Buy now</button>
</div>

 <script src="js/script.js"></script>
</body>
</html>

CSS

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.product-details {
  
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1rem;
  border: 1px solid rgb(5, 5, 5);
  border-radius: 0.5rem;

}

.product-details-name {
	margin-bottom: 1rem;
	text-align: center;
} 

.product-details-price {
	margin-bottom: 1rem;
	text-align: center;
}

.price {
  font-size: 1.5rem;
}

.button {
  appearance: none;
  display: block;
  width: 100%;
  padding: 0.8em;
  border: 0;
  color: white;
  background-color: green;
}

img {
  max-width: 100%;
}

.product .pagination {
	text-align: center;
	padding:40px 0px;
}
.product .pagination button{
	border:none;
    width:25px;
    height: 25px;
    margin:4px;
    cursor: pointer;

}

.product .pagination button.active{
	animation: activeButton 1s linear alternate infinite;
}

JavaScript

const API_URL = 'https://res.cloudinary.com/lautsprecher-teufel/raw/upload/v1599581070/test_assets/bikiniberlin-fixed.json'
const IMAGE_BASE_PATH = 'https://res.cloudinary.com/lautsprecher-teufel/image/upload/c_fill,f_auto,h_200,q_auto,w_300/'
let IMG = document.querySelector("#product-img")
let jsonObj

const getJSONData = async url => {
  const response = await fetch(url)
  return new Promise(function(resolve, reject) {   
    response.ok ? resolve(response.json()) : reject (response.statusText)
 })
}

getJSONData(API_URL).then(data => {
  jsonObj = {...data}
  colorButtonPagination(data)
}).catch(error => {
  console.error(error)
})

const colorButtonPagination = (data) => {
  for (let i in data) {
    const button = document.createElement("button")
      button.id = i
      button.setAttribute("onclick", "onClickChangeImage(this)")
      button.style.backgroundColor = data[i].productColour

    // set initial price for swatches.
    if(i == Object.keys(data)[0]) {
      document.getElementById("price").innerHTML = `&euro;${priceFormate(data[i].productPrice)}`
    }
    document.querySelector(".pagination").appendChild(button)
  }
}

// change image when pagination button click
const onClickChangeImage = (element) => {
  const buttons = [document.querySelector(".pagination").children]

  buttons && buttons.map((item, i) => {
    item[i].id == item.id ? item[i].classList.add("active") : item[i].classList.remove("active") 
  })

  //check if product is in Stock if not then button will be disabled
  disableBtn(jsonObj[element.id].inStock)

  //on click set new product image and price
  setInitialImageAndPrice(element)
}

const setInitialImageAndPrice = (element) => {
  IMG.src = `${IMAGE_BASE_PATH}${jsonObj[element.id].imageUrl}` 
  document.getElementById("price").innerHTML = `&euro;${priceFormate(jsonObj[element.id].productPrice)}`
}

const disableBtn = (element) => {
  return !element 
    ? document.getElementById("button").style.backgroundColor = '#dddddd'
 ...