From 7d1145c8277dca942df372bff15eea5a0fbeebe2 Mon Sep 17 00:00:00 2001 From: 712Kunal Date: Sun, 29 Dec 2024 20:17:06 +0530 Subject: [PATCH 1/4] added the environmental variables from the github --- backend/.env.example | 1 + backend/.gitignore | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 backend/.gitignore diff --git a/backend/.env.example b/backend/.env.example index 2ec4ef4c..207b22a8 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -3,3 +3,4 @@ EMAIL_PASS="email_password" ADMIN_EMAIL= ADMIN_EMAIL_PASSWORD= RECEIVER_EMAIL= # email that will receive the form responses +CONTRIBUTORS_TOKEN = # token for contributors \ No newline at end of file diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 00000000..1dcef2d9 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,2 @@ +node_modules +.env \ No newline at end of file From d21fa96052d72a1ccc28f7706e79789ef44dd119 Mon Sep 17 00:00:00 2001 From: 712Kunal Date: Sun, 29 Dec 2024 20:23:20 +0530 Subject: [PATCH 2/4] added the route for the contributors controller in server.js --- .gitignore | 1 + backend/controllers/contributors.js | 0 backend/server.js | 65 +++++++++++++++-------------- 3 files changed, 35 insertions(+), 31 deletions(-) create mode 100644 backend/controllers/contributors.js diff --git a/.gitignore b/.gitignore index 3c3629e6..1dcef2d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.env \ No newline at end of file diff --git a/backend/controllers/contributors.js b/backend/controllers/contributors.js new file mode 100644 index 00000000..e69de29b diff --git a/backend/server.js b/backend/server.js index a0c7a496..e5625c18 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,51 +1,53 @@ - -const express = require('express'); -const nodemailer = require('nodemailer'); -const bodyParser = require('body-parser'); -const cors = require('cors'); -const mongoose = require('mongoose'); -const { subscribeUser } = require('./controllers/subscribe'); -const dotenv = require('dotenv'); -const { submitFeedback } = require('./controllers/feedback'); -const {Contactus} = require('./controllers/contactus'); +const express = require("express"); +const nodemailer = require("nodemailer"); +const bodyParser = require("body-parser"); +const cors = require("cors"); +const mongoose = require("mongoose"); +const { subscribeUser } = require("./controllers/subscribe"); +const dotenv = require("dotenv"); +const { submitFeedback } = require("./controllers/feedback"); +const { Contactus } = require("./controllers/contactus"); +const { contributors } = require("./controllers/contributors"); dotenv.config(); - - - // Initialize Express app const app = express(); const PORT = process.env.PORT || 3000; // Middleware -app.use(cors()); +app.use( + cors({ + origin: "*", // Be more specific in production + methods: ["GET", "POST"], + }) +); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // Connect to MongoDB -mongoose.connect("mongodb+srv://amnalpha7:IAtC1nJtXv4avH4Q@cluster0.y6w4aqp.mongodb.net/Meta", { - useNewUrlParser: true, - useUnifiedTopology: true, -}); +mongoose.connect( + "mongodb+srv://amnalpha7:IAtC1nJtXv4avH4Q@cluster0.y6w4aqp.mongodb.net/Meta", + { + useNewUrlParser: true, + useUnifiedTopology: true, + } +); const contactSchema = new mongoose.Schema({ name: String, email: String, message: String, date: { type: Date, default: Date.now }, - }); -const feedbackSchema= new mongoose.Schema({ - feedback: { - type:String, - trim:true - } +const feedbackSchema = new mongoose.Schema({ + feedback: { + type: String, + trim: true, + }, }); -const Feedback=mongoose.model("Feedbabck",feedbackSchema); - - +const Feedback = mongoose.model("Feedbabck", feedbackSchema); const Contact = mongoose.model("Contact", contactSchema); @@ -115,11 +117,12 @@ app.post("/contact", async (req, res) => { } }); -app.post("/subscribe", subscribeUser) -app.post('/rate-us', submitFeedback); -app.post('/contact-us', Contactus); +app.post("/subscribe", subscribeUser); +app.post("/rate-us", submitFeedback); +app.post("/contact-us", Contactus); +app.get("/contributorsPage", contributors); // Start the server app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); -}); +}); \ No newline at end of file From 8720cf5f6b0e60ade96101b47b540a37b00f2488 Mon Sep 17 00:00:00 2001 From: 712Kunal Date: Sun, 29 Dec 2024 20:28:05 +0530 Subject: [PATCH 3/4] added the logic for the contributor's controller --- backend/controllers/contributors.js | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/backend/controllers/contributors.js b/backend/controllers/contributors.js index e69de29b..e59696ed 100644 --- a/backend/controllers/contributors.js +++ b/backend/controllers/contributors.js @@ -0,0 +1,60 @@ +const express = require("express"); +const router = express.Router(); + +const contributors = async (req, res) => { + const token = process.env.CONTRIBUTORS_TOKEN; + const page1 = 1; + const page2 = 2; + const perPage = 100; + const owner = "apu52"; + const repo = "METAVERSE"; + + const url1 = `https://api.github.com/repos/${owner}/${repo}/contributors?page=${page1}&per_page=${perPage}`; + const url2 = `https://api.github.com/repos/${owner}/${repo}/contributors?page=${page2}&per_page=${perPage}`; + + try { + const response1 = await fetch(url1, { + method: "GET", + headers: { + Authorization: `token ${token}`, + Accept: "application/vnd.github.v3+json", + "User-Agent": "Node.js", + }, + }); + + if (!response1.ok) { + throw new Error(`GitHub API responded with status ${response1.status}`); + } + + const response2 = await fetch(url2, { + method: "GET", + headers: { + Authorization: `token ${token}`, + Accept: "application/vnd.github.v3+json", + "User-Agent": "Node.js", + }, + }); + + if (!response2.ok) { + throw new Error(`GitHub API responded with status ${response2.status}`); + } + + const contributorsData1 = await response1.json(); + const contributorsData2 = await response2.json(); + const contributorsData = [...contributorsData1, ...contributorsData2]; + + // Send the data back to the client + res.json({ + success: true, + data: contributorsData, + }); + } catch (error) { + console.error(`Error while fetching the contributors data: ${error}`); + res.status(500).json({ + success: false, + error: error.message, + }); + } +}; + +module.exports = { contributors }; \ No newline at end of file From 1f99dfc4cae6b2d427011bc53d1c87bb7c01a0c1 Mon Sep 17 00:00:00 2001 From: 712Kunal Date: Sun, 29 Dec 2024 20:30:03 +0530 Subject: [PATCH 4/4] updated the frontend contributors file to fetch the data from the backend --- assets/js/contributors.js | 178 ++++++++++++++++++++++---------------- 1 file changed, 102 insertions(+), 76 deletions(-) diff --git a/assets/js/contributors.js b/assets/js/contributors.js index ba2bba76..bcdcbd8f 100644 --- a/assets/js/contributors.js +++ b/assets/js/contributors.js @@ -1,84 +1,110 @@ document.addEventListener("DOMContentLoaded", function () { - const contributorsContainer = document.getElementById('contributors'); - const statsContainer = document.getElementById('stats'); - const loadingIndicator = document.getElementById('loading'); - + const contributorsContainer = document.getElementById("contributors"); + const statsContainer = document.getElementById("stats"); + const loadingIndicator = document.getElementById("loading"); + // Fetch contributors and repo stats async function fetchData() { - loadingIndicator.style.display = 'flex'; - - try { - const contributorsResponse = await axios.get('https://api.github.com/repos/apu52/METAVERSE/contributors'); - const contributorsData = contributorsResponse.data; - - const repoResponse = await axios.get('https://api.github.com/repos/apu52/METAVERSE'); - const repoData = repoResponse.data; - - populateStats(repoData, contributorsData); - populateContributors(contributorsData); - } catch (error) { - console.error('Error fetching data:', error); - } finally { - loadingIndicator.style.display = 'none'; - } + loadingIndicator.style.display = "flex"; + + try { + // Get contributors data from your server endpoint + const response = await axios.get( + "http://localhost:3000/contributorsPage" + ); + const contributorsData = response.data.data; // Note the nested .data property + + // Get repo data directly from GitHub + const repoResponse = await axios.get( + "https://api.github.com/repos/apu52/METAVERSE" + ); + const repoData = repoResponse.data; + + populateStats(repoData, contributorsData); + populateContributors(contributorsData); + } catch (error) { + console.error("Error fetching data:", error); + // Add some user-friendly error handling here + } finally { + loadingIndicator.style.display = "none"; + } } - + function populateStats(repoData, contributors) { - const stats = [ - { label: "Contributors", value: contributors.length, icon: '' }, - { label: "Total Contributions", value: contributors.reduce((sum, contributor) => sum + contributor.contributions, 0), icon: '' }, - { label: "GitHub Stars", value: repoData.stargazers_count, icon: '' }, - { label: "Forks", value: repoData.forks_count, icon: '' }, - ]; - - statsContainer.innerHTML = ''; - stats.forEach((stat, index) => { - const statCard = document.createElement('div'); - statCard.className = "stat-card"; - statCard.innerHTML = ` -
${stat.icon}
-

${stat.value}

-

${stat.label}

- `; - statCard.style.opacity = '0'; - statCard.style.transform = 'translateY(20px)'; - statsContainer.appendChild(statCard); - - setTimeout(() => { - statCard.style.transition = 'opacity 0.5s, transform 0.5s'; - statCard.style.opacity = '1'; - statCard.style.transform = 'translateY(0)'; - }, index * 100); - }); + const stats = [ + { + label: "Contributors", + value: contributors.length, + icon: '', + }, + { + label: "Total Contributions", + value: contributors.reduce( + (sum, contributor) => sum + contributor.contributions, + 0 + ), + icon: '', + }, + { + label: "GitHub Stars", + value: repoData.stargazers_count, + icon: '', + }, + { + label: "Forks", + value: repoData.forks_count, + icon: '', + }, + ]; + + statsContainer.innerHTML = ""; + stats.forEach((stat, index) => { + const statCard = document.createElement("div"); + statCard.className = "stat-card"; + statCard.innerHTML = ` +
${stat.icon}
+

${stat.value}

+

${stat.label}

+ `; + statCard.style.opacity = "0"; + statCard.style.transform = "translateY(20px)"; + statsContainer.appendChild(statCard); + + setTimeout(() => { + statCard.style.transition = "opacity 0.5s, transform 0.5s"; + statCard.style.opacity = "1"; + statCard.style.transform = "translateY(0)"; + }, index * 100); + }); } - - function populateContributors(contributors) { - contributorsContainer.innerHTML = ''; - contributors.forEach((contributor, index) => { - const contributorCard = document.createElement('div'); - contributorCard.className = "contributor-card"; - contributorCard.innerHTML = ` - ${contributor.login} -

${contributor.login}

-

${contributor.type}

-
${contributor.contributions} contributions
- - - - - - View Profile - - `; - contributorCard.style.opacity = '0'; - contributorsContainer.appendChild(contributorCard); - - setTimeout(() => { - contributorCard.style.transition = 'opacity 0.5s'; - contributorCard.style.opacity = '1'; - }, index * 100); - }); + + function populateContributors(contributorsData) { + contributorsContainer.innerHTML = ""; + contributorsData.forEach((contributor, index) => { + const contributorCard = document.createElement("div"); + contributorCard.className = "contributor-card"; + contributorCard.innerHTML = ` + ${contributor.login} +

${contributor.login}

+

${contributor.type}

+
${contributor.contributions} contributions
+ + + + + + View Profile + + `; + contributorCard.style.opacity = "0"; + contributorsContainer.appendChild(contributorCard); + + setTimeout(() => { + contributorCard.style.transition = "opacity 0.5s"; + contributorCard.style.opacity = "1"; + }, index * 100); + }); } - + fetchData(); -}); \ No newline at end of file + }); \ No newline at end of file