Skip to content

Commit 2b4b06d

Browse files
committed
shows countdown to next taks if none current
1 parent c9dd337 commit 2b4b06d

6 files changed

Lines changed: 158 additions & 59 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from "react";
2+
3+
export default function TaskDisplay(task_name: string) {
4+
return (
5+
<div className="m-3 flex flex-col items-center justify-center rounded-3xl bg-slate-900 p-10 shadow-xl shadow-black/40">
6+
<h1 className="mb-2 font-inter text-4xl font-semibold">Current Focus</h1>
7+
<div className="rounded-full bg-indigo-400 p-3 px-8 font-inter text-xl font-semibold">
8+
{task_name}
9+
</div>
10+
</div>
11+
);
12+
}

client/src/components/ui/timeDisplay.tsx

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,57 @@ import Timer from "./timer";
44

55
interface TimeDisplayProps {
66
statusSignal: (data: string) => void;
7-
end_time: string;
7+
time: string;
8+
current: boolean;
89
}
910

1011
export default function TimeDisplay({
1112
statusSignal,
12-
end_time,
13+
time,
14+
current,
1315
}: TimeDisplayProps) {
1416
const [timeRemaining, setTimeRemaining] = useState(0);
1517

1618
useEffect(() => {
17-
function updateStatus(s: string) {
18-
statusSignal(s);
19-
}
20-
2119
const getTimeRemaining = setInterval(() => {
22-
const [endHours, endMins, endSec] = end_time.split(":").map(Number);
20+
const [Hours, Mins, Sec] = time.split(":").map(Number);
2321

2422
const d = new Date();
25-
const end_time_serial = endHours * 60 * 60 + endMins * 60 + endSec;
23+
const time_serial = Hours * 60 * 60 + Mins * 60 + Sec;
2624
const cur_time =
2725
d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds();
2826

29-
const remaining_time = end_time_serial - cur_time;
27+
let remaining_time = 0;
28+
29+
remaining_time = time_serial - cur_time;
3030
if (remaining_time <= 1) {
31-
updateStatus("finished");
3231
clearInterval(getTimeRemaining);
3332
}
3433

3534
setTimeRemaining(remaining_time);
3635
}, 1000);
3736

3837
return () => clearInterval(getTimeRemaining);
39-
}, [end_time, timeRemaining, statusSignal]);
38+
}, [time, timeRemaining]);
39+
40+
useEffect(() => {
41+
if (timeRemaining <= 1) {
42+
statusSignal("finished");
43+
}
44+
}, [timeRemaining, statusSignal]);
4045

4146
return (
42-
<div>
43-
<h1>Timer</h1>
44-
<div className="time left">{Timer(timeRemaining)}</div>
47+
<div className="m-3 flex flex-col items-center justify-center rounded-3xl bg-slate-900 p-10 shadow-xl shadow-black/40">
48+
{current ? (
49+
<>
50+
<h1 className="mb-2 font-inter text-4xl font-semibold">Timer</h1>
51+
</>
52+
) : (
53+
<>
54+
<h1 className="mb-2 font-inter text-4xl font-semibold">Next Task</h1>
55+
</>
56+
)}
57+
<div className="time_left">{Timer(timeRemaining)}</div>
4558
<div></div>
4659
</div>
4760
);

