Skip to content

Commit 2be100d

Browse files
authored
Add files via upload
1 parent 5052a59 commit 2be100d

8 files changed

Lines changed: 484 additions & 0 deletions

File tree

homework/src/App.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
'use strict';
2+
3+
/* global Util, Repository, Contributor */
4+
5+
class App {
6+
constructor(url) {
7+
this.initialize(url);
8+
}
9+
10+
/**
11+
* Initialization
12+
* @param {string} url The GitHub URL for obtaining the organization's repositories.
13+
*/
14+
async initialize(url) {
15+
// Add code here to initialize your app
16+
// 1. Create the fixed HTML elements of your page
17+
// 2. Make an initial XMLHttpRequest using Util.fetchJSON() to populate your <select> element
18+
19+
const root = document.getElementById('root');
20+
// ...
21+
22+
try {
23+
// ...
24+
const repos = await Util.fetchJSON(url);
25+
this.repos = repos.map(repo => new Repository(repo));
26+
// ...
27+
} catch (error) {
28+
this.renderError(error);
29+
}
30+
}
31+
32+
/**
33+
* Removes all child elements from a container element
34+
* @param {*} container Container element to clear
35+
*/
36+
clearContainer(container) {
37+
while (container.firstChild) {
38+
container.removeChild(container.firstChild);
39+
}
40+
}
41+
42+
/**
43+
* Fetch contributor information for the selected repository and render the
44+
* repo and its contributors as HTML elements in the DOM.
45+
* @param {number} index The array index of the repository.
46+
*/
47+
async fetchContributorsAndRender(index) {
48+
try {
49+
const repo = this.repos[index];
50+
const contributors = await repo.fetchContributors();
51+
52+
const container = document.getElementById('container');
53+
this.clearContainer(container);
54+
55+
const leftDiv = Util.createAndAppend('div', container);
56+
const rightDiv = Util.createAndAppend('div', container);
57+
58+
const contributorList = Util.createAndAppend('ul', rightDiv);
59+
60+
repo.render(leftDiv);
61+
62+
contributors
63+
.map(contributor => new Contributor(contributor))
64+
.forEach(contributor => contributor.render(contributorList));
65+
} catch (error) {
66+
this.renderError(error);
67+
}
68+
}
69+
70+
/**
71+
* Render an error to the DOM.
72+
* @param {Error} error An Error object describing the error.
73+
*/
74+
renderError(error) {
75+
// Replace this comment with your code
76+
}
77+
}
78+
79+
const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
80+
81+
window.onload = () => new App(HYF_REPOS_URL);

homework/src/Contributor.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
/* global Util */
4+
5+
// eslint-disable-next-line no-unused-vars
6+
class Contributor {
7+
constructor(data) {
8+
this.data = data;
9+
}
10+
11+
/**
12+
* Render the contributor info to the DOM.
13+
* @param {HTMLElement} contributorList The parent element in which to render the contributor.
14+
*/
15+
render(contributorList) {
16+
// Replace this comment with your code
17+
}
18+
}

homework/src/Repository.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
/* global Util */
4+
5+
// eslint-disable-next-line no-unused-vars
6+
class Repository {
7+
constructor(data) {
8+
this.data = data;
9+
}
10+
11+
/**
12+
* Render the repository info to the DOM.
13+
* @param {HTMLElement} parent The parent element in which to render the repository.
14+
*/
15+
render(parent) {
16+
//
17+
// Replace this comment with your code
18+
//
19+
}
20+
21+
/**
22+
* Returns an array of contributors as a promise
23+
*/
24+
fetchContributors() {
25+
return Util.fetchJSON(this.data.contributors_url);
26+
}
27+
28+
/**
29+
* Returns the name of the repository
30+
*/
31+
name() {
32+
return this.data.name;
33+
}
34+
}

