|
import React, { useState, useEffect } from "react"; |
|
import { GetServerSidePropsContext } from "next"; |
|
import { OpenSourceHeatmapProps } from "../../types/heatmap"; |
|
import { generateCalendarData } from "../../utils/calendar"; |
|
import Heatmap from "../../components/Heatmap"; |
|
import { fetchUserData, fetchAuthorData } from "../../utils/authors"; |
|
|
|
const DEFAULT_COLOR = "#FF9D00"; |
|
|
|
const OpenSourceHeatmap: React.FC<OpenSourceHeatmapProps> = ({ |
|
calendarData, |
|
providers, |
|
}) => { |
|
const [isLoading, setIsLoading] = useState(true); |
|
|
|
useEffect(() => { |
|
if (calendarData && Object.keys(calendarData).length > 0) { |
|
setIsLoading(false); |
|
} |
|
}, [calendarData]); |
|
|
|
return ( |
|
<div className="w-full max-w-screen-lg mx-auto p-4"> |
|
{isLoading ? ( |
|
<p className="text-center">Loading...</p> |
|
) : ( |
|
<div> |
|
{Object.entries(providers) |
|
.sort( |
|
([keyA], [keyB]) => |
|
calendarData[keyB].reduce((sum, day) => sum + day.count, 0) - |
|
calendarData[keyA].reduce((sum, day) => sum + day.count, 0) |
|
) |
|
.map(([providerName, { color, fullName, avatarUrl }]) => ( |
|
<Heatmap |
|
key={providerName} |
|
data={calendarData[providerName]} |
|
color={color} |
|
providerName={providerName} |
|
fullName={fullName ?? providerName} |
|
avatarUrl={avatarUrl ?? ''} |
|
/> |
|
))} |
|
</div> |
|
)} |
|
</div> |
|
); |
|
}; |
|
|
|
export async function getServerSideProps(context: GetServerSidePropsContext) { |
|
const { author, color } = context.query; |
|
|
|
const authorColor = color || DEFAULT_COLOR; |
|
|
|
try { |
|
const { fullName, avatarUrl } = await fetchUserData([author as string]); |
|
|
|
const providers = { |
|
[author as string]: { |
|
color: authorColor as string, |
|
authors: [author as string], |
|
fullName, |
|
avatarUrl, |
|
}, |
|
}; |
|
|
|
const flatData = await fetchAuthorData(author as string); |
|
const calendarData = generateCalendarData(flatData, [providers[author as string]]); |
|
|
|
return { |
|
props: { |
|
calendarData, |
|
color: authorColor, |
|
providers, |
|
}, |
|
}; |
|
} catch (error) { |
|
console.error("Error fetching data:", error); |
|
return { |
|
props: { |
|
calendarData: {}, |
|
color: authorColor, |
|
providers: { |
|
[author as string]: { |
|
color: authorColor as string, |
|
authors: [author as string], |
|
fullName: author, |
|
avatarUrl: null, |
|
}, |
|
}, |
|
}, |
|
}; |
|
} |
|
} |
|
|
|
export default OpenSourceHeatmap; |