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