1+ import React from 'react' ;
2+ import { fetchMoviesWithComments , fetchMoviesByYear , fetchDirectorStats } from '../lib/api' ;
3+ import styles from './aggregations.module.css' ;
4+
5+ // Type definitions for better type safety
6+ interface MovieWithComments {
7+ _id : string ;
8+ title : string ;
9+ year : number ;
10+ genres : string [ ] ;
11+ imdbRating : number ;
12+ totalComments : number ;
13+ recentComments : Array < {
14+ userName : string ;
15+ userEmail : string ;
16+ text : string ;
17+ date : string ;
18+ } > ;
19+ }
20+
21+ interface YearlyStats {
22+ year : number ;
23+ movieCount : number ;
24+ averageRating : number ;
25+ highestRating : number ;
26+ lowestRating : number ;
27+ totalVotes : number ;
28+ }
29+
30+ interface DirectorStats {
31+ director : string ;
32+ movieCount : number ;
33+ averageRating : number ;
34+ }
35+
36+ export default async function AggregationsPage ( ) {
37+
38+ // Fetch all aggregation data with error handling
39+ const [ commentsResult , yearResult , directorsResult ] = await Promise . allSettled ( [
40+ fetchMoviesWithComments ( 5 ) ,
41+ fetchMoviesByYear ( ) ,
42+ fetchDirectorStats ( 15 )
43+ ] ) ;
44+
45+ // Process results with fallbacks
46+ const commentsData = commentsResult . status === 'fulfilled' ? commentsResult . value : { success : false , error : 'Failed to fetch comments data' } ;
47+ const yearData = yearResult . status === 'fulfilled' ? yearResult . value : { success : false , error : 'Failed to fetch year data' } ;
48+ const directorsData = directorsResult . status === 'fulfilled' ? directorsResult . value : { success : false , error : 'Failed to fetch directors data' } ;
49+
50+ console . log ( 'Aggregations SSR: Data fetch completed' , {
51+ comments : commentsData . success ,
52+ year : yearData . success ,
53+ directors : directorsData . success
54+ } ) ;
55+
56+ return (
57+ < div className = { styles . container } >
58+ < h1 className = { styles . title } > Movie Analytics Aggregations</ h1 >
59+ < p className = { styles . subtitle } >
60+ Explore movie data through various aggregations and insights
61+ </ p >
62+
63+ { /* Movies with Recent Comments Section */ }
64+ < section className = { styles . section } >
65+ < h2 className = { styles . sectionTitle } > Movies with Recent Comments</ h2 >
66+ { commentsData . success && commentsData . data ? (
67+ < div className = { styles . tableContainer } >
68+ < table className = { styles . table } >
69+ < thead >
70+ < tr >
71+ < th > Movie Title</ th >
72+ < th > Year</ th >
73+ < th > Rating</ th >
74+ < th > Total Comments</ th >
75+ < th > Recent Comments</ th >
76+ </ tr >
77+ </ thead >
78+ < tbody >
79+ { ( commentsData . data as MovieWithComments [ ] ) . map ( ( movie ) => (
80+ < tr key = { movie . _id } >
81+ < td className = { styles . movieTitle } > { movie . title } </ td >
82+ < td > { movie . year } </ td >
83+ < td > { movie . imdbRating ? movie . imdbRating . toFixed ( 1 ) : 'N/A' } </ td >
84+ < td > { movie . totalComments } </ td >
85+ < td >
86+ < div className = { styles . commentsContainer } >
87+ { movie . recentComments ?. slice ( 0 , 2 ) . map ( ( comment , index ) => (
88+ < div key = { index } className = { styles . comment } >
89+ < div className = { styles . commentText } >
90+ “{ ( comment . text || 'No text' ) . slice ( 0 , 80 ) } { comment . text ?. length > 80 ? '...' : '' } ”
91+ </ div >
92+ < div className = { styles . commentMeta } >
93+ by { comment . userName } on { new Date ( comment . date ) . toLocaleDateString ( ) }
94+ </ div >
95+ </ div >
96+ ) ) || < div > No recent comments</ div > }
97+ </ div >
98+ </ td >
99+ </ tr >
100+ ) ) }
101+ </ tbody >
102+ </ table >
103+ </ div >
104+ ) : (
105+ < div className = { styles . error } >
106+ Failed to load movies with comments: { commentsData . error || 'Unknown error' }
107+ </ div >
108+ ) }
109+ </ section >
110+
111+ { /* Movies by Year Section */ }
112+ < section className = { styles . section } >
113+ < h2 className = { styles . sectionTitle } > Movies by Year Statistics</ h2 >
114+ { yearData . success && yearData . data ? (
115+ < div className = { styles . tableContainer } >
116+ < table className = { styles . table } >
117+ < thead >
118+ < tr >
119+ < th > Year</ th >
120+ < th > Movie Count</ th >
121+ < th > Average Rating</ th >
122+ < th > Highest Rating</ th >
123+ < th > Lowest Rating</ th >
124+ < th > Total Votes</ th >
125+ </ tr >
126+ </ thead >
127+ < tbody >
128+ { ( yearData . data as YearlyStats [ ] ) . slice ( 0 , 20 ) . map ( ( yearStats ) => (
129+ < tr key = { yearStats . year } >
130+ < td className = { styles . year } > { yearStats . year } </ td >
131+ < td > { yearStats . movieCount } </ td >
132+ < td > { yearStats . averageRating ? yearStats . averageRating . toFixed ( 2 ) : 'N/A' } </ td >
133+ < td > { yearStats . highestRating ? yearStats . highestRating . toFixed ( 1 ) : 'N/A' } </ td >
134+ < td > { yearStats . lowestRating ? yearStats . lowestRating . toFixed ( 1 ) : 'N/A' } </ td >
135+ < td > { yearStats . totalVotes ?. toLocaleString ( ) || 'N/A' } </ td >
136+ </ tr >
137+ ) ) }
138+ </ tbody >
139+ </ table >
140+ </ div >
141+ ) : (
142+ < div className = { styles . error } >
143+ Failed to load yearly statistics: { yearData . error || 'Unknown error' }
144+ </ div >
145+ ) }
146+ </ section >
147+
148+ { /* Directors with Most Movies Section */ }
149+ < section className = { styles . section } >
150+ < h2 className = { styles . sectionTitle } > Directors with Most Movies</ h2 >
151+ { directorsData . success && directorsData . data ? (
152+ < div className = { styles . tableContainer } >
153+ < table className = { styles . table } >
154+ < thead >
155+ < tr >
156+ < th > Rank</ th >
157+ < th > Director</ th >
158+ < th > Movie Count</ th >
159+ < th > Average Rating</ th >
160+ </ tr >
161+ </ thead >
162+ < tbody >
163+ { ( directorsData . data as DirectorStats [ ] ) . map ( ( director , index ) => (
164+ < tr key = { director . director } >
165+ < td className = { styles . rank } > #{ index + 1 } </ td >
166+ < td className = { styles . directorName } > { director . director } </ td >
167+ < td > { director . movieCount } </ td >
168+ < td > { director . averageRating ? director . averageRating . toFixed ( 2 ) : 'N/A' } </ td >
169+ </ tr >
170+ ) ) }
171+ </ tbody >
172+ </ table >
173+ </ div >
174+ ) : (
175+ < div className = { styles . error } >
176+ Failed to load director statistics: { directorsData . error || 'Unknown error' }
177+ </ div >
178+ ) }
179+ </ section >
180+ </ div >
181+ ) ;
182+ }
0 commit comments