diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..f38f4d78 Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/settings.json b/.vscode/settings.json index e8783bfe..f336de0c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,23 @@ { - "liveServer.settings.port": 5505 -} \ No newline at end of file + "liveServer.settings.port": 5506, + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#fbed80", + "activityBar.activeBorder": "#06b9a5", + "activityBar.background": "#fbed80", + "activityBar.foreground": "#15202b", + "activityBar.inactiveForeground": "#15202b99", + "activityBarBadge.background": "#06b9a5", + "activityBarBadge.foreground": "#15202b", + "sash.hoverBorder": "#fbed80", + "statusBar.background": "#f9e64f", + "statusBar.foreground": "#15202b", + "statusBarItem.hoverBackground": "#f7df1e", + "statusBarItem.remoteBackground": "#f9e64f", + "statusBarItem.remoteForeground": "#15202b", + "titleBar.activeBackground": "#f9e64f", + "titleBar.activeForeground": "#15202b", + "titleBar.inactiveBackground": "#f9e64f99", + "titleBar.inactiveForeground": "#15202b99" + }, + "peacock.color": "#f9e64f" +} diff --git a/README.md b/README.md index 1613a3b0..222e419c 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ # 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. +This is my version of a GitHub Tracker. It's a webpage that displays my profile and all projects I've made during the Technigo Frontend Boot Camp together with selected information about it fetched through GitHub API's. ## 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 started out by studying the project brief and getting familiar to the use of the GitHub API's as I started to add code to the project. I finished the projects requirements and added extra features. The extra features includes the formatting of the fetched project name, adding the language percentage for each project and links to view the projects live. + +This project opened up my eyes to the clever use of dynamic id's. By using it I was able to keep the functions separate and invoking them with arguments in the main function (getRepos) instead of having to collect them all in the main function in a "waterfall" structure to access the values of the variables inside. + +Next step would be to add if the projects has collaborators or not (group or individual assignment), names of collaborators and the commits made for projects I've been a collaborator on. To be able to sort and/or search for the projects will come in handy when the number of projects will increase. ## 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://priceless-kepler-739442.netlify.app/ diff --git a/code/.DS_Store b/code/.DS_Store new file mode 100644 index 00000000..01a692b6 Binary files /dev/null and b/code/.DS_Store differ diff --git a/code/assets/.DS_Store b/code/assets/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/code/assets/.DS_Store differ diff --git a/code/assets/background.png b/code/assets/background.png new file mode 100644 index 00000000..a4c8b05d Binary files /dev/null and b/code/assets/background.png differ diff --git a/code/assets/github-tracker.svg b/code/assets/github-tracker.svg new file mode 100644 index 00000000..a5026623 --- /dev/null +++ b/code/assets/github-tracker.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/code/assets/location_icon.svg b/code/assets/location_icon.svg new file mode 100644 index 00000000..83362467 --- /dev/null +++ b/code/assets/location_icon.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/code/chart.js b/code/chart.js index 92e85a30..c96d9e55 100644 --- a/code/chart.js +++ b/code/chart.js @@ -1,4 +1,35 @@ -//DOM-selector for the canvas ๐Ÿ‘‡ const ctx = document.getElementById('chart').getContext('2d') -//"Draw" the chart here ๐Ÿ‘‡ +const drawChart = (amount) => { + const config = { + type: 'doughnut', + data: { + labels: [ + `Pushed projects`, + `Projects to go`, + ], + datasets: [{ + label: 'Technigo progress', + data: [amount, 19-amount], + backgroundColor: [ + '#F59B99', + '#FAECD2' + ], + borderColor: [ + 'transparent', + 'transparent' + ], + hoverOffset: 0 + }] + }, + options: { + plugins: { + legend: { + position: '', + } + } + } + } + const myChart = new Chart(ctx, config) +} + diff --git a/code/index.html b/code/index.html index 2fb5e0ae..6604db50 100644 --- a/code/index.html +++ b/code/index.html @@ -6,14 +6,35 @@ Project GitHub Tracker + + + + -

GitHub Tracker

-

Projects:

-
- - +
+
+ +
+
+
+
+
+
+

Technigo Projects

