Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week2 #11

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"editor.detectIndentation": false,
"editor.tabSize": 2,
"cSpell.words": [
"Cramer",
"linebreak",
"plusplus",
"tabindex"
]
}
2 changes: 1 addition & 1 deletion homework/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class App {
* @param {Error} error An Error object describing the error.
*/
renderError(error) {
console.log(error); // TODO: replace with your own code
throw new Error(error); // TODO: replace with your own code
}
}

Expand Down
188 changes: 147 additions & 41 deletions homework/index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,153 @@
'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();
}
const mainDiv = document.body;
function createElement(parentElement, element, nameId) {
const newElement = document.createElement(element);
newElement.setAttribute('id', nameId);
parentElement.appendChild(newElement);
return newElement;
}

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;
}
const fetchRepositories = async url => {
const response = await fetch(url);
const dataList = await response.json();
return dataList;
};

const createOption = (item, index) => {
const newOption = document.createElement('option');
const repositoriesSelect = document.getElementById('repositoriesSelect');
newOption.className = 'repositoryOption';
newOption.text = item.name;
newOption.value = index;
repositoriesSelect.appendChild(newOption);
};

function appendToLi(indexLi, element, nameIdP1, textNodeP1, nameIdP2, textNodeP2) {
const p1 = createElement(indexLi, element, nameIdP1);
const contentP1 = document.createTextNode(textNodeP1);
p1.appendChild(contentP1);
const p2 = createElement(indexLi, element, nameIdP2);
const contentP2 = document.createTextNode(textNodeP2);
p2.appendChild(contentP2);
}

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) });
}
});
function createList(parentElement, element, lio, li1, li2, li3, aUrl) {
for (let y = 0; y < 4; y++) {
createElement(parentElement, element, `li${y}`);
}
const liTags = document.getElementsByTagName('li');
const p0 = createElement(liTags[0], 'p', 'repository');
const contentP0 = document.createTextNode('Repository:');
p0.appendChild(contentP0);
const aElement = createElement(liTags[0], 'a', 'repositoryValue');
aElement.href = aUrl;
const aContent = document.createTextNode(lio);
aElement.appendChild(aContent);
appendToLi(liTags[1], 'p', 'description', 'Description:', 'descriptionValue', li1);
appendToLi(liTags[2], 'p', 'forks', 'Forks:', 'forksValue', li2);
appendToLi(liTags[3], 'p', 'updated', 'Updated:', 'updatedValue', li3);
}

function handleContributors(contributors) {
const rightDiv = document.getElementById('rightDiv');
rightDiv.innerHTML = '';
const contributorsTitle = createElement(rightDiv, 'div', 'contributorsTitle');
const contributorsTitleContent = document.createTextNode('Contributors');
contributorsTitle.appendChild(contributorsTitleContent);
contributors.forEach(contributor => {
// create subDiv for each contributor
const subDiv = document.createElement('div');
subDiv.className = 'contributor';
rightDiv.appendChild(subDiv);
const image = document.createElement('img');
image.className = 'image';
image.setAttribute('src', contributor.avatar_url);
subDiv.appendChild(image);
const login = createElement(subDiv, 'p', 'login');
const loginContent = document.createTextNode(contributor.login);
login.appendChild(loginContent);
const contributions = createElement(subDiv, 'p', 'contributions');
const contributionsContent = document.createTextNode(contributor.contributions);
contributions.appendChild(contributionsContent);
});
}

const REPOS_URL = 'https://api.github.com/orgs/foocoding/repos?per_page=100';
const logContributors = async url => {
try {
const contributorsData = await fetchRepositories(url);
const FooCodingContributors = contributorsData.sort((a, b) =>
a.login.localeCompare(b.login, 'fr', { ignorePunctuation: true }),
);
handleContributors(FooCodingContributors);
} catch (error) {
const errorDiv = createElement(mainDiv, 'div', 'errorDiv');
const errorContent = document.createTextNode('error');
errorDiv.appendChild(errorContent);
}
};

