<div id="root">
</div>
#root {
  
  width : 100%;
  vertical-align: center;
  z-index: 100;
}

h1  {
  width: 100%
}

.fullWidth{
  width: 100%
}

.background {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transition:all 0.8s ease;
    z-index: -1;
}

.info {
  transition:all 0.8s ease;
}

//INPUT

// Base Colors
$shade-10: #2c3e50 !default;
$shade-1: #d7dcdf !default;
$shade-0: #fff !default;
$teal: #1abc9c !default;


// Reset
* {
  &,
  &:before,
  &:after {
    box-sizing: border-box;
  }
}

body {
  font-family: sans-serif;
  padding: 60px 20px;
  
  @media (min-width: 600px) {
    padding: 60px;
  }
}

.range-slider {
  margin: 60px 0 0 0%;
}


// Range Slider
$range-width: 100% !default;

$range-handle-color: $shade-10 !default;
$range-handle-color-hover: $teal !default;
$range-handle-size: 20px !default;

$range-track-color: $shade-1 !default;
$range-track-height: 10px !default;

$range-label-color: $shade-10 !default;
$range-label-width: 60px !default;

.range-slider {
  width: $range-width;
}

.range-slider__range {
  -webkit-appearance: none;
  width: calc(100% - (#{$range-label-width + 13px}));
  height: $range-track-height;
  border-radius: 5px;
  background: $range-track-color;
  outline: none;
  padding: 0;
  margin: 0;

  // Range Handle
  &::-webkit-slider-thumb {
    appearance: none;
    width: $range-handle-size;
    height: $range-handle-size;
    border-radius: 50%;
    background: $range-handle-color;
    cursor: pointer;
    transition: background .15s ease-in-out;

    &:hover {
      background: $range-handle-color-hover;
    }
  }

  &:active::-webkit-slider-thumb {
    background: $range-handle-color-hover;
  }

  &::-moz-range-thumb {
    width: $range-handle-size;
    height: $range-handle-size;
    border: 0;
    border-radius: 50%;
    background: $range-handle-color;
    cursor: pointer;
    transition: background .15s ease-in-out;

    &:hover {
      background: $range-handle-color-hover;
    }
  }

  &:active::-moz-range-thumb {
    background: $range-handle-color-hover;
  }
}


// Range Label
.range-slider__value {
  display: inline-block;
  position: relative;
  width: $range-label-width;
  color: $shade-0;
  line-height: 20px;
  text-align: center;
  border-radius: 3px;
  background: $range-label-color;
  padding: 5px 10px;
  margin-left: 8px;

  &:after {
    position: absolute;
    top: 8px;
    left: -7px;
    width: 0;
    height: 0;
    border-top: 7px solid transparent;
    border-right: 7px solid $range-label-color;
    border-bottom: 7px solid transparent;
    content: '';
  }
}


// Firefox Overrides
::-moz-range-track {
    background: $range-track-color;
    border: 0;
}

input::-moz-focus-inner,
input::-moz-focus-outer { 
  border: 0; 
}
View Compiled
class Title extends React.Component {
  constructor() {
    super();
    this.state = {
      visible:false
    }
  
    this.toggleInfo = this.toggleInfo.bind(this);
  }
  
  toggleInfo() 
  {
    this.setState((prevState, props) => {
    return {visible: !prevState.visible };
  });
  }
  
  render() {
  return (<div >
          <div className="col">
          <h1 className="text-center">FreeCodeCamp Pomodoro Clock <i className="fa fa-info-circle" aria-hidden="true" onClick={this.toggleInfo}></i></h1>
          </div>
          <div className="col info" hidden={!this.state.visible}>
          <h4 className="text-center"> Click <a target="_blank"href="https://en.wikipedia.org/wiki/Pomodoro_Technique">here</a> to go to Wikipedia</h4>
          </div>
          </div>
         )};
}

class Background extends React.Component {

  render() {
    
    const divStyle = {
     color: 'blue',
     height: this.props.percentage,
     backgroundColor: this.props.state ? 'rgba(124,252,0,0.7)' : 'rgba(255,160,122,0.7)'
};
    return (<div style= {divStyle} className="background"></div>);
  }
}

function Timer(props) {
  return (<div>
          <h1>{props.minutes}:{props.seconds< 10 ? 0 : ""}{props.seconds}</h1>
          <h4>{props.name}</h4>
          </div>);
}

class Buttons extends React.Component {
  
  onInput() {
    var breakInput = document.getElementById("breakInput");
    var sessionInput = document.getElementById("sessionInput");
    var currentVal = input.value;
    this.setState({
      value: currentVal
    })
}
  
  render() {
    return (<div class="btn-group" role="group">
            <button className="btn btn-primary" type="button" onClick={this.props.startTimer}>Start</button>
            <button className="btn btn-warning" type="button" onClick={this.props.stopTimer}>Stop</button>
            <button className="btn btn-danger" type="button" onClick={this.props.resetTimer}>Reset</button>
           </div>);
  }
}

class Slider extends React.Component {
    constructor(props){
  super(props);
    this.state = {
      value: this.props.defaultValue
    }
    }
      
  onInput() {
    var input = document.getElementById(this.props.name);
    var currentVal = input.value;
    this.props.setTime(currentVal);
    this.setState({
      value: currentVal
    });
}
  
  render() {
    return (<div>
            <h4>{this.props.name}</h4>
            <div className="range-slider">
            <input id={this.props.name} className="range-slider__range" type="range" min={this.props.min} max={this.props.max} step="1" defaultValue={this.props.defaultValue} onInput={this.onInput.bind(this)}/>
    <span className="range-slider__value">{this.state.value}</span>
           </div>
    </div>
    );
  }
}


class Clock extends React.Component {
  constructor(){
  super();
    this.state = {
      time: 0,
      seconds: 0,
      sessionTime: 25,
      breakTime: 5,
      min: 1,
      max: 30,
      status: true,
      intervalId: null,
      statusName: "Session Time"
    }
      
      this.startTimer = this.startTimer.bind(this);
      this.stopTimer = this.stopTimer.bind(this);
      this.resetTimer = this.resetTimer.bind(this);
      this.setBreakTime = this.setBreakTime.bind(this);
      this.setSessionTime = this.setSessionTime.bind(this);
      this.getPercentage = this.getPercentage.bind(this);
      this.countDown = this.countDown.bind(this);
      this.changeStatus = this.changeStatus.bind(this);
      this.decrementSeconds = this.decrementSeconds.bind(this);
  }
    
    componentWillMount(){
    this.setState({time: this.state.sessionTime});
}

    startTimer() {
      if(!this.state.intervalId)
        {
          this.state.intervalId = setInterval(this.countDown, 1000);
        } 
  }
    stopTimer() {
      if(this.state.intervalId)
          clearInterval(this.state.intervalId);
      
      this.setState({intervalId: null});
    }
  
  resetTimer() {
      if(this.state.intervalId)
          clearInterval(this.state.intervalId);
      
      this.setState({
      time: this.state.sessionTime,
      seconds: 0,
      sessionTime: 25,
      breakTime: 5,
      min: 1,
      max: 30,
      status: true,
      intervalId: null,
      statusName: "Session Time"});
    }
  
  setBreakTime(time) {
    this.setState({
      breakTime: time
    });
    
    if(!this.state.status) 
      {
        this.setState({
      time: time,
      seconds: 0
    });
      }
  }
  
  setSessionTime(time) {
    this.setState({sessionTime: time});
    
    if(this.state.status) 
      {
        this.setState({time: time, seconds: 0
    });
      }
  }
  
  countDown(){
    if(this.state.time == 0 && this.state.seconds == 0)
      {
        this.changeStatus();
      } else
        {
          this.decrementSeconds();
        }
  }
  
  changeStatus() {
        this.setState((prevState, props) => {
    return {
      status: !prevState.status,
      statusName: !prevState.status ? "Session Time" : "Break Time",
      time: !prevState.status ? prevState.sessionTime :  prevState.breakTime
    };
  });
  }
  
  decrementSeconds() {
    if(this.state.seconds === 0)
      {
        this.setState((prevState, props) => {return {time : prevState.time -1, seconds : 59}});
      } else 
        {
          this.setState((prevState, props) => {return {seconds :prevState.seconds -1}});
        }
  }
  
  getPercentage() {
    let maxSeconds = this.state.status ? this.state.sessionTime *60 : this.state.breakTime *60;
    maxSeconds !== 0 ? maxSeconds : 1;
  
    let seconds = ((this.state.time) * 60 ) + this.state.seconds;
    
    return 100- (seconds * 100 / maxSeconds) + "%";
  }
  
  
  render() {
    return (<div className= "fullWidth">
            <div className = "row">
            <div className = "col">
            <Slider name="Break" min={this.state.min} max={this.state.max} defaultValue = "5" setTime={this.setBreakTime }></Slider>
            </div>
            <div className = "col">
            <Slider name="Session" min={this.state.min} max={this.state.max} defaultValue = "25" setTime={this.setSessionTime }></Slider>
            </div>
            </div>
            <Timer minutes={this.state.time} seconds= {this.state.seconds} name={this.state.statusName}></Timer>
            <Buttons startTimer ={this.startTimer} stopTimer ={this.stopTimer} resetTimer ={this.resetTimer}></Buttons>
            <Background state={this.state.status} percentage={this.getPercentage()}></Background>
            </div>);
  }
}


ReactDOM.render(
  
  <div className="">
    <Title></Title>
  <div className="container text-center">
  <Clock></Clock>
  </div>
  </div>,
  document.getElementById('root')
);
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css
  2. https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css
  3. https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.2.0/css/ion.rangeSlider.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js