diff --git a/README.md b/README.md index 1613a3b0..e2042429 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,21 @@ # GitHub Tracker -Replace this readme with your own information about your project. +A site made to practice fetching from the GitHub API. -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +## Features -## The problem +- Dynamic styling through DOM manipulation in JavaScript. +- Mobile-first styling. +- Data retrieved from GitHub's API: Basic user info, projects forked from Technigo (filtered by date of creation), number of commits, and whether there has been a pull request yet. +- Use of methods like filter, find, and sort to organize the data. +- A chart visualization of completed projects vs. projects left to do, using chart.js. -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? +## Challenges and Lessons learned -## View it live +- The biggest challenge in terms of fetching was the getCommits function, since the API didn't have a direct path to fetch each commit. The solution was to first fetch all repos, then filter the forked ones. Then get their pull requests, and finally invoke the getCommits function within a conditional (if the project had any pull requests). +- Dynamic CSS with JavaScript was also a challenge, since the styling mindset was purely based on the HTML document up to this point. I learned to check the dev tools more often, to make sure the dynamic structure of the document was still coherent. +- The responsiveness of the chart was tricky because of the quirky nature of chart.js. I used a combination of the library's documentation and Stack Overflow answers to get ahead. In the end, I decided to go for a bar graphic instead of a donut. Its rectangular forms matched my layout better. -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. +## Deployed version + +github-tracker-gonzalez.netlify.app diff --git a/code/chart.js b/code/chart.js index 92e85a30..d0d688ff 100644 --- a/code/chart.js +++ b/code/chart.js @@ -1,4 +1,39 @@ -//DOM-selector for the canvas 👇 -const ctx = document.getElementById('chart').getContext('2d') +// DOM-selector for the canvas +const ctx = document.getElementById('myChart').getContext('2d'); -//"Draw" the chart here 👇 +// Generate the chart based on the data fetched on script.js +const drawChart = (amount) => { + const config = { + type: 'bar', + data: { + labels: ['Finished Projects', 'Projects Left'], + datasets: [ + { + label: 'Completed Projects', + data: [amount, 19 - amount], + backgroundColor: ['#D365C8', '#3aafc9'], + hoverOffset: 4, + }, + ], + }, + options: { + // The first two options make the chart responsive + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + tooltips: { + callbacks: { + label: function (tooltipItem) { + return tooltipItem.yLabel; + }, + }, + }, + }, + }, + }; + + const myChart = new Chart(ctx, config); +}; diff --git a/code/index.html b/code/index.html index 2fb5e0ae..acf57452 100644 --- a/code/index.html +++ b/code/index.html @@ -1,21 +1,40 @@ - - - - - Project GitHub Tracker - - - -

GitHub Tracker

-

Projects:

-
- - - - - - - - \ No newline at end of file + + + + + Project GitHub Tracker + + + + + + + + + +
+
+
+
+
+

Technigo Projects

+
+
+
+ +
+ +
+ + + + + diff --git a/code/script.js b/code/script.js index e69de29b..c2be447e 100644 --- a/code/script.js +++ b/code/script.js @@ -0,0 +1,96 @@ +// The strict mode in JavaScript prevents several bugs. For example, it won't let you use undeclared variables. +'use strict'; + +// Global variables +const USER = 'isomoth'; +const USER_URL = `https://api.github.com/users/${USER}`; +const REPOS_URL = `https://api.github.com/users/${USER}/repos`; +const userInfo = document.getElementById('user-info'); +const projectsContainer = document.getElementById('project-grid'); + +// Fetch user info and inject it into a div +const getUserProfile = () => { + fetch(USER_URL) + .then((response) => response.json()) + .then((data) => { + userInfo.innerHTML += ` +
+ +
+

${data.name}

+

${data.login}

+

${data.bio}

+

Public repos: ${data.public_repos}

