diff --git a/README.md b/README.md index 1613a3b0..05305f63 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,22 @@ -# GitHub Tracker - -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +# GitHub Tracker๐Ÿ˜Ž +This project was to create a place to keep track of the GitHub repos that I am using at Technigo. It was a good chance to practice JavaScript and API skills with the help of GitHub's own documentation. +# What Does it Include? +- A list of all repos that are forked ones from Technigo +- My username and profile picture +- Most recent update (push) for each repo +- Name of my default branch for each repo +- URL to the actual GitHub repo +- Number of commit messages for each repo +- All pull requests +- A chart of how many projects I've done so far, compared to how many I will do using +- ## The problem - -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +Diving in to an APIโ€™s documentation was a little bit overwhelming. +1. To get started with the project, I fetched all of the repos and log them to the console. +2. Then I filtered out and only show the forked projects another branch. +3. Then I filtered out only the forks from *Technigo*. I could use the fact that Technigo projects *start* with 'project-' and the filtering was based on that. ## View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +https://haruahn-github-tracker.netlify.app diff --git a/code/assets/background.jpg b/code/assets/background.jpg new file mode 100644 index 00000000..a862b8ef Binary files /dev/null and b/code/assets/background.jpg differ diff --git a/code/chart.js b/code/chart.js index 92e85a30..753876a2 100644 --- a/code/chart.js +++ b/code/chart.js @@ -1,4 +1,21 @@ -//DOM-selector for the canvas ๐Ÿ‘‡ -const ctx = document.getElementById('chart').getContext('2d') +const ctx = document.getElementById("chart").getContext("2d"); -//"Draw" the chart here ๐Ÿ‘‡ +// Chart +const drawChart = (numberOfProjects) => { + const config = { + type: "doughnut", + data: { + labels: ["Finished projects", "Projects left"], + datasets: [ + { + label: "Technigo Projects", + data: [numberOfProjects, 19 - numberOfProjects], + backgroundColor: ["rgb(255, 99, 132)", "rgb(255, 205, 86)"], + hoverOffset: 5, + }, + ], + }, + }; + + const reposChart = new Chart(ctx, config); +}; diff --git a/code/index.html b/code/index.html index 2fb5e0ae..243cdb7e 100644 --- a/code/index.html +++ b/code/index.html @@ -1,21 +1,48 @@ - - - - - Project GitHub Tracker - - - -

GitHub Tracker

-

Projects:

-
+ + + + + Ru's GitHub Tracker - - + + + + - - - - \ No newline at end of file + + + + + + + + + + + + + +
+
+
+
+
+

Overview of Projects

+
+ +
+
+
+ + + + + diff --git a/code/instruction b/code/instruction new file mode 100644 index 00000000..9103513b --- /dev/null +++ b/code/instruction @@ -0,0 +1,56 @@ +//### What to include + +//- A list of all repos that are forked ones from Technigo +//- Your username and profile picture +//- Most recent update (push) for each repo +//- Name of your default branch for each repo +//- URL to the actual GitHub repo +//- Number of commit messages for each repo +//- All pull requests +//- A chart of how many projects you've done so far, compared to how many you will do using [Chart.js](https://www.chartjs.org/). [Here](https://www.chartjs.org/docs/latest/getting-started/)'s documentation on how to get started, and in the left menu you can also find [example usage](https://www.chartjs.org/docs/latest/getting-started/usage.html). + +//### Where to begin + +//1. To get started with the project, **fetch all of your repos and log them to the console**. +//2. We only care about the ones you forked from Technigo, so be sure to filter out and only show the *forked* ones. In the response you'll get, there'll be a "flag" in each repo that says if it is a *fork* or not. We can use that property to filter out only the *forks*. PS. If you haven't already, fork any group projects that you are not the owner of, so that these also show up amongst your repos. +//3. Then it's time to filter out only the forks from *Technigo*. Let's use the fact that Technigo projects *start* with 'project-' and filter based on that. + +//Apart from this you also have to fetch pull requests and commits, but a suggestion is to work with one thing at a time since the API has a rate limit of 60 calls per hour. Here are some hints that might come in useful: + + + +//When fetching the pull requests we need to do a fetch for each repo. Here's an example of how you could do it. +//Remember to pass along your filtered repos as an argument when +//you are calling this function + +const getPullRequests = (repos) => { + //Get all the PRs for each project. + repos.forEach(repo => { + fetch('https://api.github.com/repos/technigo/' + repo.name + '/pulls') + .then(res => res.json()) + .then(data => { + //TODO + //1. Find only the PR that you made by comparing pull.user.login + // with repo.owner.login + //2. Now you're able to get the commits for each repo by using + // the commits_url as an argument to call another function + //3. You can also get the comments for each PR by calling + // another function with the review_comments_url as argument + }) + }) +} +//Example of setting a dynamic id +//Let's say you have a function where you fetch data. You create your HTML elements inside this function and inject your data. All good so far. But what if you create another function that *also* should inject some data in the HTML elements created in another function ๐Ÿค” We could set an `id` when we create the element, but what if the elements are created in a loop? They can't all have the same `id`. The solution is: dynamic `id`! + +repos.forEach(repo => { + document.getElementById('container').innerHTML += ` +
+

