JSFiddle - React, Tailwind, and code Playground

by rayra

HTML

<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.0/umd/react.development.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.0/umd/react-dom.development.js"></script>

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

<div id="container">
  <div id="app"></div>
</div>

CSS

@import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');

* {
  font-family: 'Century Gothic', sans-serif;
}

body{
  background-color:#474A51;
  color:#FFF;
  font-size: 20px;
  text-align: center;
}

.settings {
  display: flex;
  justify-content: space-around;
}

.SetTimer {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.SetTimer-controls {
  display: flex;
  justify-content: center;
  align-items: center;
}

.Timer {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 20px auto 10px auto;
  width: 200px;
  height: 190px;
  position: relative;
  border-radius: 50%;
}

.Controls {
  display: flex;
  justify-content: center;
}

.main-title {
  font-size: 50px;
  margin-bottom: 20px;
}

button {
  background: none;
  outline: none;
  border: none;
  color: white;
  cursor: pointer;
}

@media screen and (max-width: 500px) {
    body {
    transform: scale(0.8);
    -webkit-transform: scale(0.8);
    -moz-transform: scale(0.8);
    -ms-transform: scale(0.8);
    -o-transform: scale(0.8);
  }
}

Babel + JSX

const Header=()=><h1 className="main-title">Pomodoro</h1>

const SetTimer=({type, value, handleClick})=>(
  <div className="SetTimer">
    <div id={`${type}-label`}>{type === 'session' ? 'Session ' : 'Break '}</div>
    <div className="SetTimer-controls">
      <button id={`${type}-decrement`} onClick={()=>handleClick(false,`${type}Value`)} ><i className="fa fa-arrow-down fa-2x"/></button>
      <div id={`${type}-length`}>{value}</div>
      <button id={`${type}-increment`} onClick={()=>handleClick(true,`${type}Value`)}><i className="fa fa-arrow-up fa-2x"/></button>
    </div>
  </div>
)

const Timer=({mode, time})=>(
  <div className="Timer">
    <h1 id="timer-label">{mode==='session'?'Session':'Break'}</h1>
    <h1 id="time-left">{time}</h1>
  </div>
)

const Controls=({active, handleReset, handlePlayPause})=>(
  <div className="Controls">
    <button id="start_stop" onClick={handlePlayPause}>
      { active ? <span><i className="fa fa-pause fa-2x"/></span> : <span><i className="fa fa-play fa-2x"/></span> }
    </button>
    <button id="reset" onClick={handleReset}><i className="fa fa-refresh fa-2x"/></button>
  </div>
)

class App extends React.Component{
  constructor(props){
    super(props)
    this.state={
      breakValue:5,
      sessionValue:25,
      mode:'session',
      time:25*60*1000,
      active:false,
      touched: false,
    }
  }
  
  componentDidUpdate(prevProps, prevState){
    if(prevState.time===0 && prevState.mode==='session'){
      this.setState({time: this.state.breakValue*60*1000, mode:'break'})
      this.audio.play()
    }
    if(prevState.time===0 && prevState.mode=='break'){
      this.setState({time: this.state.sessionValue*60*1000, mode:'session'})
      this.audio.play()
    }
  }
  handleSetTimers=(inc, type)=>{
    if(!this.state.active && !this.state.touched){
      if(this.state[type] === 60 && inc){
        return
      }
      if(this.state[type] === 1 && !inc){
        return
      }
     ...