+ +
+
+ `; + }); +}; + +getUserProfile(); + +// Fetch all of the user's projects where a pull request has been made +const getPullRequests = (allRepos) => { + allRepos.forEach((repo) => { + const PULL_URL = `https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`; + fetch(PULL_URL) + .then((response) => response.json()) + .then((data) => { + const userPullRequest = data.find( + (pull) => pull.user.login === repo.owner.login + ); + // Filter out pull requests from other users and fetch commits from them + if (userPullRequest) { + getCommits(userPullRequest.commits_url, repo.name); + } else { + // Catch exception when no pull request has been made + document.getElementById(`commit-${repo.name}`).innerHTML = + 'No pull requests so far.'; + } + }); + }); +}; + +//Fetch all commits from filtered projects +const getCommits = (myCommitsUrl, myRepoName) => { + fetch(myCommitsUrl) // this will be 'commits_url' from line 45 + .then((res) => res.json()) + .then((data) => { + // Count amount of commits + document.getElementById(`commit-${myRepoName}`).innerHTML += data.length; + }); +}; + +// Fetch all repositories that the user has forked from Technigo +const getRepositories = () => { + fetch(REPOS_URL) + .then((response) => response.json()) + .then((data) => { + let forkedRepos = data.filter( + (repo) => repo.fork && repo.name.includes('project-') + ); + // Sort repos based on date of creation ("created_at") + forkedRepos.sort( + (b, a) => new Date(a.created_at) - new Date(b.created_at) + ); + // Finally, use a loop to generate a card container for each project and fetch other relevant info about it + forkedRepos.forEach((repo) => { + projectsContainer.innerHTML += `
+

${ + repo.name + }

+ +

Default branch: ${repo.default_branch}

+

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

+

Amount of commits:

+ +

`; + }); + getPullRequests(forkedRepos), + //Use the data above to generate the chart from chart.js, displaying elapsed vs. remaining projects + drawChart(forkedRepos.length); + }); +}; + +getRepositories(); diff --git a/code/style.css b/code/style.css index 7c8ad447..f29edc82 100644 --- a/code/style.css +++ b/code/style.css @@ -1,3 +1,192 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +/* PALETTE + +Dark grey: #222a36 +Light grey: #D5CABD +Aquamarine: #3aafc9 +Light purple: #676cdb +Magenta: #D6434A + + +*/ + +/* ----------------------------------------------- */ +/* GLOBAL COMPONENTS */ +/* ----------------------------------------------- */ + body { - background: #FFECE9; -} \ No newline at end of file + background: #d5cabd; + font-family: 'Martel Sans', Helvetica, Arial, sans-serif; + color: #37888a; + margin: 1rem; + font-size: 16px; +} + +a { + color: #3aafc9; +} + +/* ----------------------------------------------- */ +/* USER INFO SECTION */ +/* ----------------------------------------------- */ + +.user-info { + display: block; + margin-top: 2rem; +} + +.user-names { + margin: 1rem; + display: block; + text-align: center; +} + +.bio { + margin-top: 1rem; + padding-left: 2rem; + padding-right: 2rem; +} + +.bio, +.public, +.twitter { + color: #474554; +} + +.divider-title { + padding: 0.5rem; + margin-bottom: 5px; + width: 100%; + background: #ddebeb; + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; + border-style: solid; + border-width: 1px; + border-radius: 6px; +} + +.user-image { + width: 50%; + height: fit-content; + border-radius: 50%; + box-shadow: 0 0 0 0.1px; + display: block; + margin-left: auto; + margin-right: auto; +} + +/* ----------------------------------------------- */ +/* PROJECT SECTION */ +/* ----------------------------------------------- */ + +#project-grid { + display: grid; + grid-template-columns: repeat(1, 1fr); +} + +.repo-card { + background: #676cdb; + color: #fff; + margin-top: 1rem; + padding: 1rem; + border-style: solid; + border-width: 1px; + border-radius: 6px; +} + +.repo-link { + color: #d6434a; + font-size: 20px; +} + +/* ----------------------------------------------- */ +/* CHART */ +/* ----------------------------------------------- */ + +.chart-container { + margin-top: 2rem; + margin-left: auto; + margin-right: auto; + width: 80vw; + height: 60vh; +} + +/* ----------------------------------------------- */ +/* MEDIA QUERIES */ +/* ----------------------------------------------- */ + +@media screen and (min-width: 600px) { + #project-grid { + grid-template-columns: repeat(2, 1fr); + grid-gap: 30px; + } + .user-image { + width: 30%; + height: auto; + } +} + +@media screen and (min-width: 768px) { + .user-image { + width: 40%; + height: auto; + } +} + +@media screen and (min-width: 1024px) { + .profile-container { + display: grid; + grid-template-columns: 1fr 3fr; + margin: 10rem; + } + + #project-grid { + grid-gap: 20px; + } + + .user-info { + flex-wrap: wrap; + justify-content: flex-start; + margin-top: 0; + } + + .user-image { + width: 75%; + } + + .divider-title { + margin-bottom: 20px; + } + + h1 { + font-size: 3em; + } + h2 { + font-size: 2em; + } + h3 { + font-size: 1em; + } + .bio { + font-size: 1em; + } + .repo-link { + font-size: 1.5em; + } +} + +@media screen and (min-width: 3840px) { + body { + max-width: 2000px; + } + .chart-container { + max-width: 1500px; + } +}