diff --git a/README.md b/README.md index 1613a3b0..494f4d16 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,25 @@ # GitHub Tracker -Replace this readme with your own information about your project. +This project is all about working with the Github-API. + +The tracker shows +- username/pic +- all the repos that are done by me during the Technigo bootcamp +- no. of commits and commit messages for each repository +- a doughnut pie from chart.js + + -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. ## 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? +I focussed in this project on gaining data from the API and filter/sort it in a way that I get all the entries I want to show in my tracker. + +I kept the design simple and made it look close to the original GitHub-website. + +If I would have more time, I would like to add "no. of commits" to the sort field and maybe add a search field also. + ## 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. +Take a look at the project here: https://github-tracker-nehrwein.netlify.app/ diff --git a/code/chart.js b/code/chart.js index 92e85a30..5a399638 100644 --- a/code/chart.js +++ b/code/chart.js @@ -1,4 +1,34 @@ //DOM-selector for the canvas 👇 const ctx = document.getElementById('chart').getContext('2d') + +const drawChart = (doneProjects) => { + //config for the the doughnut-chart: + const config = { + type: 'doughnut', + data: { + labels: [ + 'Finished Projects', + 'Projects left' + ], + datasets: [{ + label: 'My First Dataset', + data: [doneProjects, totalProjects - doneProjects], + backgroundColor: [ + 'rgb(120, 129, 131)', + 'rgb(198, 207, 215)', + ], + hoverOffset: 5 + }], + }, + options: { + plugins: { + legend: { + position: 'right', + } + } + } + }; -//"Draw" the chart here 👇 + //rendering the chart in the browser/ newChart(where to put it, what to put) + const chart = new Chart(ctx, config); +} \ No newline at end of file diff --git a/code/index.html b/code/index.html index 2fb5e0ae..2e82cb14 100644 --- a/code/index.html +++ b/code/index.html @@ -6,15 +6,28 @@ Project GitHub Tracker + + + + + -

GitHub Tracker

-

Projects:

-
- - - - +
+ +

GitHub Tracker

+
+
+
+
+
+ +
+ +
+ +
+ diff --git a/code/script.js b/code/script.js index e69de29b..85f192c8 100644 --- a/code/script.js +++ b/code/script.js @@ -0,0 +1,135 @@ +//DOM SELECTORS +const userSection = document.getElementById("user-section") + +//GLOBAL VARIABLES +/* const options = { + method: 'GET', + headers: { + Authorization: `token xxx` + }, +}; */ + +const REPO_API = "https://api.github.com/users/nehrwein/repos"; +const totalProjects = 19; + +//FUNCTIONS + + +const getRepos = () => { + fetch(REPO_API, /* options */) + .then((res) => res.json()) + .then((data) => { + + //forkedRepos shows a list of all repos that are forked ones from Technigo + const forkedRepos = data.filter(repo => repo.fork && repo.name.startsWith('project-')) + + //show the newest repos first (default) + forkedRepos.sort((a, b) => { + return new Date(b.pushed_at) - new Date(a.pushed_at); + }); + + //My name, username and profile picture + const userName = data[0].owner.login + const profilePic = data[0].owner.avatar_url + + userSection.innerHTML += /* html */` +
+
+ Github Avatar +
+
+

Birgit

+

${userName}

+
+
+ + + + ` + + const sortBtn = document.getElementById('sort') + sortBtn.addEventListener('change', () => sort(sortBtn.value, forkedRepos)) + + drawProjects(forkedRepos); + drawChart(forkedRepos.length) + }) +} + +//sorting the projects by name, last updated +const sort = (value, repos) => { + if (value === "name") { + repos.sort((a, b) => { + return (a.name) > (b.name) ? 1 : -1; + }); + drawProjects(repos) + } else if (value === "updated") { + repos.sort((a, b) => { + return new Date(b.pushed_at) - new Date(a.pushed_at); + }); + drawProjects(repos) + } +} + +const drawProjects = (forkedRepositories) => { + document.getElementById('projects-section').innerHTML = ` ` + forkedRepositories.forEach((repo) => { + document.getElementById('projects-section').innerHTML += ` +
+ ${repo.name} +

default branch: ${repo.default_branch}

+

Last push: ${new Date(repo.pushed_at).toLocaleDateString('en-GB')}

+

Commits: 0

