@@ -7,77 +7,78 @@ export const dynamic = "force-dynamic";
77
88export async function GET ( ) {
99 const session = await getServerSession ( authOptions ) ;
10-
10+
1111 if ( ! session ?. githubId ) {
1212 return NextResponse . json ( { error : "Unauthorized" } , { status : 401 } ) ;
1313 }
1414
15- const { data : user } = await supabaseAdmin
16- . from ( "users" )
17- . select ( "id, wakatime_api_key_encrypted" )
18- . eq ( "github_id" , session . githubId )
19- . single ( ) ;
20-
21- if ( ! user ) {
22- return NextResponse . json ( { error : "User not found" } , { status : 404 } ) ;
23- }
24-
25- if ( ! user . wakatime_api_key_encrypted ) {
26- return NextResponse . json ( { hasData : false , not_configured : true } ) ;
27- }
28-
29- // Get last 7 days of stats
30- const date7DaysAgo = new Date ( ) ;
31- date7DaysAgo . setDate ( date7DaysAgo . getDate ( ) - 7 ) ;
32- const dateStr = date7DaysAgo . toISOString ( ) . split ( "T" ) [ 0 ] ;
15+ try {
16+ const { data : user } = await supabaseAdmin
17+ . from ( "users" )
18+ . select ( "id, wakatime_api_key_encrypted" )
19+ . eq ( "github_id" , session . githubId )
20+ . single ( ) ;
21+
22+ if ( ! user ) {
23+ return NextResponse . json ( { hasData : false , not_configured : true } ) ;
24+ }
25+
26+ if ( ! user . wakatime_api_key_encrypted ) {
27+ return NextResponse . json ( { hasData : false , not_configured : true } ) ;
28+ }
29+
30+ const date7DaysAgo = new Date ( ) ;
31+ date7DaysAgo . setDate ( date7DaysAgo . getDate ( ) - 7 ) ;
32+ const dateStr = date7DaysAgo . toISOString ( ) . split ( "T" ) [ 0 ] ;
33+
34+ const { data : stats , error } = await supabaseAdmin
35+ . from ( "wakatime_stats" )
36+ . select ( "*" )
37+ . eq ( "user_id" , user . id )
38+ . gte ( "date" , dateStr )
39+ . order ( "date" , { ascending : true } ) ;
40+
41+ if ( error || ! stats || stats . length === 0 ) {
42+ return NextResponse . json ( { hasData : false } ) ;
43+ }
44+
45+ const today = stats [ stats . length - 1 ] ;
46+ const todaysSeconds = today ?. total_seconds || 0 ;
47+
48+ let totalSeconds7Days = 0 ;
49+ const languagesMap : Record < string , number > = { } ;
50+ const projectsMap : Record < string , number > = { } ;
51+
52+ const chartData = stats . map ( ( day : any ) => {
53+ const totalSeconds = day . total_seconds || 0 ;
54+ totalSeconds7Days += totalSeconds ;
55+
56+ ( day . languages || [ ] ) . forEach ( ( lang : any ) => {
57+ languagesMap [ lang . name ] = ( languagesMap [ lang . name ] || 0 ) + lang . total_seconds ;
58+ } ) ;
59+
60+ ( day . projects || [ ] ) . forEach ( ( proj : any ) => {
61+ projectsMap [ proj . name ] = ( projectsMap [ proj . name ] || 0 ) + proj . total_seconds ;
62+ } ) ;
63+
64+ return {
65+ date : day . date ,
66+ hours : parseFloat ( ( totalSeconds / 3600 ) . toFixed ( 2 ) ) ,
67+ } ;
68+ } ) ;
3369
34- const { data : stats , error } = await supabaseAdmin
35- . from ( "wakatime_stats" )
36- . select ( "*" )
37- . eq ( "user_id" , user . id )
38- . gte ( "date" , dateStr )
39- . order ( "date" , { ascending : true } ) ;
70+ const getTop = ( map : Record < string , number > ) =>
71+ Object . entries ( map ) . sort ( ( a , b ) => b [ 1 ] - a [ 1 ] ) [ 0 ] ?. [ 0 ] || "None" ;
4072
41- if ( error || ! stats || stats . length === 0 ) {
73+ return NextResponse . json ( {
74+ hasData : true ,
75+ todaysSeconds,
76+ totalSeconds7Days,
77+ chartData,
78+ topLanguage : getTop ( languagesMap ) ,
79+ topProject : getTop ( projectsMap ) ,
80+ } ) ;
81+ } catch {
4282 return NextResponse . json ( { hasData : false } ) ;
4383 }
44-
45- // Process data from DB cache
46- const today = stats [ stats . length - 1 ] ;
47- const todaysSeconds = today ?. total_seconds || 0 ;
48-
49- let totalSeconds7Days = 0 ;
50- const languagesMap : Record < string , number > = { } ;
51- const projectsMap : Record < string , number > = { } ;
52-
53- const chartData = stats . map ( ( day : any ) => {
54- const totalSeconds = day . total_seconds || 0 ;
55- totalSeconds7Days += totalSeconds ;
56-
57- ( day . languages || [ ] ) . forEach ( ( lang : any ) => {
58- languagesMap [ lang . name ] = ( languagesMap [ lang . name ] || 0 ) + lang . total_seconds ;
59- } ) ;
60-
61- ( day . projects || [ ] ) . forEach ( ( proj : any ) => {
62- projectsMap [ proj . name ] = ( projectsMap [ proj . name ] || 0 ) + proj . total_seconds ;
63- } ) ;
64-
65- return {
66- date : day . date ,
67- hours : parseFloat ( ( totalSeconds / 3600 ) . toFixed ( 2 ) ) ,
68- } ;
69- } ) ;
70-
71- const getTop = ( map : Record < string , number > ) => {
72- return Object . entries ( map ) . sort ( ( a , b ) => b [ 1 ] - a [ 1 ] ) [ 0 ] ?. [ 0 ] || "None" ;
73- } ;
74-
75- return NextResponse . json ( {
76- hasData : true ,
77- todaysSeconds,
78- totalSeconds7Days,
79- chartData,
80- topLanguage : getTop ( languagesMap ) ,
81- topProject : getTop ( projectsMap ) ,
82- } ) ;
8384}
0 commit comments