import { notFound } from "next/navigation";
import { graphql } from "@octokit/graphql";
import { GitForkIcon, StarIcon } from "lucide-react";
import PageTitle from "../../components/PageTitle";
import Link from "../../components/Link";
import RelativeTime from "../../components/RelativeTime";
import { addMetadata } from "../../lib/helpers/metadata";
import * as config from "../../lib/config";
import type { User } from "@octokit/graphql-schema";
import styles from "./page.module.css";
export const metadata = addMetadata({
title: "Projects",
description: `Most-starred repositories by @${config.authorSocial?.github} on GitHub`,
alternates: {
canonical: "/projects",
},
});
const getRepos = async () => {
// don't fail the entire site build if the required API key for this page is missing
if (!process.env.GITHUB_TOKEN) {
console.warn(`ERROR: I can't fetch any GitHub projects without "GITHUB_TOKEN" set! Disabling projects page.`);
// just return a 404 since this page would be blank anyways
notFound();
}
// https://docs.github.com/en/graphql/reference/objects#repository
const { user } = await graphql<{ user: User }>(
`
query ($username: String!, $sort: RepositoryOrderField!, $limit: Int) {
user(login: $username) {
repositories(
first: $limit
isLocked: false
isFork: false
ownerAffiliations: OWNER
privacy: PUBLIC
orderBy: { field: $sort, direction: DESC }
) {
edges {
node {
name
url
description
pushedAt
stargazerCount
forkCount
primaryLanguage {
name
color
}
}
}
}
}
}
`,
{
username: config.authorSocial.github,
sort: "STARGAZERS",
limit: 12,
headers: {
accept: "application/vnd.github.v3+json",
authorization: `token ${process.env.GITHUB_TOKEN}`,
},
request: {
// override fetch() to use next's extension to cache the response
// https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options
fetch: (url: string | URL | Request, options?: RequestInit) => {
return fetch(url, {
...options,
cache: "force-cache",
next: {
revalidate: 600, // 10 minutes
tags: ["github-api"],
},
});
},
},
}
);
return user.repositories.edges?.map((edge) => edge!.node);
};
const Page = async () => {
const repos = await getRepos();
return (
<>
{repo!.description}
}View more on{" "} {" "} GitHub...
> ); }; export default Page;