diff --git a/Week1/homework/js-exercises/dogPhotoGallary.js b/Week1/homework/js-exercises/dogPhotoGallary.js
new file mode 100644
index 000000000..61bb2fd02
--- /dev/null
+++ b/Week1/homework/js-exercises/dogPhotoGallary.js
@@ -0,0 +1,42 @@
+'use strict'
+//add event listener
+
+const xhrBtn = document.getElementById('xhr');
+const axiosBtn = document.getElementById('axi');
+
+xhrBtn.addEventListener('click', imageXHR);
+axiosBtn.addEventListener('click', imageAxios);
+
+//XHR function
+function imageXHR() {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', 'https://dog.ceo/api/breeds/image/random');
+ xhr.responseType = 'json';
+ xhr.onload = () => {
+ createImage(xhr.response.message);
+ };
+ xhr.send();
+}
+//Axios function
+function imageAxios() {
+ axios
+ .get('https://dog.ceo/api/breeds/image/random')
+ .then(res => {
+ createImage(res.data.message);
+ })
+ .catch(err => console.error(err));
+}
+
+//Manupolating DOM function
+function createImage(dogImg) {
+
+ const imgUl = document.getElementById('imgUl');
+ const img = document.createElement('img');
+ const li = document.createElement('li');
+
+ img.setAttribute('src', dogImg);
+ img.style = 'width:200px; height:200px';
+
+ li.appendChild(img);
+ imgUl.appendChild(li);
+}
\ No newline at end of file
diff --git a/Week1/homework/js-exercises/dogPhotoGallery.html b/Week1/homework/js-exercises/dogPhotoGallery.html
new file mode 100644
index 000000000..9143fd811
--- /dev/null
+++ b/Week1/homework/js-exercises/dogPhotoGallery.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+ Dog Photos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week1/homework/js-exercises/programmerHumor.html b/Week1/homework/js-exercises/programmerHumor.html
new file mode 100644
index 000000000..1edcfc706
--- /dev/null
+++ b/Week1/homework/js-exercises/programmerHumor.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Programmer Humor
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week1/homework/js-exercises/programmerHumor.js b/Week1/homework/js-exercises/programmerHumor.js
new file mode 100644
index 000000000..f7edc350d
--- /dev/null
+++ b/Week1/homework/js-exercises/programmerHumor.js
@@ -0,0 +1,48 @@
+
+//XHR function
+function apiWithXhr(url, callback) {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = 'json';
+ xhr.onload = () => {
+ callback(null, {
+ response: xhr.response,
+ status: xhr.status,
+ readyState: xhr.readyState,
+ });
+ }
+ xhr.onerror = () => callback('Error!');
+ xhr.send();
+}
+
+const url = 'https://xkcd.now.sh/?comic=614';
+//error handeler
+apiWithXhr(url, (err, data) => {
+ if (err) {
+ console.error(err);
+ return;
+ }else if (data.status == 200 && data.readyState == 4) {
+ renderImg(data.response, 'Images with XHR');
+ }else {
+ console.error('Error(load: ', data.response, 'Status: ', data.status);
+ }
+});
+
+//axios function
+axios
+.get('https://xkcd.now.sh/?comic=614')
+.then(res => {
+ renderImg(res.data, 'Images with AXIOS');
+})
+.catch(err => console.error(err));
+
+function renderImg(data, text) {
+
+ console.log(data);
+ const h1 = document.createElement('h1');
+ h1.textContent = text;
+ const img = document.createElement('img');
+ img.setAttribute('src', data.img);
+ document.body.appendChild(h1);
+ document.body.appendChild(img);
+}
\ No newline at end of file
diff --git a/Week1/homework/js-exercises/whoDo.html b/Week1/homework/js-exercises/whoDo.html
new file mode 100644
index 000000000..2990181d5
--- /dev/null
+++ b/Week1/homework/js-exercises/whoDo.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+ Who Do we have here?
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week1/homework/project/index.html b/Week1/homework/project/index.html
new file mode 100644
index 000000000..ebbfb1120
--- /dev/null
+++ b/Week1/homework/project/index.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ HYF-GITHUB
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week1/homework/project/index.js b/Week1/homework/project/index.js
new file mode 100644
index 000000000..874014316
--- /dev/null
+++ b/Week1/homework/project/index.js
@@ -0,0 +1,91 @@
+'use strict';
+
+{
+ function fetchJSON(url, cb) {
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = 'json';
+ xhr.onload = () => {
+ if (xhr.status >= 200 && xhr.status <= 299) {
+ 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.entries(options).forEach(([key, value]) => {
+ if (key === 'text') {
+ elem.textContent = value;
+ } else {
+ elem.setAttribute(key, value);
+ }
+ });
+ return elem;
+ }
+
+ function renderRepoDetails(repo, ul) {
+ // create repositories list
+ const li = createAndAppend('li', ul, { class: 'repoList' });
+ const div = createAndAppend('div', li, { class: 'repository' });
+ // create Repository table
+ const table = createAndAppend('table', div);
+
+ // create Repository title row
+ const tr1 = createAndAppend('tr', table);
+ createAndAppend('td', tr1, { text: 'Repository:', class: 'title' });
+ const td = createAndAppend('td', tr1);
+ createAndAppend('a', td, {
+ href: repo.html_url,
+ text: repo.name,
+ target: '_blank'
+ });
+
+ // create Description row
+ const tr2 = createAndAppend('tr', table);
+ createAndAppend('td', tr2, { text: 'Description:', class: 'title' });
+ createAndAppend('td', tr2, { text: repo.description });
+
+ // create Fork row
+ const tr3 = createAndAppend('tr', table);
+ createAndAppend('td', tr3, { text: 'Forks:', class: 'title' });
+ createAndAppend('td', tr3, { text: repo.forks });
+
+ // create Updated row
+ const tr4 = createAndAppend('tr', table);
+ createAndAppend('td', tr4, { text: 'Updated:', class: 'title' });
+ createAndAppend('td', tr4, { text: repo.updated_at });
+ }
+
+ function main(url) {
+ fetchJSON(url, (err, repos) => {
+ const root = document.getElementById('root');
+ // create the page header
+ createAndAppend('div', root, {
+ text: 'HYF Repositories',
+ class: 'head',
+ });
+
+ if (err) {
+ createAndAppend('div', root, {
+ text: err.message,
+ class: 'alert-error',
+ });
+ return;
+ }
+ const ul = createAndAppend('ul', root, {class: 'repoUl'});
+ // sorting the repositories form A to Z
+ repos.sort((currentRepo, nextRepo) => currentRepo.name.localeCompare(nextRepo.name));
+ repos.forEach(repo => renderRepoDetails(repo, ul));
+ });
+ }
+
+ const HYF_REPOS_URL =
+ 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
+ window.onload = () => main(HYF_REPOS_URL);
+}
\ No newline at end of file
diff --git a/Week1/homework/project/style.css b/Week1/homework/project/style.css
new file mode 100644
index 000000000..734ee9180
--- /dev/null
+++ b/Week1/homework/project/style.css
@@ -0,0 +1,57 @@
+body {
+ font-family: italic 20px Serif;
+}
+
+ #root {
+ width: 80%;
+ margin: auto;
+ }
+
+ .alert-error {
+ color: #9D1C24;
+ background-color: #F8D7DA;
+ height: 50px;
+ padding: 20px 0 0 10px;
+ margin-top: 5px;
+ }
+
+ .head {
+ background-color: purple;
+ color: #ffffff;
+ height: 50px;
+ padding: 20px 0 0 10px;
+ margin-top: 5px;;
+ font-size: 1.5rem;
+ }
+
+ .title {
+ font-weight: bold;
+ padding: 5px 0 5px 5px;
+ }
+
+ .repoUl {
+ margin: 0;
+ padding: 0;
+ }
+
+ .repoList {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ }
+
+ .repository {
+ box-shadow: 2px 2px 15px -2px rgba(133,126,133,1);
+ margin: 7px 0 7px 0;
+ }
+
+ @media only screen and (max-width: 600px) {
+ #root {
+ width: 100%;
+ font-size: 14px;
+ }
+
+ .head {
+ text-align: center;
+ }
+ }
\ No newline at end of file
diff --git a/Week2/homework/index.html b/Week2/homework/index.html
new file mode 100644
index 000000000..d71898f8f
--- /dev/null
+++ b/Week2/homework/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ HYF Version-2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week2/homework/index.js b/Week2/homework/index.js
new file mode 100644
index 000000000..dc309f91a
--- /dev/null
+++ b/Week2/homework/index.js
@@ -0,0 +1,141 @@
+/* eslint-disable no-console */
+/* eslint-disable no-use-before-define */
+/* eslint-disable no-unused-vars */
+const createAndAppend = (name, parent, options = {}) => {
+ const elem = document.createElement(name);
+ parent.appendChild(elem);
+ Object.entries(options).forEach(([key, value]) => {
+ if (key === 'innerHTML') {
+ elem.innerHTML = value;
+ } else if (key === 'text') {
+ elem.textContent = value;
+ } else {
+ elem.setAttribute(key, value);
+ }
+ });
+ return elem;
+ };
+ const errorHandler = err => {
+ const root = document.getElementById('root');
+ createAndAppend('div', root, {
+ text: err.message,
+ class: 'alert-error',
+ });
+ };
+
+ const optionLoading = items => {
+ const selectEl = document.querySelector('#reposName');
+ items
+ .sort((current, next) => current.name.localeCompare(next.name))
+ .forEach(repo => {
+ createAndAppend('option', selectEl, {
+ text: repo.name,
+ value: repo.name,
+ });
+ });
+ };
+
+ const renderRepoContainer = repo => {
+ const { selectedIndex } = document.querySelector('select');
+ const convertedDate = new Date(
+ repo[selectedIndex].updated_at,
+ ).toLocaleString();
+ const repoContainer = document.querySelector('.repo-container');
+
+ createAndAppend('ul', repoContainer, { class: 'repoDetails' });
+ const cardUl = document.querySelector('.repoDetails');
+
+ createAndAppend('li', cardUl, {
+ innerHTML: `Repository :${repo[selectedIndex].name}`,
+ });
+ createAndAppend('li', cardUl, {
+ innerHTML: `Description: ${repo[selectedIndex].description}`,
+ });
+ createAndAppend('li', cardUl, {
+ innerHTML: `Forks: ${repo[selectedIndex].forks_count}`,
+ });
+ createAndAppend('li', cardUl, {
+ innerHTML: `Updated: ${convertedDate}`,
+ });
+
+ return repo;
+ };
+
+ const renderRepoContributors = repo => {
+ const { selectedIndex } = document.querySelector('select');
+ const selectedRepo = repo[selectedIndex];
+
+ const repoContributors = document.querySelector('.contributors-container');
+ createAndAppend('ul', repoContributors, { class: 'repoContributors' });
+ const ulContributors = document.querySelector('.repoContributors');
+
+ createAndAppend('h5', ulContributors, {
+ text: 'Contributions',
+ style: 'margin:0 0 5px 0; font-size: 15px; ',
+ });
+
+ fetchJSON(selectedRepo.contributors_url)
+ .then(data =>
+ data.forEach(dataSelected => {
+ const li = createAndAppend('li', ulContributors, {
+ style:
+ 'display: flex;text-align: center; justify-content: space-between; border-bottom: 2px solid #687466;',
+ });
+ const imgAvatar = createAndAppend('img', li, {
+ src: dataSelected.avatar_url,
+ class: 'avatar',
+ });
+ const contInfo = createAndAppend('a', li, {
+ text: dataSelected.login,
+ href: dataSelected.html_url,
+ target: '_blank',
+ style: 'margin: 20px auto 0 5px; text-decoration: none;',
+ });
+ const contCount = createAndAppend('span', li, {
+ text: dataSelected.contributions,
+ class: 'contributions-count',
+ });
+ }),
+ )
+ .catch(err => console.error(err));
+ };
+
+ const renderSelectedOptionChange = repo => {
+ const selectRepo = document.querySelector('select');
+ selectRepo.addEventListener('change', () => {
+ document.querySelector('section.repo-container ul').remove();
+ document.querySelector('.repoContributors').remove();
+
+ renderRepoContainer(repo);
+ renderRepoContributors(repo);
+ });
+ };
+
+ const fetchJSON = url => {
+ const repos = fetch(url)
+ .then(res => {
+ if (!res.ok) {
+ throw new Error('Network response was not ok');
+ }
+ return res.json();
+ })
+ .then(data => data)
+ .catch(err => errorHandler(err));
+ return repos;
+ };
+
+ const main = url => {
+ fetchJSON(url)
+ .then(data => {
+ optionLoading(data);
+ renderRepoContainer(data);
+ renderRepoContributors(data);
+ renderSelectedOptionChange(data);
+ })
+ .catch(err => errorHandler(err));
+ };
+
+ const HYF_REPOS_URL =
+ 'https://api.github.com/orgs/HackYourFuture/repos?per_page=30';
+
+ main(HYF_REPOS_URL);
\ No newline at end of file
diff --git a/Week2/homework/style.css b/Week2/homework/style.css
new file mode 100644
index 000000000..fbae9cdfa
--- /dev/null
+++ b/Week2/homework/style.css
@@ -0,0 +1,84 @@
+
+body {
+ font-family: italic 20px Serif;
+}
+.CardHeader {
+ background-color:palevioletred;
+ color: white;
+ justify-content: left;
+ padding:10px;
+ margin-bottom: 5px;
+ border: 1px solid aqua;
+ width: auto;
+}
+
+.repoDetails {
+ display: inline-block;
+ background-color: white;
+ padding: 15px;
+ line-height: 20px;
+ border: 1px solid black;
+ list-style-type: none;
+}
+
+.repoDetails li span {
+ font-size: 15px;
+ white-space: normal;
+}
+.firstText {
+ display: inline-block;
+ margin-right: 5px;
+ font-weight: bolder;
+ width: 85px;
+}
+.main-container {
+ display: flex;
+}
+.repoContributors {
+ display: inline-block;
+ width: 90%;
+ background-color: white;
+ padding: 15px;
+ line-height: 20px;
+ border: 1px solid black;
+ list-style-type: none;
+}
+
+.repo-container {
+ width: 100%;
+ margin-left: 15px;
+}
+.contributors-container {
+ width: 100%;
+}
+.avatar {
+ margin-bottom: 3px;
+ margin-top: 3px;
+ width: 65px;
+ border-radius: 50%;
+}
+.contributions-count {
+ background-color: cadetblue;
+ border: 2px solid rgba(0, 0, 0, 0.17);
+ font-weight: bold;
+ border-radius: 5px;
+ padding: 7px;
+ margin: 15px 5px 25px 0;
+}
+.alert-error {
+ width: 72%;
+ margin: 2px 0;
+ padding: 10px;
+ border-radius: 3px 3px 3px 3px;
+ color: #d8000c;
+ background-color: #ffbaba;
+}
+@media screen and (max-width: 700px) {
+ .repo-container,
+ .contributors-container {
+ width: 100%;
+ }
+ .main-container {
+ display: block;
+ }
+}
\ No newline at end of file
diff --git a/Week3/homework/part1/hyf.png b/Week3/homework/part1/hyf.png
new file mode 100644
index 000000000..76bc5a13b
Binary files /dev/null and b/Week3/homework/part1/hyf.png differ
diff --git a/Week3/homework/part1/index.html b/Week3/homework/part1/index.html
new file mode 100644
index 000000000..f9cc7119e
--- /dev/null
+++ b/Week3/homework/part1/index.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ HYF-GITHUB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week3/homework/part1/index.js b/Week3/homework/part1/index.js
new file mode 100644
index 000000000..4e4cbc7e9
--- /dev/null
+++ b/Week3/homework/part1/index.js
@@ -0,0 +1,175 @@
+'use strict';
+
+{
+ // root div declaration
+ const root = document.getElementById('root');
+
+ // this function will fetch JSON data using async/await and axios
+ async function fetchJSON(url) {
+
+ try {
+
+ const response = await axios.get(url);
+ // throw the error if exists
+ if (!response.statusText) {
+ throw new Error(`Network error: ${response.status},${response.statusText}`);
+ }
+ const resData = await response.data;
+ // return the fetched data
+ return resData;
+
+ }
+ catch (error) {
+ // catch the error if exists
+ printError(error);
+
+ }
+ }
+
+ // this function create and append elements
+ function createAndAppend(name, parent, options = {}) {
+ const elem = document.createElement(name);
+ parent.appendChild(elem);
+ Object.entries(options).forEach(([key, value]) => {
+ if (key === 'text') {
+ elem.textContent = value;
+ } else {
+ elem.setAttribute(key, value);
+ }
+ });
+ return elem;
+ }
+
+ // this function render the selected Repository details
+ function renderRepoDetails(repo, repoContainer) {
+ // create Repository table
+ const table = createAndAppend('table', repoContainer);
+
+ // create Repository title row
+ const titleTr = createAndAppend('tr', table);
+ createAndAppend('td', titleTr, { text: 'Repository:', class: 'title' });
+ const td = createAndAppend('td', titleTr);
+ createAndAppend('a', td, {
+ href: repo.html_url,
+ text: repo.name,
+ target: '_blank'
+ });
+
+ // create Description row
+ const descriptionTr = createAndAppend('tr', table);
+ createAndAppend('td', descriptionTr, { text: 'Description:', class: 'title' });
+ createAndAppend('td', descriptionTr, { text: repo.description });
+
+ // create Fork row
+ const forksTr = createAndAppend('tr', table);
+ createAndAppend('td', forksTr, { text: 'Forks:', class: 'title' });
+ createAndAppend('td', forksTr, { text: repo.forks });
+
+ // create Updated row
+ const updatedTr = createAndAppend('tr', table);
+ createAndAppend('td', updatedTr, { text: 'Updated:', class: 'title' });
+ createAndAppend('td', updatedTr, { text: repo.updated_at });
+ }
+
+ // this function render the Contributions details
+ async function renderContributorsDetails(repo, contributorsContainer) {
+ // create section title
+ const ul = createAndAppend('ul', contributorsContainer, {
+ text: 'Contributions',
+ class: 'contributors-ul'
+ });
+
+ // fetch contributors data
+ try {
+ const contributors = await fetchJSON(repo.contributors_url);
+ // create contributors list
+ contributors.forEach( Contributor => {
+ const li = createAndAppend('li', ul, { class: 'Contributor-li' });
+ const ContributorDiv = createAndAppend('div', li, { class: 'Contributor-div' });
+
+ // create contributor image
+ createAndAppend('img', ContributorDiv, {
+ class: 'contributors-img',
+ src: Contributor.avatar_url,
+ });
+
+ // create contributor name
+ createAndAppend('a', ContributorDiv, {
+ class: 'contributors-a',
+ text: Contributor.login,
+ href: Contributor.html_url,
+ target: '_blank',
+ });
+
+ // create contributors number
+ createAndAppend('span', ContributorDiv, {
+ class: 'contributors-span',
+ text: Contributor.contributions,
+ });
+ });
+ }
+ catch(err) {
+ // catch the error if exists
+ printError(err);
+ }
+ }
+
+ // this function removes all childs of passed element
+ function removeElems(elem) {
+ while (elem.lastElementChild) {
+ elem.removeChild(elem.lastElementChild);
+ }
+ }
+
+ // this function print the catched error to window
+ function printError(err) {
+ createAndAppend('div', root, {
+ text: err.message,
+ class: 'alert-error',
+ });
+ }
+
+ // this is the main function
+ async function main(url) {
+ // fetch Repositories data
+ try {
+ const repos = await fetchJSON(url);
+ // declare the DOM elements for list and containers
+ const reposList = document.getElementById('repos-List');
+ const repoContainer = document.querySelector('.repo-container');
+ const contributorsContainer = document.querySelector('.contributors-container');
+
+ // sorting the repositories form A to Z
+ repos.sort((currentRepo, nextRepo) => currentRepo.name.localeCompare(nextRepo.name));
+
+ // filling the dropdown list with sorted repositories titles
+ repos.forEach(repo => {
+ createAndAppend('option', reposList, { text: repo.name, value: repo.name });
+ });
+
+ // display information about the first repository
+ renderRepoDetails(repos[0], repoContainer);
+ renderContributorsDetails(repos[0], contributorsContainer);
+
+ // refreshed for the newly selected repository when the user changes the selection
+ reposList.addEventListener('change', () => {
+ // empty the containers from old data when the user changes the selection
+ removeElems(repoContainer);
+ removeElems(contributorsContainer);
+ // find the selected repository and render the details
+ let currentRepo = repos.filter( repo => repo.name == reposList.value );
+ renderRepoDetails(currentRepo[0], repoContainer);
+ renderContributorsDetails(currentRepo[0], contributorsContainer);
+ });
+
+ }
+ catch(err) {
+ // catch the error if exists
+ printError(err);
+ }
+ }
+
+ const HYF_REPOS_URL =
+ 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
+ window.onload = () => main(HYF_REPOS_URL);
+}
\ No newline at end of file
diff --git a/Week3/homework/part1/style.css b/Week3/homework/part1/style.css
new file mode 100644
index 000000000..9913dba3f
--- /dev/null
+++ b/Week3/homework/part1/style.css
@@ -0,0 +1,146 @@
+body {
+ margin: 0;
+ padding: 0;
+ font-size: 16px;
+ font-family: Arial, Helvetica, sans-serif;
+ }
+
+ #root {
+ width: 80%;
+ margin: auto;
+ }
+
+ .alert-error {
+ color: #9D1C24;
+ background-color: #F8D7DA;
+ height: 50px;
+ padding: 20px 0 0 10px;
+ margin-top: 5px;
+ }
+
+ .head {
+ background-color: #3F51B5;
+ color: #ffffff;
+ height: 100px;
+ padding: 0px;
+ margin-top: 5px;
+ display: flex;
+ }
+
+ .head > h1 {
+ padding: 0.5rem 0 0 1rem;
+ }
+
+ #repos-List {
+ height: auto;
+ width: 20rem;
+ margin: auto 1rem ;
+ font-size: large;
+ }
+
+ .title {
+ font-weight: bold;
+ padding: 5px 0 5px 5px;
+ }
+
+ .main-container {
+ display: flex;
+ }
+
+ .repo-container, .contributors-container {
+ box-shadow: 2px 2px 15px -2px rgba(133,126,133,1);
+ margin: 7px 0 7px 0;
+ width: 50%;
+ }
+
+ .repo-container {
+ height: 8rem;
+ margin-right: 0.5rem;
+ }
+
+ .contributors-ul {
+ font-weight: bold;
+ padding: 5px 0 5px 5px;
+ list-style: none;
+ }
+
+ .Contributor-li {
+ margin: 1rem 0 1rem 0;
+ border-bottom: 1px solid #dfdcdc;
+ }
+
+ .Contributor-div {
+ height: 4.5rem;
+ }
+
+ .contributors-img {
+ width: 50px;
+ margin-left: 1rem;
+ }
+
+ .contributors-a {
+ margin: auto 1rem;
+ font-weight: normal;
+ position: relative;
+ bottom: 1.5rem;
+ }
+
+ .contributors-span {
+ margin: 1rem 1rem 0 0;
+ float: right;
+ font-weight: normal;
+ font-size: small;
+ text-align: center;
+ width: 2rem;
+ color: #ffffff;
+ background-color: #5f5d5d;
+ border-radius: 0.2rem;
+ }
+
+ /* Change style to be responsive to ---Mobile devices--- */
+
+ @media (max-width: 600px) {
+ #root {
+ width: 100%;
+ font-size: 14px;
+ }
+
+ .head > h1 {
+ font-size: 1rem;
+ padding: 2rem 0 0 1rem;
+ }
+
+ #repos-List {
+ width: 5rem;
+ margin: auto 1rem ;
+ font-size: small;
+ position: relative;
+
+ }
+
+ #repos-List option{
+ width: 5rem;
+
+ }
+
+ .main-container {
+ display: block;
+ }
+ .repo-container, .contributors-container {
+ width: 100%;
+ }
+ }
+
+ /* Change style to be responsive to --Tablets devices--*/
+
+ @media (min-width: 600px) and (max-width: 1024px) {
+ #root {
+ width: 95%;
+ font-size: 14px;
+ }
+
+ .head > h1 {
+ font-size: 1.5rem;
+ padding: 1rem 0 0 1rem;
+ }
+ }
\ No newline at end of file
diff --git a/Week3/homework/part2/App.js b/Week3/homework/part2/App.js
new file mode 100644
index 000000000..316fb93a7
--- /dev/null
+++ b/Week3/homework/part2/App.js
@@ -0,0 +1,56 @@
+use strict';
+
+{
+ const accounts = {
+ hyf: {
+ name: 'HackYourFuture',
+ type: 'org',
+ },
+ microsoft: {
+ name: 'Microsoft',
+ type: 'org',
+ },
+ jim: {
+ name: 'remarcmij',
+ type: 'user',
+ },
+ };
+
+ const { Model, HeaderView, RepoView, ContributorsView, ErrorView } = window;
+ const { createAndAppend } = window.Util;
+
+ class App {
+ constructor(account) {
+ const containers = App.renderContainers();
+
+ const model = new Model(account);
+ const fetchData = model.fetchData.bind(model);
+
+ model.subscribe(new HeaderView(account, containers.header, fetchData));
+ model.subscribe(new RepoView(containers.repo));
+ model.subscribe(new ContributorsView(containers.contributors));
+ model.subscribe(new ErrorView(containers.error));
+
+ fetchData();
+ }
+
+ static renderContainers() {
+ const root = document.getElementById('root');
+ const header = createAndAppend('header', root, { class: 'header' });
+ const error = createAndAppend('div', root);
+ const main = createAndAppend('main', root, {
+ class: 'main-container',
+ });
+ const repo = createAndAppend('section', main, {
+ class: 'repo-container whiteframe',
+ });
+ const contributors = createAndAppend('section', main, {
+ class: 'contributors-container whiteframe',
+ });
+ return { header, error, main, repo, contributors };
+ }
+ }
+
+ const ACCOUNT_KEY = 'hyf';
+ window.onload = () => new App(accounts[ACCOUNT_KEY]);
+}
\ No newline at end of file
diff --git a/Week3/homework/part2/ContributorsView.js b/Week3/homework/part2/ContributorsView.js
new file mode 100644
index 000000000..9161a3ddb
--- /dev/null
+++ b/Week3/homework/part2/ContributorsView.js
@@ -0,0 +1,62 @@
+'use strict';
+
+{
+ const { createAndAppend } = window.Util;
+
+ class ContributorsView {
+ constructor(container) {
+ this.container = container;
+ }
+
+ update(state) {
+ if (!state.error) {
+ this.render(state.contributors);
+ }
+ }
+
+ /**
+ * Renders the list of contributors
+ * @param {Object[]} contributors An array of contributor objects
+ */
+ render(contributors) {
+ // TODO: replace this comment and the console.log with your own code
+
+ // empty the conatainer from its old data
+ this.container.textContent = '';
+
+ // create section title
+ const ul = createAndAppend('ul', this.container, {
+ text: 'Contributions',
+ class: 'contributors-ul'
+ });
+
+ // create the contributors list
+ contributors.forEach( Contributor => {
+ const li = createAndAppend('li', ul, { class: 'Contributor-li' });
+ const ContributorDiv = createAndAppend('div', li, { class: 'Contributor-div' });
+
+ // create contributor image
+ createAndAppend('img', ContributorDiv, {
+ class: 'contributors-img',
+ src: Contributor.avatar_url,
+ });
+
+ // create contributor name
+ createAndAppend('a', ContributorDiv, {
+ class: 'contributors-a',
+ text: Contributor.login,
+ href: Contributor.html_url,
+ target: '_blank',
+ });
+
+ // create contributors number
+ createAndAppend('span', ContributorDiv, {
+ class: 'contributors-span',
+ text: Contributor.contributions,
+ });
+ });
+ }
+ }
+
+ window.ContributorsView = ContributorsView;
+}
\ No newline at end of file
diff --git a/Week3/homework/part2/ErrorView.js b/Week3/homework/part2/ErrorView.js
new file mode 100644
index 000000000..d71aec290
--- /dev/null
+++ b/Week3/homework/part2/ErrorView.js
@@ -0,0 +1,31 @@
+use strict';
+
+{
+ const { createAndAppend } = window.Util;
+
+ class ErrorView {
+ constructor(container) {
+ this.container = container;
+ }
+
+ update(state) {
+ this.render(state.error);
+ }
+
+ /**
+ * Renders an error for the 'error' message type.
+ * @param {Error} error An Error object
+ */
+ render(error) {
+ this.container.innerHTML = '';
+ if (error) {
+ createAndAppend('div', this.container, {
+ text: error.message,
+ class: 'alert alert-error',
+ });
+ }
+ }
+ }
+
+ window.ErrorView = ErrorView;
+}
\ No newline at end of file
diff --git a/Week3/homework/part2/HeaderView.js b/Week3/homework/part2/HeaderView.js
new file mode 100644
index 000000000..f49c3e77e
--- /dev/null
+++ b/Week3/homework/part2/HeaderView.js
@@ -0,0 +1,46 @@
+'use strict';
+
+{
+ const { createAndAppend } = window.Util;
+
+ class HeaderView {
+ constructor(account, header, fetchData) {
+ this.account = account;
+ this.header = header;
+ this.fetchData = fetchData;
+ this.select = null;
+ }
+
+ update(state) {
+ if (!this.select && !state.error) {
+ this.render(state.repos);
+ }
+ }
+
+ /**
+ * Renders the data for the 'select' message type. Create a