Skip to content

Commit a403446

Browse files
authored
Merge pull request #103 from refactor-group/coaching_session_page_tweaks
2 parents b049bf4 + 3573f47 commit a403446

File tree

4 files changed

+46
-93
lines changed

4 files changed

+46
-93
lines changed

src/app/coaching-sessions/[id]/page.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default function CoachingSessionsPage() {
3636
return (
3737
// Never grow wider than the site-header
3838
<div className="max-w-screen-2xl">
39-
<div className="flex-col h-full md:flex ">
39+
<div className="flex-col h-full pl-4 md:flex ">
4040
<div className="flex flex-col items-start justify-between space-y-2 py-4 px-4 sm:flex-row sm:items-center sm:space-y-0 md:h-16">
4141
<CoachingSessionTitle
4242
locale={siteConfig.locale}
@@ -53,7 +53,9 @@ export default function CoachingSessionsPage() {
5353
</div>
5454
</div>
5555

56-
<Separator />
56+
<div className="px-3">
57+
<Separator />
58+
</div>
5759

5860
<OverarchingGoalContainer userId={userId} />
5961

src/components/ui/coaching-session-selector.tsx

Lines changed: 40 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,18 @@ import {
1212
} from "@/components/ui/select";
1313
import { getDateTimeFromString, Id } from "@/types/general";
1414
import { useCoachingSessionList } from "@/lib/api/coaching-sessions";
15-
import { useEffect, useState } from "react";
15+
import { useEffect } from "react";
1616
import { DateTime } from "ts-luxon";
1717
import { useCoachingSessionStateStore } from "@/lib/providers/coaching-session-state-store-provider";
18-
import { OverarchingGoalApi } from "@/lib/api/overarching-goals";
19-
import { OverarchingGoal } from "@/types/overarching-goal";
2018
import { CoachingSession } from "@/types/coaching-session";
19+
import {
20+
useOverarchingGoalBySession,
21+
useOverarchingGoalList,
22+
} from "@/lib/api/overarching-goals";
2123

2224
interface CoachingSessionsSelectorProps extends PopoverProps {
23-
/// The CoachingRelationship Id for which to get a list of associated CoachingSessions
2425
relationshipId: Id;
25-
/// Disable the component from interaction with the user
2626
disabled: boolean;
27-
/// Called when a CoachingSession is selected
2827
onSelect?: (coachingSessionId: Id) => void;
2928
}
3029

@@ -33,81 +32,28 @@ function CoachingSessionsSelectItems({
3332
}: {
3433
relationshipId: Id;
3534
}) {
36-
// TODO: for now we hardcode a 2 month window centered around now,
37-
// eventually we want to make this be configurable somewhere
38-
// (either on the page or elsewhere)
3935
const fromDate = DateTime.now().minus({ month: 1 });
4036
const toDate = DateTime.now().plus({ month: 1 });
4137

4238
const {
4339
coachingSessions,
4440
isLoading: isLoadingSessions,
4541
isError: isErrorSessions,
46-
refresh,
4742
} = useCoachingSessionList(relationshipId, fromDate, toDate);
4843

4944
const { setCurrentCoachingSessions } = useCoachingSessionStateStore(
5045
(state) => state
5146
);
52-
const [goals, setGoals] = useState<(OverarchingGoal[] | undefined)[]>([]);
53-
const [isLoadingGoals, setIsLoadingGoals] = useState(false);
5447

5548
useEffect(() => {
5649
if (!coachingSessions.length) return;
5750
setCurrentCoachingSessions(coachingSessions);
5851
}, [coachingSessions]);
5952

60-
useEffect(() => {
61-
const fetchGoals = async () => {
62-
setIsLoadingGoals(true);
63-
try {
64-
const sessionIds = coachingSessions?.map((session) => session.id) || [];
65-
const goalsPromises = sessionIds.map((id) =>
66-
OverarchingGoalApi.list(id)
67-
);
68-
const fetchedGoals = await Promise.all(goalsPromises);
69-
setGoals(fetchedGoals);
70-
} catch (error) {
71-
console.error("Error fetching goals:", error);
72-
} finally {
73-
setIsLoadingGoals(false);
74-
}
75-
};
76-
77-
if (coachingSessions?.length) {
78-
fetchGoals();
79-
}
80-
}, [coachingSessions]);
81-
82-
if (isLoadingSessions || isLoadingGoals) return <div>Loading...</div>;
53+
if (isLoadingSessions) return <div>Loading...</div>;
8354
if (isErrorSessions) return <div>Error loading coaching sessions</div>;
8455
if (!coachingSessions?.length) return <div>No coaching sessions found</div>;
8556

86-
const SessionItem = ({
87-
session,
88-
goals,
89-
sessionIndex,
90-
}: {
91-
session: CoachingSession;
92-
goals: (OverarchingGoal[] | undefined)[];
93-
sessionIndex: number;
94-
}) => (
95-
<SelectItem value={session.id}>
96-
<div className="flex min-w-0 w-[calc(100%-20px)]">
97-
<div className="min-w-0 w-full">
98-
<p className="truncate text-sm font-medium">
99-
{goals[sessionIndex]?.[0]?.title || "No goal set"}
100-
</p>
101-
<p className="truncate text-sm text-gray-400">
102-
{getDateTimeFromString(session.date).toLocaleString(
103-
DateTime.DATETIME_FULL
104-
)}
105-
</p>
106-
</div>
107-
</div>
108-
</SelectItem>
109-
);
110-
11157
return (
11258
<>
11359
{[
@@ -129,14 +75,7 @@ function CoachingSessionsSelectItems({
12975
{coachingSessions
13076
.filter((session) => condition(session.date))
13177
.map((session) => (
132-
<SessionItem
133-
key={session.id}
134-
session={session}
135-
goals={goals}
136-
sessionIndex={coachingSessions.findIndex(
137-
(s) => s.id === session.id
138-
)}
139-
/>
78+
<SessionItemWithGoal key={session.id} session={session} />
14079
))}
14180
</SelectGroup>
14281
)
@@ -145,6 +84,33 @@ function CoachingSessionsSelectItems({
14584
);
14685
}
14786

87+
// Separate component to handle individual session goal fetching
88+
function SessionItemWithGoal({ session }: { session: CoachingSession }) {
89+
const { overarchingGoal, isLoading, isError } = useOverarchingGoalBySession(
90+
session.id
91+
);
92+
93+
if (isLoading) return <div>Loading goal...</div>;
94+
if (isError) return <div>Error loading goal</div>;
95+
96+
return (
97+
<SelectItem value={session.id}>
98+
<div className="flex min-w-0">
99+
<div className="min-w-0 w-full">
100+
<p className="truncate text-sm font-medium">
101+
{overarchingGoal.title || "No goal set"}
102+
</p>
103+
<p className="truncate text-sm text-gray-400">
104+
{getDateTimeFromString(session.date).toLocaleString(
105+
DateTime.DATETIME_FULL
106+
)}
107+
</p>
108+
</div>
109+
</div>
110+
</SelectItem>
111+
);
112+
}
113+
148114
export default function CoachingSessionSelector({
149115
relationshipId,
150116
disabled,
@@ -157,31 +123,15 @@ export default function CoachingSessionSelector({
157123
getCurrentCoachingSession,
158124
} = useCoachingSessionStateStore((state) => state);
159125

160-
const [currentGoal, setCurrentGoal] = useState<OverarchingGoal | undefined>();
161-
const [isLoadingGoal, setIsLoadingGoal] = useState(false);
162-
163126
const currentSession = currentCoachingSessionId
164127
? getCurrentCoachingSession(currentCoachingSessionId)
165128
: null;
166129

167-
useEffect(() => {
168-
const fetchGoal = async () => {
169-
if (!currentCoachingSessionId) return;
170-
171-
setIsLoadingGoal(true);
172-
try {
173-
const goals = await OverarchingGoalApi.list(currentCoachingSessionId);
174-
setCurrentGoal(goals[0]);
175-
} catch (error) {
176-
console.error("Error fetching goal:", error);
177-
} finally {
178-
setIsLoadingGoal(false);
179-
}
180-
};
181-
182-
fetchGoal();
183-
}, [currentCoachingSessionId]);
184-
130+
const {
131+
overarchingGoal,
132+
isLoading: isLoadingGoal,
133+
isError: isErrorGoal,
134+
} = useOverarchingGoalBySession(currentCoachingSessionId);
185135
const handleSetCoachingSession = (coachingSessionId: Id) => {
186136
setCurrentCoachingSessionId(coachingSessionId);
187137
if (onSelect) {
@@ -192,7 +142,7 @@ export default function CoachingSessionSelector({
192142
const displayValue = currentSession ? (
193143
<div className="flex flex-col w-full">
194144
<span className="truncate text-left">
195-
{currentGoal?.title || "No goal set"}
145+
{isLoadingGoal ? "Loading..." : overarchingGoal.title || "No goal set"}
196146
</span>
197147
<span className="text-sm text-gray-500 text-left truncate">
198148
{getDateTimeFromString(currentSession.date).toLocaleString(

src/components/ui/coaching-sessions/overarching-goal-container.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
1515
import { OverarchingGoalComponent } from "./overarching-goal";
1616
import {
1717
useOverarchingGoalBySession,
18+
useOverarchingGoalList,
1819
useOverarchingGoalMutation,
1920
} from "@/lib/api/overarching-goals";
2021
import {

src/components/ui/site-header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { UserNav } from "@/components/ui/user-nav";
77

88
export function SiteHeader() {
99
return (
10-
<header className="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
10+
<header className="sticky top-0 z-50 w-full max-w-screen-2xl border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
1111
<div className="flex h-14 pl-4 pt-2 max-w-screen-2xl items-start">
1212
<MainNav />
1313
<div className="flex flex-1 items-center justify-between space-x-2 md:justify-end">

0 commit comments

Comments
 (0)