|
import React, { useState, useEffect, useMemo } from "react"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import AIPoliciesTable from "../components/AIPoliciesTable"; |
|
import fs from 'fs'; |
|
import path from 'path'; |
|
import matter from 'gray-matter'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface PolicyData { |
|
title: string; |
|
language: string; |
|
originalLink: string; |
|
slug: string; |
|
fileName: string; |
|
releaseDate: string; |
|
} |
|
|
|
export async function getStaticProps() { |
|
try { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const policiesDir = path.join(process.cwd(), 'content', 'policies'); |
|
const policyFolders = fs.readdirSync(policiesDir); |
|
|
|
const policyData: PolicyData[] = []; |
|
|
|
for (const folder of policyFolders) { |
|
const zhFilePath = path.join(policiesDir, folder, 'zh.md'); |
|
const enFilePath = path.join(policiesDir, folder, 'en.md'); |
|
|
|
if (fs.existsSync(zhFilePath) && fs.existsSync(enFilePath)) { |
|
const zhContent = fs.readFileSync(zhFilePath, 'utf-8'); |
|
const enContent = fs.readFileSync(enFilePath, 'utf-8'); |
|
|
|
const { data: zhData } = matter(zhContent); |
|
const { data: enData } = matter(enContent); |
|
|
|
policyData.push({ |
|
...zhData, |
|
slug: folder, |
|
fileName: 'zh.md', |
|
releaseDate: zhData.releaseDate ? zhData.releaseDate.toString() : '', |
|
} as PolicyData); |
|
policyData.push({ |
|
...enData, |
|
slug: folder, |
|
fileName: 'en.md', |
|
releaseDate: enData.releaseDate ? enData.releaseDate.toString() : '', |
|
} as PolicyData); |
|
} |
|
} |
|
|
|
|
|
policyData.sort((a, b) => { |
|
const dateA = a.releaseDate ? new Date(a.releaseDate).getTime() : 0; |
|
const dateB = b.releaseDate ? new Date(b.releaseDate).getTime() : 0; |
|
return dateB - dateA; |
|
}); |
|
|
|
return { |
|
props: { |
|
policyData, |
|
}, |
|
revalidate: 3600, |
|
}; |
|
} catch (error) { |
|
console.error("Error fetching data:", error); |
|
return { |
|
props: { |
|
policyData: [], |
|
}, |
|
revalidate: 60, |
|
}; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const OpenSourceHeatmap: React.FC<{ policyData: PolicyData[] }> = ({ |
|
policyData, |
|
}) => { |
|
return ( |
|
<div className="w-full min-h-screen bg-white dark:bg-gray-900 dark:text-white"> |
|
<div className="max-w-screen-lg mx-auto p-4 py-16"> |
|
<h1 className="text-3xl lg:text-5xl mt-16 font-bold text-center mb-2"> |
|
China AI policy research π€ |
|
</h1> |
|
|
|
<AIPoliciesTable policies={policyData} /> |
|
</div> |
|
|
|
{/* <div className="text-center text-sm my-8 space-y-4"> |
|
<p> |
|
Models, Datasets, and Spaces from the top AI labs. |
|
</p> |
|
<div className="flex justify-center space-x-4"> |
|
<UserSearchDialog /> |
|
</div> |
|
</div> |
|
|
|
<div className="h-px max-w-lg mx-auto bg-gray-200 dark:bg-gray-700 my-16" /> |
|
|
|
{isLoading ? ( |
|
<p className="text-center">Loading...</p> |
|
) : ( |
|
<div className="space-y-16"> |
|
{sortedProviders.map((provider) => ( |
|
<ProviderHeatmap |
|
key={provider.fullName || provider.authors[0]} |
|
provider={provider} |
|
calendarData={calendarData} |
|
/> |
|
))} |
|
</div> |
|
)} */} |
|
</div> |
|
); |
|
}; |
|
|
|
export default React.memo(OpenSourceHeatmap); |
|
|