diff --git a/client/src/components/ui/focus/currentTaskTitle.tsx b/client/src/components/ui/focus/currentTaskTitle.tsx
new file mode 100644
index 0000000..50954fc
--- /dev/null
+++ b/client/src/components/ui/focus/currentTaskTitle.tsx
@@ -0,0 +1,12 @@
+import React from "react";
+
+export default function CurrentTaskTitle(task_name: string) {
+ return (
+
+
Current Focus
+
+ {task_name}
+
+
+ );
+}
diff --git a/client/src/components/ui/focus/taskDisplay.tsx b/client/src/components/ui/focus/taskDisplay.tsx
new file mode 100644
index 0000000..9fc30ee
--- /dev/null
+++ b/client/src/components/ui/focus/taskDisplay.tsx
@@ -0,0 +1,34 @@
+interface Task {
+ id: number;
+ name: string;
+ description: string;
+}
+
+interface Time {
+ id: number;
+ day: number;
+ start_time: string;
+ end_time: string;
+ repeating: boolean;
+ task: number;
+}
+
+export default function TaskDisplay({
+ task,
+ time,
+}: {
+ task: Task;
+ time: Time;
+}) {
+ return (
+
+
+
{task.name}:
+
+ {time.start_time} - {time.end_time}
+
+
+
{task.description}
+
+ );
+}
diff --git a/client/src/components/ui/focus/timeDisplay.tsx b/client/src/components/ui/focus/timeDisplay.tsx
new file mode 100644
index 0000000..965ffd9
--- /dev/null
+++ b/client/src/components/ui/focus/timeDisplay.tsx
@@ -0,0 +1,61 @@
+import React, { useEffect, useState } from "react";
+
+import Timer from "./timer";
+
+interface TimeDisplayProps {
+ statusSignal: (data: string) => void;
+ time: string;
+ current: boolean;
+}
+
+export default function TimeDisplay({
+ statusSignal,
+ time,
+ current,
+}: TimeDisplayProps) {
+ const [timeRemaining, setTimeRemaining] = useState(0);
+
+ useEffect(() => {
+ const getTimeRemaining = setInterval(() => {
+ const [Hours, Mins, Sec] = time.split(":").map(Number);
+
+ const d = new Date();
+ const time_serial = Hours * 60 * 60 + Mins * 60 + Sec;
+ const cur_time =
+ d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds();
+
+ let remaining_time = 0;
+
+ remaining_time = time_serial - cur_time;
+ if (remaining_time <= 1) {
+ clearInterval(getTimeRemaining);
+ }
+
+ setTimeRemaining(remaining_time);
+ }, 1000);
+
+ return () => clearInterval(getTimeRemaining);
+ }, [time, timeRemaining]);
+
+ useEffect(() => {
+ if (timeRemaining <= 1) {
+ statusSignal("finished");
+ }
+ }, [timeRemaining, statusSignal]);
+
+ return (
+
+ {current ? (
+ <>
+
Timer
+ >
+ ) : (
+ <>
+
Next Task
+ >
+ )}
+
{Timer(timeRemaining)}
+
+
+ );
+}
diff --git a/client/src/components/ui/focus/timer.tsx b/client/src/components/ui/focus/timer.tsx
new file mode 100644
index 0000000..353ac7a
--- /dev/null
+++ b/client/src/components/ui/focus/timer.tsx
@@ -0,0 +1,33 @@
+const Timer = (timeRemaining: number) => {
+ const formatTime = (time: number) => {
+ const seconds = Math.floor(time % 60);
+ const minutes = Math.floor((time / 60) % 60);
+ const hours = Math.floor((time / (60 * 60)) % 24);
+
+ return (
+
+
+ {hours > 0 ? (
+ <>
+ {hours.toString()}
+ :
+ >
+ ) : (
+ <>>
+ )}
+ {minutes.toString().padStart(2, "0")}
+ :
+ {seconds.toString().padStart(2, "0")}
+
+
+ );
+ };
+
+ return (
+
+ {formatTime(timeRemaining)}
+
+ );
+};
+
+export default Timer;
diff --git a/client/src/components/ui/focus/upcomingTasks.tsx b/client/src/components/ui/focus/upcomingTasks.tsx
new file mode 100644
index 0000000..95d3236
--- /dev/null
+++ b/client/src/components/ui/focus/upcomingTasks.tsx
@@ -0,0 +1,71 @@
+import { useEffect, useState } from "react";
+
+import TaskDisplay from "./taskDisplay";
+
+interface Task {
+ id: number;
+ name: string;
+ description: string;
+}
+
+interface Time {
+ id: number;
+ day: number;
+ start_time: string;
+ end_time: string;
+ repeating: boolean;
+ task: number;
+}
+
+interface Tasks {
+ tasks: Task[];
+ times: Time[];
+}
+
+function serializeTime(time: string) {
+ const [Hours, Mins, Sec] = time.split(":").map(Number);
+ return Hours * 60 * 60 + Mins * 60 + Sec;
+}
+
+export default function UpcomingTasks({ tasks, times }: Tasks) {
+ const [upcomingTimes, setUpcomingTimes] = useState