Skip to content

Instantly share code, notes, and snippets.

@sergixnet
Last active April 18, 2019 11:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergixnet/491f423c8b6ba538507911f922a47131 to your computer and use it in GitHub Desktop.
Save sergixnet/491f423c8b6ba538507911f922a47131 to your computer and use it in GitHub Desktop.
Pomodoro Clock - FreeCodeCamp
// audio https://freesound.org/data/previews/198/198841_285997-lq.mp3
let counter, audio;
const Header = () => <h1 className="header">Pomodoro Clock</h1>;
const TimeSetter = ({ type, label, time, click }) => (
<div className="TimeSetter">
<span className="TimeSetter__label" id={`${type}-label`}>{label}</span>
<button id={`${type}-increment`} onClick={() => click(type, 1)}><i className="fas fa-arrow-up"></i></button>
<span className="TimeSetter__time" id={`${type}-length`}>{time}</span>
<button id={`${type}-decrement`} onClick={() => click(type, -1)}><i className="fas fa-arrow-down"></i></button>
</div>
);
const Timer = ({ label, time }) => (
<div className="Timer">
<h2 className="Timer__title" id="timer-label">{label}</h2>
<span className="Timer__time" id="time-left">{time}</span>
</div>
);
const Controls = ({ handleReset, handleTimeCount, playPauseClass }) => (
<div className="Controls">
<button id="start_stop" onClick={handleTimeCount}><i className={playPauseClass}></i></button>
<button id="reset" onClick={handleReset}><i className="fas fa-sync-alt"></i></button>
</div>
);
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
session: 25,
break: 5,
currentTime: 25 * 60,
running: 'Session',
paused: true
}
}
handleReset = () => {
clearInterval(counter);
this.setState({
session: 25,
break: 5,
currentTime: 25 * 60,
running: 'Session',
paused: true
});
audio = document.getElementById('beep');
audio.currentTime = 0;
audio.pause();
}
handleTimeSetter = (type, increment) => {
if (this.state.paused) {
let newTime = this.state[type] + increment;
const newState = {};
newTime = newTime >= 60 ? 60 : newTime;
newTime = newTime <= 1 ? 1 : newTime;
newState[type] = newTime;
if (type === 'session') {
newState.currentTime = newTime * 60;
}
this.setState(newState);
}
}
startTimeCount = () => {
counter = setInterval(() => {
if (this.state.currentTime === 0) {
clearInterval(counter);
audio = document.getElementById('beep');
audio.play();
this.switchTime();
this.startTimeCount();
} else {
this.setState({
currentTime: this.state.currentTime - 1
})
}
}, 1000);
}
switchTime = () => {
if (this.state.running === 'Session') {
this.setState({
running: 'Break',
currentTime: this.state.break * 60
});
} else {
this.setState({
running: 'Session',
currentTime: this.state.session * 60
});
}
}
handleTimeCount = () => {
if (this.state.paused) {
this.startTimeCount();
this.setState({
paused: false
});
} else {
clearInterval(counter);
this.setState({
paused: true
});
}
}
formatTime = () => {
let minutes = Math.floor(this.state.currentTime / 60);
let seconds = this.state.currentTime - minutes * 60;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
return minutes + ':' + seconds;
}
render() {
const currentTime = this.formatTime(this.state.currentTime);
const playPauseClass = this.state.paused ? 'fas fa-play' : 'fas fa-pause';
return (
<div className="tomato">
<Header/>
<div className="TimeSetter__container">
<TimeSetter
type="session"
label="Session"
time={this.state.session}
click={this.handleTimeSetter}
/>
<TimeSetter
type="break"
label="Break"
time={this.state.break}
click={this.handleTimeSetter}/>
</div>
<Timer label={this.state.running} time={currentTime} />
<Controls
handleReset={this.handleReset}
handleTimeCount={this.handleTimeCount}
playPauseClass={playPauseClass}/>
<audio id="beep" src="https://freesound.org/data/previews/198/198841_285997-lq.mp3" />
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
<script src="https://codepen.io/no_stack_dub_sack/pen/VKJGKd"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro');
* {
&,
&:before,
&:after {
box-sizing: border-box;
}
}
body {
font-family: 'Source Code Pro', monospace;
color: white;
}
#root {
height: 100vh;
width: 100%;
margin: 0;
position: absolute;
top: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: lightgreen;
}
.tomato {
position: relative;
z-index: 2;
width: 500px;
&:after,
&:before {
content: '';
position: absolute;
width: 350px;
height: 350px;
background-color: tomato;
border-radius: 50%;
z-index: -1;
}
&:before {
top: 50%;
left: 50%;
transform: translate(-70%, -50%);
}
&:after {
top: 50%;
right: 50%;
transform: translate(70%, -50%);
}
}
.header {
font-size: 1.5rem;
text-align: center;
position: relative;
&:before {
content: '(';
position: absolute;
top: -80px;
left:50%;
color: green;
font-weight: 900;
font-size: 4rem;
letter-spacing: -1;
transform: translateX(-50%)
}
}
.TimeSetter__container {
display: flex;
justify-content: center;
}
.TimeSetter {
margin: 0 2rem;
button {
background-color: transparent;
border: none;
font-size: 1.4rem;
color: white;
}
}
.TimeSetter__label {
display: block;
text-align: center;
font-size: 1rem;
margin-bottom: 1rem;
margin-top: 0;
}
.TimeSetter__time {
font-size: 1.4rem;
}
.Timer {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 1rem;
&__title {
font-size: 2rem;
margin-top: 1rem;
margin-bottom: 1rem;
}
&__time {
font-size: 4rem,
}
}
.Controls {
display: flex;
justify-content: center;
button {
color: white;
background-color: transparent;
border: none;
font-size: 1.5rem;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.1/css/all.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment