mirror of
https://github.com/r-freeman/portfolio.git
synced 2024-11-11 18:45:41 +00:00
Added code to get project repos dynamically
This commit is contained in:
parent
bc9b674a6a
commit
0dcf899129
@ -4,3 +4,4 @@ SPOTIFY_REFRESH_TOKEN=
|
|||||||
NEXT_PUBLIC_SITE_URL=https://example.com
|
NEXT_PUBLIC_SITE_URL=https://example.com
|
||||||
DATABASE_URL=
|
DATABASE_URL=
|
||||||
SHADOW_DATABASE_URL=
|
SHADOW_DATABASE_URL=
|
||||||
|
GITHUB_ACCESS_TOKEN=
|
47
lib/github.ts
Normal file
47
lib/github.ts
Normal file
@ -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
|
||||||
|
}
|
@ -1,53 +1,13 @@
|
|||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
|
|
||||||
import {Card} from '@/components/Card'
|
import {Card} from '@/components/Card'
|
||||||
import {SimpleLayout} from '@/components/SimpleLayout'
|
import {SimpleLayout} from '@/components/SimpleLayout'
|
||||||
import {GitHubIcon} from '@/components/SocialIcons'
|
import {GitHubIcon} from '@/components/SocialIcons'
|
||||||
import {SocialLink} from '@/components/SocialLink'
|
import {SocialLink} from '@/components/SocialLink'
|
||||||
|
import {GetStaticProps} from 'next'
|
||||||
|
import {getPinnedRepos} from '@/lib/github'
|
||||||
|
import type {Repo} from '@/types'
|
||||||
|
|
||||||
type Project = {
|
export default function Projects({pinnedRepos}: { pinnedRepos: Repo[] }) {
|
||||||
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() {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
@ -74,19 +34,20 @@ export default function Projects() {
|
|||||||
role="list"
|
role="list"
|
||||||
className="grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3"
|
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) => (
|
||||||
<Card as="li" key={project.name}>
|
<Card as="li" key={repo.name}>
|
||||||
<h2 className="text-base font-semibold text-zinc-800 dark:text-zinc-100">
|
<h2 className="text-base font-semibold text-zinc-800 dark:text-zinc-100">
|
||||||
<Card.Link href={project.link.href}>{project.name}</Card.Link>
|
<Card.Link href={repo.url}>{repo.name}</Card.Link>
|
||||||
</h2>
|
</h2>
|
||||||
<Card.Description>{project.description}</Card.Description>
|
<Card.Description>{repo.description}</Card.Description>
|
||||||
<p className="relative z-10 mt-6 flex text-sm font-medium text-zinc-400 transition group-hover:text-indigo-500 dark:text-zinc-200">
|
<p
|
||||||
|
className="relative z-10 mt-6 flex text-sm font-medium text-zinc-400 transition group-hover:text-indigo-500 dark:text-zinc-200">
|
||||||
<SocialLink
|
<SocialLink
|
||||||
href={project.link.href}
|
href={repo.url}
|
||||||
ariaLabel={`Checkout ${project.name} on GitHub`}
|
ariaLabel={`Checkout ${repo.name} on GitHub`}
|
||||||
icon={GitHubIcon}
|
icon={GitHubIcon}
|
||||||
/>
|
/>
|
||||||
<span className="ml-2">{project.link.label}</span>
|
<span className="ml-2">{`r-freeman/${repo.name}`}</span>
|
||||||
</p>
|
</p>
|
||||||
</Card>
|
</Card>
|
||||||
))}
|
))}
|
||||||
@ -94,4 +55,14 @@ export default function Projects() {
|
|||||||
</SimpleLayout>
|
</SimpleLayout>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = async () => {
|
||||||
|
const pinnedRepos = await getPinnedRepos()
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
pinnedRepos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,4 +10,15 @@ export type Article = {
|
|||||||
export type Props = {
|
export type Props = {
|
||||||
className?: string
|
className?: string
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Repo = {
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
url: string
|
||||||
|
stargazerCount: number
|
||||||
|
primaryLanguage: {
|
||||||
|
name: string
|
||||||
|
color: string
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user