From 59d0c1873d5d167072d6c600c637e76c6fbc8df7 Mon Sep 17 00:00:00 2001 From: Valeria Date: Wed, 20 Mar 2019 13:18:26 +0100 Subject: [PATCH 01/19] Homework week1 JavaScript3 --- homework/App.js | 3 +- homework/index.js | 100 ++++++++++++++++++++++++++- homework/indexTemp.js | 47 +++++++++++++ homework/style.css | 153 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 298 insertions(+), 5 deletions(-) create mode 100644 homework/indexTemp.js diff --git a/homework/App.js b/homework/App.js index 32b71e34b..513627ca9 100644 --- a/homework/App.js +++ b/homework/App.js @@ -72,7 +72,8 @@ class App { * @param {Error} error An Error object describing the error. */ renderError(error) { - console.log(error); // TODO: replace with your own code + return error; + // console.log(error); // TODO: replace with your own code } } diff --git a/homework/index.js b/homework/index.js index d3a97645e..3c7692db4 100644 --- a/homework/index.js +++ b/homework/index.js @@ -12,7 +12,7 @@ cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); } }; - xhr.onerror = () => cb(new Error('Network request failed')); + xhr.onerror = () => cb(new Error('Network request failed')); // “communication errors”: connection is lost or the remote server does not respond at all. xhr.send(); } @@ -30,13 +30,109 @@ return elem; } + // Display repository options in the header + function selectOptions(nameOption) { + const selectRepoHYF = document.getElementById('selectRepoHYF'); + for (let i = 0; i < nameOption.length; i++) { + createAndAppend('option', selectRepoHYF, { value: i, text: nameOption[i].name }); + } + } + + // Information on left side inside a table + function displayInformation(element) { + const container = document.getElementById('container'); + const infoDiv = createAndAppend('div', container, { + id: 'leftArea', + class: 'left-div whiteframe', + }); + createAndAppend('table', infoDiv, { id: 'table' }); + const table = document.getElementById('table'); + createAndAppend('tbody', table, { id: 'tbody' }); + function createTableRow(label, description) { + const tRow = createAndAppend('tr', table); + createAndAppend('td', tRow, { text: label, class: 'label' }); + createAndAppend('td', tRow, { text: description }); + } + + createTableRow('Repository: ', element.name); + createTableRow('Description: ', element.description); + createTableRow('Forks : ', element.forks); + const date2 = new Date(element.updated_at).toLocaleString(); + createTableRow('Updated: ', date2); + } + + // Show contributors + function contributorsList(element) { + fetchJSON(element.contributors_url, (err, data) => { + const container = document.getElementById('container'); + createAndAppend('div', container, { + id: 'rightArea', + class: 'right-div whiteframe', + }); + const rightArea = document.getElementById('rightArea'); + createAndAppend('h7', rightArea, { + text: 'Contributions', + class: 'contributor-header', + }); + createAndAppend('ul', rightArea, { + id: 'contList', + class: 'contributor-list', + }); + let contributorURL; + let contributorItem; + let contributorData; + const contList = document.getElementById('contList'); + for (let i = 0; i < data.length; i++) { + contributorURL = createAndAppend('a', contList, { + href: data[i].html_url, + target: '_blank', + }); + contributorItem = createAndAppend('li', contributorURL, { + class: 'contributor-item', + }); + + createAndAppend('img', contributorItem, { + src: data[i].avatar_url, + class: 'contributor-avatar', + }); + contributorData = createAndAppend('div', contributorItem, { + class: 'contributor-data', + }); + createAndAppend('div', contributorData, { text: data[i].login }); + createAndAppend('div', contributorData, { + text: data[i].contributions, + class: 'contributor-badge', + }); + } + }); + } + function main(url) { fetchJSON(url, (err, data) => { const root = document.getElementById('root'); if (err) { createAndAppend('div', root, { text: err.message, class: 'alert-error' }); } else { - createAndAppend('pre', root, { text: JSON.stringify(data, null, 2) }); + createAndAppend('header', root, { id: 'topArea', class: 'header' }); + const topArea = document.getElementById('topArea'); + createAndAppend('h7', topArea, { id: 'title', text: 'HYF Repositories' }); + createAndAppend('select', topArea, { id: 'selectRepoHYF', class: 'repo-selector' }); + createAndAppend('div', root, { id: 'container' }); + data.sort((a, b) => a.name.localeCompare(b.name)); + selectOptions(data); + displayInformation(data[0]); + contributorsList(data[0]); + + document.getElementById('selectRepoHYF').onchange = function startListener() { + const selectedItem = this.options[this.selectedIndex].value; + const infoLeft = document.getElementById('leftArea'); + infoLeft.parentNode.removeChild(infoLeft); + const contributors = document.getElementById('rightArea'); + contributors.parentNode.removeChild(contributors); + + displayInformation(data[selectedItem]); + contributorsList(data[selectedItem]); + }; } }); } diff --git a/homework/indexTemp.js b/homework/indexTemp.js new file mode 100644 index 000000000..d3a97645e --- /dev/null +++ b/homework/indexTemp.js @@ -0,0 +1,47 @@ +'use strict'; + +{ + function fetchJSON(url, cb) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + 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 main(url) { + fetchJSON(url, (err, data) => { + const root = document.getElementById('root'); + if (err) { + createAndAppend('div', root, { text: err.message, class: 'alert-error' }); + } else { + createAndAppend('pre', root, { text: JSON.stringify(data, null, 2) }); + } + }); + } + + const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + + window.onload = () => main(HYF_REPOS_URL); +} diff --git a/homework/style.css b/homework/style.css index a8985a8a5..b3c23c168 100644 --- a/homework/style.css +++ b/homework/style.css @@ -1,3 +1,152 @@ +body { + width: 768px; + margin-left: auto; + margin-right: auto; + background-color: #f8f8f8; + font-family: 'Roboto', sans-serif; + color: rgb(0, 0, 0, 87%); + margin-top: 0; +} + +#container { + display: flex; + flex-direction: row; + align-items: flex-start; +} + +@media (max-width: 767px) { + body { + width: 100%; + } + #container { + margin: 0; + flex-direction: column; + align-items: stretch; + } +} + +h1, +h2, +h3, +h4 { + color: rgb(0, 0, 0, 54%); +} + +.header { + color: white; + background-color: #3f51b5; + padding: 8px 16px; + margin-bottom: 16px; + display: flex; + flex-direction: row; + align-items: center; +} + +.repo-selector { + margin-left: 16px; + font-size: 14px; + width: 250px; + height: 32px; + padding: 2px; +} + +.left-div, +.right-div { + background-color: white; + flex: 1; +} + +.left-div { + padding: 16px; + margin-right: 16px; +} + +@media (max-width: 767px) { + .left-div { + margin: 0; + } +} + +.contributor-list { + list-style-type: none; + padding: 0; + margin: 0; +} + +.alert { + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border-radius: 0.25rem; + flex: 1; +} + .alert-error { - color: red; -} \ No newline at end of file + color: #721c24; + background-color: #f8d7da; +} + +.contributor-header { + font-size: 0.8rem; + color: rgb(0, 0, 0, 54%); + padding: 16px 16px 8px 16px; +} + +.contributor-item { + border-bottom: solid 1px rgb(0, 0, 0, 12%); + padding: 16px; + display: flex; + flex-direction: row; + align-items: center; + cursor: pointer; +} + +.contributor-avatar { + border-radius: 3px; + margin-right: 16px; + height: 48px; +} + +.contributor-data { + flex: 1; + display: flex; + flex-direction: row; + justify-content: space-between; + align-content: center; +} + +.contributor-badge { + font-size: 12px; + padding: 2px 8px; + line-height: 1rem; + background-color: gray; + color: white; + border-radius: 4px; +} + +table { + table-layout: fixed; + color: rgb(0, 0, 0, 81%); +} + +td { + vertical-align: top; +} + +td:first-child { + width: 100px; + min-width: 100px; + max-width: 100px; +} + +td.label { + font-weight: bold; +} + +.whiteframe { + margin-bottom: 8px; + border: none; + border-radius: 2px; + background-color: #fff; + box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.14), + 0 3px 3px -2px rgba(0, 0, 0, 0.12); +} From 9ad5c8711b5d2e627662786893398daf08a1cd8f Mon Sep 17 00:00:00 2001 From: Nahui Date: Wed, 20 Mar 2019 13:28:02 +0100 Subject: [PATCH 02/19] Files for the homework of week1 JavaScript3 Files were previously pulled to /JavaScript3/homework folder, but that folder will change in every week, so uploading everything inside /JavaScript3/week1 so it doesn't get lost. --- Week1/App.js | 82 +++++++++++++++++++++++ Week1/Contributor.js | 19 ++++++ Week1/Repository.js | 33 ++++++++++ Week1/Util.js | 35 ++++++++++ Week1/hyf.png | Bin 0 -> 6971 bytes Week1/index.html | 23 +++++++ Week1/index.js | 143 ++++++++++++++++++++++++++++++++++++++++ Week1/index2.html | 27 ++++++++ Week1/style.css | 152 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 514 insertions(+) create mode 100644 Week1/App.js create mode 100644 Week1/Contributor.js create mode 100644 Week1/Repository.js create mode 100644 Week1/Util.js create mode 100644 Week1/hyf.png create mode 100644 Week1/index.html create mode 100644 Week1/index.js create mode 100644 Week1/index2.html create mode 100644 Week1/style.css diff --git a/Week1/App.js b/Week1/App.js new file mode 100644 index 000000000..513627ca9 --- /dev/null +++ b/Week1/App.js @@ -0,0 +1,82 @@ +'use strict'; + +/* global Util, Repository, Contributor */ + +class App { + constructor(url) { + this.initialize(url); + } + + /** + * Initialization + * @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 + + const root = document.getElementById('root'); + + Util.createAndAppend('h1', root, { text: 'It works!' }); // TODO: replace with your own code + + try { + const repos = await Util.fetchJSON(url); + this.repos = repos.map(repo => new Repository(repo)); + // TODO: add your own code here + } catch (error) { + this.renderError(error); + } + } + + /** + * Removes all child elements from a container element + * @param {*} container Container element to clear + */ + static clearContainer(container) { + while (container.firstChild) { + container.removeChild(container.firstChild); + } + } + + /** + * Fetch contributor information for the selected repository and render the + * repo and its contributors as HTML elements in the DOM. + * @param {number} index The array index of the repository. + */ + async fetchContributorsAndRender(index) { + try { + const repo = this.repos[index]; + const contributors = await repo.fetchContributors(); + + const container = document.getElementById('container'); + App.clearContainer(container); + + const leftDiv = Util.createAndAppend('div', container); + const rightDiv = Util.createAndAppend('div', container); + + const contributorList = Util.createAndAppend('ul', rightDiv); + + repo.render(leftDiv); + + contributors + .map(contributor => new Contributor(contributor)) + .forEach(contributor => contributor.render(contributorList)); + } catch (error) { + this.renderError(error); + } + } + + /** + * Render an error to the DOM. + * @param {Error} error An Error object describing the error. + */ + renderError(error) { + return error; + // console.log(error); // TODO: replace with your own code + } +} + +const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + +window.onload = () => new App(HYF_REPOS_URL); diff --git a/Week1/Contributor.js b/Week1/Contributor.js new file mode 100644 index 000000000..0bfd5a15e --- /dev/null +++ b/Week1/Contributor.js @@ -0,0 +1,19 @@ +'use strict'; + +/* global Util */ + +// eslint-disable-next-line no-unused-vars +class Contributor { + constructor(contributor) { + this.contributor = contributor; + } + + /** + * Render the contributor info to the DOM. + * @param {HTMLElement} container The container element in which to render the contributor. + */ + render(container) { + // TODO: replace the next line with your code. + Util.createAndAppend('pre', container, JSON.stringify(this.contributor, null, 2)); + } +} diff --git a/Week1/Repository.js b/Week1/Repository.js new file mode 100644 index 000000000..267960a5a --- /dev/null +++ b/Week1/Repository.js @@ -0,0 +1,33 @@ +'use strict'; + +/* global Util */ + +// eslint-disable-next-line no-unused-vars +class Repository { + constructor(repository) { + this.repository = repository; + } + + /** + * Render the repository info to the DOM. + * @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, JSON.stringify(this.repository, null, 2)); + } + + /** + * Returns an array of contributors as a promise + */ + fetchContributors() { + return Util.fetchJSON(this.repository.contributors_url); + } + + /** + * Returns the name of the repository + */ + name() { + return this.repository.name; + } +} diff --git a/Week1/Util.js b/Week1/Util.js new file mode 100644 index 000000000..981fea47a --- /dev/null +++ b/Week1/Util.js @@ -0,0 +1,35 @@ +'use strict'; + +// eslint-disable-next-line no-unused-vars +class Util { + static 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; + } + + static fetchJSON(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + resolve(xhr.response); + } else { + reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.onerror = () => reject(new Error('Network request failed')); + xhr.send(); + }); + } +} diff --git a/Week1/hyf.png b/Week1/hyf.png new file mode 100644 index 0000000000000000000000000000000000000000..a4626c91cc28dd92f3a8843aa3919c472d609984 GIT binary patch literal 6971 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

yYR!c>hm$${Gy*N9&8XDjZ!65Rw_ciO4 z0&aFLEIenv__Nv_t*>({#yj`xE&E==WFBy2C{3B&xkGWnzEKCWENz0#Jwmk4zVlFkwA zUE)Mh&#vxEf;BeYy)nJloYs7`DnyjD`0Y^YQxyIS4d+#4vCtj@wK(UEa7cSZ{%+_S zF5bPJcnZ{2mGzB;1m2r>)!K>%2Gu6MG)9*tE%!%>7iF8elLW^N_ATFxu1g9EHe#TP zioN@YLEDN*VPJ4@2<(Btz*yzfz(+*aind)cZ;In-Ma_C>M7IU7bV^BSGjy@pn_Oiy zl(>YaYv~ZLZ6?2| zypqx#xM_@it9|v)xZLTBUY$2}F#h#dZw(FfZMj~GCAIsW9-ejAu^{m6fGn&mwBazA z$4SkC7#JSJ5ORgz?e8Za7blKG zizmAOF6s_0y+`YkEtdk66Bg{o)5UJp?R6bosX}uWa5r9Z;`c2J>xic=TTI`dXBr*WBCNn29fqV6ysrW=%FRy~JIbo7vs+uqhLB(6-tKNnYKpCmouZ+D4Ut!foH9vbFwA+LF zI7vtr2nkSgSy6J!bGN8T54?{ONFInoHx(5ujzh>RfnKf&aCZm;~Lq@38Pp8iO=Vl3`;QmS7? z>df*6iV+(X9gIBIsiWyB&yQYTtgLi&bp8{}c6k5psn*E*JjN>kJ>x?S?L9m?e5`+Yb*8W^Xi^TEM;a8OWq*Wp?nQa`5QB q{eMOe|IHi!$Di^1?!}AeXDJlZH8z|Z3FM~O3k6wKnM$dzKmQAHWO%^< literal 0 HcmV?d00001 diff --git a/Week1/index.html b/Week1/index.html new file mode 100644 index 000000000..9c8f80c1a --- /dev/null +++ b/Week1/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + + HYF-GITHUB + + + + + +

+ + + + \ No newline at end of file diff --git a/Week1/index.js b/Week1/index.js new file mode 100644 index 000000000..3c7692db4 --- /dev/null +++ b/Week1/index.js @@ -0,0 +1,143 @@ +'use strict'; + +{ + function fetchJSON(url, cb) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + cb(null, xhr.response); + } else { + cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.onerror = () => cb(new Error('Network request failed')); // “communication errors”: connection is lost or the remote server does not respond at all. + 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; + } + + // Display repository options in the header + function selectOptions(nameOption) { + const selectRepoHYF = document.getElementById('selectRepoHYF'); + for (let i = 0; i < nameOption.length; i++) { + createAndAppend('option', selectRepoHYF, { value: i, text: nameOption[i].name }); + } + } + + // Information on left side inside a table + function displayInformation(element) { + const container = document.getElementById('container'); + const infoDiv = createAndAppend('div', container, { + id: 'leftArea', + class: 'left-div whiteframe', + }); + createAndAppend('table', infoDiv, { id: 'table' }); + const table = document.getElementById('table'); + createAndAppend('tbody', table, { id: 'tbody' }); + function createTableRow(label, description) { + const tRow = createAndAppend('tr', table); + createAndAppend('td', tRow, { text: label, class: 'label' }); + createAndAppend('td', tRow, { text: description }); + } + + createTableRow('Repository: ', element.name); + createTableRow('Description: ', element.description); + createTableRow('Forks : ', element.forks); + const date2 = new Date(element.updated_at).toLocaleString(); + createTableRow('Updated: ', date2); + } + + // Show contributors + function contributorsList(element) { + fetchJSON(element.contributors_url, (err, data) => { + const container = document.getElementById('container'); + createAndAppend('div', container, { + id: 'rightArea', + class: 'right-div whiteframe', + }); + const rightArea = document.getElementById('rightArea'); + createAndAppend('h7', rightArea, { + text: 'Contributions', + class: 'contributor-header', + }); + createAndAppend('ul', rightArea, { + id: 'contList', + class: 'contributor-list', + }); + let contributorURL; + let contributorItem; + let contributorData; + const contList = document.getElementById('contList'); + for (let i = 0; i < data.length; i++) { + contributorURL = createAndAppend('a', contList, { + href: data[i].html_url, + target: '_blank', + }); + contributorItem = createAndAppend('li', contributorURL, { + class: 'contributor-item', + }); + + createAndAppend('img', contributorItem, { + src: data[i].avatar_url, + class: 'contributor-avatar', + }); + contributorData = createAndAppend('div', contributorItem, { + class: 'contributor-data', + }); + createAndAppend('div', contributorData, { text: data[i].login }); + createAndAppend('div', contributorData, { + text: data[i].contributions, + class: 'contributor-badge', + }); + } + }); + } + + function main(url) { + fetchJSON(url, (err, data) => { + const root = document.getElementById('root'); + if (err) { + createAndAppend('div', root, { text: err.message, class: 'alert-error' }); + } else { + createAndAppend('header', root, { id: 'topArea', class: 'header' }); + const topArea = document.getElementById('topArea'); + createAndAppend('h7', topArea, { id: 'title', text: 'HYF Repositories' }); + createAndAppend('select', topArea, { id: 'selectRepoHYF', class: 'repo-selector' }); + createAndAppend('div', root, { id: 'container' }); + data.sort((a, b) => a.name.localeCompare(b.name)); + selectOptions(data); + displayInformation(data[0]); + contributorsList(data[0]); + + document.getElementById('selectRepoHYF').onchange = function startListener() { + const selectedItem = this.options[this.selectedIndex].value; + const infoLeft = document.getElementById('leftArea'); + infoLeft.parentNode.removeChild(infoLeft); + const contributors = document.getElementById('rightArea'); + contributors.parentNode.removeChild(contributors); + + displayInformation(data[selectedItem]); + contributorsList(data[selectedItem]); + }; + } + }); + } + + const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + + window.onload = () => main(HYF_REPOS_URL); +} diff --git a/Week1/index2.html b/Week1/index2.html new file mode 100644 index 000000000..2d1fc8fa7 --- /dev/null +++ b/Week1/index2.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + HYF-GITHUB + + + + + +
+ + + + + + diff --git a/Week1/indexTemp.js b/Week1/indexTemp.js new file mode 100644 index 000000000..d3a97645e --- /dev/null +++ b/Week1/indexTemp.js @@ -0,0 +1,47 @@ +'use strict'; + +{ + function fetchJSON(url, cb) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + 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 main(url) { + fetchJSON(url, (err, data) => { + const root = document.getElementById('root'); + if (err) { + createAndAppend('div', root, { text: err.message, class: 'alert-error' }); + } else { + createAndAppend('pre', root, { text: JSON.stringify(data, null, 2) }); + } + }); + } + + const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + + window.onload = () => main(HYF_REPOS_URL); +} diff --git a/Week1/style.css b/Week1/style.css new file mode 100644 index 000000000..b3c23c168 --- /dev/null +++ b/Week1/style.css @@ -0,0 +1,152 @@ +body { + width: 768px; + margin-left: auto; + margin-right: auto; + background-color: #f8f8f8; + font-family: 'Roboto', sans-serif; + color: rgb(0, 0, 0, 87%); + margin-top: 0; +} + +#container { + display: flex; + flex-direction: row; + align-items: flex-start; +} + +@media (max-width: 767px) { + body { + width: 100%; + } + #container { + margin: 0; + flex-direction: column; + align-items: stretch; + } +} + +h1, +h2, +h3, +h4 { + color: rgb(0, 0, 0, 54%); +} + +.header { + color: white; + background-color: #3f51b5; + padding: 8px 16px; + margin-bottom: 16px; + display: flex; + flex-direction: row; + align-items: center; +} + +.repo-selector { + margin-left: 16px; + font-size: 14px; + width: 250px; + height: 32px; + padding: 2px; +} + +.left-div, +.right-div { + background-color: white; + flex: 1; +} + +.left-div { + padding: 16px; + margin-right: 16px; +} + +@media (max-width: 767px) { + .left-div { + margin: 0; + } +} + +.contributor-list { + list-style-type: none; + padding: 0; + margin: 0; +} + +.alert { + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border-radius: 0.25rem; + flex: 1; +} + +.alert-error { + color: #721c24; + background-color: #f8d7da; +} + +.contributor-header { + font-size: 0.8rem; + color: rgb(0, 0, 0, 54%); + padding: 16px 16px 8px 16px; +} + +.contributor-item { + border-bottom: solid 1px rgb(0, 0, 0, 12%); + padding: 16px; + display: flex; + flex-direction: row; + align-items: center; + cursor: pointer; +} + +.contributor-avatar { + border-radius: 3px; + margin-right: 16px; + height: 48px; +} + +.contributor-data { + flex: 1; + display: flex; + flex-direction: row; + justify-content: space-between; + align-content: center; +} + +.contributor-badge { + font-size: 12px; + padding: 2px 8px; + line-height: 1rem; + background-color: gray; + color: white; + border-radius: 4px; +} + +table { + table-layout: fixed; + color: rgb(0, 0, 0, 81%); +} + +td { + vertical-align: top; +} + +td:first-child { + width: 100px; + min-width: 100px; + max-width: 100px; +} + +td.label { + font-weight: bold; +} + +.whiteframe { + margin-bottom: 8px; + border: none; + border-radius: 2px; + background-color: #fff; + box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.14), + 0 3px 3px -2px rgba(0, 0, 0, 0.12); +} diff --git a/homework/index.js b/homework/index.js index 3c7692db4..3ce768524 100644 --- a/homework/index.js +++ b/homework/index.js @@ -1,19 +1,20 @@ 'use strict'; { - function fetchJSON(url, cb) { - const xhr = new XMLHttpRequest(); - xhr.open('GET', url); - xhr.responseType = 'json'; - xhr.onload = () => { - if (xhr.status < 400) { - cb(null, xhr.response); - } else { - cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); - } - }; - xhr.onerror = () => cb(new Error('Network request failed')); // “communication errors”: connection is lost or the remote server does not respond at all. - xhr.send(); + function fetchJSON(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + resolve(xhr.response); + } else { + reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.send(); + }); } function createAndAppend(name, parent, options = {}) { @@ -63,7 +64,7 @@ // Show contributors function contributorsList(element) { - fetchJSON(element.contributors_url, (err, data) => { + fetchJSON(element.contributors_url).then(data => { const container = document.getElementById('container'); createAndAppend('div', container, { id: 'rightArea', @@ -108,11 +109,12 @@ } function main(url) { - fetchJSON(url, (err, data) => { - const root = document.getElementById('root'); - if (err) { - createAndAppend('div', root, { text: err.message, class: 'alert-error' }); - } else { + const root = document.getElementById('root'); + fetchJSON(url) + .catch(reject => { + createAndAppend('div', root, { text: reject.message, class: 'alert-error' }); + }) + .then(data => { createAndAppend('header', root, { id: 'topArea', class: 'header' }); const topArea = document.getElementById('topArea'); createAndAppend('h7', topArea, { id: 'title', text: 'HYF Repositories' }); @@ -133,8 +135,7 @@ displayInformation(data[selectedItem]); contributorsList(data[selectedItem]); }; - } - }); + }); } const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; From 76683a0b3ca26f2b394c732404a08653ca4b51b6 Mon Sep 17 00:00:00 2001 From: Valeria Date: Wed, 20 Mar 2019 15:53:51 +0100 Subject: [PATCH 04/19] Homework week2 JavaScript3 with right directories --- Week2/App.js | 82 +++++++++++++++++++++++ Week2/Contributor.js | 19 ++++++ Week2/Repository.js | 33 ++++++++++ Week2/Util.js | 35 ++++++++++ Week2/hyf.png | Bin 0 -> 6971 bytes Week2/index.html | 23 +++++++ Week2/index.js | 144 ++++++++++++++++++++++++++++++++++++++++ Week2/index2.html | 27 ++++++++ Week2/indexTemp.js | 47 +++++++++++++ Week2/style.css | 152 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 562 insertions(+) create mode 100644 Week2/App.js create mode 100644 Week2/Contributor.js create mode 100644 Week2/Repository.js create mode 100644 Week2/Util.js create mode 100644 Week2/hyf.png create mode 100644 Week2/index.html create mode 100644 Week2/index.js create mode 100644 Week2/index2.html create mode 100644 Week2/indexTemp.js create mode 100644 Week2/style.css diff --git a/Week2/App.js b/Week2/App.js new file mode 100644 index 000000000..513627ca9 --- /dev/null +++ b/Week2/App.js @@ -0,0 +1,82 @@ +'use strict'; + +/* global Util, Repository, Contributor */ + +class App { + constructor(url) { + this.initialize(url); + } + + /** + * Initialization + * @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 - - const root = document.getElementById('root'); - - Util.createAndAppend('h1', root, { text: 'It works!' }); // TODO: replace with your own code - - try { - const repos = await Util.fetchJSON(url); - this.repos = repos.map(repo => new Repository(repo)); - // TODO: add your own code here - } catch (error) { - this.renderError(error); - } - } - - /** - * Removes all child elements from a container element - * @param {*} container Container element to clear - */ - static clearContainer(container) { - while (container.firstChild) { - container.removeChild(container.firstChild); - } - } - - /** - * Fetch contributor information for the selected repository and render the - * repo and its contributors as HTML elements in the DOM. - * @param {number} index The array index of the repository. - */ - async fetchContributorsAndRender(index) { - try { - const repo = this.repos[index]; - const contributors = await repo.fetchContributors(); - - const container = document.getElementById('container'); - App.clearContainer(container); - - const leftDiv = Util.createAndAppend('div', container); - const rightDiv = Util.createAndAppend('div', container); - - const contributorList = Util.createAndAppend('ul', rightDiv); - - repo.render(leftDiv); - - contributors - .map(contributor => new Contributor(contributor)) - .forEach(contributor => contributor.render(contributorList)); - } catch (error) { - this.renderError(error); - } - } - - /** - * Render an error to the DOM. - * @param {Error} error An Error object describing the error. - */ - renderError(error) { - return error; - // console.log(error); // TODO: replace with your own code - } -} - -const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; - -window.onload = () => new App(HYF_REPOS_URL); From ad3a204f08e16e55d058cbe5d0859082722ed54b Mon Sep 17 00:00:00 2001 From: Nahui Date: Sat, 30 Mar 2019 22:03:02 +0100 Subject: [PATCH 07/19] Delete Contributor.js --- Week2/Contributor.js | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 Week2/Contributor.js diff --git a/Week2/Contributor.js b/Week2/Contributor.js deleted file mode 100644 index 0bfd5a15e..000000000 --- a/Week2/Contributor.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -/* global Util */ - -// eslint-disable-next-line no-unused-vars -class Contributor { - constructor(contributor) { - this.contributor = contributor; - } - - /** - * Render the contributor info to the DOM. - * @param {HTMLElement} container The container element in which to render the contributor. - */ - render(container) { - // TODO: replace the next line with your code. - Util.createAndAppend('pre', container, JSON.stringify(this.contributor, null, 2)); - } -} From 948333994d518d0eb81eccf0e8cc986b21953b45 Mon Sep 17 00:00:00 2001 From: Nahui Date: Sat, 30 Mar 2019 22:03:11 +0100 Subject: [PATCH 08/19] Delete Repository.js --- Week2/Repository.js | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 Week2/Repository.js diff --git a/Week2/Repository.js b/Week2/Repository.js deleted file mode 100644 index 267960a5a..000000000 --- a/Week2/Repository.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -/* global Util */ - -// eslint-disable-next-line no-unused-vars -class Repository { - constructor(repository) { - this.repository = repository; - } - - /** - * Render the repository info to the DOM. - * @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, JSON.stringify(this.repository, null, 2)); - } - - /** - * Returns an array of contributors as a promise - */ - fetchContributors() { - return Util.fetchJSON(this.repository.contributors_url); - } - - /** - * Returns the name of the repository - */ - name() { - return this.repository.name; - } -} From 7a3d572ff4f397767db41562a172cf795fe817c2 Mon Sep 17 00:00:00 2001 From: Nahui Date: Sat, 30 Mar 2019 22:03:19 +0100 Subject: [PATCH 09/19] Delete Util.js --- Week2/Util.js | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 Week2/Util.js diff --git a/Week2/Util.js b/Week2/Util.js deleted file mode 100644 index 981fea47a..000000000 --- a/Week2/Util.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -// eslint-disable-next-line no-unused-vars -class Util { - static 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; - } - - static fetchJSON(url) { - return new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.open('GET', url); - xhr.responseType = 'json'; - xhr.onload = () => { - if (xhr.status < 400) { - resolve(xhr.response); - } else { - reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); - } - }; - xhr.onerror = () => reject(new Error('Network request failed')); - xhr.send(); - }); - } -} From 40f548ae72987a9ac4f1b1598e743de8089f2332 Mon Sep 17 00:00:00 2001 From: Nahui Date: Sat, 30 Mar 2019 22:03:28 +0100 Subject: [PATCH 10/19] Delete hyf.png --- Week2/hyf.png | Bin 6971 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Week2/hyf.png diff --git a/Week2/hyf.png b/Week2/hyf.png deleted file mode 100644 index a4626c91cc28dd92f3a8843aa3919c472d609984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6971 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

yYR!c>hm$${Gy*N9&8XDjZ!65Rw_ciO4 z0&aFLEIenv__Nv_t*>({#yj`xE&E==WFBy2C{3B&xkGWnzEKCWENz0#Jwmk4zVlFkwA zUE)Mh&#vxEf;BeYy)nJloYs7`DnyjD`0Y^YQxyIS4d+#4vCtj@wK(UEa7cSZ{%+_S zF5bPJcnZ{2mGzB;1m2r>)!K>%2Gu6MG)9*tE%!%>7iF8elLW^N_ATFxu1g9EHe#TP zioN@YLEDN*VPJ4@2<(Btz*yzfz(+*aind)cZ;In-Ma_C>M7IU7bV^BSGjy@pn_Oiy zl(>YaYv~ZLZ6?2| zypqx#xM_@it9|v)xZLTBUY$2}F#h#dZw(FfZMj~GCAIsW9-ejAu^{m6fGn&mwBazA z$4SkC7#JSJ5ORgz?e8Za7blKG zizmAOF6s_0y+`YkEtdk66Bg{o)5UJp?R6bosX}uWa5r9Z;`c2J>xic=TTI`dXBr*WBCNn29fqV6ysrW=%FRy~JIbo7vs+uqhLB(6-tKNnYKpCmouZ+D4Ut!foH9vbFwA+LF zI7vtr2nkSgSy6J!bGN8T54?{ONFInoHx(5ujzh>RfnKf&aCZm;~Lq@38Pp8iO=Vl3`;QmS7? z>df*6iV+(X9gIBIsiWyB&yQYTtgLi&bp8{}c6k5psn*E*JjN>kJ>x?S?L9m?e5`+Yb*8W^Xi^TEM;a8OWq*Wp?nQa`5QB q{eMOe|IHi!$Di^1?!}AeXDJlZH8z|Z3FM~O3k6wKnM$dzKmQAHWO%^< From c796ed69c3b74a6f1cbb5a815b442068f9383145 Mon Sep 17 00:00:00 2001 From: Nahui Date: Sat, 30 Mar 2019 22:03:45 +0100 Subject: [PATCH 11/19] Delete index2.html --- Week2/index2.html | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 Week2/index2.html diff --git a/Week2/index2.html b/Week2/index2.html deleted file mode 100644 index 2d1fc8fa7..000000000 --- a/Week2/index2.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - HYF-GITHUB - - - - - -

- - - - - - From 251b185e22efa0edfa4e2a17549b0c981f522818 Mon Sep 17 00:00:00 2001 From: Nahui Date: Sat, 30 Mar 2019 22:04:01 +0100 Subject: [PATCH 12/19] Delete App.js --- Week1/App.js | 82 ---------------------------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 Week1/App.js diff --git a/Week1/App.js b/Week1/App.js deleted file mode 100644 index 513627ca9..000000000 --- a/Week1/App.js +++ /dev/null @@ -1,82 +0,0 @@ -'use strict'; - -/* global Util, Repository, Contributor */ - -class App { - constructor(url) { - this.initialize(url); - } - - /** - * Initialization - * @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 + + const root = document.getElementById('root'); + + Util.createAndAppend('h1', root, { text: 'It works!' }); // TODO: replace with your own code + + try { + const repos = await Util.fetchJSON(url); + this.repos = repos.map(repo => new Repository(repo)); + // TODO: add your own code here + } catch (error) { + this.renderError(error); + } + } + + /** + * Removes all child elements from a container element + * @param {*} container Container element to clear + */ + static clearContainer(container) { + while (container.firstChild) { + container.removeChild(container.firstChild); + } + } + + /** + * Fetch contributor information for the selected repository and render the + * repo and its contributors as HTML elements in the DOM. + * @param {number} index The array index of the repository. + */ + async fetchContributorsAndRender(index) { + try { + const repo = this.repos[index]; + const contributors = await repo.fetchContributors(); + + const container = document.getElementById('container'); + App.clearContainer(container); + + const leftDiv = Util.createAndAppend('div', container); + const rightDiv = Util.createAndAppend('div', container); + + const contributorList = Util.createAndAppend('ul', rightDiv); + + repo.render(leftDiv); + + contributors + .map(contributor => new Contributor(contributor)) + .forEach(contributor => contributor.render(contributorList)); + } catch (error) { + this.renderError(error); + } + } + + /** + * Render an error to the DOM. + * @param {Error} error An Error object describing the error. + */ + renderError(error) { + return error; + // console.log(error); // TODO: replace with your own code + } +} + +const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + +window.onload = () => new App(HYF_REPOS_URL); diff --git a/Week3/part2/Contributor.js b/Week3/part2/Contributor.js new file mode 100644 index 000000000..0bfd5a15e --- /dev/null +++ b/Week3/part2/Contributor.js @@ -0,0 +1,19 @@ +'use strict'; + +/* global Util */ + +// eslint-disable-next-line no-unused-vars +class Contributor { + constructor(contributor) { + this.contributor = contributor; + } + + /** + * Render the contributor info to the DOM. + * @param {HTMLElement} container The container element in which to render the contributor. + */ + render(container) { + // TODO: replace the next line with your code. + Util.createAndAppend('pre', container, JSON.stringify(this.contributor, null, 2)); + } +} diff --git a/Week3/part2/Repository.js b/Week3/part2/Repository.js new file mode 100644 index 000000000..267960a5a --- /dev/null +++ b/Week3/part2/Repository.js @@ -0,0 +1,33 @@ +'use strict'; + +/* global Util */ + +// eslint-disable-next-line no-unused-vars +class Repository { + constructor(repository) { + this.repository = repository; + } + + /** + * Render the repository info to the DOM. + * @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, JSON.stringify(this.repository, null, 2)); + } + + /** + * Returns an array of contributors as a promise + */ + fetchContributors() { + return Util.fetchJSON(this.repository.contributors_url); + } + + /** + * Returns the name of the repository + */ + name() { + return this.repository.name; + } +} diff --git a/Week3/part2/Util.js b/Week3/part2/Util.js new file mode 100644 index 000000000..981fea47a --- /dev/null +++ b/Week3/part2/Util.js @@ -0,0 +1,35 @@ +'use strict'; + +// eslint-disable-next-line no-unused-vars +class Util { + static 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; + } + + static fetchJSON(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + resolve(xhr.response); + } else { + reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.onerror = () => reject(new Error('Network request failed')); + xhr.send(); + }); + } +} diff --git a/Week3/part2/hyf.png b/Week3/part2/hyf.png new file mode 100644 index 0000000000000000000000000000000000000000..a4626c91cc28dd92f3a8843aa3919c472d609984 GIT binary patch literal 6971 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

yYR!c>hm$${Gy*N9&8XDjZ!65Rw_ciO4 z0&aFLEIenv__Nv_t*>({#yj`xE&E==WFBy2C{3B&xkGWnzEKCWENz0#Jwmk4zVlFkwA zUE)Mh&#vxEf;BeYy)nJloYs7`DnyjD`0Y^YQxyIS4d+#4vCtj@wK(UEa7cSZ{%+_S zF5bPJcnZ{2mGzB;1m2r>)!K>%2Gu6MG)9*tE%!%>7iF8elLW^N_ATFxu1g9EHe#TP zioN@YLEDN*VPJ4@2<(Btz*yzfz(+*aind)cZ;In-Ma_C>M7IU7bV^BSGjy@pn_Oiy zl(>YaYv~ZLZ6?2| zypqx#xM_@it9|v)xZLTBUY$2}F#h#dZw(FfZMj~GCAIsW9-ejAu^{m6fGn&mwBazA z$4SkC7#JSJ5ORgz?e8Za7blKG zizmAOF6s_0y+`YkEtdk66Bg{o)5UJp?R6bosX}uWa5r9Z;`c2J>xic=TTI`dXBr*WBCNn29fqV6ysrW=%FRy~JIbo7vs+uqhLB(6-tKNnYKpCmouZ+D4Ut!foH9vbFwA+LF zI7vtr2nkSgSy6J!bGN8T54?{ONFInoHx(5ujzh>RfnKf&aCZm;~Lq@38Pp8iO=Vl3`;QmS7? z>df*6iV+(X9gIBIsiWyB&yQYTtgLi&bp8{}c6k5psn*E*JjN>kJ>x?S?L9m?e5`+Yb*8W^Xi^TEM;a8OWq*Wp?nQa`5QB q{eMOe|IHi!$Di^1?!}AeXDJlZH8z|Z3FM~O3k6wKnM$dzKmQAHWO%^< literal 0 HcmV?d00001 diff --git a/Week3/part2/index.html b/Week3/part2/index.html new file mode 100644 index 000000000..9c8f80c1a --- /dev/null +++ b/Week3/part2/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + + HYF-GITHUB + + + + + +

+ + + + \ No newline at end of file diff --git a/Week3/part2/index.js b/Week3/part2/index.js new file mode 100644 index 000000000..8d3bac382 --- /dev/null +++ b/Week3/part2/index.js @@ -0,0 +1,144 @@ +'use strict'; + +{ + function fetchJSON(url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + resolve(xhr.response); + } else { + reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); + } + }; + xhr.onerror = () => reject(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; + } + + // Display repository options in the header + function selectOptions(nameOption) { + const selectRepoHYF = document.getElementById('selectRepoHYF'); + for (let i = 0; i < nameOption.length; i++) { + createAndAppend('option', selectRepoHYF, { value: i, text: nameOption[i].name }); + } + } + + // Information on left side inside a table + function displayInformation(element) { + const container = document.getElementById('container'); + const infoDiv = createAndAppend('div', container, { + id: 'leftArea', + class: 'left-div whiteframe', + }); + createAndAppend('table', infoDiv, { id: 'table' }); + const table = document.getElementById('table'); + createAndAppend('tbody', table, { id: 'tbody' }); + function createTableRow(label, description) { + const tRow = createAndAppend('tr', table); + createAndAppend('td', tRow, { text: label, class: 'label' }); + createAndAppend('td', tRow, { text: description }); + } + + createTableRow('Repository: ', element.name); + createTableRow('Description: ', element.description); + createTableRow('Forks : ', element.forks); + const date2 = new Date(element.updated_at).toLocaleString(); + createTableRow('Updated: ', date2); + } + + // Show contributors + function contributorsList(element) { + fetchJSON(element.contributors_url).then(data => { + const container = document.getElementById('container'); + createAndAppend('div', container, { + id: 'rightArea', + class: 'right-div whiteframe', + }); + const rightArea = document.getElementById('rightArea'); + createAndAppend('p', rightArea, { + text: 'Contributions', + class: 'contributor-header', + }); + createAndAppend('ul', rightArea, { + id: 'contList', + class: 'contributor-list', + }); + let contributorURL; + let contributorItem; + let contributorData; + const contList = document.getElementById('contList'); + for (let i = 0; i < data.length; i++) { + contributorURL = createAndAppend('a', contList, { + href: data[i].html_url, + target: '_blank', + }); + contributorItem = createAndAppend('li', contributorURL, { + class: 'contributor-item', + }); + + createAndAppend('img', contributorItem, { + src: data[i].avatar_url, + class: 'contributor-avatar', + }); + contributorData = createAndAppend('div', contributorItem, { + class: 'contributor-data', + }); + createAndAppend('div', contributorData, { text: data[i].login }); + createAndAppend('div', contributorData, { + text: data[i].contributions, + class: 'contributor-badge', + }); + } + }); + } + + async function main(url) { + const root = document.getElementById('root'); + try { + const data = await fetchJSON(url); + data.sort((a, b) => a.name.localeCompare(b.name)); + createAndAppend('header', root, { id: 'topArea', class: 'header' }); + const topArea = document.getElementById('topArea'); + createAndAppend('p', topArea, { id: 'title', text: 'HYF Repositories' }); + createAndAppend('select', topArea, { id: 'selectRepoHYF', class: 'repo-selector' }); + createAndAppend('div', root, { id: 'container' }); + selectOptions(data); + displayInformation(data[0]); + contributorsList(data[0]); + + document.getElementById('selectRepoHYF').onchange = function startListener() { + const selectedItem = this.options[this.selectedIndex].value; + const infoLeft = document.getElementById('leftArea'); + infoLeft.parentNode.removeChild(infoLeft); + const contributors = document.getElementById('rightArea'); + contributors.parentNode.removeChild(contributors); + + displayInformation(data[selectedItem]); + contributorsList(data[selectedItem]); + }; + } catch (err) { + createAndAppend('div', root, { 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); +} diff --git a/Week3/part2/index2.html b/Week3/part2/index2.html new file mode 100644 index 000000000..2d1fc8fa7 --- /dev/null +++ b/Week3/part2/index2.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + HYF-GITHUB + + + + + +
+ + + + + + diff --git a/Week3/part2/indexTemp.js b/Week3/part2/indexTemp.js new file mode 100644 index 000000000..d3a97645e --- /dev/null +++ b/Week3/part2/indexTemp.js @@ -0,0 +1,47 @@ +'use strict'; + +{ + function fetchJSON(url, cb) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'json'; + xhr.onload = () => { + if (xhr.status < 400) { + 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 main(url) { + fetchJSON(url, (err, data) => { + const root = document.getElementById('root'); + if (err) { + createAndAppend('div', root, { text: err.message, class: 'alert-error' }); + } else { + createAndAppend('pre', root, { text: JSON.stringify(data, null, 2) }); + } + }); + } + + const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100'; + + window.onload = () => main(HYF_REPOS_URL); +} diff --git a/Week3/part2/style.css b/Week3/part2/style.css new file mode 100644 index 000000000..b3c23c168 --- /dev/null +++ b/Week3/part2/style.css @@ -0,0 +1,152 @@ +body { + width: 768px; + margin-left: auto; + margin-right: auto; + background-color: #f8f8f8; + font-family: 'Roboto', sans-serif; + color: rgb(0, 0, 0, 87%); + margin-top: 0; +} + +#container { + display: flex; + flex-direction: row; + align-items: flex-start; +} + +@media (max-width: 767px) { + body { + width: 100%; + } + #container { + margin: 0; + flex-direction: column; + align-items: stretch; + } +} + +h1, +h2, +h3, +h4 { + color: rgb(0, 0, 0, 54%); +} + +.header { + color: white; + background-color: #3f51b5; + padding: 8px 16px; + margin-bottom: 16px; + display: flex; + flex-direction: row; + align-items: center; +} + +.repo-selector { + margin-left: 16px; + font-size: 14px; + width: 250px; + height: 32px; + padding: 2px; +} + +.left-div, +.right-div { + background-color: white; + flex: 1; +} + +.left-div { + padding: 16px; + margin-right: 16px; +} + +@media (max-width: 767px) { + .left-div { + margin: 0; + } +} + +.contributor-list { + list-style-type: none; + padding: 0; + margin: 0; +} + +.alert { + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border-radius: 0.25rem; + flex: 1; +} + +.alert-error { + color: #721c24; + background-color: #f8d7da; +} + +.contributor-header { + font-size: 0.8rem; + color: rgb(0, 0, 0, 54%); + padding: 16px 16px 8px 16px; +} + +.contributor-item { + border-bottom: solid 1px rgb(0, 0, 0, 12%); + padding: 16px; + display: flex; + flex-direction: row; + align-items: center; + cursor: pointer; +} + +.contributor-avatar { + border-radius: 3px; + margin-right: 16px; + height: 48px; +} + +.contributor-data { + flex: 1; + display: flex; + flex-direction: row; + justify-content: space-between; + align-content: center; +} + +.contributor-badge { + font-size: 12px; + padding: 2px 8px; + line-height: 1rem; + background-color: gray; + color: white; + border-radius: 4px; +} + +table { + table-layout: fixed; + color: rgb(0, 0, 0, 81%); +} + +td { + vertical-align: top; +} + +td:first-child { + width: 100px; + min-width: 100px; + max-width: 100px; +} + +td.label { + font-weight: bold; +} + +.whiteframe { + margin-bottom: 8px; + border: none; + border-radius: 2px; + background-color: #fff; + box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.14), + 0 3px 3px -2px rgba(0, 0, 0, 0.12); +}