Skip to content

Commit 1f24756

Browse files
committed
refactor(today): separate TodayView content into TodayViewContent component
- Extract TodayViewContent from TodayView for better modularity - Maintain existing functionality while improving code organization - Update TodayView to use the new TodayViewContent component
1 parent f603ea7 commit 1f24756

File tree

2 files changed

+115
-110
lines changed

2 files changed

+115
-110
lines changed

packages/web/src/views/Today/TodayView.tsx

Lines changed: 3 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,7 @@
11
import { useFeatureFlagEnabled } from "posthog-js/react";
2-
import React, { useRef, useState } from "react";
3-
import { CalendarAgenda } from "./components/CalendarAgenda";
4-
import { TaskList } from "./components/TaskList";
5-
import { TaskProvider, useTasks } from "./context/TaskProvider";
6-
import { useKeyboardShortcuts } from "./hooks/useKeyboardShortcuts";
7-
8-
function TodayViewContent() {
9-
const { tasks } = useTasks();
10-
const [focusedTaskId, setFocusedTaskId] = useState<string | null>(null);
11-
const [selectedTaskIndex, setSelectedTaskIndex] = useState(0);
12-
const tasksScrollRef = useRef<HTMLDivElement>(null);
13-
14-
const activeElement =
15-
typeof document !== "undefined"
16-
? (document.activeElement as HTMLElement | null)
17-
: null;
18-
const isEditableElement =
19-
(typeof HTMLInputElement !== "undefined" &&
20-
activeElement instanceof HTMLInputElement) ||
21-
(typeof HTMLTextAreaElement !== "undefined" &&
22-
activeElement instanceof HTMLTextAreaElement) ||
23-
activeElement?.getAttribute("contenteditable") === "true";
24-
25-
const focusTaskAtIndex = (index: number) => {
26-
if (index < 0 || index >= tasks.length) return;
27-
const task = tasks[index];
28-
if (!task) return;
29-
30-
setSelectedTaskIndex(index);
31-
setFocusedTaskId(task.id);
32-
33-
const button = tasksScrollRef.current?.querySelector<HTMLButtonElement>(
34-
`[data-task-id="${task.id}"]`,
35-
);
36-
if (button) {
37-
try {
38-
button.focus({ preventScroll: true });
39-
} catch {
40-
try {
41-
button.focus();
42-
} catch {
43-
// Ignore if focus fails
44-
}
45-
}
46-
try {
47-
button.scrollIntoView({
48-
block: "nearest",
49-
inline: "nearest",
50-
behavior: "smooth",
51-
});
52-
} catch {
53-
// Ignore if scrollIntoView fails
54-
}
55-
}
56-
};
57-
58-
const focusFirstTask = () => {
59-
if (!tasks.length) return;
60-
focusTaskAtIndex(0);
61-
};
62-
63-
const handleNextTask = () => {
64-
if (!tasks.length) return;
65-
const currentIndex = tasks.findIndex((task) => task.id === focusedTaskId);
66-
if (currentIndex === -1) {
67-
focusTaskAtIndex(0);
68-
return;
69-
}
70-
const nextIndex = (currentIndex + 1) % tasks.length;
71-
focusTaskAtIndex(nextIndex);
72-
};
73-
74-
const handlePrevTask = () => {
75-
if (!tasks.length) return;
76-
const currentIndex = tasks.findIndex((task) => task.id === focusedTaskId);
77-
if (currentIndex === -1) {
78-
focusTaskAtIndex(tasks.length - 1);
79-
return;
80-
}
81-
const prevIndex = (currentIndex - 1 + tasks.length) % tasks.length;
82-
focusTaskAtIndex(prevIndex);
83-
};
84-
85-
useKeyboardShortcuts({
86-
onFocusTasks: focusFirstTask,
87-
onNextTask: handleNextTask,
88-
onPrevTask: handlePrevTask,
89-
hasFocusedTask: !!focusedTaskId,
90-
isInInput: isEditableElement,
91-
});
92-
93-
return (
94-
<div className="flex h-screen bg-darkBlue-400">
95-
{/* Tasks Panel */}
96-
<div className="w-96 flex-shrink-0">
97-
<TaskList
98-
onTaskFocus={setFocusedTaskId}
99-
focusedTaskId={focusedTaskId}
100-
onSelectTask={setSelectedTaskIndex}
101-
selectedTaskIndex={selectedTaskIndex}
102-
/>
103-
</div>
104-
105-
{/* Calendar Panel */}
106-
<div className="flex-1">
107-
<CalendarAgenda />
108-
</div>
109-
</div>
110-
);
111-
}
2+
import React from "react";
3+
import { TodayViewContent } from "./TodayViewContent";
4+
import { TaskProvider } from "./context/TaskProvider";
1125

1136
export function TodayView() {
1147
const isPlannerEnabled = useFeatureFlagEnabled("experiment_planner");
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React, { useRef, useState } from "react";
2+
import { CalendarAgenda } from "./components/CalendarAgenda";
3+
import { TaskList } from "./components/TaskList";
4+
import { useTasks } from "./context/TaskProvider";
5+
import { useKeyboardShortcuts } from "./hooks/useKeyboardShortcuts";
6+
7+
export const TodayViewContent = () => {
8+
const { tasks } = useTasks();
9+
const [focusedTaskId, setFocusedTaskId] = useState<string | null>(null);
10+
const [selectedTaskIndex, setSelectedTaskIndex] = useState(0);
11+
const tasksScrollRef = useRef<HTMLDivElement>(null);
12+
13+
const activeElement =
14+
typeof document !== "undefined"
15+
? (document.activeElement as HTMLElement | null)
16+
: null;
17+
const isEditableElement =
18+
(typeof HTMLInputElement !== "undefined" &&
19+
activeElement instanceof HTMLInputElement) ||
20+
(typeof HTMLTextAreaElement !== "undefined" &&
21+
activeElement instanceof HTMLTextAreaElement) ||
22+
activeElement?.getAttribute("contenteditable") === "true";
23+
24+
const focusTaskAtIndex = (index: number) => {
25+
if (index < 0 || index >= tasks.length) return;
26+
const task = tasks[index];
27+
if (!task) return;
28+
29+
setSelectedTaskIndex(index);
30+
setFocusedTaskId(task.id);
31+
32+
const button = tasksScrollRef.current?.querySelector<HTMLButtonElement>(
33+
`[data-task-id="${task.id}"]`,
34+
);
35+
if (button) {
36+
try {
37+
button.focus({ preventScroll: true });
38+
} catch {
39+
try {
40+
button.focus();
41+
} catch {
42+
// Ignore if focus fails
43+
}
44+
}
45+
try {
46+
button.scrollIntoView({
47+
block: "nearest",
48+
inline: "nearest",
49+
behavior: "smooth",
50+
});
51+
} catch {
52+
// Ignore if scrollIntoView fails
53+
}
54+
}
55+
};
56+
57+
const focusFirstTask = () => {
58+
if (!tasks.length) return;
59+
focusTaskAtIndex(0);
60+
};
61+
62+
const handleNextTask = () => {
63+
if (!tasks.length) return;
64+
const currentIndex = tasks.findIndex((task) => task.id === focusedTaskId);
65+
if (currentIndex === -1) {
66+
focusTaskAtIndex(0);
67+
return;
68+
}
69+
const nextIndex = (currentIndex + 1) % tasks.length;
70+
focusTaskAtIndex(nextIndex);
71+
};
72+
73+
const handlePrevTask = () => {
74+
if (!tasks.length) return;
75+
const currentIndex = tasks.findIndex((task) => task.id === focusedTaskId);
76+
if (currentIndex === -1) {
77+
focusTaskAtIndex(tasks.length - 1);
78+
return;
79+
}
80+
const prevIndex = (currentIndex - 1 + tasks.length) % tasks.length;
81+
focusTaskAtIndex(prevIndex);
82+
};
83+
84+
useKeyboardShortcuts({
85+
onFocusTasks: focusFirstTask,
86+
onNextTask: handleNextTask,
87+
onPrevTask: handlePrevTask,
88+
hasFocusedTask: !!focusedTaskId,
89+
isInInput: isEditableElement,
90+
});
91+
92+
return (
93+
<div className=" flex min-h-screen justify-center bg-darkBlue-400 px-6 py-8">
94+
<div className="flex w-full max-witems-stretch gap-8">
95+
{/* Tasks Panel */}
96+
<div className="flex w-96 text-white flex-shrink-0">
97+
<TaskList
98+
onTaskFocus={setFocusedTaskId}
99+
focusedTaskId={focusedTaskId}
100+
onSelectTask={setSelectedTaskIndex}
101+
selectedTaskIndex={selectedTaskIndex}
102+
/>
103+
</div>
104+
105+
{/* Calendar Panel */}
106+
<div className="flex flex-1 min-w-0">
107+
<CalendarAgenda />
108+
</div>
109+
</div>
110+
</div>
111+
);
112+
};

0 commit comments

Comments
 (0)