<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