diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2c1117b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +secret.js \ No newline at end of file diff --git a/README.md b/README.md index 1613a3b0..6f067dba 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,47 @@ # GitHub Tracker -Replace this readme with your own information about your project. +### What to include -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +- 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). -## The problem +## Requirements ๐Ÿงช -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? +Your project should fulfil the three **๐Ÿ”ต Blue Level Requirements** , **๐Ÿ”ด Red Level** and **โšซ Black Level Requirements** to push your knowledge to the next level! + +### **๐Ÿ”ต Blue Level (Minimum Requirements)** + +Your page should include: + +- A list of all repos that are forked 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 commits for each repo +- It should be responsive (mobile first) +- A visualisation, for example through a pie chart, of how many projects you've done so far, compared to how many you will do (in total it will be 19 weekly projects ๐Ÿฅณ). + +### **๐Ÿ”ด Red Level (Intermediary Goals)** + +- Sort your list in different ways. +**Example of what you can sort by:** creation date, name, most commits, followers or stargazers +- Create the opportunity to filter the repos based on a condition, e.g. only JavaScript repos +- Display the actual commit messages for each repo in a good way. Maybe by adding a modal (popup) or an accordion? +- Display the comments you got from each pull request +- When you're browsing through the repo object, you'll see that there's a lot of data that we can use. Create a chart over some of the data. +**Example of data to use:** Repo size, people that starred your repo (stargazers) or amount of commits on each repo. + +### **โšซ Black Level (Advanced Goals)** + +- Implement a search field to find a specific repo based on name ## 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://pedantic-roentgen-a54a90.netlify.app/ diff --git a/chart.js b/chart.js new file mode 100644 index 00000000..580f8357 --- /dev/null +++ b/chart.js @@ -0,0 +1,46 @@ +//DOM-selector for the canvas ๐Ÿ‘‡ +const ctx = document.getElementById('chart').getContext('2d') + +//"Draw" the chart here ๐Ÿ‘‡ +const drawChart = (amount) => { +const labels = [ + 'Completed projects', + 'Projects to do', + ]; + + const data = { + labels: labels, + datasets: [{ + label: 'My First dataset', + backgroundColor: [ + '#a07a99', + '#125e91', + ], + borderColor: '#000000', + data: [amount, 19 - amount], + }] + }; + + const options = { + layout: { + padding: 25 + }, + plugins: { + legend: { + labels: { + font: { + size: 16 + } + } + } + } +} + + const config = { + type: 'doughnut', + data:data, + options: options + }; + + const myChart = new Chart(ctx, config); +} diff --git a/code/chart.js b/code/chart.js deleted file mode 100644 index 92e85a30..00000000 --- a/code/chart.js +++ /dev/null @@ -1,4 +0,0 @@ -//DOM-selector for the canvas ๐Ÿ‘‡ -const ctx = document.getElementById('chart').getContext('2d') - -//"Draw" the chart here ๐Ÿ‘‡ diff --git a/code/index.html b/code/index.html deleted file mode 100644 index 2fb5e0ae..00000000 --- a/code/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Project GitHub Tracker - - - -

GitHub Tracker

-

Projects:

