diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9230628d..1f8477d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,8 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 'Install dependencies' run: npm install @@ -32,6 +34,7 @@ jobs: run: | git restore src/app/projects/assets/upcomingProjects.json git restore src/app/projects/assets/projects.json + git restore src/app/projects/assets/contributors.json - name: 'Fetch branches' run: git fetch origin diff --git a/src/app/contributors/page.tsx b/src/app/contributors/page.tsx new file mode 100644 index 00000000..b1e70123 --- /dev/null +++ b/src/app/contributors/page.tsx @@ -0,0 +1,75 @@ +"use client"; + +import Link from "next/link"; +import React from "react"; +import github from "../../../public/images/social-media/github.png"; +import Image from "next/image"; +import contributorList from "../projects/assets/contributors.json"; + +const Contributors = () => { + const contributorsArray = Object.values(contributorList); + return ( + <> +
+
+

+ Our Contributors +

+

+ We’re a dynamic group of individuals who are passionate about what + we do. +

+ {contributorsArray ? ( +
+ {contributorsArray.map((contributor) => ( +
+
+ {`Contributor +
+ {contributor.login} +
+

+ Contributions: {contributor.contributions} +

+
+ + github_img + +
+
+
+ ))} +
+ ) : ( +
+

+ No records found! +

+
+ )} +
+
+ + ); +}; + +export default Contributors; diff --git a/src/app/projects/assets/contributors.json b/src/app/projects/assets/contributors.json new file mode 100644 index 00000000..160dbf26 --- /dev/null +++ b/src/app/projects/assets/contributors.json @@ -0,0 +1,9 @@ +{ + "lakinmindfire": { + "id": 80667930, + "contributions": 116, + "html_url": "https://github.com/lakinmindfire", + "avatar_url": "https://avatars.githubusercontent.com/u/80667930?v=4", + "login": "lakinmindfire" + } +} diff --git a/src/app/projects/components/ProjectCard.tsx b/src/app/projects/components/ProjectCard.tsx index 92ba7ae1..68e8fa3f 100644 --- a/src/app/projects/components/ProjectCard.tsx +++ b/src/app/projects/components/ProjectCard.tsx @@ -33,7 +33,7 @@ export default function ProjectCard({
{githubUrl && githubUrl !== "NA" ? ( - facebook_img + github_img ) : null} {documentationUrl && documentationUrl !== "NA" ? ( diff --git a/src/constants/index.ts b/src/constants/index.ts index 5542ae0a..3bf3c226 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -22,6 +22,10 @@ const navigations: Navigation[] = [ name: "Projects", path: ["/projects", "/current-projects", "/upcoming-projects"], }, + { + name: "Contributors", + path: ["/contributors"], + }, { name: "GitHub", path: ["https://github.com/mindfiredigital"], diff --git a/tsconfig.json b/tsconfig.json index 59ff4a8f..4d69ab56 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,19 +15,19 @@ "incremental": true, "plugins": [ { - "name": "next", - }, + "name": "next" + } ], "paths": { - "@/*": ["./src/*"], - }, + "@/*": ["./src/*"] + } }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", - "build/types/**/*.ts", + "build/types/**/*.ts" ], - "exclude": ["node_modules"], + "exclude": ["node_modules"] } diff --git a/updateProject.mjs b/updateProject.mjs index 442a6195..6d0a7b68 100644 --- a/updateProject.mjs +++ b/updateProject.mjs @@ -122,5 +122,88 @@ async function getUpcomingProjects() { } } +//get list of contributors from github repo +async function getContributorsList() { + const githubApiUrl = "https://api.github.com/users/mindfiredigital/repos"; + const githubToken = process.env.GITHUB_TOKEN; + + try { + const github_response = await fetch(githubApiUrl, { + method: "GET", + headers: { + Authorization: `token ${githubToken}`, + Accept: "application/vnd.github.v3+json", + }, + }); + + if (!github_response.ok) { + throw new Error( + `Failed to fetch repositories. Status: ${github_response.status}` + ); + } + const repositories = await github_response.json(); + const repoNames = repositories.map((repo) => repo.name); + + const contributorsObject = {}; + for (const repoName of repoNames) { + const repoContributorsUrl = `https://api.github.com/repos/mindfiredigital/${repoName}/contributors`; + + const contributorsResponse = await fetch(repoContributorsUrl, { + method: "GET", + headers: { + Authorization: `token ${githubToken}`, + Accept: "application/vnd.github.v3+json", + }, + }); + + if (!contributorsResponse.ok) { + console.error( + `Failed to fetch contributors for ${repoName}. Status: ${contributorsResponse.status}` + ); + continue; + } + + const contributors = await contributorsResponse.json(); + contributorsObject[repoName] = contributors; + } + let contributionsMap = {}; + + for (let repo in contributorsObject) { + contributorsObject[repo].forEach((contributor) => { + const { login, contributions, id, avatar_url, html_url } = contributor; + if (contributionsMap.hasOwnProperty(login)) { + contributionsMap[login].contributions += contributions; + } else { + contributionsMap[login] = { + id, + contributions, + html_url, + avatar_url, + login, + }; + } + }); + } + let sortedContributions = Object.fromEntries( + Object.entries(contributionsMap).sort( + ([, a], [, b]) => b.contributions - a.contributions + ) + ); + + const projectsJsonPath = path.join( + __dirname, + "src/app/projects/assets/contributors.json" + ); + + fs.writeFileSync( + projectsJsonPath, + JSON.stringify(sortedContributions, null, 2) + ); + } catch (error) { + console.log(error); + } +} + getCurrentProjects(); getUpcomingProjects(); +getContributorsList();