+
+
+ +
+
+
+
+
+
+
+ + diff --git a/code/script.js b/code/script.js index e69de29b..7952a004 100644 --- a/code/script.js +++ b/code/script.js @@ -0,0 +1,163 @@ +const USER = 'elsisco' +let repoName = 'project-weather-app' // Default value + +const API_REPOS = `https://api.github.com/users/${USER}/repos` +// const API_REPOS_PUSHED = `https://api.github.com/users/${USER}/repos?sort=pushed` +const API_USER = `https://api.github.com/users/${USER}` + +const projectsContainer = document.getElementById('projects') +const profileContainer = document.getElementById('profile') + +// Fetch content for profile section +const getUser = () => { + fetch(API_USER) + .then((res) => res.json()) + .then((data) => { + // Profile content + profileContainer.innerHTML += /*html*/ ` +
+
+ +
+
${data.name}
+
${data.login}
+ + +
+ +
${data.location}
+
+
${data.bio}
+
+ ` + }) +} + +// Fetch content for projects section +const getRepos = () => { + fetch(API_REPOS) + .then((res) => res.json()) + .then((data) => { + console.log(data) + // Filtering the Technigo project repos + const forkedRepos = data.filter( + (repo) => repo.fork && repo.name.startsWith('project-') + ) + + const sortedRepos = forkedRepos.sort((a, b) => (a.name > b.name ? 1 : -1)) + // forkedRepos.sort(function (oldestRepo, newestRepo) { + // return new Date(newestRepo.pushed_at) - new Date(oldestRepo.pushed_at) + // }) + + sortedRepos.forEach((repo) => + fetch(`https://api.github.com/repos/${USER}/${repo.name}/commits`) + .then((res) => res.json()) + .then((data) => { + // Formatting the title of projects to start all words with capital letter + let projectName = `${repo.name}` + + const formattedProjectName = projectName.split('-') + for (let i = 0; i < formattedProjectName.length; i++) { + formattedProjectName[i] = + formattedProjectName[i][0].toUpperCase() + + formattedProjectName[i].substr(1) + } + + let newProjectName = formattedProjectName.join(' ') + + // Date for most recent update of project + let latestCommit = new Date(repo.pushed_at).toLocaleString( + 'en-ZA', + { dateStyle: 'short' } + ) + + // Adding content to the projects + projectsContainer.innerHTML += /*html*/ ` +
+
${newProjectName}
+ +

Most recent push: ${latestCommit}

+

Default branch: ${repo.default_branch}

+

(commits yet to be displayed)

+
+

Languages