${repo.name}

+
+ ` + }) + + //That way, we can reach it by DOM-selector in another function, as long as we have the `repo.name` + document.getElementById(repoName).innerHTML += 'New data to inject' + +//When you have the data that you need from the API, it's time to display it in a good way on the page. Think about how you want your page to look. Do you want to use an HTML table? Maybe the repos could be displayed in a grid format, with all the information inside? Maybe you want to make it look as closely to GitHub as possible? diff --git a/code/script.js b/code/script.js index e69de29b..4b7efc64 100644 --- a/code/script.js +++ b/code/script.js @@ -0,0 +1,85 @@ +const USER = "ruruahn"; +const REPOS_URL = `https://api.github.com/users/${USER}/repos`; +const projectsContainer = document.getElementById("projects-container"); +const userContainer = document.getElementById("user-container"); + +const getUser = () => { + fetch(`https://api.github.com/users/${USER}`) + .then((response) => response.json()) + .then((data) => { + userContainer.innerHTML += /*html*/ ` + +

${data.login}

+ `; + }); +}; + +getUser(); + +const getRepos = () => { + fetch(REPOS_URL) + .then((response) => response.json()) + .then((data) => { + const technigoProjects = data.filter((repo) => repo.fork && repo.name.startsWith("project-")); + + technigoProjects.sort((oldestRepo, newestRepo) => new Date(newestRepo.pushed_at) - new Date(oldestRepo.pushed_at)); + + technigoProjects.forEach((repo) => { + projectsContainer.innerHTML += /*html*/ ` + +
+

${repo.name}

+

Default branch ${repo.default_branch}

+

Recent push: ${new Date(repo.pushed_at).toDateString()}

+

Amount of commits:

+
+
+
+ `; + }); + + getPullRequests(technigoProjects); + drawChart(technigoProjects.length); + }); +}; + +getRepos(); + +const getPullRequests = (repos) => { + repos.forEach((repo) => { + fetch(`https://api.github.com/repos/technigo/${repo.name}/pulls?per_page=100`) + .then((response) => response.json()) + .then((data) => { + const filteredPull = data.find((pull) => pull.user.login === repo.owner.login); + + if (filteredPull) { + getCommits(filteredPull.commits_url, repo.name); + getReview(filteredPull.review_comments_url, repo.name); + } else { + document.getElementById(`commits-${repo.name}`).innerHTML = "No pull request"; + } + }); + }); +}; + +const getCommits = (url, repoName) => { + fetch(url) + .then((response) => response.json()) + .then((data) => { + document.getElementById(`commits-${repoName}`).innerHTML += data.length; + }); +}; + +const getReview = (url, repoName) => { + fetch(url) + .then((response) => response.json()) + .then((data) => { + if (data.length === 0) { + document.getElementById(`${repoName}-container`).innerHTML += ""; + } else { + document.getElementById(`${repoName}-container`).innerHTML += /*html*/ ` +

Reviewed by ${data[0].user.login}

+ `; + } + }); +}; \ No newline at end of file diff --git a/code/style.css b/code/style.css index 7c8ad447..082f86d1 100644 --- a/code/style.css +++ b/code/style.css @@ -1,3 +1,119 @@ +* { + margin: 0; + padding: 0; +} + body { - background: #FFECE9; -} \ No newline at end of file + font-family: "Roboto", sans-serif; + color: #222222; +} + +.hero-image { + width: 100vw; + /* height: 280px; */ + height: 40vh; + background-image: url(./assets/background.jpg); + background-position: center; + background-size: cover; + background-repeat: no-repeat; +} + +.user-container { + position: relative; + text-align: center; + bottom: 72px; +} + +.user-image { + border-radius: 50%; + width: 126px; + border: solid 6px #ffffff; +} + +.user-name { + font-size: 26px; + font-weight: 700; + margin-top: 3px; +} + +.project { + display: flex; + flex-direction: column; + align-items: center; + padding: 40px 0; +} + +.projects-container { + line-height: 1.8; + margin-top: -40px; +} + +.project-info { + font-family: "Open Sans", sans-serif; + font-size: 15px; + font-weight: 400; + color: #666666; + pointer-events: none; +} + +.project-name, +.chart-heading { + font-family: "Open Sans", sans-serif; + color: #222222; + font-size: 18px; + font-weight: 700; + pointer-events: none; +} + +.project-link { + text-decoration: none; +} + +.project-link :hover { + background: linear-gradient( + 90deg, + white, + #e6e6e6 50%, + #e6e6e6 50%, + #e6e6e6 50%, + white + ); +} + +hr { + margin: auto; + width: 75vw; + background: linear-gradient(90deg, white, #e6e6e6, #e6e6e6, #e6e6e6, white); + height: 1px; + border: none; +} + +.chart-section { + display: flex; + flex-direction: column; + align-items: center; + margin: 40px 0 80px; +} + +.chart-container { + width: 70vw; +} + +.chart { + margin-top: 20px; +} + +@media (min-width: 768px) { + .chart-container { + width: 40vw; + } +} + +@media (min-width: 1025px) { + .hero-image { + height: 70vh; + } + .chart-container { + width: 30vw; + } +}