From 0dcf899129c5bfcd5428e108932941d5ae1305c3 Mon Sep 17 00:00:00 2001 From: r-freeman Date: Tue, 24 Jan 2023 22:27:59 +0000 Subject: [PATCH] Added code to get project repos dynamically --- .env.example | 1 + lib/github.ts | 47 ++++++++++++++++++++++++++++ pages/projects.tsx | 77 +++++++++++++++------------------------------- types/index.ts | 11 +++++++ 4 files changed, 83 insertions(+), 53 deletions(-) create mode 100644 lib/github.ts diff --git a/.env.example b/.env.example index 0558a2c..ae88d0a 100644 --- a/.env.example +++ b/.env.example @@ -4,3 +4,4 @@ SPOTIFY_REFRESH_TOKEN= NEXT_PUBLIC_SITE_URL=https://example.com DATABASE_URL= SHADOW_DATABASE_URL= +GITHUB_ACCESS_TOKEN= \ No newline at end of file diff --git a/lib/github.ts b/lib/github.ts new file mode 100644 index 0000000..6f3494d --- /dev/null +++ b/lib/github.ts @@ -0,0 +1,47 @@ +import fetch from 'node-fetch' +import type {Repo} from '@/types' + +const GITHUB_ACCESS_TOKEN = process.env.GITHUB_ACCESS_TOKEN +const GITHUB_GRAPHQL = "https://api.github.com/graphql" + +type Response = { + data: { + user: { + pinnedItems: { + nodes: Repo[] + } + } + } +} + +export async function getPinnedRepos() { + const response = await fetch(GITHUB_GRAPHQL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${GITHUB_ACCESS_TOKEN}` + }, + body: JSON.stringify({ + query: `{ + user(login: "r-freeman") { + pinnedItems(first: 6, types: REPOSITORY) { + nodes { + ... on Repository { + name + description + url + stargazerCount + primaryLanguage { + name + color + } + } + } + } + } + }` + }) + }).then(r => r.json()) as Response + + return response.data.user.pinnedItems.nodes +} \ No newline at end of file diff --git a/pages/projects.tsx b/pages/projects.tsx index 80a3720..1df3149 100644 --- a/pages/projects.tsx +++ b/pages/projects.tsx @@ -1,53 +1,13 @@ import Head from 'next/head' - import {Card} from '@/components/Card' import {SimpleLayout} from '@/components/SimpleLayout' import {GitHubIcon} from '@/components/SocialIcons' import {SocialLink} from '@/components/SocialLink' +import {GetStaticProps} from 'next' +import {getPinnedRepos} from '@/lib/github' +import type {Repo} from '@/types' -type Project = { - name: string - description: string - link: { - href: string - label: string - } -} - -const projects: Project[] = [ - { - name: 'Portfolio', - description: - 'This is my personal website built with TypeScript, Next.js, React and Tailwind CSS. It is a customised version of the Spotlight template from Tailwind UI.', - link: {href: 'https://github.com/r-freeman/portfolio', label: 'r-freeman/portfolio'}, - }, - { - name: 'Intellagent', - description: - 'Intellagent is a cloud-based help desk software solution for small business, powered by AI and machine learning.', - link: {href: 'https://github.com/r-freeman/intellagent-server', label: 'r-freeman/intellagent-server'}, - }, - { - name: 'Super Mario Run', - description: - 'Mobile game inspired by Super Mario Bros, built with JavaScript and Phaser.', - link: {href: 'https://github.com/r-freeman/super-mario-run', label: 'r-freeman/super-mario-run'}, - }, - { - name: 'ASOS Prototype', - description: - 'Working prototype of ASOS\' website built in Axure RP 8.', - link: {href: 'https://github.com/r-freeman/ASOS-Axure-Prototype', label: 'r-freeman/ASOS-Axure-Prototype'}, - }, - { - name: 'College App', - description: - 'Full-stack application built with Laravel 6, Vue.js and Tailwind CSS.', - link: {href: 'https://github.com/r-freeman/college-app', label: 'r-freeman/college-app'}, - } -] - -export default function Projects() { +export default function Projects({pinnedRepos}: { pinnedRepos: Repo[] }) { return ( <> @@ -74,19 +34,20 @@ export default function Projects() { role="list" className="grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3" > - {projects.map((project) => ( - + {pinnedRepos.map((repo) => ( +

- {project.name} + {repo.name}

- {project.description} -

+ {repo.description} +

- {project.link.label} + {`r-freeman/${repo.name}`}

))} @@ -94,4 +55,14 @@ export default function Projects() { ) -} \ No newline at end of file +} + +export const getStaticProps: GetStaticProps = async () => { + const pinnedRepos = await getPinnedRepos() + + return { + props: { + pinnedRepos + } + } +} diff --git a/types/index.ts b/types/index.ts index 8aa60e8..ebd5165 100644 --- a/types/index.ts +++ b/types/index.ts @@ -10,4 +10,15 @@ export type Article = { export type Props = { className?: string children?: ReactNode +} + +export type Repo = { + name: string + description: string + url: string + stargazerCount: number + primaryLanguage: { + name: string + color: string + } } \ No newline at end of file