1
1
import React , { useState } from 'react' ;
2
2
import { useApiData } from '@/hooks/use-api-data' ;
3
- import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from '@/components/ui/select' ;
3
+ import { Select , SelectContent , SelectGroup , SelectItem , SelectLabel , SelectTrigger , SelectValue } from '@/components/ui/select' ;
4
+ import { CoachingSession , isCoachingSession } from '@/types/coaching-session' ;
5
+ import { DateTime } from 'ts-luxon' ;
4
6
5
7
interface DynamicApiSelectProps < T > {
6
8
url : string ;
@@ -24,11 +26,11 @@ export function DynamicApiSelect<T>({
24
26
method = 'GET' ,
25
27
params = { } ,
26
28
onChange,
27
- placeholder = "Select an organization " ,
29
+ placeholder = "Select an option " ,
28
30
getOptionLabel,
29
31
getOptionValue,
30
32
elementId,
31
- groupByDate
33
+ groupByDate = false
32
34
} : DynamicApiSelectProps < T > ) {
33
35
const { data : response , isLoading, error } = useApiData < ApiResponse < T > > ( url , { method, params } ) ;
34
36
const [ value , setValue ] = useState < string > ( '' ) ;
@@ -38,26 +40,63 @@ export function DynamicApiSelect<T>({
38
40
onChange ( newValue ) ;
39
41
}
40
42
41
- if ( isLoading ) return < p > Loading...</ p >
42
- if ( error ) return < p > Error: { error . message } </ p >
43
- if ( ! response || response . status_code !== 200 ) return < p > Error: Invalid response</ p >
43
+ if ( isLoading ) return < p > Loading...</ p > ;
44
+ if ( error ) return < p > Error: { error . message } </ p > ;
45
+ if ( ! response || response . status_code !== 200 ) return < p > Error: Invalid response</ p > ;
44
46
45
47
const items = response . data ;
46
48
47
- return (
48
- < Select
49
- value = { value }
50
- onValueChange = { handleValueChange } >
51
- < SelectTrigger id = { elementId } className = 'w-auto' >
52
- < SelectValue placeholder = { placeholder } />
53
- </ SelectTrigger >
54
- < SelectContent className = 'w-full' >
55
- { items . map ( ( item , index ) => (
49
+ const renderSessions = ( sessions : CoachingSession [ ] , label : string , filterFn : ( session : CoachingSession ) => boolean ) => {
50
+ const filteredSessions = sessions . filter ( filterFn ) ;
51
+ return filteredSessions . length > 0 && (
52
+ < SelectGroup >
53
+ < SelectLabel > { label } </ SelectLabel >
54
+ { filteredSessions . map ( session => (
55
+ < SelectItem value = { session . id } key = { session . id } >
56
+ { DateTime . fromISO ( session . date . toString ( ) ) . toLocaleString ( DateTime . DATETIME_FULL ) }
57
+ </ SelectItem >
58
+ ) ) }
59
+ </ SelectGroup >
60
+ ) ;
61
+ } ;
62
+
63
+ const renderCoachingSessions = ( sessions : CoachingSession [ ] ) => (
64
+ < SelectContent >
65
+ { sessions . length === 0 ? (
66
+ < SelectItem disabled value = "none" > None found</ SelectItem >
67
+ ) : (
68
+ < >
69
+ { renderSessions ( sessions , 'Previous Sessions' , session => DateTime . fromISO ( session . date . toString ( ) ) < DateTime . now ( ) ) }
70
+ { renderSessions ( sessions , 'Upcoming Sessions' , session => DateTime . fromISO ( session . date . toString ( ) ) >= DateTime . now ( ) ) }
71
+ </ >
72
+ ) }
73
+ </ SelectContent >
74
+ ) ;
75
+
76
+ const renderOtherItems = ( items : T [ ] ) => (
77
+ < SelectContent >
78
+ { items . length === 0 ? (
79
+ < SelectItem disabled value = "none" > None found</ SelectItem >
80
+ ) : (
81
+ items . map ( ( item , index ) => (
56
82
< SelectItem key = { index } value = { getOptionValue ( item ) } >
57
83
{ getOptionLabel ( item ) }
58
84
</ SelectItem >
59
- ) ) }
60
- </ SelectContent >
85
+ ) )
86
+ ) }
87
+ </ SelectContent >
88
+ ) ;
89
+
90
+ const coachingSessions = groupByDate ? items . filter ( isCoachingSession ) as CoachingSession [ ] : [ ] ;
91
+
92
+ return (
93
+ < Select value = { value } onValueChange = { handleValueChange } >
94
+ < SelectTrigger id = { elementId } >
95
+ < SelectValue placeholder = { placeholder } />
96
+ </ SelectTrigger >
97
+ { groupByDate && coachingSessions . length > 0
98
+ ? renderCoachingSessions ( coachingSessions )
99
+ : renderOtherItems ( items ) }
61
100
</ Select >
62
101
) ;
63
- }
102
+ }
0 commit comments