@@ -12,19 +12,18 @@ import {
1212} from "@/components/ui/select" ;
1313import { getDateTimeFromString , Id } from "@/types/general" ;
1414import { useCoachingSessionList } from "@/lib/api/coaching-sessions" ;
15- import { useEffect , useState } from "react" ;
15+ import { useEffect } from "react" ;
1616import { DateTime } from "ts-luxon" ;
1717import { useCoachingSessionStateStore } from "@/lib/providers/coaching-session-state-store-provider" ;
18- import { OverarchingGoalApi } from "@/lib/api/overarching-goals" ;
19- import { OverarchingGoal } from "@/types/overarching-goal" ;
2018import { CoachingSession } from "@/types/coaching-session" ;
19+ import {
20+ useOverarchingGoalBySession ,
21+ useOverarchingGoalList ,
22+ } from "@/lib/api/overarching-goals" ;
2123
2224interface 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+
148114export 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 (
0 commit comments