client/src/components/ui/timer.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@ const Timer = (timeRemaining: number) => {
77
return (
88
<div className="countdown-display">
99
<div className="countdown-value">
10-
{hours.toString().padStart(2, "0")}
11-
<span>:</span>
10+
{hours > 0 ? (
11+
<>
12+
{hours.toString()}
13+
<span>:</span>
14+
</>
15+
) : (
16+
<></>
17+
)}
1218
{minutes.toString().padStart(2, "0")}
1319
<span>:</span>
1420
{seconds.toString().padStart(2, "0")}
@@ -18,7 +24,7 @@ const Timer = (timeRemaining: number) => {
1824
};
1925

2026
return (
21-
<div className="rounded-full bg-indigo-400 p-3 px-8">
27+
<div className="rounded-full bg-indigo-400 p-3 px-8 font-inter text-xl font-semibold">
2228
{formatTime(timeRemaining)}
2329
</div>
2430
);

client/src/pages/focus.tsx

Lines changed: 107 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
1-
import React, { useState } from "react";
1+
import React, { useEffect, useState } from "react";
22

3+
import TaskDisplay from "@/components/ui/taskDisplay";
34
import TimeDisplay from "@/components/ui/timeDisplay";
45

5-
interface Task {
6+
interface Time {
67
id: number;
8+
day: number;
79
start_time: string;
810
end_time: string;
11+
repeating: boolean;
12+
task: number;
13+
}
14+
15+
interface Task {
16+
id: number;
17+
name: string;
18+
}
19+
20+
function serializeTime(time: string) {
21+
const [Hours, Mins, Sec] = time.split(":").map(Number);
22+
23+
return Hours * 60 * 60 + Mins * 60 + Sec;
924
}
1025

1126
const CountdownTimer = () => {
27+
const [times, setTimes] = useState<Time[]>([]);
1228
const [tasks, setTasks] = useState<Task[]>([]);
13-
const [currentTask, setCurrentTask] = useState<Task>();
29+
const [currentTime, setCurrentTime] = useState<Time | null>();
30+
const [currentTask, setCurrentTask] = useState<Task | null>();
31+
const [nextTime, setNextTime] = useState<Time | null>();
1432
const [loading, setLoading] = useState(false);
1533

16-
async function refreshTasks() {
34+
async function refreshTimes() {
1735
setLoading(true);
1836

1937
try {
@@ -23,44 +41,68 @@ const CountdownTimer = () => {
2341
}
2442

2543
const result = await response.json();
26-
setTasks(result);
27-
getCurrentTask();
44+
setTimes(result);
45+
getCurrentTask(result);
2846
setLoading(false);
2947
} catch (error) {
3048
console.error(error);
3149
}
3250
}
3351

34-
function getCurrentTask() {
35-
console.log("getting current task");
36-
let task_time = 1000000;
37-
38-
tasks.forEach((task) => {
39-
const [startHours, startMins, startSec] = task.start_time
40-
.split(":")
41-
.map(Number);
42-
const [endHours, endMins, endSec] = task.end_time.split(":").map(Number);
43-
44-
const d = new Date();
45-
const start_time = startHours * 60 * 60 + startMins * 60 + startSec;
46-
const end_time = endHours * 60 * 60 + endMins * 60 + endSec;
47-
const cur_time =
48-
d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds();
49-
50-
if (start_time <= cur_time && end_time >= cur_time) {
51-
if (start_time < task_time) {
52-
console.log("new time", start_time);
53-
setCurrentTask(task);
54-
task_time = start_time;
52+
useEffect(() => {
53+
async function fetchTask() {
54+
try {
55+
const response = await fetch("http://localhost:8000/api/planner/task/");
56+
if (!response.ok) {
57+
throw new Error(`Response status: ${response.status}`);
5558
}
59+
const result = await response.json();
60+
setTasks(result);
61+
const cur_task = tasks.filter((task) => task.id === currentTime?.task);
62+
setCurrentTask(cur_task[0]);
63+
} catch (error) {
64+
console.error(error);
5665
}
66+
}
67+
68+
fetchTask();
69+
}, [tasks, currentTime]);
70+
71+
function getCurrentTask(ts: Time[]) {
72+
let upcomingTimes: Time[];
73+
74+
const d = new Date();
75+
const cur_time =
76+
d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds();
77+
78+
// filter out finished tasks
79+
upcomingTimes = ts.filter((time) => {
80+
const end_time = serializeTime(time.end_time);
81+
return end_time > cur_time;
82+
});
83+
84+
// sort by start time
85+
upcomingTimes = upcomingTimes.sort((a, b) => {
86+
return serializeTime(a.start_time) - serializeTime(b.start_time);
5787
});
88+
89+
// logic for if there are no tasks currently or at all
90+
if (upcomingTimes.length > 0) {
91+
if (serializeTime(upcomingTimes[0].start_time) < cur_time) {
92+
setCurrentTime(upcomingTimes[0]);
93+
} else {
94+
setCurrentTime(null);
95+
setNextTime(upcomingTimes[0]);
96+
}
97+
} else {
98+
setCurrentTime(null);
99+
setNextTime(null);
100+
}
58101
}
59102

60103
function onTaskEnd(status: string) {
61104
if (status == "finished") {
62-
console.log("finished");
63-
getCurrentTask();
105+
getCurrentTask(times);
64106
}
65107
}
66108

@@ -73,7 +115,7 @@ const CountdownTimer = () => {
73115
// lonk out
74116

75117
return (
76-
<div className="h-screen bg-slate-800 p-8">
118+
<div className="h-screen bg-slate-800 p-8 font-inter">
77119
<div className="flex h-screen flex-col items-center justify-start rounded-xl bg-slate-700 p-8 font-mono text-white shadow-inner shadow-slate-900">
78120
{loading ? (
79121
<div>
@@ -104,25 +146,48 @@ const CountdownTimer = () => {
104146
</div>
105147
) : (
106148
<button
107-
onClick={refreshTasks}
149+
onClick={refreshTimes}
108150
className="rounded-full bg-indigo-400 p-3 px-8 hover:bg-indigo-500"
109151
>
110152
refresh
111153
</button>
112154
)}
113-
114-
<div>
115-
{currentTask ? (
155+
<p className="font-inter text-4xl font-semibold">FOCUS</p>
156+
<div className="flex flex-row justify-center">
157+
<div className="flex flex-col">
116158
<div>
117-
<p>{currentTask.end_time}</p>
118-
<TimeDisplay
119-
statusSignal={onTaskEnd}
120-
end_time={currentTask.end_time}
121-
/>
159+
{currentTime ? (
160+
<div>
161+
<TimeDisplay
162+
statusSignal={onTaskEnd}
163+
time={currentTime.end_time}
164+
current={true}
165+
/>
166+
</div>
167+
) : (
168+
<></>
169+
)}
170+
{nextTime && !currentTime ? (
171+
<div>
172+
<TimeDisplay
173+
statusSignal={onTaskEnd}
174+
time={nextTime.start_time}
175+
current={false}
176+
/>
177+
</div>
178+
) : (
179+
<></>
180+
)}
122181
</div>
123-
) : (
124-
<></>
125-
)}
182+
<div>
183+
{currentTask ? (
184+
<div>{TaskDisplay(currentTask.name)}</div>
185+
) : (
186+
<div>{TaskDisplay("none")}</div>
187+
)}
188+
</div>
189+
</div>
190+
<div className="flex flex-row justify-center">upcoming</div>
126191
</div>
127192
</div>
128193
</div>

client/src/styles/globals.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
2+
13
@tailwind base;
24
@tailwind components;
35
@tailwind utilities;

client/tailwind.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const config = {
2222
extend: {
2323
fontFamily: {
2424
sans: ["var(--font-sans)", ...fontFamily.sans],
25+
inter: ["Inter", ...fontFamily.sans],
2526
},
2627
colors: {
2728
border: "hsl(var(--border))",

0 commit comments

Comments
 (0)