From 42c52b05347a890174d14485a974d864a17aaefa Mon Sep 17 00:00:00 2001 From: Priscila Alfaro Date: Sun, 26 Sep 2021 20:13:20 +0200 Subject: [PATCH 1/5] html, css and basic javascript with logic related with api fetch --- README.md | 6 +- code/index.html | 25 +++++- code/script.js | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ code/style.css | 61 ++++++++++++++- 4 files changed, 287 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1613a3b0..87536284 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# GitHub Tracker +# Week 7- Technigo Bootcamp -Replace this readme with your own information about your project. +# Project GitHub Tracker -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +This week, we want you to create a place to keep track of the GitHub repos that you're using here at Technigo. You will continue practicing your JavaScript and API skills with the help of GitHub's own documentation. ## The problem diff --git a/code/index.html b/code/index.html index 2fb5e0ae..3902b3ba 100644 --- a/code/index.html +++ b/code/index.html @@ -1,5 +1,6 @@ + @@ -7,10 +8,27 @@ Project GitHub Tracker + -

GitHub Tracker

-

Projects:

-
+ +
+ +
+ +

GitHub Tracker

+ + +
+

User name:

+
+
+ + +
+ + +
+
@@ -18,4 +36,5 @@

Projects:

+ \ No newline at end of file diff --git a/code/script.js b/code/script.js index e69de29b..e383f2dc 100644 --- a/code/script.js +++ b/code/script.js @@ -0,0 +1,202 @@ + +//see: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token +const PAT = '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' +const username = "PriscilaAlfaro"; + +const projectsInfo = document.getElementById('projects-info'); +const userName = document.getElementById('user-name'); +const profileImage = document.getElementById('profile-image'); +// const pullRequest = document.getElementById('pull-request'); + +// const defaultBranch = document.getElementById('default-branch'); + + +const reposFetch = async () => { + try { + const response = await fetch(`https://api.github.com/users/${username}/repos`, { + headers: { + 'Authorization': `token ${PAT}` + }, + }); + if (response.ok) { + const repositories = await response.json(); + const forkedRepositories = repositories.filter(repo => repo.fork === true); + forkedRepositories.map(async repo => { + const allPullRequest = await pullRequestFetch(repo.name); + repo.allPullRequest = allPullRequest; + builRepoHtml(repo); + }) + + } else { + throw new Error('Request failed!') + } + } catch (error) { + console.log(`Error: ${error}`); + } +} + + +const builRepoHtml = (repo) => { + + console.log("repo", repo) + projectsInfo.innerHTML += + `
+
+

Project:

+

${repo.name}

+

Default branch:

+

${repo.default_branch}

+

Url:

+

${repo.url}

+
+ +
+

Pull requests

+
+

Total pullrequest ${repo.allPullRequest.total_count}

