JSFiddle - React, Tailwind, and code Playground

HTML

<div class="enough-energy">
  <p>You have enough energy to continue your trip.</p>
</div>
<div class="wrapper">
  <div class="charge-stage"></div>
</div>
<div class="timer">
  <span class="hour">0</span> <span class="label">hour  </span><span class="minute">0</span><span class="label">minutes</span>
</div>

CSS

.enough-energy {
  opacity: 0;
}
.wrapper {
  border: 1px solid #ccc;
  height: 50px;
  width: 300px;
  margin: 20px 0;
  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIxcHgiIGhlaWdodD0iMXB4IiB2aWV3Qm94PSIwIDAgMSAxIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPiAgICAgICAgPHRpdGxlPlJlY3RhbmdsZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgZmlsbD0iI0NDQ0NDQyIgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSI+PC9yZWN0PiAgICA8L2c+PC9zdmc+);
    background-position:80%;
    background-position-y: initial;
    background-repeat-x: no-repeat;
}

.charge-stage{
  width: 0%;
  height: 100%;
  background: #23b900;
}

.timer span {
  font-size: 28px;
}

.timer span.label {
  font-size: 18px;
  color: #999;
}

JavaScript

let batteriesTimeToChargeMap  = {
	"90D" : [
  	{ minute: 0, percentage: 15 },
  	{ minute: 1, percentage: 20 },
  	{ minute: 3, percentage: 30 },
  	{ minute: 5, percentage: 40 },
  	{ minute: 8, percentage: 50 },
  	{ minute: 13, percentage: 60 },
  	{ minute: 21, percentage: 70 },
    { minute: 30, percentage: 80 },
    { minute: 50, percentage: 90 },
    { minute: 84, percentage: 100 }
  ]
}

let intervalTime = 12 // higher the number slower the animation speed
let intervalSpeed = 10
let chargeTracker = 0
let speedOffset = intervalTime
let timeTracker = intervalTime 
 
animate(batteriesTimeToChargeMap["90D"])

function updateTime() {
    timeTracker++
    //console.log(timeTracker)
    let minute = Math.floor(timeTracker/speedOffset)
    let hour = 0
    console.log(minute)
    if (minute >= 60 ) {
    	hour = Math.floor(minute/60)
      minute = minute - hour*60
    }
  	document.querySelector('.hour').textContent = hour
		document.querySelector('.minute').textContent = minute
}

function animate(battery) {
  let maxTime = battery[chargeTracker+1].minute - battery[chargeTracker].minute
  let maxPercentage =  battery[chargeTracker+1].percentage - battery[chargeTracker].percentage
  window.width = battery[chargeTracker].percentage
	window.percentageIncreament = (maxPercentage/maxTime)/speedOffset
  
  // Display enough energy
  if (battery[chargeTracker].percentage >= 80) {
    // Once it hits 60% make it slower
    //intervalTime = 20
  	document.querySelector('.enough-energy').style.opacity = `1`    
  }
  
  chargeTracker++
	window.animation = setInterval(updateWidth.bind(null, battery[chargeTracker].percentage, battery, chargeTracker), intervalTime)
 
}

function updateWidth(maxPercentage, battery, chargeTracker) {
		width += percentageIncreament
    
    // Keep increasing the width till the max percentage
    if(width <= maxPercentage) {
    	updateTime()
			return document.querySelector('.charge-stage').style.width = `${width}%`    
   ...