Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
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 3 .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 2 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 188 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 132 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;
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.