import { graphql } from "@octokit/graphql"; import { NextSeo } from "next-seo"; import Content from "../components/Content"; import PageTitle from "../components/PageTitle"; import Link from "../components/Link"; import RepositoryCard from "../components/RepositoryCard"; import { SiGithub } from "react-icons/si"; import { styled, theme } from "../lib/styles/stitches.config"; import config from "../lib/config"; import type { GetStaticProps, InferGetStaticPropsType } from "next"; import type { User, Repository } from "@octokit/graphql-schema"; import type { Project } from "../types"; const Wrapper = styled("div", { display: "flex", flexFlow: "row wrap", justifyContent: "space-between", alignItems: "flex-start", width: "100%", lineHeight: 1.1, }); const Card = styled(RepositoryCard, { flexGrow: 1, margin: "0.6em", width: "370px", }); const ViewMore = styled("p", { textAlign: "center", marginBottom: 0, fontWeight: 500, }); const GitHubLogo = styled(SiGithub, { display: "inline", width: "1.2em", height: "1.2em", verticalAlign: "-0.2em", margin: "0 0.15em", fill: theme.colors.text, }); const Projects = ({ repos }: InferGetStaticPropsType) => { return ( <> 💾 Projects {repos.map((repo) => ( ))} View more on GitHub... ); }; export const getStaticProps: GetStaticProps<{ repos: Project[]; }> = async () => { // don't fail the entire site build if the required API key for this page is missing if (!process.env.GH_PUBLIC_TOKEN || process.env.GH_PUBLIC_TOKEN === "") { console.warn(`ERROR: I can't fetch any GitHub projects without "GH_PUBLIC_TOKEN" set! Skipping for now...`); return { notFound: true, }; } // 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.GH_PUBLIC_TOKEN}`, }, } ); const results = user.repositories.edges as Array<{ node: Repository }>; const repos = results.map(({ node: repo }) => ({ name: repo.name, url: repo.url, description: repo.description as string, updatedAt: repo.pushedAt, stars: repo.stargazerCount, forks: repo.forkCount, language: repo.primaryLanguage as Project["language"], })); return { props: { repos, }, // fetch updated data and update page every 10 minutes (as needed) // https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration revalidate: 600, }; }; export default Projects;