+ +
+ `; + + getCommits(forkedRepositories, repo.name); + }); + + forkedRepositories.forEach((repo) => { + document + .getElementById(`commit-${repo.name}`) + .addEventListener('click', () => { + document + .getElementById(`commitMessages-${repo.name}`) + .classList.toggle('active'); + }); + }); +}; + +const getCommits = (filteredArray, myRepoName) => { + + //First make a new array with all the needed APIs (found under commit_urls in forkedRepos) + const allCommitUrls = filteredArray.map(repo => repo.commits_url) + + allCommitUrls.forEach(commitAPI => { + //the URLs end with {/sha}, therefore the last 6 chars need to be sliced + commitAPI = commitAPI.slice(0, -6) + + //now the URLs can be passed on to get data about number and content of commits + fetch(commitAPI, /* options */) + .then((res) => res.json()) + .then((data) => { + const authorCommits = data.filter(commits => commits.author.login === 'nehrwein' && commits.url.includes(myRepoName)) + if (authorCommits.length > 0) { + document.getElementById(`commit-${myRepoName}`).innerHTML = ` + Commits: ${authorCommits.length} + ` + authorCommits.forEach(element => { + document.getElementById(`commitMessages-${myRepoName}`).innerHTML += ` +
  • ${element.commit.message}
  • + ` + }) + } + }) + }); +} + + + +getRepos(); + diff --git a/code/style.css b/code/style.css index 7c8ad447..5129e58e 100644 --- a/code/style.css +++ b/code/style.css @@ -1,3 +1,211 @@ +/* GLOBAL STYLES */ + +html { + box-sizing: border-box; +} +*, *:before, *:after { + box-sizing: inherit; +} + body { - background: #FFECE9; + background: white; + font-family: 'Roboto', sans-serif; + margin: 0; +} + +/* HEADER */ + +header { + display: flex; + background-color: black; + justify-content: center; + align-items: center; +} + +h1 { + color: white; + text-decoration: none; + font-size: 22px; +} + +header a { + text-decoration: none; +} + +.fab { + color: white; + font-size: 22px; + margin-right: 4px; +} + + + + +/* USER-SECTION */ +.user { + padding: 16px; + display: flex; + justify-content: space-between; + align-items: flex-end; +} + +.userImage_Text { + display: flex; + align-items: flex-end; +} + +.userImageDiv { + display: inline-flex; +} + +.userImage { + border: 1px solid lightgray; + border-radius: 50%; + width: 57px; + margin-right: 10px; +} + +.userTextDiv { + display: inline-flex; + flex-direction: column; +} + +.userTextDiv p { + margin: 0; +} + +.myName { + font-size: 26px; +} + +.userName { + font-size: 20px; + font-style: lighter; + font-weight: 100; +} + +.sort { + margin-left: 25px; + height: 25px; + background-color: #F3F4F6; + border: 0.75px solid lightgray; + border-radius: 4px; + font-size: 16px; +} + + +/* PROJECTS-SECTION */ + +.projects { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 1rem; +} + +.projects-div { + border: 0.75px solid lightgray; + border-radius: 4px; + padding: 5px 16px; + margin: 0 16px; +} + +.projects-div a { + display: block; + margin-bottom: 8px; + color: #0969DA; + font-size: 18px; + margin-bottom: 4px; +} + +.projects p, ul { + font-size: 16px; + margin: 0; +} + +.fas { + color:#0969DA; + cursor: pointer; + margin-left: 3px; +} + +/* Toggle between show/hide the Commit-messages */ +.projects ul { + display: none; + padding-left: 16px; + margin-top: 2px; +} + +.projects ul.active { + display: block; +} + +/* CHART */ +.chart { + margin-top: -60px; + margin-left: 16px; + width: 330px; + height: 165px; +} + +/* ***********MEDIA QUERIES*************** */ + +/* TABLET */ +@media (min-width: 667px) { + + header { + justify-content: flex-start; + padding-left: 16px; + } + + + + main { + display:flex; + } + + .user { + align-items: flex-start; + } + + .userImage_Text { + flex-direction: column; + align-items: flex-start; + } + + .userImage { + width: 168px; + } + + .myName { + font-size: 29px; + } + + .userName { + font-size: 26px; + } + + .projects { + flex-grow: 2; + padding-top: 16px; + padding-right: 16px; + } + + .projects-div { + margin: 0; + } + +} + +/* DESKTOP */ +@media (min-width: 1024px) { + + .userImage { + width: 216px; + } + + .chart { + width: 380px; + height: 190px; + } + } \ No newline at end of file