homework/src/Util.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
// eslint-disable-next-line no-unused-vars
4+
class Util {
5+
static createAndAppend(name, parent, options = {}) {
6+
const elem = document.createElement(name);
7+
parent.appendChild(elem);
8+
Object.keys(options).forEach((key) => {
9+
const value = options[key];
10+
if (key === 'text') {
11+
elem.innerText = value;
12+
} else {
13+
elem.setAttribute(key, value);
14+
}
15+
});
16+
return elem;
17+
}
18+
19+
static fetchJSON(url) {
20+
return new Promise((resolve, reject) => {
21+
const xhr = new XMLHttpRequest();
22+
xhr.open('GET', url);
23+
xhr.responseType = 'json';
24+
xhr.onload = () => {
25+
if (xhr.status < 400) {
26+
resolve(xhr.response);
27+
} else {
28+
reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`));
29+
}
30+
};
31+
xhr.onerror = () => reject(new Error('Network request failed'));
32+
xhr.send();
33+
});
34+
}
35+
}

homework/src/hyf.png

6.81 KB
Loading

homework/src/index.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
7+
<meta name="theme-color" content="#000000">
8+
<meta name="apple-mobile-web-app-capable" content="yes">
9+
<meta name="mobile-web-app-capable" content="yes">
10+
<meta name="format-detection" content="telephone=no">
11+
<link rel="apple-touch-icon" href="./hyf.png">
12+
<link rel="shortcut icon" type="image/png" href="./hyf.png" />
13+
<title>HYF-GITHUB</title>
14+
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet">
15+
<link rel="stylesheet" href="./style.css">
16+
</head>
17+
18+
<body>
19+
<div id="root"></div>
20+
<script src="./index.js"></script>
21+
</body>
22+
23+
</html>

homework/src/index.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
'use strict';
2+
3+
{
4+
function fetchJSON(url) {
5+
return new Promise((resolve, reject) => {
6+
const xhr = new XMLHttpRequest();
7+
xhr.open('GET', url);
8+
xhr.responseType = 'json';
9+
xhr.onload = () => {
10+
if (xhr.status < 400) {
11+
resolve(xhr.response);
12+
} else {
13+
reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`));
14+
}
15+
};
16+
xhr.onerror = () => reject(new Error('Network request failed'));
17+
xhr.send();
18+
});
19+
}
20+
21+
function createAndAppend(name, parent, options = {}) {
22+
const elem = document.createElement(name);
23+
parent.appendChild(elem);
24+
Object.keys(options).forEach((key) => {
25+
const value = options[key];
26+
if (key === 'text') {
27+
elem.innerText = value;
28+
} else {
29+
elem.setAttribute(key, value);
30+
}
31+
});
32+
return elem;
33+
}
34+
const root = document.getElementById('root');
35+
36+
function repo(data) {
37+
data.sort((a, b) => a.name.localeCompare(b.name));
38+
const root = document.getElementById('root');
39+
const div = createAndAppend("div", root, { id: "mainCon" });
40+
createAndAppend("p", div, { text: "HYF Repositories", id: "HYF_Repositories" });
41+
const select = createAndAppend("select", div);
42+
for (let i = 0; i < data.length; i++) {
43+
createAndAppend("option", select, { text: data[i].name, value: i, class: "options" });
44+
}
45+
select.addEventListener("change", () => repoInfo(data, select));
46+
repoInfo(data, select);
47+
}
48+
49+
function repoInfo(data, select) {
50+
if (document.getElementById("info")) {
51+
document.getElementById("info").remove();
52+
}
53+
const link = data[select.value].html_url;
54+
const name = data[select.value].name;
55+
const description = data[select.value].description;
56+
const forks = data[select.value].forks;
57+
const newDate = new Date(data[select.value].updated_at);
58+
const div = createAndAppend("div", root, { id: "info" });
59+
const ul = createAndAppend("ul", div, { id: "repository_info" });
60+
const li = createAndAppend("li", ul, { text: "Name: ", class: "repository_details" });
61+
createAndAppend("a", li, { text: name, href: link, target: "_blank" });
62+
createAndAppend("li", ul, { text: "Description: " + description, class: "repository_details" });
63+
createAndAppend("li", ul, { text: "Forks: " + forks, class: "repository_details" });
64+
createAndAppend("li", ul, { text: "Updated: " + newDate.toLocaleString('en-GB', { timeZone: 'UTC' }), class: "repository_details" });
65+
fetchJSON(data[select.value].contributors_url)
66+
.then((data) => { contributors(data); });
67+
}
68+
function contributors(data) {
69+
if (document.getElementById("contributors")) {
70+
document.getElementById("contributors").remove();
71+
}
72+
73+
const div = createAndAppend("div", root, { id: "contributors" });
74+
const h1 = createAndAppend("h1", div, { text: "Contributors" });
75+
const ul = createAndAppend("ul", div, { id: "contributors_info" });
76+
for (let i = 0; i < data.length; i++) {
77+
let li = createAndAppend("li", ul, { id: "contributor" });
78+
let img = createAndAppend("img", li, { src: data[i].avatar_url });
79+
let contname = data[i].login;
80+
let p = createAndAppend("p", li, { id: "name" });
81+
let link = data[i].html_url;
82+
createAndAppend("a", p, { text: contname, href: link, target: "_blank", id: "links" });
83+
let emptyDiv = createAndAppend("div", li, { id: "contributions" });
84+
let p1 = createAndAppend("p", emptyDiv, { text: data[i].contributions, id: "numbers" });
85+
86+
}
87+
}
88+
89+
function renderError(error) {
90+
console.log(error);
91+
}
92+
93+
function main(url) {
94+
fetchJSON(url)
95+
.then(data => repo(data))
96+
.catch(err => renderError(err));
97+
98+
}
99+
100+
const HYF_REPOS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
101+
window.onload = () => main(HYF_REPOS_URL);
102+
}

0 commit comments

Comments
 (0)