+
+
+
+
+
HTML
+
+
+
+
CSS
+
+
+
+
JavaScript
+
+
+
+
+ ` + calculateLanguagePercentage(repo) + }) + ) + fetchPullRequestsArray(forkedRepos) + drawChart(forkedRepos.length) + }) +} + +// A calculator for percentage of language per project +const calculateLanguagePercentage = (repo) => { + fetch(`https://api.github.com/repos/${USER}/${repo.name}/languages`) + .then((res) => res.json()) + .then((language) => { + const html = language.HTML || 0 + const css = language.CSS || 0 + const js = language.JavaScript || 0 + const sum = html + css + js + + const htmlPercentage = ((html / sum) * 100).toFixed(1) + const cssPercentage = ((css / sum) * 100).toFixed(1) + const jsPercentage = ((js / sum) * 100).toFixed(1) + + document.getElementById(`progress-${repo.name}`).innerHTML = /*html*/ ` +
+
+
+ ` + }) +} + +// Fetch all pull requests per project +const fetchPullRequestsArray = (allRepositories) => { + allRepositories.forEach((repo) => { + fetch( + `https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100` + ) + .then((res) => res.json()) + .then((data) => { + // Hard coded the || below to get the commits for Project Chatbot for which I was not a collaborator + const myPullRequests = data.find( + (pull) => + pull.user.login === repo.owner.login || + (pull.user.login === 'Svempolin' && pull.number === 67) + ) + fetchCommits(myPullRequests.commits_url, repo.name) + }) + }) +} + +// Fetching all the commits connected to the username +const fetchCommits = (myCommitsUrl, myRepoName) => { + fetch(myCommitsUrl) + .then((res) => res.json()) + .then((data) => { + document.getElementById( + `commits-${myRepoName}` + ).innerHTML = `${data.length} commits` + }) +} + +getUser() +getRepos() diff --git a/code/style.css b/code/style.css index 7c8ad447..5fd67744 100644 --- a/code/style.css +++ b/code/style.css @@ -1,3 +1,298 @@ body { - background: #FFECE9; -} \ No newline at end of file + font-family: "Roboto", "sans-serif"; + box-sizing: border-box; + width: 100%; + height: 100%; + margin: 0; + background-image: url("./assets/background.png"); + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; +} + +a { + text-decoration: none; + font-weight: 800; + color: black; +} + +a:hover { + color: #56b093; +} + +.text { + font-size: 14px; + line-height: 1.4; + margin: 0; + margin-bottom: 5px; + font-weight: 300; +} + +.project-headline { + font-family: "Playfair Display", "serif"; + font-size: 22px; + margin: 7px 0 4px 0; +} + +.links-text { + font-size: 14px; + font-weight: 600; + margin: 8px 0; +} + +.thin-headline { + font-size: 18px; + font-weight: 300; +} + +.small-headline { + font-size: 14px; + font-weight: 400; + margin: 10px 0; +} + +.header { + width: 225px; + height: 58px; + max-width: 1024px; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto; + background-color: #56b093; + border-radius: 0 0 10px 10px; + box-shadow: 0px 3px 4px 0 rgba(0, 0, 0, 0.15); +} + +.header img { + width: 80%; +} + +.main-wrapper { + max-width: 1024px; + margin: 0 auto; + padding-bottom: 20px; + height: 100%; +} + +.profile-wrapper { + background-color: rgba(255, 255, 255, 0.5); + text-align: center; + margin: 15px auto; + display: flex; + align-items: flex-start; + justify-content: space-evenly; + flex-direction: row; + padding: 15px 0; +} + +.profile { + width: 55%; + border-right: 1px lightgray solid; + text-align: left; + padding: 3%; +} + +.location { + display: flex; +} + +.location img { + height: 12px; + margin-right: 5px; + margin-top: 1.5px; +} + +.chart-section { + width: 25%; + display: flex; + flex-direction: column; + align-items: center; + padding: 3%; +} + +.chart-wrapper { + width: 100%; +} + +chart { + padding: 5px; +} + +.headline-wrapper { + display: flex; + align-items: center; + justify-content: center; +} + +.avatar-wrapper { + width: 100%; + max-width: 220px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: center; + padding-bottom: 20px; +} + +.avatar { + width: 80%; + border-radius: 1000px; + margin: 0 auto; + text-align: center; + border: 5px lightgrey solid; + padding: 3px; +} + +.projects { + width: 100%; +} + +.project-card { + background-color: rgba(255, 255, 255, 0.5); + margin-top: 15px; + padding: 20px 25px; +} + +.progress { + display: flex; + width: 85%; + border-radius: 10px; + overflow: hidden; +} + +.progress-js { + height: 10px; + background-color: #f59b99; +} +.progress-css { + height: 10px; + background-color: #ebbc4e; +} + +.progress-html { + height: 10px; + background-color: #56b093; +} + +.the-languages { + display: flex; + align-items: center; + justify-content: flex-start; + padding: 10px 0; +} + +.js-wrapper { + display: flex; + align-items: center; +} + +.html-wrapper { + display: flex; + align-items: center; +} + +.css-wrapper { + display: flex; + align-items: center; +} + +.language-dot { + width: 10px; + height: 10px; + border-radius: 10px; + background-color: white; + margin-right: 5px; +} + +.language-text { + font-size: 12px; + margin-right: 15px; +} + +.footer { + width: 100%; + background-color: #56b093; + color: white; + margin: 0 auto; + padding: 10px; + text-align: center; + font-size: 11px; + line-height: 1.5; + box-sizing: border-box; +} + +@media (min-width: 668px) { + .main-wrapper { + display: flex; + flex-direction: row; + justify-content: space-evenly; + height: 100%; + } + + .header { + position: fixed; + } + + .profile-wrapper { + flex-direction: column; + justify-content: flex-start; + width: 300px; + height: 70%; + margin: 15px 0 0 15px; + padding: 15px; + margin-top: 85px; + background-color: rgba(255, 255, 255, 0.5); + } + + .profile { + width: 95%; + border-right: none; + margin-bottom: 10px; + } + + .avatar { + width: 80%; + margin-top: 10px; + } + + .chart-section { + width: 70%; + justify-content: center; + margin: 15px auto; + } + + .projects-wrapper { + width: 60%; + padding-top: 70px; + } + + .project-card { + background-color: rgba(255, 255, 255, 0.5); + margin: 15px auto; + width: 80%; + } +} + +@media (min-width: 1024px) { + .profile-wrapper { + width: 25%; + margin-right: 10px; + } + + .projects-wrapper { + width: 70%; + } + + .projects { + display: flex; + flex-direction: row; + flex-wrap: wrap; + padding-bottom: 20px; + } + + .project-card { + width: 40%; + margin: 15px 10px 5px 10px; + } +}