Skip to content

Commit 04e9d5e

Browse files
committed
fixed sizing issues on tooltips where the tooltip exceeded the visible timetable area, now properly resizes to fit; added a separator between the time column and day columns that is static while scrolling; added indication of the current day by brightening the background colour of timetable slots within the current days column to increase readability;
1 parent d763149 commit 04e9d5e

5 files changed

Lines changed: 100 additions & 51 deletions

File tree

client/src/components/time_indicator.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ function TimeIndicator() {
4646
<>
4747
<div
4848
id="time-indicator-label"
49-
className="absolute z-[1000] h-fit w-fit rounded-full bg-slate-400 p-1 pl-2 pr-2"
49+
className="absolute z-[75] h-fit w-fit rounded-full bg-slate-400 p-1 pl-2 pr-2"
5050
>
5151
<p className="text-slate-100">Now</p>
5252
</div>
5353
<div
5454
id="time-indicator"
55-
className="absolute z-[100] min-h-[2px] bg-slate-200 opacity-75"
55+
className="absolute z-[75] min-h-[2px] bg-slate-200 opacity-75"
5656
></div>
5757
</>
5858
);

client/src/components/timetable.tsx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ export function getVisibleTimetableRect() {
1818
if (timetable_barrier == null) return;
1919
const timetable_barrier_rect = timetable_barrier.getBoundingClientRect();
2020

21+
const timetable_separator = document.getElementById("timetable-separator");
22+
if (timetable_separator == null) return;
23+
const timetable_separator_rect = timetable_separator.getBoundingClientRect();
24+
2125
const rect = {
22-
left: time_header_rect.right,
26+
left: time_header_rect.right + timetable_separator_rect.width,
2327
right: timetable_barrier_rect.left + timetable_barrier.clientWidth,
2428
top: time_header_rect.bottom,
2529
bottom: timetable_barrier_rect.top + timetable_barrier.clientHeight,
@@ -59,7 +63,22 @@ export function getDayLeftPosition(day: string) {
5963
return day_label.getBoundingClientRect().left;
6064
}
6165

66+
function resizeAndPositionTimetableSeparator() {
67+
const separator = document.getElementById("timetable-separator");
68+
if (separator == null) return;
69+
70+
const time_col = document.getElementById("Time");
71+
if (time_col == null) return;
72+
73+
const col_rect = time_col.getBoundingClientRect();
74+
if (col_rect == undefined) return;
75+
76+
separator.style.left = col_rect.right + "px";
77+
separator.style.height = col_rect.height + "px";
78+
}
79+
6280
export function resizeTimetableElements() {
81+
resizeAndPositionTimetableSeparator();
6382
resizeAndPositionTimetableTasks();
6483
resizeAndPositionTimeIndicator();
6584
}
@@ -75,7 +94,7 @@ export function scrollToCurrentTime(align?: string) {
7594
if (timetable == null) return;
7695

7796
const time_header = document.getElementById("time-header");
78-
if (time_header == undefined) return;
97+
if (time_header == null) return;
7998
const time_header_height = time_header.getBoundingClientRect().height;
8099
if (time_header_height == undefined) return;
81100

@@ -178,7 +197,7 @@ function Timetable({ children }: TimetableProps) {
178197
>
179198
<div
180199
id="timetable"
181-
className="timetable flex h-full w-full flex-row gap-1"
200+
className="timetable flex h-full w-full flex-row gap-[4px]"
182201
>
183202
<TimetableTimeColumn />
184203
<TimetableDayColumn day="Monday" label="Monday" />
@@ -195,6 +214,10 @@ function Timetable({ children }: TimetableProps) {
195214
>
196215
{children}
197216
</div>
217+
<div
218+
id="timetable-separator"
219+
className="absolute z-[10] w-[4px] bg-slate-900"
220+
></div>
198221
</div>
199222
</div>
200223
</div>

client/src/components/timetable_column.tsx

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default function TimetableColumn({
1515
sticky,
1616
}: TimetableColumnProps) {
1717
let class_name =
18-
"timetable-column w-full min-w-48 h-full \
18+
"timetable-column w-full min-w-32 md:min-w-48 h-full \
1919
flex flex-col bg-slate-500";
2020

2121
if (sticky === true) {
@@ -32,33 +32,45 @@ export default function TimetableColumn({
3232
}
3333

3434
export function TimetableDayColumn({ label, day }: TimetableColumnProps) {
35+
const now = new Date(Date.now());
36+
enum DateDay {
37+
Monday = 1,
38+
Tuesday,
39+
Wednesday,
40+
Thursday,
41+
Friday,
42+
Saturday,
43+
Sunday,
44+
}
45+
const current_day = DateDay[now.getDay()];
46+
3547
return (
3648
<TimetableColumn day={day} label={label}>
3749
<TimetableSlot time="Header" label={label} header={true} />
38-
<TimetableSlot time="00:00:00" />
39-
<TimetableSlot time="01:00:00" />
40-
<TimetableSlot time="02:00:00" />
41-
<TimetableSlot time="03:00:00" />
42-
<TimetableSlot time="04:00:00" />
43-
<TimetableSlot time="05:00:00" />
44-
<TimetableSlot time="06:00:00" />
45-
<TimetableSlot time="07:00:00" />
46-
<TimetableSlot time="08:00:00" />
47-
<TimetableSlot time="09:00:00" />
48-
<TimetableSlot time="10:00:00" />
49-
<TimetableSlot time="11:00:00" />
50-
<TimetableSlot time="12:00:00" />
51-
<TimetableSlot time="13:00:00" />
52-
<TimetableSlot time="14:00:00" />
53-
<TimetableSlot time="15:00:00" />
54-
<TimetableSlot time="16:00:00" />
55-
<TimetableSlot time="17:00:00" />
56-
<TimetableSlot time="18:00:00" />
57-
<TimetableSlot time="19:00:00" />
58-
<TimetableSlot time="20:00:00" />
59-
<TimetableSlot time="21:00:00" />
60-
<TimetableSlot time="22:00:00" />
61-
<TimetableSlot time="23:00:00" />
50+
<TimetableSlot time="00:00:00" highlight={day === current_day} />
51+
<TimetableSlot time="01:00:00" highlight={day === current_day} />
52+
<TimetableSlot time="02:00:00" highlight={day === current_day} />
53+
<TimetableSlot time="03:00:00" highlight={day === current_day} />
54+
<TimetableSlot time="04:00:00" highlight={day === current_day} />
55+
<TimetableSlot time="05:00:00" highlight={day === current_day} />
56+
<TimetableSlot time="06:00:00" highlight={day === current_day} />
57+
<TimetableSlot time="07:00:00" highlight={day === current_day} />
58+
<TimetableSlot time="08:00:00" highlight={day === current_day} />
59+
<TimetableSlot time="09:00:00" highlight={day === current_day} />
60+
<TimetableSlot time="10:00:00" highlight={day === current_day} />
61+
<TimetableSlot time="11:00:00" highlight={day === current_day} />
62+
<TimetableSlot time="12:00:00" highlight={day === current_day} />
63+
<TimetableSlot time="13:00:00" highlight={day === current_day} />
64+
<TimetableSlot time="14:00:00" highlight={day === current_day} />
65+
<TimetableSlot time="15:00:00" highlight={day === current_day} />
66+
<TimetableSlot time="16:00:00" highlight={day === current_day} />
67+
<TimetableSlot time="17:00:00" highlight={day === current_day} />
68+
<TimetableSlot time="18:00:00" highlight={day === current_day} />
69+
<TimetableSlot time="19:00:00" highlight={day === current_day} />
70+
<TimetableSlot time="20:00:00" highlight={day === current_day} />
71+
<TimetableSlot time="21:00:00" highlight={day === current_day} />
72+
<TimetableSlot time="22:00:00" highlight={day === current_day} />
73+
<TimetableSlot time="23:00:00" highlight={day === current_day} />
6274
</TimetableColumn>
6375
);
6476
}

client/src/components/timetable_slot.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,34 @@ interface TimetableSlotProps {
33
header?: boolean;
44
time_label?: boolean;
55
time: string;
6+
highlight?: boolean;
67
}
78

89
function TimetableSlot({
910
label,
1011
header,
1112
time_label,
1213
time,
14+
highlight,
1315
}: TimetableSlotProps) {
1416
let class_name =
1517
"timetable-slot w-full h-full min-h-16 \
1618
flex justify-center items-center border-solid ";
1719

1820
if (header === true) {
19-
class_name =
20-
class_name +
21-
" bg-slate-800 sticky top-0 z-10 \
21+
class_name +=
22+
" timetable-header bg-slate-800 sticky top-0 z-10 \
2223
border-b-2 border-b-slate-900";
2324
} else {
24-
class_name =
25-
class_name +
26-
" bg-slate-600 \
27-
border-t border-b border-t-slate-400 border-b-slate-400";
25+
const bg_color = highlight === true ? " bg-slate-500" : " bg-slate-600";
26+
class_name +=
27+
bg_color +
28+
" border-t border-b \
29+
border-t-slate-400 border-b-slate-400";
2830
}
2931

3032
if (header !== true && time_label !== true) {
31-
class_name = class_name + " hover:bg-slate-500";
33+
class_name += " hover:bg-slate-500";
3234
}
3335

3436
// There's probably a better way to do this

client/src/components/timetable_task.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,28 +115,38 @@ function resizeAndPositionTimetableTaskTooltip(tooltip: HTMLElement) {
115115
if (task == null) return;
116116

117117
const task_rect = task.getBoundingClientRect();
118-
if (task_rect == undefined) return;
119118

120119
tooltip.style.display = "flex";
121120
const tooltip_rect = tooltip.getBoundingClientRect();
122-
if (tooltip_rect == undefined) return;
123121

124122
const visible = getVisibleTimetableRect();
125123
if (visible == undefined) return;
126124

127-
if (task_rect.left - visible.left > visible.right - task_rect.right) {
125+
const left_space = task_rect.left - visible.left;
126+
const right_space = visible.right - task_rect.right;
127+
128+
if (left_space > right_space) {
128129
tooltip.style.left = task_rect.left - tooltip_rect.width + "px";
130+
// Tooltip has a max width so won't get too big
131+
tooltip.style.width = left_space + "px";
129132
} else {
130133
tooltip.style.left = task_rect.right + "px";
134+
// Tooltip has a max width so won't get too big
135+
tooltip.style.width = right_space + "px";
136+
}
137+
138+
if (tooltip_rect.height > visible.height) {
139+
tooltip.style.height = visible.height + "px";
131140
}
132141

133142
const target_pos =
134143
task_rect.top + task_rect.height / 2 - tooltip_rect.height / 2;
135144

136145
let tooltip_top = target_pos;
146+
137147
if (target_pos < visible.top) {
138148
tooltip_top = visible.top;
139-
} else if (target_pos > visible.bottom) {
149+
} else if (target_pos > visible.bottom - tooltip_rect.height) {
140150
tooltip_top = visible.bottom - tooltip_rect.height;
141151
}
142152

@@ -279,19 +289,21 @@ function TimetableTask({
279289
</div>
280290
<div
281291
id={id + "-tooltip"}
282-
className="timetable-task-tooltip absolute z-[75] flex w-64 flex-col items-center justify-center gap-3 overflow-auto rounded-lg bg-slate-800 p-3"
292+
className="timetable-task-tooltip absolute z-[75] max-w-64 rounded-lg bg-slate-800 p-3"
283293
style={{ display: "none" }}
284294
onMouseOver={mouseOverHandler}
285295
onMouseOut={mouseOutHandler}
286296
>
287-
{tooltip_props.map((props) => (
288-
<div
289-
key={id + "-tooltip-" + props.name}
290-
className="z-[75] h-fit w-full rounded-lg bg-slate-400 p-3 text-slate-100"
291-
>
292-
<TimetableTaskContent {...props} time_display="both" />
293-
</div>
294-
))}
297+
<div className="tooltip-content-container flex h-full w-full flex-col gap-3 overflow-auto">
298+
{tooltip_props.map((props) => (
299+
<div
300+
key={id + "-tooltip-" + props.name}
301+
className="z-[75] h-fit w-full rounded-lg bg-slate-400 p-3 text-slate-100"
302+
>
303+
<TimetableTaskContent {...props} time_display="both" />
304+
</div>
305+
))}
306+
</div>
295307
</div>
296308
</>
297309
);

0 commit comments

Comments
 (0)