cfahlgren1's picture
cfahlgren1 HF Staff
little better naming
6580e54
import React, { useState, useEffect } from "react";
import { ProviderInfo, ModelData, CalendarData } from "../types/heatmap";
import OrganizationButton from "../components/OrganizationButton";
import HeatmapGrid from "../components/HeatmapGrid";
import Navbar from "../components/Navbar";
import { getProviders } from "../utils/ranking";
import { ORGANIZATIONS } from "../constants/organizations";
interface PageProps {
calendarData: CalendarData;
providers: ProviderInfo[];
}
function Page({
calendarData,
providers,
}: PageProps) {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
if (calendarData && Object.keys(calendarData).length > 0) {
setIsLoading(false);
}
}, [calendarData]);
return (
<div className="w-full">
<Navbar />
<div className="w-full p-4 py-16">
<div className="text-center mb-16 max-w-4xl mx-auto">
<h1 className="text-2xl sm:text-3xl md:text-4xl lg:text-6xl font-bold text-foreground mb-6 bg-gradient-to-r from-foreground to-foreground/80 bg-clip-text">
<span className="inline-flex items-center gap-1 sm:gap-2">
Hugging Face Heatmap
<img
src="/hf-icon.svg"
alt="Hugging Face icon"
className="size-6 sm:size-8 md:size-10"
/>
</span>
</h1>
<p className="text-base sm:text-lg lg:text-xl text-muted-foreground max-w-2xl mx-auto leading-relaxed px-4">
Open models, datasets, and apps from popular AI labs in the last year.
</p>
</div>
<div className="mb-16 mx-auto">
<div className="overflow-x-auto scrollbar-hide">
<div className="flex gap-6 px-4 py-2 min-w-max justify-center">
{providers.map((provider, index) => (
<OrganizationButton
key={provider.fullName || provider.authors[0]}
provider={provider}
calendarData={calendarData}
rank={index + 1}
/>
))}
</div>
</div>
</div>
<HeatmapGrid
sortedProviders={providers}
calendarData={calendarData}
isLoading={isLoading}
/>
</div>
</div>
);
}
export async function getStaticProps() {
try {
const { calendarData, providers } = await getProviders(ORGANIZATIONS);
return {
props: {
calendarData,
providers,
},
revalidate: 3600, // regenerate every hour
};
} catch (error) {
console.error("Error fetching data:", error);
return {
props: {
calendarData: {},
providers: ORGANIZATIONS,
},
revalidate: 60, // retry after 1 minute if there was an error
};
}
}
export default Page;