-
- - - - - - - - \ No newline at end of file diff --git a/code/script.js b/code/script.js deleted file mode 100644 index e69de29b..00000000 diff --git a/code/style.css b/code/style.css deleted file mode 100644 index 7c8ad447..00000000 --- a/code/style.css +++ /dev/null @@ -1,3 +0,0 @@ -body { - background: #FFECE9; -} \ No newline at end of file diff --git a/img/favicon.png b/img/favicon.png new file mode 100644 index 00000000..1176e028 Binary files /dev/null and b/img/favicon.png differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..03b69217 --- /dev/null +++ b/index.html @@ -0,0 +1,42 @@ + + + + + + + + Eyahya's GitHub Tracker + + + + + + + + + +
+

GitHub Tracker

+
+
+ + +
+
+
+ +
+
+ +
+ +
+ +
+ + + + + + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 00000000..870ea11c --- /dev/null +++ b/script.js @@ -0,0 +1,85 @@ +const USER = 'eyahya-khan' +const userContainer = document.getElementById('myProfile') +const searchField = document.getElementById('search-field') +const searchForm = document.getElementById('search-form') +const REPOS_URL = `https://api.github.com/users/${USER}/repos?per_page=100` +const USER_URL = `https://api.github.com/users/${USER}` +const projectsContainer = document.getElementById('projects') +const ldsripple = document.getElementById('loading') + +const Auth = { + method: 'GET', + headers: { + Authorization: `${API_TOKEN}` + } +} + +let repos; + +//profile image and info +const userProfile = () => { + fetch(USER_URL, Auth) + .then(res => res.json()) + .then(data => { + userContainer.innerHTML = ` +
+

${data.name}

+ @${data.login} +

${data.location}

+
+
+ ` + + }) +} +userProfile() + +const getRepos = () => { + fetch(REPOS_URL, Auth) + .then(response => response.json()) + .then(data => { + const forkedRepos = data.filter(repo => repo.fork && repo.name.startsWith('project-')) + getPullRequests(forkedRepos) + drawChart(forkedRepos.length) + }) +} +getRepos() + +//function to get the repos +const getPullRequests = (repos) => { + + projectsContainer.innerHTML = ''; + repos.forEach(repo => { + + fetch(`https://api.github.com/repos/Technigo/${repo.name}/pulls?per_page=100`, Auth) + .then(res => res.json()) + .then(data => { + + const myPullRequest = data.filter((pull) => { return pull.user.login === repo.owner.login }) + + const commitUrl = myPullRequest[0].commits_url + + fetch(commitUrl) + .then(res => res.json()) + .then(data => { + + const numberCommit = data.length + + //added function so the DOM do not self close tags + let boxHtml = `
`; + boxHtml += `

${repo.name}

` + boxHtml += `

Number of commits: ${numberCommit}

` + boxHtml += `

Created at: ${new Date(repo.created_at).toDateString()}

` + boxHtml += `

Last update: ${new Date(repo.pushed_at).toDateString()}

` + boxHtml += `

Default branch: ${repo.default_branch}

` + boxHtml += `

First comment: ${data[0].commit.message}

` + boxHtml += `

Last comment: ${data[numberCommit-1].commit.message}

` + boxHtml += `

Go to repo

` + boxHtml += '
' + projectsContainer.innerHTML += boxHtml; //closing the div tag + ldsripple.style.display = 'none' //loading icon + }) + + }) + }) +} diff --git a/style.css b/style.css new file mode 100644 index 00000000..1d34cf59 --- /dev/null +++ b/style.css @@ -0,0 +1,280 @@ +body { + background-color: #f0f0f0; + margin: 0; + padding: 0; + font-family: 'Barlow', sans-serif; +} + +/*header*/ +.header { + background-color: #125e91; + display: grid; + grid-column: span 12; + justify-content: center; +} + +.header-text { + color: #fff; + display: grid; + grid-column: span 2/8; + font-weight: 300; + font-size: 25px; +} + +form#search-form { + grid-column: span 12; + margin-bottom: 10px; +} + +.icon_header { + padding: 10px 0px 10px 0px; + height: 50px; + display: inline; + display: grid; + grid-column: span 8/12; +} + +/*search field*/ +.search-container { + grid-template-columns: repeat(12, 1fr); + grid-column: span 12; +} + +.input-field { + margin: 7px 0px 8px 0px; + grid-column: 1/12; + padding: 10px 20px; + border-radius: 15px; + font-size: 15px; + color: #7aa094; + border: 1px solid #7aa094; + font-family: 'Barlow', sans-serif; + font-weight: 500; +} + +.button-search { + margin: 7px 0px 7px 0px; + grid-column: 2/4; + padding: 10px 20px; + border-radius: 15px; + color: #fff; + background-color: #56786d; + font-size: 15px; + border: 1px solid #7aa094; + font-family: 'Barlow', sans-serif; + font-weight: 500; +} + +.button-search:hover { + color: #364b45; + background-color: #56786d; + font-weight: 500; +} + +/*main grid*/ +.main-grid { + display: grid; + grid-template-columns: repeat(12, 1fr); +} + +.grid-container { + display: grid; + grid-template-columns: repeat(12, 1fr); + grid-column: span 12; + column-gap: 10px; + row-gap: 10px; +} + +/*profile*/ +.my-profile { + background-color: #f0f0f0; + display: grid; + grid-template-columns: repeat(12, 1fr); + grid-column: span 12; + border-radius: 25px 0px; + margin: 15px 0px 15px 0px; +} + +.profileinfo { + background-color: #f0f0f0; + grid-column: span 2/4; +} + +.profileinfo a { + color: black; + text-decoration: none; +} + +.profileimg { + grid-column: 6/12; +} + +.profileimg img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 25px 0px; +} + +/*repos*/ +.box-repo { + padding: 10px; + background-color: #125e91; + display: grid; + grid-column: span 12; + border-radius: 25px 0px; +} + +.box-repo p { + text-align:center; + margin-block-start: 0em; + margin-block-end: 0.2em; + font-size: 16px; +} + +.box-repo h3 { + text-align:center; + margin-block-start: 0.2em; + margin-block-end: 0.3em; + font-size: 22px; +} + +.box-repo a { + text-align:center; + color: #fff; + text-decoration: none; + cursor: pointer; + font-size: 20px; +} + +/*chart*/ +.chart { + grid-column: span 12; + max-width: 100%; + max-height: 500px; + display: grid; +} + + +/*Loading icon*/ +.lds-ripple { + position: relative; + display: grid; + grid-column: 6/8; + width: 80px; + height: 80px; +} + +.lds-ripple div { + position: absolute; + border: 4px solid #125e91; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; +} + +.lds-ripple div:nth-child(2) { + animation-delay: -0.5s; +} + +@keyframes lds-ripple { + 0% { + top: 36px; + left: 36px; + width: 0; + height: 0; + opacity: 1; + } + 100% { + top: 0px; + left: 0px; + width: 72px; + height: 72px; + opacity: 0; + } +} + + +/* tablet */ +@media (min-width: 768px) { + .box-repo { + grid-column: span 6; + border-radius: 20px; + } + + .chart { + grid-column: 4/10; + } + + .my-profile { + grid-template-areas: ". info ." + ". image ."; + grid-template-columns: 4fr 4fr 4fr; + } + + .profileimg { + grid-area: image; + } + + .profileimg img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 20px; + } + + .profileinfo { + grid-column: span 5/11; + grid-area: info; + } + + .profileinfo h2 { + margin-block-start: 0.2em; + margin-block-end: 0.2em; + } + + .profileinfo p { + margin-block-start: 0.3em; + } + +} + +/* desktop */ +@media (min-width: 992px) { + + + .header { + display: grid; + grid-column: span 12; + } + + .my-profile { + grid-template-areas: ". info image"; + grid-template-columns: 4fr 4fr 4fr 4fr; + } + + .profileinfo { + text-align: right; + padding-right: 10px; + } + + .profileimg { + grid-area: image; + } + + .profileimg img { + max-height: 200px; + max-width: 200px; + + } + + .box-repo { + grid-column: span 4; + border-radius: 20px; + } + + .grid-container { + grid-column: 2/12; + } + +} \ No newline at end of file