Skip to content

Commit 144cf28

Browse files
committed
Merge branch 'use_uv' into issue-7-Allow_CRUD_Operations_on_Tasks
2 parents dd588c0 + 4c8d10c commit 144cf28

34 files changed

Lines changed: 2574 additions & 56 deletions

client/src/components/task_form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect,useState } from "react";
1+
import { useEffect, useState } from "react";
22

33
import { TimeInput } from "@/components/time_input";
44
import { TopicInput } from "@/components/topic_input";
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {
2+
getTimeTopPosition,
3+
getVisibleTimetableRect,
4+
} from "@/components/timetable";
5+
6+
/*
7+
Resizes the time indicator to the correct width and positions it at the
8+
y-position corresponding to the current time.
9+
*/
10+
export function resizeAndPositionTimeIndicator() {
11+
const time_indicator = document.getElementById("time-indicator");
12+
if (time_indicator == null) return;
13+
14+
const now_label = document.getElementById("time-indicator-label");
15+
if (now_label == null) return;
16+
17+
const separator_rect = document
18+
.getElementById("timetable-separator")
19+
?.getBoundingClientRect();
20+
if (separator_rect == undefined) return;
21+
22+
const content_rect = document
23+
.getElementById("timetable-content")
24+
?.getBoundingClientRect();
25+
if (content_rect == undefined) return;
26+
27+
const visible = getVisibleTimetableRect();
28+
if (visible == undefined) return;
29+
30+
const now = new Date(Date.now());
31+
const hour = now.getHours();
32+
const mins = now.getMinutes();
33+
34+
const time_top = getTimeTopPosition(hour, mins);
35+
if (time_top == undefined) return;
36+
37+
time_indicator.style.left =
38+
visible.left - separator_rect.width - content_rect.left + "px";
39+
time_indicator.style.top = time_top - content_rect.top + "px";
40+
time_indicator.style.width = visible.width + separator_rect.width + "px";
41+
42+
const now_label_rect = now_label.getBoundingClientRect();
43+
if (now_label_rect == undefined) return;
44+
45+
const now_label_left =
46+
visible.left - now_label_rect.width - separator_rect.width;
47+
const now_label_top = time_top - now_label_rect.height / 2;
48+
49+
const parent_rect = time_indicator.parentElement?.getBoundingClientRect();
50+
if (parent_rect == undefined) return;
51+
52+
now_label.style.left = now_label_left - parent_rect.left + "px";
53+
now_label.style.top = now_label_top - parent_rect.top + "px";
54+
}
55+
56+
/*
57+
Component consisting of a rounded label containing the text "Now" and a 2px
58+
thick line stretching across the visible area of the timetable.
59+
60+
There should only be one TimeIndicator per page.
61+
*/
62+
function TimeIndicator() {
63+
return (
64+
<>
65+
<div
66+
id="time-indicator-label"
67+
className="absolute z-[100] h-fit w-fit rounded-full bg-slate-400 p-1 pl-2 pr-2"
68+
>
69+
<p className="text-slate-100">Now</p>
70+
</div>
71+
<div
72+
id="time-indicator"
73+
className="absolute z-[100] min-h-[2px] bg-slate-200 opacity-75"
74+
></div>
75+
</>
76+
);
77+
}
78+
79+
export default TimeIndicator;

client/src/components/time_tag.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { getDurationMinutes } from "@/components/timetable";
2+
3+
/*
4+
@prop start_time: string of form HH:MM:SS containing the start time to display
5+
@prop end_time: string of form HH:MM:SS containing the end time to display
6+
@prop display: (optional) string describing what to display in the tag,
7+
defaults to displaying the start and end times, "duration" to display duration,
8+
or "both" to display start and end times with duration in brackets.
9+
*/
10+
interface TimeTagProps {
11+
start_time: string;
12+
end_time: string;
13+
display?: string;
14+
}
15+
16+
/*
17+
A small round tag containing a clock icon and either the start and end times,
18+
the duration, or both, specified by the display prop.
19+
*/
20+
function TimeTag({ start_time, end_time, display }: TimeTagProps) {
21+
const time_string =
22+
start_time.substring(0, 5) + "-" + end_time.substring(0, 5);
23+
24+
const duration_minutes = getDurationMinutes(start_time, end_time);
25+
const hours = Math.floor(duration_minutes / 60);
26+
const minutes = duration_minutes % 60;
27+
const duration_string = hours + "h " + minutes + "m";
28+
29+
let display_string = time_string; // Default to time string
30+
if (display != undefined) {
31+
display = display.toLowerCase();
32+
if (display == "duration") display_string = duration_string;
33+
else if (display == "both") display_string += " (" + duration_string + ")";
34+
}
35+
36+
return (
37+
<div
38+
className={
39+
"flex h-fit w-fit flex-row items-center justify-center rounded-full text-lg font-medium"
40+
}
41+
>
42+
<div className="placeholder-clock aspect-1/1 h-5 w-5 rounded-[50] bg-slate-200"></div>
43+
<p className="ml-1">{display_string}</p>
44+
</div>
45+
);
46+
}
47+
48+
export default TimeTag;

0 commit comments

Comments
 (0)