+ ${repo.allPullRequest.total_count === 0 ? + `

This repository don't have PR

` : repo.allPullRequest.items.map(pullRequest => + `

PullRequest #${pullRequest.number}

+ +
+
Commits
+ ${pullRequest.commits.length === 0 ? + `

This repository don't have commits for this PR

` : + pullRequest.commits.map(individualCommit => + `
    +
  1. Commit #${individualCommit.sha}
  2. +
  3. Message${individualCommit.commit.message}
  4. +
  5. Autor${individualCommit.commit.author.name}
  6. +
`).join('')} +
+ +
+
Comments
+ ${pullRequest.comments.length === 0 ? + `

This repository don't have comments for this PR

` : + pullRequest.comments.map(individualComment => + `
    +
  1. Created at ${individualComment.created_at}
  2. +
  3. Message${individualComment.body}
  4. +
  5. Autor${individualComment.user.login}
  6. +
`).join('')} +
` + )} +
+
+
` + +} + + + +const userNameFetch = async () => { + try { + const response = await fetch(`https://api.github.com/users/${username}`, { + headers: { + 'Authorization': `token ${PAT}` + }, + }); + if (response.ok) { + const data = await response.json(); + userName.innerHTML = `${data.login}`; + profileImage.src = `${data.avatar_url}`; + } else { + throw new Error('Request failed!') + } + + } catch (error) { + console.log(`Error: ${error}`); + } +} + + +//ultimo comit https://api.github.com/repos/PriscilaAlfaro/project-business-site/commits [0] primero es el ultimo commit /limit:30 default +//numero de commit messages contar el length + + + +const pullRequestFetch = async (repoName) => { + //see: https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests + const url = `https://api.github.com/search/issues?q=is:pr+repo:technigo/${repoName}+author:${username}`; + + try { + const response = await fetch(url, { + headers: { + 'Authorization': `token ${PAT}` + }, + }); + if (response.ok) { + const pullRequests = await response.json(); + await Promise.all(pullRequests.items.map(async pullRequest => { + pullRequest.comments = await fetchCommentsFromPullRequest(repoName, pullRequest.number); + pullRequest.commits = await fetchCommitsFromPullRequest(repoName, pullRequest.number); + return pullRequest; + })); + return pullRequests; + } else { + throw new Error('Request failed!') + } + + } catch (error) { + console.log(`Error: ${error}`); + } +} + +const fetchCommentsFromPullRequest = async (repoName, pullRequestNumber) => { + + try { + if (pullRequestNumber) { + const response = await fetch(`https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/comments`, { + headers: { + 'Authorization': `token ${PAT}` + }, + }); + if (response.ok) { + const pullRequestComments = await response.json(); + // console.log("pullRequestComments from origin", pullRequestComments) + + // gitHubInformation.pullRequestComments += pullRequestComments; + // if (pullRequestComments.items.length > 0 && pullRequestComments.items[0].comments === 0) { + // return [{ body: 'No comments', user: { login: "No commenter" } }] + // } + return pullRequestComments; + + } else { + throw new Error('Request failed!') + + } + + } else { + return [{ body: 'No comments', user: { login: "No commenter" } }] + } + + } catch (error) { + console.log(`Error: ${error}`); + } +} + + +const fetchCommitsFromPullRequest = async (repoName, pullRequestNumber) => { + + try { + const response = await fetch(`https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/commits`, { + headers: { + 'Authorization': `token ${PAT}` + }, + }); + if (response.ok) { + const commits = await response.json() + return commits; + + } else { + throw new Error('Request failed!') + } + + } catch (error) { + console.log(`Error: ${error}`); + } +} + +reposFetch(); +userNameFetch(); diff --git a/code/style.css b/code/style.css index 7c8ad447..4dce3c6d 100644 --- a/code/style.css +++ b/code/style.css @@ -1,3 +1,62 @@ body { - background: #FFECE9; + background: #FFECE9; +} + +.general-info{ + background-color: rgb(194, 138, 235); + padding: 20px; + display: flex; + justify-content:flex-start; + flex-direction: column; +} + +.general-title{ + font-weight: 600; +} + +.profile-image{ + max-width: 100px; + max-height: 100px; + border-radius: 50%; +} + +.profile-info-wraper{ + margin-left: 10px; + display: grid; +} + +.main-section{ + border: 1px solid blue +} + + +.projects-info { + background-color: aquamarine; + border: 1px solid red; + display: flex; + margin: 10px; +} + +.card{ + background-color: palegoldenrod; + border: 1px solid black; + display: flex; + margin: 10px; +} + +@media screen and (min-width: 768px){ + .general-title { + width: 100%; + +} + +.general-info{ + flex-direction: row; +} + + +} + +@media screen and (min-width: 991px){ + } \ No newline at end of file From 86538b86fedd5dd815ed4b28197032ae3cfb577f Mon Sep 17 00:00:00 2001 From: Priscila Alfaro Date: Thu, 30 Sep 2021 21:15:00 +0200 Subject: [PATCH 2/5] adding style changes and collapsible library --- .DS_Store | Bin 0 -> 6148 bytes .env | 1 + code/chart.js | 42 +++++++ code/collapsible.js | 283 ++++++++++++++++++++++++++++++++++++++++++++ code/index.html | 19 ++- code/script.js | 114 ++++++++++-------- code/style.css | 89 ++++++++++++-- package-lock.json | 11 ++ 8 files changed, 496 insertions(+), 63 deletions(-) create mode 100644 .DS_Store create mode 100644 .env create mode 100644 code/collapsible.js create mode 100644 package-lock.json diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0647067d3a4b3d9ddba218a9021dd0b97e5ff93a GIT binary patch literal 6148 zcmeH~F$w}f3`G;&V!>uh%V|7-HyA`u-~|K~8*xF)z$?L_2URHKLJSWDxSmLu%B!J&7q|#Dlq;CI0gn1_$q-1 Dp;i*E literal 0 HcmV?d00001 diff --git a/.env b/.env new file mode 100644 index 00000000..b20c379c --- /dev/null +++ b/.env @@ -0,0 +1 @@ +TOKEN = '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' \ No newline at end of file diff --git a/code/chart.js b/code/chart.js index 92e85a30..1017f0f5 100644 --- a/code/chart.js +++ b/code/chart.js @@ -2,3 +2,45 @@ const ctx = document.getElementById('chart').getContext('2d') //"Draw" the chart here 👇 +const drawChart = (numberOfFinishedProjects) => { + config = { + type: 'pie', + data: { + labels: ['Finished Projects', 'Left Projects'], + datasets: [{ + label: 'Technigo Projects', + data: [numberOfFinishedProjects, 20 - numberOfFinishedProjects], + backgroundColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + ], + borderColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + ], + borderWidth: 1 + }] + }, + options: { + plugins: { + title: { + display: true, + text: "Comparison Technigo Project left-projects built", + position: 'top', + padding: { + top: 10, + bottom: 20 + } + } + } + + } + + } + const myChart = new Chart(ctx, config); +} + + + + + diff --git a/code/collapsible.js b/code/collapsible.js new file mode 100644 index 00000000..a47da6f7 --- /dev/null +++ b/code/collapsible.js @@ -0,0 +1,283 @@ +/** + * Collapsible - A plug and play plugin for expanding and + * collapsing elements (i.e. accordion) on a website. + * + * @author Murtada al Mousawy (https://murtada.nl) + */ +(function() { + 'use strict'; + + /** + * Creates an instance of Collapsible. + * + * @constructor + * @param {Object} options + * @param {(HTMLElement|NodeList)} options.node The HTML elements that will be manipulated. + * @param {HTMLElement} [options.eventNode] The HTML element on which the eventListener will be attached. + * @param {Boolean} [options.isCollapsed] Assign the state of the node element. + * @param {Boolean} [options.observe] Assign a MutationObserver to observe child DOM changes. + * @param {Function} [options.expandCallback] Assign a callback for the [{@link Collapsible.prototype.expand} event. + * @param {Function} [options.collapseCallback] Assign a callback for the {@link Collapsible.prototype.collapse} event. + * @param {Function} [options.observeCallback] Assign a callback for the {@link Collapsible.prototype.initObserver} event. + */ + var Collapsible = function(options) { + // Initialize HTML nodes + if (NodeList.prototype.isPrototypeOf(options.node)) { + options.node.forEach(function(nodeItem) { + var singleNodeOptions = options; + singleNodeOptions.node = nodeItem; + new Collapsible(singleNodeOptions); + }); + return; + } else if (options.node instanceof HTMLElement) { + this.node = options.node; + this.eventNode = (options.eventNode ? this.node.querySelector(options.eventNode) : this.node); + this.isCollapsed = (typeof this.node.dataset.collapsibleCollapsed !== 'undefined' + ? true + : null); + + if (!this.isCollapsed) { + this.isCollapsed = ((options.isCollapsed + && typeof options.isCollapsed === 'boolean') + ? options.isCollapsed + : false); + } + + this.observe = (typeof options.observe === 'boolean' ? options.observe : false); + this.expandCallback = (typeof options.expandCallback === 'function' ? options.expandCallback : null); + this.collapseCallback = (typeof options.collapseCallback === 'function' ? options.collapseCallback : null); + this.observeCallback = (typeof options.observeCallback === 'function' ? options.observeCallback : null); + this.mutationCallback = (typeof options.mutationCallback === 'function' ? options.mutationCallback : null); + + this.init(); + } else { + console.error(options.node, 'is not a NodeList or an instance of HTMLElement'); + } + }; + + /** + * Initialize the collapsing and expanding events. + */ + Collapsible.prototype.init = function() { + this.updateHeights(); + + if (this.isCollapsed) { + this.node.style.height = this.collapsedHeight + 'px'; + this.node.classList.add('is-collapsed'); + } else { + this.node.classList.add('is-expanded'); + } + + this.eventNode.addEventListener('click', function() { + this.toggleCollapse(); + }.bind(this)); + + window.addEventListener('resize', this.updateHeights.bind(this, null)); + + // Observe children of the node + if (this.observe) { + this.initObserver(); + } + + // Attach the prototype instance to the node + this.node.collapsible = this; + }; + + /** + * Update the collapsed and expanded heights on page resize. + * + * @param {int} [heightDifference] Height value to add or subtract from the parent. + */ + Collapsible.prototype.updateHeights = function(heightDifference) { + heightDifference = heightDifference || 0; + + // Calculate the collapsed height + this.collapsedHeight = Collapsible.parseNumber( + window.getComputedStyle(this.eventNode)['height'] + ); + + // Calculate the expanded height + this.node.style.height = 'auto'; + + this.expandedHeight = Collapsible.parseNumber( + window.getComputedStyle(this.node)['height'] + ); + + // Add or subtract the childNode's height difference + this.expandedHeight += heightDifference; + this.expandedHeight = Math.max(this.expandedHeight, this.collapsedHeight); + + // Reset height to what it was before + if (this.isCollapsed) { + this.node.style.height = this.collapsedHeight + 'px'; + } + + this.updateParentNode(this.expandedHeight - this.collapsedHeight); + }; + + /** + * Toggle the node state and calls the appropriate function. + */ + Collapsible.prototype.toggleCollapse = function() { + if (this.isCollapsed) { + this.expand(); + } else { + this.collapse(); + } + }; + + /** + * Expand the node. + */ + Collapsible.prototype.expand = function() { + this.updateHeights(); + + void this.node.offsetWidth; + + this.node.style.height = 'auto'; + this.node.style.height = this.expandedHeight + 'px'; + this.node.classList.remove('is-collapsed'); + this.node.classList.add('is-expanded'); + + this.isCollapsed = false; + + // Create a custom event + var expandEvent = new CustomEvent('toggle', { + bubbles: true, + detail: { + action: 'expand', + origin: this.eventNode + } + }); + + this.node.dispatchEvent(expandEvent); + + // Run callback if it exists + if (this.expandCallback) { + this.expandCallback.bind(this, expandEvent)(); + } + + this.updateParentNode(this.expandedHeight - this.collapsedHeight); + }; + + /** + * Collapse the node. + */ + Collapsible.prototype.collapse = function() { + this.node.style.height = window.getComputedStyle(this.node)['height']; + + void this.node.offsetWidth; + + this.node.style.height = this.collapsedHeight + 'px'; + this.node.classList.remove('is-expanded'); + this.node.classList.add('is-collapsed'); + + this.isCollapsed = true; + + // Create a custom event + var collapseEvent = new CustomEvent('toggle', { + bubbles: true, + detail: { + action: 'collapse', + origin: this.eventNode + } + }); + + this.node.dispatchEvent(collapseEvent); + + // Run callback if it exists + if (this.collapseCallback) { + this.collapseCallback.bind(this, collapseEvent)(); + } + + this.updateParentNode(-(this.expandedHeight - this.collapsedHeight)); + }; + + /** + * Update parent heights if collapsible. + * + * @see {@link Collapsible.prototype.updateHeights} + */ + Collapsible.prototype.updateParentNode = function(heightDifference) { + if (this.node.parentNode && this.node.parentNode.collapsible) { + this.node.parentNode.collapsible.updateHeights(heightDifference); + } + }; + + /** + * Observe the direct children list of the node. + * Will adjust the expanded height automatically if necessary. + */ + Collapsible.prototype.initObserver = function() { + this.mutationObserver = new window.MutationObserver(function(mutationsList) { + var mutatedNode, + mutationAction; + + if (mutationsList[0]['addedNodes'].length > 0) { + mutationAction = 'add'; + mutatedNode = mutationsList[0]['addedNodes'][0]; + } else { + mutationAction = 'remove'; + mutatedNode = mutationsList[0]['removedNodes'][0]; + } + + if (!this.isCollapsed) { + var mutatedNodeStyle = window.getComputedStyle(mutatedNode); + + var mutatedNodeHeight = + Collapsible.parseNumber( + mutatedNodeStyle['height']) + + Collapsible.parseNumber( + mutatedNodeStyle['margin-top']) + + Collapsible.parseNumber( + mutatedNodeStyle['margin-bottom']); + + this.node.style.height = 'auto'; + + var currentHeight = Collapsible.parseNumber( + window.getComputedStyle(this.node)['height'] + ); + + if (mutationAction == 'add') { + this.node.style.height = (currentHeight - mutatedNodeHeight) + 'px'; + void this.node.offsetWidth; + this.node.style.height = currentHeight + 'px'; + } else { + this.node.style.height = this.expandedHeight + 'px'; + void this.node.offsetWidth; + this.node.style.height = currentHeight + 'px'; + } + } + + this.expandedHeight = currentHeight; + + // Create a custom event + var mutationEvent = new CustomEvent('mutate', { + bubbles: true, + detail: { + action: mutationAction, + node: mutatedNode + } + }); + + this.node.dispatchEvent(mutationEvent); + + // Run callback if it exists + if (this.mutationCallback) { + this.mutationCallback.bind(this, mutationEvent)(); + } + }.bind(this)); + + this.mutationObserver.observe(this.node, { + childList: true + }); + }; + + // Helper functions + Collapsible.parseNumber = function(numberString) { + return Number.parseInt(numberString.slice(0, -2)); + }; + + // Expose the prototype function to the global scope + window.Collapsible = Collapsible; +})(); diff --git a/code/index.html b/code/index.html index 3902b3ba..75b184b9 100644 --- a/code/index.html +++ b/code/index.html @@ -7,6 +7,7 @@ Project GitHub Tracker + @@ -26,13 +27,25 @@

User name:

-
+ - - +
+ +
+ + + diff --git a/code/script.js b/code/script.js index e383f2dc..6f2d38cf 100644 --- a/code/script.js +++ b/code/script.js @@ -1,30 +1,38 @@ //see: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token -const PAT = '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' +// require('dotenv').config(); + +const PersonalAccessToken = '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' +console.log("PersonalAccessToken", PersonalAccessToken) const username = "PriscilaAlfaro"; const projectsInfo = document.getElementById('projects-info'); const userName = document.getElementById('user-name'); const profileImage = document.getElementById('profile-image'); -// const pullRequest = document.getElementById('pull-request'); - -// const defaultBranch = document.getElementById('default-branch'); - const reposFetch = async () => { try { + const response = await fetch(`https://api.github.com/users/${username}/repos`, { headers: { - 'Authorization': `token ${PAT}` + 'Authorization': `token ${PersonalAccessToken}` }, }); if (response.ok) { const repositories = await response.json(); - const forkedRepositories = repositories.filter(repo => repo.fork === true); + const forkedRepositories = repositories.filter(repo => repo.fork && repo.name.includes("project-")); + drawChart(forkedRepositories.length); + forkedRepositories.map(async repo => { const allPullRequest = await pullRequestFetch(repo.name); repo.allPullRequest = allPullRequest; builRepoHtml(repo); + + new Collapsible({ + node: document.querySelectorAll('.collapsible'), + eventNode: '.collapsible_title', + isCollapsed: true + }); }) } else { @@ -37,54 +45,58 @@ const reposFetch = async () => { const builRepoHtml = (repo) => { - - console.log("repo", repo) projectsInfo.innerHTML += `
-
-

Project:

-

${repo.name}

-

Default branch:

-

${repo.default_branch}

-

Url:

-

${repo.url}

+ -
-

Pull requests

-
-

Total pullrequest ${repo.allPullRequest.total_count}

+ + +
+

Pull requests

+
+

Total pullrequest: ${repo.allPullRequest.total_count}

${repo.allPullRequest.total_count === 0 ? - `

This repository don't have PR

` : repo.allPullRequest.items.map(pullRequest => - `

PullRequest #${pullRequest.number}

- -
-
Commits
+ `

This repository don't any have Pull Request

` : + repo.allPullRequest.items.map(pullRequest => + `

Pull Request #${pullRequest.number}

${pullRequest.commits.length === 0 ? - `

This repository don't have commits for this PR

` : - pullRequest.commits.map(individualCommit => - `
    -
  1. Commit #${individualCommit.sha}
  2. -
  3. Message${individualCommit.commit.message}
  4. -
  5. Autor${individualCommit.commit.author.name}
  6. -
`).join('')} + `

This repository don't have commits for this PR

` : + `
+
+
+
    + ${pullRequest.commits.map(individualCommit => + `
  1. +
    Commit #: ${individualCommit.sha}
    +
    Message: ${individualCommit.commit.message}
    +
    Autor: ${individualCommit.commit.author.name}
    +
  2. `).join('') + } +
- -
-
Comments
- ${pullRequest.comments.length === 0 ? - `

This repository don't have comments for this PR

` : - pullRequest.comments.map(individualComment => - `
    -
  1. Created at ${individualComment.created_at}
  2. -
  3. Message${individualComment.body}
  4. -
  5. Autor${individualComment.user.login}
  6. -
`).join('')} -
` - )}
+
+
+
+
    + ${pullRequest.comments.map(individualComment => + `
  1. +
    Created at: ${new Date(individualComment.created_at).toDateString()}
    +
    Message: ${individualComment.body}
    +
    Autor: ${individualComment.user.login}
    +
  2. `).join('') + } +
-
` +
`} +
` + )} +
+
` } @@ -94,7 +106,7 @@ const userNameFetch = async () => { try { const response = await fetch(`https://api.github.com/users/${username}`, { headers: { - 'Authorization': `token ${PAT}` + 'Authorization': `token ${PersonalAccessToken}` }, }); if (response.ok) { @@ -123,7 +135,7 @@ const pullRequestFetch = async (repoName) => { try { const response = await fetch(url, { headers: { - 'Authorization': `token ${PAT}` + 'Authorization': `token ${PersonalAccessToken}` }, }); if (response.ok) { @@ -149,7 +161,7 @@ const fetchCommentsFromPullRequest = async (repoName, pullRequestNumber) => { if (pullRequestNumber) { const response = await fetch(`https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/comments`, { headers: { - 'Authorization': `token ${PAT}` + 'Authorization': `token ${PersonalAccessToken}` }, }); if (response.ok) { @@ -182,7 +194,7 @@ const fetchCommitsFromPullRequest = async (repoName, pullRequestNumber) => { try { const response = await fetch(`https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/commits`, { headers: { - 'Authorization': `token ${PAT}` + 'Authorization': `token ${PersonalAccessToken}` }, }); if (response.ok) { @@ -198,5 +210,7 @@ const fetchCommitsFromPullRequest = async (repoName, pullRequestNumber) => { } } + + reposFetch(); userNameFetch(); diff --git a/code/style.css b/code/style.css index 4dce3c6d..3aeb84ab 100644 --- a/code/style.css +++ b/code/style.css @@ -1,13 +1,30 @@ body { background: #FFECE9; + font-family: Arial, Helvetica, sans-serif; + margin: 0px +} + +.main-section{ + border: 1px solid blue; + + } .general-info{ - background-color: rgb(194, 138, 235); + background-color: rgb(25, 23, 27); + color: white; + width: auto; padding: 20px; - display: flex; - justify-content:flex-start; - flex-direction: column; +} + + +.project-title{ + background-color: rgb(21, 3, 63); + width: 100%; +} + +.pr-info{ + padding: 10px 20px; } .general-title{ @@ -18,6 +35,8 @@ body { max-width: 100px; max-height: 100px; border-radius: 50%; + border: 2px solid white; + justify-content: center; } .profile-info-wraper{ @@ -25,23 +44,70 @@ body { display: grid; } -.main-section{ - border: 1px solid blue -} .projects-info { - background-color: aquamarine; + background-color: rgb(138, 161, 154); border: 1px solid red; display: flex; margin: 10px; + display: inline-flex; + align-items: center; + flex-direction: row; + justify-content: center; + flex-wrap: wrap; } .card{ - background-color: palegoldenrod; + background-color:rgb(197, 206, 236); border: 1px solid black; display: flex; - margin: 10px; + flex-direction: row; + flex-wrap: wrap; + width: 400px; + height: auto; + font-size: 60%; + box-shadow: 0px 0px 5px 1px gray; + margin: 20px 0px; +} + +.collapsible{ + overflow: hidden; + background-color:rgb(197, 206, 236); + + +} + +.collapsible_title { + color: darkgrey; + height: auto; + display: grid; + width: 160px; +} + +.collapsible_content{ + background-color:rgb(197, 206, 236); +} + +.chart{ + display: flex; + width: 80%; + padding: 30px; + border: 1px solid black; + margin: 30px auto; +} + + +.footer{ + background-color: rgb(12, 10, 19); + margin-top: 3rem; + padding: 1rem 0rem; + display: grid; + justify-content: center; + font-size: small; + font-style: italic; + text-align: center; + color: white } @media screen and (min-width: 768px){ @@ -54,6 +120,9 @@ body { flex-direction: row; } +.chart{ + width: 40%; +} } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..fec92a5c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + } + } +} From fde07280d63329c82e199297e5a4e0fac99df7f7 Mon Sep 17 00:00:00 2001 From: Priscila Alfaro Date: Fri, 1 Oct 2021 20:58:13 +0200 Subject: [PATCH 3/5] css style and adjustments to html --- code/chart.js | 4 +- code/index.html | 18 +++--- code/script.js | 25 ++++++--- code/style.css | 121 ++++++++++++++++++++++++++--------------- images/github-icon.svg | 1 + 5 files changed, 108 insertions(+), 61 deletions(-) create mode 100644 images/github-icon.svg diff --git a/code/chart.js b/code/chart.js index 1017f0f5..09d1f479 100644 --- a/code/chart.js +++ b/code/chart.js @@ -6,7 +6,7 @@ const drawChart = (numberOfFinishedProjects) => { config = { type: 'pie', data: { - labels: ['Finished Projects', 'Left Projects'], + labels: ['Finished Projects', 'Projects Left'], datasets: [{ label: 'Technigo Projects', data: [numberOfFinishedProjects, 20 - numberOfFinishedProjects], @@ -25,7 +25,7 @@ const drawChart = (numberOfFinishedProjects) => { plugins: { title: { display: true, - text: "Comparison Technigo Project left-projects built", + text: "Comparison Technigo Course Finished projects vs Projects left", position: 'top', padding: { top: 10, diff --git a/code/index.html b/code/index.html index 75b184b9..8b49f031 100644 --- a/code/index.html +++ b/code/index.html @@ -12,37 +12,39 @@ -
- +

GitHub Tracker

-
-

User name:

+

+
Junior Full Stack Engineer
+
Stockholm, Sweden
+
-
- -
+
+
+
-
diff --git a/code/script.js b/code/script.js index 6f2d38cf..c030afd1 100644 --- a/code/script.js +++ b/code/script.js @@ -39,6 +39,7 @@ const reposFetch = async () => { throw new Error('Request failed!') } } catch (error) { + main - section console.log(`Error: ${error}`); } } @@ -48,16 +49,17 @@ const builRepoHtml = (repo) => { projectsInfo.innerHTML += `
-

Pull requests

-
+

Pull requests

+

Total pullrequest: ${repo.allPullRequest.total_count}

${repo.allPullRequest.total_count === 0 ? `

This repository don't any have Pull Request

` : @@ -65,8 +67,11 @@ const builRepoHtml = (repo) => { `

Pull Request #${pullRequest.number}

${pullRequest.commits.length === 0 ? `

This repository don't have commits for this PR

` : - `
-
+ `

Total commits: ${pullRequest.commits.length}

+
+
+

Click here for commits details

+
    ${pullRequest.commits.map(individualCommit => @@ -79,8 +84,13 @@ const builRepoHtml = (repo) => {
+ + +

Total comments: ${pullRequest.comments.length}

-
+
+

Click here for comments details

+
    ${pullRequest.comments.map(individualComment => @@ -93,8 +103,7 @@ const builRepoHtml = (repo) => {
`} -
` - )} + `)}
` diff --git a/code/style.css b/code/style.css index 3aeb84ab..cfb76f49 100644 --- a/code/style.css +++ b/code/style.css @@ -1,26 +1,28 @@ body { - background: #FFECE9; + background-color: rgb(182 185 194); font-family: Arial, Helvetica, sans-serif; - margin: 0px + margin: 0px } .main-section{ - border: 1px solid blue; - - + padding: 15px; } .general-info{ - background-color: rgb(25, 23, 27); + background-color: rgb(92 92 93); color: white; width: auto; - padding: 20px; + text-align: -webkit-center; + padding: 20px 0px; } .project-title{ - background-color: rgb(21, 3, 63); + background-color: rgb(38 117 120); width: 100%; + border-radius: 3%; + margin: 0px; + padding: 20px; } .pr-info{ @@ -37,45 +39,41 @@ body { border-radius: 50%; border: 2px solid white; justify-content: center; -} +} .profile-info-wraper{ - margin-left: 10px; display: grid; } - +.general-info h1, h4, h5{ + margin: 0px; + padding: 3px; +} .projects-info { - background-color: rgb(138, 161, 154); - border: 1px solid red; display: flex; - margin: 10px; - display: inline-flex; - align-items: center; - flex-direction: row; - justify-content: center; - flex-wrap: wrap; } .card{ - background-color:rgb(197, 206, 236); + background-color:rgb(210 208 227); border: 1px solid black; display: flex; - flex-direction: row; flex-wrap: wrap; - width: 400px; + width: 80% auto; height: auto; - font-size: 60%; - box-shadow: 0px 0px 5px 1px gray; + box-sizing: border-box; + margin: 10px; + box-shadow: 0px 0px 5px 1px rgb(39, 38, 38); margin: 20px 0px; + border-radius: 3%; + font-size: 60%; + text-align: center; + justify-content: center; } .collapsible{ overflow: hidden; - background-color:rgb(197, 206, 236); - - + text-align: -webkit-center; } .collapsible_title { @@ -83,49 +81,86 @@ body { height: auto; display: grid; width: 160px; + cursor: pointer; } .collapsible_content{ background-color:rgb(197, 206, 236); + text-align: -webkit-auto; + max-width: 80%; } .chart{ display: flex; - width: 80%; + width: 75%; padding: 30px; border: 1px solid black; - margin: 30px auto; + margin: 40px auto; + background-color: #d2d9df; } .footer{ - background-color: rgb(12, 10, 19); - margin-top: 3rem; - padding: 1rem 0rem; - display: grid; - justify-content: center; - font-size: small; - font-style: italic; - text-align: center; - color: white + background-color: rgb(92 92 93); + margin-top: 3rem; + padding: 1rem 0rem; + display: grid; + justify-content: center; + font-size: small; + font-style: italic; + text-align: center; + color: white +} +.github-icon{ + justify-self: center; } @media screen and (min-width: 768px){ - .general-title { - width: 100%; - +.general-title { + min-width: 309px; } .general-info{ - flex-direction: row; + flex-direction: row; } .chart{ width: 40%; } +.projects-info{ + flex-direction: column; } -@media screen and (min-width: 991px){ +.project-title{ + max-width: 35%; + min-width: 35%; + border-radius: 0; +} + +.main-section{ + margin: 20px 120px; +} + +.card{ + margin: 30px; + flex-wrap: nowrap; + border-radius: 0; + text-align: justify; + justify-content: right; +} + +.collapsible{ + text-align: left; +} +.collapsible_title { + width: 200px; +} +} + +@media screen and (min-width: 991px){ +.main-section{ + margin: 20px 180px; +} } \ No newline at end of file diff --git a/images/github-icon.svg b/images/github-icon.svg new file mode 100644 index 00000000..a3fcb98d --- /dev/null +++ b/images/github-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file From 1d6b7c8391aed3cd7ee400a7b1a8fb39a89daf35 Mon Sep 17 00:00:00 2001 From: Priscila Alfaro Date: Sat, 2 Oct 2021 17:57:10 +0200 Subject: [PATCH 4/5] adding styles and icons --- .env | 1 - README.md | 10 +++++-- code/chart.js | 8 ++--- code/index.html | 23 ++++++++------- code/script.js | 75 ++++++++++------------------------------------- code/style.css | 15 +++++++--- package-lock.json | 11 ------- 7 files changed, 52 insertions(+), 91 deletions(-) delete mode 100644 .env delete mode 100644 package-lock.json diff --git a/.env b/.env deleted file mode 100644 index b20c379c..00000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -TOKEN = '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' \ No newline at end of file diff --git a/README.md b/README.md index 87536284..79044b89 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,14 @@ This week, we want you to create a place to keep track of the GitHub repos that ## 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? +This week the first step was to read the documentation of Github API to understand what every endpoint was about. Then I started fetching basic information and adding new functions, endpoints, and iterations in JavaScript. + +I used the `async/await` instead of `.then( )` approach to practice more about it. An interesting experience this week was digging more into promises, and how to await several promises using `Promise.all`. + +I also used an independent library for vanilla Javascript as a collapsible toggle to show details for commits and comments for every Pull Request. (See `https://www.cssscript.com/content-toggle-collapsible/`). + +Also was very interesting using the open-source `Chart.js` to create the chart about how many projects we finished and how many projects left at the Technigo course. (See `https://www.chartjs.org/docs/latest/`) ## 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. +Here is the Netlify link: diff --git a/code/chart.js b/code/chart.js index 09d1f479..63e54c02 100644 --- a/code/chart.js +++ b/code/chart.js @@ -11,12 +11,12 @@ const drawChart = (numberOfFinishedProjects) => { label: 'Technigo Projects', data: [numberOfFinishedProjects, 20 - numberOfFinishedProjects], backgroundColor: [ - 'rgba(255, 99, 132, 1)', - 'rgba(54, 162, 235, 1)', + 'rgba(223, 198, 124, 1)', + 'rgba(63, 111, 166, 1)', ], borderColor: [ - 'rgba(255, 99, 132, 1)', - 'rgba(54, 162, 235, 1)', + 'rgba(223, 198, 104, 1)', + 'rgba(63, 111, 144, 1)', ], borderWidth: 1 }] diff --git a/code/index.html b/code/index.html index 8b49f031..051655ae 100644 --- a/code/index.html +++ b/code/index.html @@ -8,19 +8,22 @@ Project GitHub Tracker + + + +
-
+

GitHub Tracker

-
Junior Full Stack Engineer
-
Stockholm, Sweden
+  Stockholm, Sweden
@@ -37,15 +40,15 @@
Stockholm, Sweden
diff --git a/code/script.js b/code/script.js index c030afd1..e856912c 100644 --- a/code/script.js +++ b/code/script.js @@ -1,23 +1,13 @@ -//see: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token -// require('dotenv').config(); - -const PersonalAccessToken = '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' -console.log("PersonalAccessToken", PersonalAccessToken) const username = "PriscilaAlfaro"; - const projectsInfo = document.getElementById('projects-info'); const userName = document.getElementById('user-name'); const profileImage = document.getElementById('profile-image'); const reposFetch = async () => { + const url = `https://api.github.com/users/${username}/repos` try { - - const response = await fetch(`https://api.github.com/users/${username}/repos`, { - headers: { - 'Authorization': `token ${PersonalAccessToken}` - }, - }); + const response = await fetch(url) if (response.ok) { const repositories = await response.json(); const forkedRepositories = repositories.filter(repo => repo.fork && repo.name.includes("project-")); @@ -49,17 +39,14 @@ const builRepoHtml = (repo) => { projectsInfo.innerHTML += `
- -

Pull requests

-

Total pullrequest: ${repo.allPullRequest.total_count}

${repo.allPullRequest.total_count === 0 ? `

This repository don't any have Pull Request

` : @@ -67,6 +54,8 @@ const builRepoHtml = (repo) => { `

Pull Request #${pullRequest.number}

${pullRequest.commits.length === 0 ? `

This repository don't have commits for this PR

` : + + `

Total commits: ${pullRequest.commits.length}

@@ -83,10 +72,11 @@ const builRepoHtml = (repo) => { }
-
+
`} - -

Total comments: ${pullRequest.comments.length}

+ ${pullRequest.comments.length === 0 ? + `

This repository don't have comments for this PR

` : + `

Total comments: ${pullRequest.comments.length}

Click here for comments details

@@ -112,12 +102,9 @@ const builRepoHtml = (repo) => { const userNameFetch = async () => { + const url = `https://api.github.com/users/${username}`; try { - const response = await fetch(`https://api.github.com/users/${username}`, { - headers: { - 'Authorization': `token ${PersonalAccessToken}` - }, - }); + const response = await fetch(url) if (response.ok) { const data = await response.json(); userName.innerHTML = `${data.login}`; @@ -125,28 +112,18 @@ const userNameFetch = async () => { } else { throw new Error('Request failed!') } - } catch (error) { console.log(`Error: ${error}`); } } -//ultimo comit https://api.github.com/repos/PriscilaAlfaro/project-business-site/commits [0] primero es el ultimo commit /limit:30 default -//numero de commit messages contar el length - - - const pullRequestFetch = async (repoName) => { //see: https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests const url = `https://api.github.com/search/issues?q=is:pr+repo:technigo/${repoName}+author:${username}`; try { - const response = await fetch(url, { - headers: { - 'Authorization': `token ${PersonalAccessToken}` - }, - }); + const response = await fetch(url) if (response.ok) { const pullRequests = await response.json(); await Promise.all(pullRequests.items.map(async pullRequest => { @@ -158,40 +135,25 @@ const pullRequestFetch = async (repoName) => { } else { throw new Error('Request failed!') } - } catch (error) { console.log(`Error: ${error}`); } } const fetchCommentsFromPullRequest = async (repoName, pullRequestNumber) => { - + const url = `https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/comments` try { if (pullRequestNumber) { - const response = await fetch(`https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/comments`, { - headers: { - 'Authorization': `token ${PersonalAccessToken}` - }, - }); + const response = await fetch(url) if (response.ok) { const pullRequestComments = await response.json(); - // console.log("pullRequestComments from origin", pullRequestComments) - - // gitHubInformation.pullRequestComments += pullRequestComments; - // if (pullRequestComments.items.length > 0 && pullRequestComments.items[0].comments === 0) { - // return [{ body: 'No comments', user: { login: "No commenter" } }] - // } return pullRequestComments; - } else { throw new Error('Request failed!') - } - } else { return [{ body: 'No comments', user: { login: "No commenter" } }] } - } catch (error) { console.log(`Error: ${error}`); } @@ -199,17 +161,12 @@ const fetchCommentsFromPullRequest = async (repoName, pullRequestNumber) => { const fetchCommitsFromPullRequest = async (repoName, pullRequestNumber) => { - + const url = `https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/commits` try { - const response = await fetch(`https://api.github.com/repos/Technigo/${repoName}/pulls/${pullRequestNumber}/commits`, { - headers: { - 'Authorization': `token ${PersonalAccessToken}` - }, - }); + const response = await fetch(url) if (response.ok) { const commits = await response.json() return commits; - } else { throw new Error('Request failed!') } diff --git a/code/style.css b/code/style.css index cfb76f49..7ffc8167 100644 --- a/code/style.css +++ b/code/style.css @@ -1,6 +1,6 @@ body { background-color: rgb(182 185 194); - font-family: Arial, Helvetica, sans-serif; + font-family: 'Signika Negative', sans-serif; margin: 0px } @@ -9,7 +9,7 @@ body { } .general-info{ - background-color: rgb(92 92 93); + background-color: rgb(56 69 114); color: white; width: auto; text-align: -webkit-center; @@ -27,6 +27,8 @@ body { .pr-info{ padding: 10px 20px; + font-size: 1rem; + font-size: 100%; } .general-title{ @@ -69,6 +71,7 @@ body { font-size: 60%; text-align: center; justify-content: center; + border: 3px solid #6b6b78; } .collapsible{ @@ -77,11 +80,14 @@ body { } .collapsible_title { - color: darkgrey; + color: black; + font-style: italic; height: auto; display: grid; width: 160px; cursor: pointer; + font-size: 90%; + } .collapsible_content{ @@ -97,11 +103,12 @@ body { border: 1px solid black; margin: 40px auto; background-color: #d2d9df; + border: 3px solid #6b6b78; } .footer{ - background-color: rgb(92 92 93); + background-color: rgb(56 69 114); margin-top: 3rem; padding: 1rem 0rem; display: grid; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index fec92a5c..00000000 --- a/package-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - } - } -} From 40e9c5329b7852ceab37a9811b96c2eeb1dd0c23 Mon Sep 17 00:00:00 2001 From: Priscila Alfaro Date: Sat, 2 Oct 2021 18:04:24 +0200 Subject: [PATCH 5/5] add deploy site and change image file --- README.md | 2 +- {images => code/images}/github-icon.svg | 0 code/index.html | 5 +++-- 3 files changed, 4 insertions(+), 3 deletions(-) rename {images => code/images}/github-icon.svg (100%) diff --git a/README.md b/README.md index 79044b89..471cf32e 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,4 @@ Also was very interesting using the open-source `Chart.js` to create the chart a ## View it live -Here is the Netlify link: +Here is the Netlify link: https://project-github-tracker.netlify.app/ diff --git a/images/github-icon.svg b/code/images/github-icon.svg similarity index 100% rename from images/github-icon.svg rename to code/images/github-icon.svg diff --git a/code/index.html b/code/index.html index 051655ae..1cf26ec3 100644 --- a/code/index.html +++ b/code/index.html @@ -40,12 +40,13 @@