window.onload = () => main(REPOS_URL);
function createPage(repositories) {
// create upperDiv
const upperDiv = createElement(mainDiv, 'div', 'upperDiv');
const upperDivP = createElement(upperDiv, 'p', 'upperDivP');
const upperDivPContent = document.createTextNode('FooCoding Repositories');
upperDivP.appendChild(upperDivPContent);
const select = createElement(upperDiv, 'select', 'repositoriesSelect');
repositories.forEach(createOption);
// create leftRightDivDiv
const leftRightDiv = createElement(mainDiv, 'div', 'leftRightDiv');
// create leftDiv
const leftDiv = createElement(leftRightDiv, 'div', 'leftDiv');
const repositoryDetails = createElement(leftDiv, 'ul', 'repositoryDetails');
const defaultRepository = repositories[0];
const updated = defaultRepository.updated_at;
const formatUpdated = updated.replace(/T/, ', ').replace(/Z/, '');
createList(
repositoryDetails,
'li',
defaultRepository.name,
defaultRepository.description,
defaultRepository.forks,
formatUpdated,
defaultRepository.html_url,
);
// create rightDiv
createElement(leftRightDiv, 'div', 'rightDiv');
// fetch contributors to implement the rightDiv
const defaultContributorsUrl = defaultRepository.contributors_url;
logContributors(defaultContributorsUrl);
// addEventListener on select change
select.addEventListener('change', () => {
const liElement = document.querySelectorAll('li');
for (let i = 0; i < liElement.length; i++) {
liElement[i].parentElement.removeChild(liElement[i]);
}
const selectedRepository = repositories[select.value];
const updatedForSelect = selectedRepository.updated_at;
const formatUpdatedForSelect = updatedForSelect.replace(/T/, ', ').replace(/Z/, '');
createList(
repositoryDetails,
'li',
selectedRepository.name,
selectedRepository.description,
selectedRepository.forks,
formatUpdatedForSelect,
);
const ContributorsUrl = selectedRepository.contributors_url;
logContributors(ContributorsUrl);
});
}

const logData = async url => {
try {
const repositoriesData = await fetchRepositories(url);
const FooCodingRepositories = repositoriesData.sort((a, b) =>
a.name.localeCompare(b.name, 'fr', { ignorePunctuation: true }),
);
createPage(FooCodingRepositories);
} catch (error) {
const errorDiv = createElement(mainDiv, 'div', 'errorDiv');
const errorContent = document.createTextNode('error');
errorDiv.appendChild(errorContent);
}
};
logData('https://api.github.com/orgs/foocoding/repos?per_page=100');
132 changes: 129 additions & 3 deletions homework/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,129 @@
.alert-error {
color: red;
}
body {
max-width: 768px;
width: 100%;
margin-top: 0px;
margin-right: auto;
margin-left: auto;
background-color: #d3d3d3;
font-family: 'Roboto', sans-serif;
text-align: left;
color: rgb(0, 0, 0, 87%);
}
#upperDiv {
display: flex;
width: 93%;
margin-left: 3%;
margin-right: 4%;
background-color: #0072ce;
}
#upperDivP {
color: white;
width: 40%;
padding-left: 2%;
font-size: 10px;
}
#repositoriesSelect {
width: 40%;
border-radius: 4px;
font-size: 9px;
}
#leftRightDiv {
display: flex;
font-size: 8px;
}
#leftDiv {
margin-top: 2%;
margin-left: 3%;
margin-right: 3%;
width: 45%;
height: 45%;
background-color: white;
}
#rightDiv {
width: 45%;
margin-top: 2%;
background-color: white;
}
ul {
margin-right: 4%;
}
#li0,
#li1,
#li2,
#li3 {
display: flex;
}
#repository,
#description,
#forks,
#updated {
width: 30%;
margin-top: 1%;
margin-left: 0%;
font-weight: bold;
}
#repositoryValue,
#descriptionValue,
#forksValue,
#updatedValue {
width: 70%;
margin-top: 1%;
padding-left: 6%;
padding-right: 6%;
}
#contributorsTitle {
margin-left: 10%;
font-weight: bold;
color: #a9a9a9;
margin-top: auto;
padding-top: 4%;
padding-bottom: 4%;
}
.contributor {
display: flex;
margin-top: auto;
border-bottom: 0.3px solid #a9a9a9;
padding-top: 4%;
padding-bottom: 4%;
}
.contributor > .image {
width: 20%;
height: 20%;
margin-left: 10%;
border-radius: 4px;
}
#login {
width: 30%;
margin-top: 15%;
margin-left: 3%;
font-weight: bold;
}
#contributions {
width: 8%;
height: 14%;
margin-top: 15%;
margin-left: 20%;
background-color: rgb(169, 169, 169);
text-align: center;
border-radius: 4px;
font-weight: bold;
color: white;
}
@media (min-width: 769px) and (max-width: 1024px) {
#leftRightDiv {
font-size: 12px;
}
}
@media (min-width: 1025px) and (max-width: 1280px) {
#upperDivP {
width: 30%;
font-size: 14px;
}
#repositoriesSelect {
width: 22%;
font-size: 12px;
}
#leftRightDiv {
font-size: 14px;
}
}