Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Binary file added code/assets/background.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 20 additions & 3 deletions code/chart.js
Original file line number Diff line number Diff line change
@@ -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);
};
61 changes: 44 additions & 17 deletions code/index.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Project GitHub Tracker</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<h1>GitHub Tracker</h1>
<h2>Projects:</h2>
<main id="projects"></main>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ru's GitHub Tracker</title>

<!-- This will be used to draw the chart 👇 -->
<canvas id="chart"></canvas>
<!-- Roboto fontfamily -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
rel="stylesheet"
/>

<script src="./script.js"></script>
<script src="./chart.js"></script>
</body>
</html>
<!-- Open Sans fontfamily -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&display=swap"
rel="stylesheet"
/>

<!-- Stylesheet -->
<link rel="stylesheet" href="./style.css" />

<!-- Chart -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>

<body>
<header class="hero-image"></header>
<main>
<section class="user-container" id="user-container"></section>
<section class="projects-container" id="projects-container"></section>
<section class="chart-section">
<h3 class="chart-heading">Overview of Projects</h3>
<div class="chart-container">
<canvas class="chart" id="chart"></canvas>
</div>
</section>
</main>

<script src="./script.js"></script>
<script src="./chart.js"></script>
</body>
</html>
56 changes: 56 additions & 0 deletions code/instruction
Original file line number Diff line number Diff line change
@@ -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 += `
<div class="repo" id=${repo.name}>
<h2>${repo.name}</h2>
</div>
`
})

//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?
85 changes: 85 additions & 0 deletions code/script.js
Original file line number Diff line number Diff line change
@@ -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*/ `
<img class="user-image" src="${data.avatar_url}"/>
<h2 class="user-name">${data.login}</h2>
`;
});
};

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*/ `
<a class="project-link" href="${repo.html_url}" target="_blank">
<div class="project" id="${repo.name}-container">
<h3 class="project-name">${repo.name}</h3>
<p class="project-info">Default branch ${repo.default_branch}</p>
<p class="project-info">Recent push: ${new Date(repo.pushed_at).toDateString()}</p>
<p class="project-info" id="commits-${repo.name}">Amount of commits: </p>
</div>
</a>
<hr>
`;
});

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*/ `
<p class="project-info">Reviewed by ${data[0].user.login}</p>
`;
}
});
};
120 changes: 118 additions & 2 deletions code/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,119 @@
* {
margin: 0;
padding: 0;
}

body {
background: #FFECE9;
}
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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice , hero img )) Cute!

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;
}
}