Skip to content
This repository was archived by the owner on May 14, 2024. It is now read-only.

Commit b47cf62

Browse files
committed
Week3 Completed
1 parent 86c64ae commit b47cf62

3 files changed

Lines changed: 310 additions & 0 deletions

File tree

‎Week3/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>

‎Week3/index.js‎

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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.send();
17+
});
18+
}
19+
20+
function createAndAppend(name, parent, options = {}) {
21+
const elem = document.createElement(name);
22+
parent.appendChild(elem);
23+
Object.keys(options).forEach(key => {
24+
const value = options[key];
25+
if (key === 'text') {
26+
elem.textContent = value;
27+
} else {
28+
elem.setAttribute(key, value);
29+
}
30+
});
31+
return elem;
32+
}
33+
function loadDetail(element) {
34+
const leftID = document.getElementById('leftID');
35+
createAndAppend('ul', leftID, { id: 'leftDetailID', class: 'leftDetailClass' });
36+
37+
const leftDetailID = document.getElementById('leftDetailID');
38+
createAndAppend('li', leftDetailID, {
39+
id: 'leftListID',
40+
class: 'leftListClass',
41+
text: 'Repository: ',
42+
});
43+
44+
const leftListID = document.getElementById('leftListID');
45+
createAndAppend('a', leftListID, {
46+
text: element.name,
47+
href: element.html_url,
48+
id: 'repositoryNameID',
49+
class: 'repositoryNameClass',
50+
});
51+
52+
createAndAppend('li', leftDetailID, {
53+
id: 'descList',
54+
text: `Description: ${element.description}`,
55+
});
56+
createAndAppend('li', leftDetailID, { text: `Forks: ${element.forks}` });
57+
const updatedAt = new Date(element.updated_at).toLocaleString();
58+
createAndAppend('li', leftDetailID, { text: `Updated: ${updatedAt}` });
59+
}
60+
async function loadContributor(element) {
61+
const root = document.getElementById('root');
62+
try {
63+
const data = await fetchJSON(element.contributors_url);
64+
const rightID = document.getElementById('rightID');
65+
createAndAppend('p', rightID, { id: 'contTextID', text: 'Contributors' });
66+
createAndAppend('ul', rightID, { id: 'contListID', class: 'contListClass' });
67+
68+
let contURL;
69+
let contData;
70+
let contDetail;
71+
const contListID = document.getElementById('contListID');
72+
for (let i = 0; i < data.length; i++) {
73+
contURL = createAndAppend('a', contListID, {
74+
href: data[i].html_url,
75+
target: '_blank',
76+
id: 'contUrlID',
77+
class: 'contUrlClass',
78+
});
79+
contData = createAndAppend('li', contURL, {
80+
id: 'contDataID',
81+
class: 'contDataClass',
82+
});
83+
84+
createAndAppend('img', contData, {
85+
src: data[i].avatar_url,
86+
id: 'contImgID',
87+
class: 'contImgClass',
88+
});
89+
90+
contDetail = createAndAppend('div', contData, {
91+
id: 'contDetailID',
92+
class: 'contDetailClass',
93+
});
94+
createAndAppend('div', contDetail, { text: data[i].login });
95+
createAndAppend('div', contDetail, {
96+
text: data[i].contributions,
97+
id: 'contBadgeID',
98+
class: 'contBadgeClass',
99+
});
100+
}
101+
} catch (err) {
102+
createAndAppend('div', root, {
103+
id: 'err.message',
104+
class: 'alert-error',
105+
});
106+
}
107+
}
108+
109+
async function main(url) {
110+
const root = document.getElementById('root');
111+
try {
112+
const data = await fetchJSON(url);
113+
createAndAppend('header', root, {
114+
id: 'topBoxID',
115+
class: 'topBoxClass',
116+
});
117+
const topBoxID = document.getElementById('topBoxID');
118+
createAndAppend('p', topBoxID, {
119+
id: 'topTextID',
120+
class: 'topTextClass',
121+
text: 'HYF Repositories',
122+
});
123+
124+
createAndAppend('div', root, { id: 'mainContainerID', class: 'mainContainerClass' });
125+
126+
const mainContainerID = document.getElementById('mainContainerID');
127+
createAndAppend('div', mainContainerID, { id: 'leftID', class: 'leftClass' });
128+
createAndAppend('div', mainContainerID, { id: 'rightID', class: 'rightClass' });
129+
createAndAppend('select', topBoxID, { id: 'repsSelectID', Class: 'repsSelectClass' });
130+
data.sort((a, b) => a.name.localeCompare(b.name));
131+
132+
const repsSelectID = document.getElementById('repsSelectID');
133+
for (let index = 0; index < data.length; index++) {
134+
createAndAppend('option', repsSelectID, {
135+
value: index,
136+
text: data[index].name,
137+
id: 'optionID',
138+
class: 'optionClass',
139+
});
140+
}
141+
const selector = document.getElementById('repsSelectID');
142+
143+
loadDetail(data[0]);
144+
loadContributor(data[0]);
145+
146+
selector.onchange = () => {
147+
const leftID = document.getElementById('leftID');
148+
leftID.parentNode.removeChild(leftID);
149+
150+
const rightID = document.getElementById('rightID');
151+
rightID.parentNode.removeChild(rightID);
152+
153+
const i = selector.value;
154+
155+
createAndAppend('div', mainContainerID, { id: 'leftID', class: 'leftClass' });
156+
createAndAppend('div', mainContainerID, { id: 'rightID', class: 'rightClass' });
157+
loadDetail(data[i]);
158+
loadContributor(data[i]);
159+
};
160+
} catch (error) {
161+
createAndAppend('div', root, { text: error.message, class: 'alert-error' });
162+
}
163+
}
164+
165+
const HYF_REPS_URL = 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
166+
167+
window.onload = () => main(HYF_REPS_URL);
168+
}

‎Week3/style.css‎

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
.alert-error {
2+
color: #721c24;
3+
background-color: #f8d7da;
4+
}
5+
6+
body {
7+
margin-left: auto;
8+
margin-right: auto;
9+
font-family: Arial, Helvetica, sans-serif;
10+
color: black;
11+
margin-top: 0;
12+
background-color: #f8f8f8;
13+
width: 900px;
14+
}
15+
16+
.mainContainerClass {
17+
display: flex;
18+
flex-direction: row;
19+
align-items: flex-start;
20+
}
21+
22+
@media (max-width: 767px) {
23+
body {
24+
width: 100%;
25+
}
26+
#mainContainerClass {
27+
margin: 0;
28+
flex-direction: column;
29+
align-items: stretch;
30+
}
31+
}
32+
33+
.topBoxClass {
34+
color: white;
35+
background-color: #3f51b5;
36+
padding: 8px 16px;
37+
margin-bottom: 16px;
38+
display: flex;
39+
flex-direction: row;
40+
align-items: center;
41+
}
42+
43+
.topTextClass {
44+
margin-left: 40px;
45+
font-size: 30px;
46+
font-family: 'Trebuchet MS';
47+
width: 350px;
48+
height: 32px;
49+
padding: 2px;
50+
}
51+
52+
.repsSelectClass {
53+
margin-left: 30px;
54+
font-size: 18px;
55+
width: 350px;
56+
height: 32px;
57+
padding: 2px;
58+
}
59+
60+
.leftClass, .rightClass {
61+
background-color: white;
62+
flex: 1;
63+
padding: 16px;
64+
margin-right: 16px;
65+
margin-bottom: 8px;
66+
border: none;
67+
border-radius: 2px;
68+
background-color: white;
69+
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)
70+
}
71+
72+
.leftDetailClass {
73+
table-layout: fixed;
74+
color: rgb(0, 0, 0, 81%);
75+
}
76+
77+
@media (max-width: 767px) {
78+
.leftClass {
79+
margin: 0;
80+
}
81+
}
82+
83+
#contTextID {
84+
font-size: 0.9rem;
85+
color: rgb(0, 0, 0, 54%);
86+
padding: 8px 16px 4px 16px;
87+
}
88+
89+
.contDataClass {
90+
border-bottom: solid 1px rgb(0, 0, 0, 12%);
91+
padding: 16px;
92+
display: flex;
93+
flex-direction: row;
94+
align-items: center;
95+
cursor: pointer;
96+
}
97+
98+
.contImgClass {
99+
border-radius: 3px;
100+
margin-right: 16px;
101+
height: 48px;
102+
}
103+
104+
.contDetailClass {
105+
flex: 1;
106+
display: flex;
107+
flex-direction: row;
108+
justify-content: space-between;
109+
align-content: center;
110+
}
111+
112+
.contBadgeClass {
113+
font-size: 12px;
114+
padding: 2px 8px;
115+
line-height: 1rem;
116+
background-color: gray;
117+
color: white;
118+
border-radius: 4px;
119+
}

0 commit comments

Comments
 (0)