1
+ 'use client' ;
2
+
3
+ import { Call , CallRecording } from '@stream-io/video-react-sdk' ;
4
+
5
+ import Loader from './Loader' ;
6
+ import { useGetCalls } from '@/hooks/useGetCalls' ;
7
+ import MeetingCard from './MeetingCard' ;
8
+ import { useEffect , useState } from 'react' ;
9
+ import { useRouter } from 'next/navigation' ;
10
+
11
+ const CallList = ( { type } : { type : 'ended' | 'upcoming' | 'recordings' } ) => {
12
+ const router = useRouter ( ) ;
13
+ const { endedCalls, upcomingCalls, callRecordings, isLoading } =
14
+ useGetCalls ( ) ;
15
+ const [ recordings , setRecordings ] = useState < CallRecording [ ] > ( [ ] ) ;
16
+
17
+ const getCalls = ( ) => {
18
+ switch ( type ) {
19
+ case 'ended' :
20
+ return endedCalls ;
21
+ case 'recordings' :
22
+ return recordings ;
23
+ case 'upcoming' :
24
+ return upcomingCalls ;
25
+ default :
26
+ return [ ] ;
27
+ }
28
+ } ;
29
+
30
+ const getNoCallsMessage = ( ) => {
31
+ switch ( type ) {
32
+ case 'ended' :
33
+ return 'No Previous Calls' ;
34
+ case 'upcoming' :
35
+ return 'No Upcoming Calls' ;
36
+ case 'recordings' :
37
+ return 'No Recordings' ;
38
+ default :
39
+ return '' ;
40
+ }
41
+ } ;
42
+
43
+ useEffect ( ( ) => {
44
+ const fetchRecordings = async ( ) => {
45
+ const callData = await Promise . all (
46
+ callRecordings ?. map ( ( meeting ) => meeting . queryRecordings ( ) ) ?? [ ] ,
47
+ ) ;
48
+
49
+ const recordings = callData
50
+ . filter ( ( call ) => call . recordings . length > 0 )
51
+ . flatMap ( ( call ) => call . recordings ) ;
52
+
53
+ setRecordings ( recordings ) ;
54
+ } ;
55
+
56
+ if ( type === 'recordings' ) {
57
+ fetchRecordings ( ) ;
58
+ }
59
+ } , [ type , callRecordings ] ) ;
60
+
61
+ if ( isLoading ) return < Loader /> ;
62
+
63
+ const calls = getCalls ( ) ;
64
+ const noCallsMessage = getNoCallsMessage ( ) ;
65
+
66
+ return (
67
+ < div className = "grid grid-cols-1 gap-5 xl:grid-cols-2" >
68
+ { calls && calls . length > 0 ? (
69
+ calls . map ( ( meeting : Call | CallRecording ) => (
70
+ < MeetingCard
71
+ key = { ( meeting as Call ) . id }
72
+ icon = {
73
+ type === 'ended'
74
+ ? '/icons/previous.svg'
75
+ : type === 'upcoming'
76
+ ? '/icons/upcoming.svg'
77
+ : '/icons/recordings.svg'
78
+ }
79
+ title = {
80
+ ( meeting as Call ) . state ?. custom ?. description ||
81
+ ( meeting as CallRecording ) . filename ?. substring ( 0 , 20 ) ||
82
+ 'No Description'
83
+ }
84
+ date = {
85
+ ( meeting as Call ) . state ?. startsAt ?. toLocaleString ( ) ||
86
+ ( meeting as CallRecording ) . start_time ?. toLocaleString ( )
87
+ }
88
+ isPreviousMeeting = { type === 'ended' }
89
+ link = {
90
+ type === 'recordings'
91
+ ? ( meeting as CallRecording ) . url
92
+ : `${ process . env . NEXT_PUBLIC_BASE_URL } /meeting/${ ( meeting as Call ) . id } `
93
+ }
94
+ buttonIcon1 = { type === 'recordings' ? '/icons/play.svg' : undefined }
95
+ buttonText = { type === 'recordings' ? 'Play' : 'Start' }
96
+ handleClick = {
97
+ type === 'recordings'
98
+ ? ( ) => router . push ( `${ ( meeting as CallRecording ) . url } ` )
99
+ : ( ) => router . push ( `/meeting/${ ( meeting as Call ) . id } ` )
100
+ }
101
+ />
102
+ ) )
103
+ ) : (
104
+ < h1 className = "text-2xl font-bold text-white" > { noCallsMessage } </ h1 >
105
+ ) }
106
+ </ div >
107
+ ) ;
108
+ } ;
109
+
110
+ export default CallList ;
0 commit comments