Skip to content
Snippets Groups Projects
Commit 070c20d7 authored by DuckyDuck69's avatar DuckyDuck69
Browse files

add special study methods (pomodoro)

parent 08662679
Branches
No related tags found
1 merge request!5add special study methods (pomodoro)
{ {
"name": "npm", "name": "npm",
"version": "0.0.0", "version": "0.0.0",
...@@ -2598,6 +2597,12 @@ ...@@ -2598,6 +2597,12 @@
"url": "https://github.com/prettier/prettier?sponsor=1" "url": "https://github.com/prettier/prettier?sponsor=1"
} }
}, },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
......
import TimeDuration from "./components/TimeDuration" import TimeDuration from "./components/TimeDuration";
import Title from "./components/Title" import Title from "./components/Title";
import FileInput from "./components/FileInput" import FileInput from "./components/FileInput";
import TodoList from "./components/ToDoList" import TodoList from "./components/ToDoList";
import Video from "./components/Video" import Video from "./components/Video";
import StudyMethod from "./components/StudyMethod";
import { useState, useEffect } from "react";
function App() { function App() {
const [hour, setHour] = useState("");
const [minute, setMinute] = useState("");
const [method, setMethod] = useState("regular");
useEffect(() => {
if (Notification.permission !== "granted") {
Notification.requestPermission();
}
}, []);
return ( return (
<> <>
<div className="page-container" style={{ display: "inline-flex" }}> <div className="page-container" style={{ display: "inline-flex" }}>
<Title /> <Title />
<Video /> <Video />
<TimeDuration/> <TimeDuration
<Video/> hour={hour}
setHour={setHour}
minute={minute}
setMinute={setMinute}
method={method}
/>
<StudyMethod
method = {method}
setMethod = {setMethod}
/>
<FileInput /> <FileInput />
<TodoList /> <TodoList />
</div> </div>
</> </>
) );
} }
export default App export default App;
import { useState, useRef } from "react";
function StudyMethod({method, setMethod }) {
function handleChanges(event) {
const selectedOne = event.target.value;
setMethod(selectedOne);
console.log("Choose study: ", selectedOne);
}
return (
<div>
<h4>Extra Study Methods: </h4>
<select value={method} onChange={handleChanges}>
<option value="regular">No Option</option>
<option value="pomodoro">Pomodoro</option>
<option value="flowtime">Flowtime Technique</option>
<option value="ultradian">Ultradian Sprints</option>
</select>
<button onClick={setMethod(method)}>Confirm method</button>
</div>
);
}
export default StudyMethod;
import { convertInput, useTimeInput } from "../utils/timeUtils"; import { convertInput, useTimeInput } from "../utils/timeUtils";
import { useState, useRef } from "react"; import { useState, useRef, useEffect } from "react";
// useState is a React hook that lets you store and manage state within functional components. // useState is a React hook that lets you store and manage state within functional components.
// It returns an array with two elements: // It returns an array with two elements:
// State value (current state) // State value (current state)
// Setter function (to update this state) // Setter function (to update this state)
function TimeDuration() { function TimeDuration({hour, setHour, minute, setMinute, method}) {
const [hour, setHour] = useState(""); //both hour and setHour is empty string,
const [minute, setMinute] = useState("");
const [second, setSecond] = useState(0); const [second, setSecond] = useState(0);
const [targetSeconds, setTargetSeconds] = useState(0);
const [isRunning, setIsRunning] = useState(false)
const [mode, setMode] = useState("work")
const intervalID = useRef(null); // This holds the interval ID across renders const intervalID = useRef(null); // This holds the interval ID across renders
...@@ -17,6 +18,61 @@ function TimeDuration() { ...@@ -17,6 +18,61 @@ function TimeDuration() {
return second return second
} }
const notifyUser = async () => {
//notify between work and break
const message = mode !== "work"
? "Take a break!"
: "Time to work!";
if (Notification.permission === "granted") {
new Notification(message);
} else if (Notification.permission !== "denied") {
const permission = await Notification.requestPermission();
if (permission === "granted") {
new Notification(message);
}
}
};
//load the final message
const finalNotify = async () => {
const message = "🎉 All study sessions completed!";
if (Notification.permission === "granted") {
new Notification(message);
} else if (Notification.permission !== "denied") {
const permission = await Notification.requestPermission();
if (permission === "granted") {
new Notification(message);
}
}
};
useEffect(() => {
if(!isRunning) return; //avooid shooting this when time is 0 and no method initialized
if (second === 0 && intervalID.current) {
clearInterval(intervalID.current);
notifyUser();
if (method !== "regular") {
if (mode === "work") {
// Subtract 25 min from target
setTargetSeconds(prev => prev - 25 * 60);
startBreak();
} else {
startWork();
}
}
}
}, [second, mode, method, isRunning]);
useEffect(() => {
// If user completed their goal, set running to false and notify them
if (targetSeconds <= 0 && isRunning) {
clearInterval(intervalID.current);
setIsRunning(false);
setSecond(0);
finalNotify();
}
}, [targetSeconds, isRunning]);
function runTime(){ function runTime(){
intervalID.current = setInterval(()=>{ intervalID.current = setInterval(()=>{
setSecond(prev => { setSecond(prev => {
...@@ -31,14 +87,55 @@ function TimeDuration() { ...@@ -31,14 +87,55 @@ function TimeDuration() {
} }
function startTimer(){ function startTimer(){
//shoot the useEffect
setIsRunning(true);
if(mode != "regular"){
const totalStudyTime = handleTimeInput(); // the goal the user entered
setTargetSeconds(totalStudyTime);
startWork();
}
else{
const totalSec = handleTimeInput(); const totalSec = handleTimeInput();
setSecond(totalSec); //set the second only when the user prompt inputs setSecond(totalSec); //set the second only when the user prompt inputs
runTime(); runTime();
} }
}
function startWork() {
if(method == "pomodoro"){
setMode("work");
setHour(0);
setMinute(25);
setSecond(25 * 60); // 25 minutes
runTime();
}
else if (method == "flowtime"){
runTime()
}else if (method == "ultradian"){
runTime()
}
}
function startBreak() {
if(method == "pomodoro"){
setMode("break");
setHour(0);
setMinute(5);
setSecond(5 * 60); // 5 minutes
runTime();
}
else if (method == "flowtime"){
runTime()
}else if (method == "ultradian"){
runTime()
}
}
return ( return (
<div className="time-duration-box"> <div className="time-duration-box">
<h3>Time Duration</h3> <h3>Time Duration ({mode})</h3>
<div className="time-boxes"> <div className="time-boxes">
<input <input
type="number" type="number"
...@@ -46,6 +143,7 @@ function TimeDuration() { ...@@ -46,6 +143,7 @@ function TimeDuration() {
placeholder="Hour" placeholder="Hour"
value={hour} value={hour}
onChange={(e) => setHour(e.target.value)} onChange={(e) => setHour(e.target.value)}
disabled={method === "pomodoro"}
/> />
<input <input
type="number" type="number"
...@@ -53,15 +151,19 @@ function TimeDuration() { ...@@ -53,15 +151,19 @@ function TimeDuration() {
placeholder="Minute" placeholder="Minute"
value={minute} value={minute}
onChange={(e) => setMinute(e.target.value)} onChange={(e) => setMinute(e.target.value)}
disabled={method === "pomodoro"}
/> />
</div> </div>
<button onClick={startTimer}>Start timer</button> <button onClick={startTimer}>Start timer</button>
<button onClick={() => clearInterval(intervalID.current)}>Stop timer</button> <button onClick={() => { clearInterval(intervalID.current); setIsRunning(false); }}>Stop timer</button>
<button onClick={runTime}>Resume</button> <button onClick={runTime}>Resume</button>
<button onClick={() => setSecond(0)}>Reset timer</button> <button onClick={() => { clearInterval(intervalID.current); setSecond(0); setIsRunning(false); }}>Reset timer</button>
<h3>Hour: {Math.floor(second / 3600)}</h3> <h3>Hour: {Math.floor(second / 3600)}</h3>
<h3>Minute: {Math.floor((second % 3600) / 60)}</h3> <h3>Minute: {Math.floor((second % 3600) / 60)}</h3>
<h3>Second: {second % 60}</h3> <h3>Second: {second % 60}</h3>
{method === "pomodoro" && (
<h4>Remaining Study Time: {Math.floor(targetSeconds / 60) - 25 } minutes</h4>
)}
</div> </div>
); );
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment