diff --git a/Week2/lecture.js b/Week2/lecture.js new file mode 100644 index 000000000..b31d48ff1 --- /dev/null +++ b/Week2/lecture.js @@ -0,0 +1,5 @@ +//promises.them and catch +//build small app that shows ransom dogs and cats +// try and catch + +//event loop \ No newline at end of file diff --git a/homework-classes/App.js b/homework-classes/App.js index 7cc1c5772..8d91829cc 100644 --- a/homework-classes/App.js +++ b/homework-classes/App.js @@ -13,30 +13,46 @@ class App { * @param {string} url The GitHub URL for obtaining the organization's repositories. */ async initialize(url) { - // Add code here to initialize your app - // 1. Create the fixed HTML elements of your page - // 2. Make an initial XMLHttpRequest using Util.fetchJSON() to populate your element try { const repos = await Util.fetchJSON(url); this.repos = repos.map(repo => new Repository(repo)); + this.addRepoNamesToSelect(); + // TODO: add your own code here } catch (error) { this.renderError(error); } } + addRepoNamesToSelect() { + const selectEl = document.getElementById('repo-select') + for (const repo of this.repos) { + Util.createAndAppend('option', selectEl, { text: repo.name() }) + } + selectEl.addEventListener('change', event => { + const selectedRepoName = event.target.value; + const selectedRepo = this.repos.filter(repo => repo.name() === selectedRepoName)[0] + selectedRepo.render(document.getElementById('repo-info')); + this.fetchContributorsAndRender(selectedRepo) + }); + + } + setupDOMElement() { + const root = document.getElementById('root'); + Util.createAndAppend('select', root, { id: 'repo-select' }) + Util.createAndAppend('div', root, { id: 'repo-info' }) + Util.createAndAppend('div', root, { id: 'repo-contributors' }) + } /** * Removes all child elements from a container element * @param {*} container Container element to clear */ - clearContainer() { - while (this.mainContainer.firstChild) { - this.mainContainer.removeChild(this.mainContainer.firstChild); + static clearContainer(container) { + while (container.firstChild) { + container.removeChild(container.firstChild); } } @@ -45,21 +61,19 @@ class App { * repo and its contributors as HTML elements in the DOM. * @param {object} repo The selected repository object */ - async selectRepository(repo) { + async fetchContributorsAndRender(repo) { try { - this.clearContainer(); + const contributors = await repo.fetchContributors(); - const repoContainer = Util.createAndAppend('div', this.mainContainer); - const contributorContainer = Util.createAndAppend('div', this.mainContainer); + const container = document.getElementById('repo-contributors'); + App.clearContainer(container); - const contributorList = Util.createAndAppend('ul', contributorContainer); - repo.render(repoContainer); contributors .map(contributor => new Contributor(contributor)) - .forEach(contributor => contributor.render(contributorList)); + .forEach(contributor => contributor.render(container)); } catch (error) { this.renderError(error); } diff --git a/homework-classes/Contributor.js b/homework-classes/Contributor.js index c74775216..8957a8639 100644 --- a/homework-classes/Contributor.js +++ b/homework-classes/Contributor.js @@ -14,6 +14,7 @@ class Contributor { */ render(container) { // TODO: replace the next line with your code. - Util.createAndAppend('pre', container, { text: JSON.stringify(this.contributor, null, 2) }); + Util.createAndAppend('img', container, { src: this.contributor.avatar_url, height: 100, width: 100, class: 'img' }); + Util.createAndAppend('p', container, { text: this.contributor.login, class: 'contribsname' }); } } diff --git a/homework-classes/Repository.js b/homework-classes/Repository.js index 86b72d71d..ece6b90fd 100644 --- a/homework-classes/Repository.js +++ b/homework-classes/Repository.js @@ -13,10 +13,13 @@ class Repository { * @param {HTMLElement} container The container element in which to render the repository. */ render(container) { - // TODO: replace the next line with your code. - Util.createAndAppend('pre', container, { text: JSON.stringify(this.repository, null, 2) }); + App.clearContainer(container); + Util.createAndAppend('h3', container, { text: 'Repository Information:' }); + Util.createAndAppend('p', container, { text: 'Name: ' + this.name() }); + Util.createAndAppend('p', container, { text: 'Forks: ' + this.repository.forks }); + Util.createAndAppend('p', container, { text: 'Created on: ' + this.repository.created_at }); + Util.createAndAppend('p', container, { text: 'Description: ' + this.repository.description }); } - /** * Returns an array of contributors as a promise */ diff --git a/homework-classes/index.html b/homework-classes/index.html index 2d1fc8fa7..a37f61f8b 100644 --- a/homework-classes/index.html +++ b/homework-classes/index.html @@ -1,27 +1,26 @@ - - - - - - - - - - HYF-GITHUB - - - - -
- - - - - - + + + + + + + + + + HYF-GITHUB + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/homework-classes/style.css b/homework-classes/style.css index a8985a8a5..0300689cf 100644 --- a/homework-classes/style.css +++ b/homework-classes/style.css @@ -1,3 +1,37 @@ .alert-error { color: red; +} + +body { + background-color: rgb(194, 238, 240); + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: center; +} + +#root { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: center; +} + +p { + + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + +} + +.img { + padding: 16px; + margin-right: 25px; + flex: row; + background-color: rgb(170, 218, 240); + display: flex; + flex-direction: column; + align-items: flex-start; } \ No newline at end of file diff --git a/homework/index.js b/homework/index.js index d150b6609..dd13c69b0 100644 --- a/homework/index.js +++ b/homework/index.js @@ -1,46 +1,90 @@ 'use strict'; -{ - function fetchJSON(url, cb) { - const xhr = new XMLHttpRequest(); - xhr.open('GET', url); - xhr.responseType = 'json'; - xhr.onload = () => { - if (xhr.status >= 200 && xhr.status <= 299) { - cb(null, xhr.response); - } else { - cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); - } - }; - xhr.onerror = () => cb(new Error('Network request failed')); - xhr.send(); - } - function createAndAppend(name, parent, options = {}) { - const elem = document.createElement(name); - parent.appendChild(elem); - Object.keys(options).forEach(key => { - const value = options[key]; - if (key === 'text') { - elem.textContent = value; - } else { - elem.setAttribute(key, value); - } - }); - return elem; - } +function createAndAppend(name, parent, options = {}) { + const elem = document.createElement(name); + parent.appendChild(elem); + Object.keys(options).forEach(key => { + const value = options[key]; + if (key === 'text') { + elem.textContent = value; + } else { + elem.setAttribute(key, value); + } + }); + return elem; +} + + + +async function main(url) { + + createAndAppend('h1', root, { class: 'h1', text: 'Hack Your Future Repositories' }) + try { + const response = await fetch(url); + const json = await response.json(); + const root = document.getElementById('root'); + const select = createAndAppend('select', root, { class: 'select' }); + createAndAppend('option', select, { text: 'Choose your favorite repo' }); + let sorted = json.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase()) ? 1 : -1); + + sorted.forEach(repo => { + const name = repo.name; + + createAndAppend('option', select, { text: name }); + }) - function main(url) { - fetchJSON(url, (err, repositories) => { - const root = document.getElementById('root'); - if (err) { - createAndAppend('div', root, { text: err.message, class: 'alert-error' }); - return; + + select.addEventListener('change', evt => { + const selectedRepo = evt.target.value; + const repo = json.filter(r => r.name == selectedRepo)[0]; + getContributorInformation(repo); + repoData(); + + function repoData() { + repoInfo.innerHTML = 'Repository Information:'; + + const addInfo = (label, value) => { + const container = createAndAppend('div', repoInfo, { class: 'container' }); + createAndAppend('span', container, { text: label }); + createAndAppend('span', container, { text: value }); + }; + addInfo('Name: ', repo.name); + addInfo('Desciption: ', repo.description); + addInfo('Number of forks: ', repo.forks); + addInfo('Updated: ', repo.updated_at) + const contributorsUrl = "https://api.github.com/repos/HackYourFuture/AngularJS/contributors"; } - createAndAppend('pre', root, { text: JSON.stringify(repositories, null, 2) }); - }); + }) + + } + catch (err) { + const root = document.getElementById('root'); + createAndAppend('div', root, { text: err.message, class: 'alert-error' }) + } + + const wraper = createAndAppend('div', root, { class: 'wraper' }); + const repoInfo = createAndAppend('div', wraper, { class: 'repoinfo' }); + let contribs = createAndAppend('div', wraper, { class: 'contribs' }); + contribs.innerHTML = 'Contributors'; + + async function getContributorInformation(data) { + contribs.innerHTML = ''; + try { - const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; - window.onload = () => main(HYF_REPOS_URL); + const contribsUrl = await fetch(data.contributors_url); + const contribsJson = await contribsUrl.json(); + contribsJson.forEach(contributor => { + + createAndAppend('div', contribs, { text: contributor.login, class: 'contributor' }) + createAndAppend('img', contribs, { src: contributor.avatar_url, height: 150, widtth: 150, id: 'img' }) + createAndAppend('div', contribs, { text: contributor.contributions }) + }) + } catch (err) { + createAndAppend('div', contribs, { text: err.message, class: 'alert-error' }) + } + } } +const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; +window.onload = () => main(HYF_REPOS_URL); \ No newline at end of file diff --git a/homework/style.css b/homework/style.css index a8985a8a5..8d588244e 100644 --- a/homework/style.css +++ b/homework/style.css @@ -1,3 +1,91 @@ .alert-error { color: red; +} + +body { + background-color:whitesmoke; +} +#root { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.header { + background-color: #444; + width: 100%; +} +.h1 { + text-align: center; + +} +.container { + display: flex; + flex-direction: row; + align-items: flex-start; + margin: 1rem; + +} +.eachContrib { + display: flex; + flex-direction: row; +} + +.wraper { + display: flex; + flex-direction: row; + align-items: flex-start; + margin: 1rem; +} +.contribs { + padding: 16px; + margin-right: 25px; + flex: row; + background-color: beige; + display: flex; + flex-direction: column; + align-items: flex-start; + +} +.select { + display: flex; + flex-direction: row; + font-size: 16px; + font-family: sans-serif; + font-weight: 700; + color: #444; + line-height: 1.3; + padding: .6em 1.4em .5em .8em; + width: auto; + max-width: 100%; + box-sizing: border-box; + margin: 0; + border: 1px solid #aaa; + box-shadow: 0 1px 0 1px rgba(0,0,0,.04); + border-radius: .5em; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + background-color: #fff; + text-align: center; + +} + +.contributions { + background-color: #aaa +} + + +@media (max-width: 767px){ + body { + width: 100%; + } + .container { + margin: 0; + flex-direction: column; + align-items: stretch; + } + .left-div { + margin: 0; + } } \ No newline at end of file