diff --git a/Week1/homework/js-exercises/.DS_Store b/Week1/homework/js-exercises/.DS_Store
new file mode 100644
index 000000000..7b3f86143
Binary files /dev/null and b/Week1/homework/js-exercises/.DS_Store differ
diff --git a/Week1/homework/js-exercises/Adyen.txt b/Week1/homework/js-exercises/Adyen.txt
new file mode 100644
index 000000000..19073a772
--- /dev/null
+++ b/Week1/homework/js-exercises/Adyen.txt
@@ -0,0 +1,12 @@
+Write down 2 insights you’ve gained listening to the developers’ personal stories:
+
+1. They had got through what we are going through in the past.
+2. we can always ask, search, learn, we are not expected to be know everything.
+
+Summarize “company life as a professional developer” in your view (max. 150 words):
+Not much feeling for now. In short, they have professionally educated background,
+familier with basic logic, structure,problem solving method.
+
+
+Write down 2 soft skills you need to work on:
+communication skills, be straight to tell the problem. don’t be shy, just try.
diff --git a/Week1/homework/js-exercises/dogGalary.css b/Week1/homework/js-exercises/dogGalary.css
new file mode 100644
index 000000000..a8ac19e05
--- /dev/null
+++ b/Week1/homework/js-exercises/dogGalary.css
@@ -0,0 +1,16 @@
+img {
+ width: 300px;
+ height: 200px;
+}
+ul li {
+ list-style-type: none;
+}
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+button {
+ margin: 20px;
+}
diff --git a/Week1/homework/js-exercises/dogGalary.html b/Week1/homework/js-exercises/dogGalary.html
new file mode 100644
index 000000000..1b92b9b4e
--- /dev/null
+++ b/Week1/homework/js-exercises/dogGalary.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
XML & Axios Dog Pictures
+
+
+
+
+
+
+
Get XML Dog!
+
+
+
+
+
+
+
+
Get Axios Dog!
+
+
+
+
+
+
+
+
diff --git a/Week1/homework/js-exercises/dogGalary.js b/Week1/homework/js-exercises/dogGalary.js
new file mode 100644
index 000000000..758ed64bd
--- /dev/null
+++ b/Week1/homework/js-exercises/dogGalary.js
@@ -0,0 +1,34 @@
+'use strict';
+const xBtn = document.getElementById('x');
+const xPic = document.querySelector('#xPic');
+
+// XML
+
+function xDog() {
+ const XHR = new XMLHttpRequest();
+ XHR.onreadystatechange = function() {
+ if (XHR.readyState == 4 && XHR.status == 200) {
+ console.log(XHR.responseText);
+ const result = JSON.parse(XHR.responseText);
+ xPic.src = result.message;
+ }
+ };
+ const url = 'https://dog.ceo/api/breeds/image/random';
+ XHR.open('GET', url);
+ XHR.send();
+}
+
+// axios
+
+const axiBtn = document.getElementById('axiBtn');
+const axiPic = document.querySelector('#axiPic');
+
+function Axios() {
+ axios
+ .get('https://dog.ceo/api/breeds/image/random')
+ .then(data => {
+ console.log(data);
+ axiPic.setAttribute('src', data.data.message);
+ })
+ .catch(err => console.error(err));
+}
diff --git a/Week1/homework/js-exercises/humor.html b/Week1/homework/js-exercises/humor.html
new file mode 100644
index 000000000..fff0a0ab1
--- /dev/null
+++ b/Week1/homework/js-exercises/humor.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
diff --git a/Week1/homework/js-exercises/humor.js b/Week1/homework/js-exercises/humor.js
new file mode 100644
index 000000000..63b5b49ae
--- /dev/null
+++ b/Week1/homework/js-exercises/humor.js
@@ -0,0 +1,44 @@
+'use strict'
+function a(url) {
+ axios.get(url).then(data => console.log(data));
+}
+const u = 'https://xkcd.now.sh/?comic=614';
+a(u);
+
+let getJSON = (url, callback) => {
+ let xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true);
+ xhr.responseType = 'json';
+
+ xhr.onload = () => {
+ let status = xhr.status;
+
+ if (status == 200) {
+ callback(null, xhr.response);
+ console.log(xhr.response);
+ const img = document.createElement('img');
+ document.body.appendChild(img);
+ img.src = xhr.response.img;
+ img.width = '300';
+ img.height = '500';
+ img.style.marginLeft = '20px';
+ } else {
+ callback(status);
+ }
+ };
+
+ xhr.send();
+};
+
+getJSON('https://xkcd.now.sh/?comic=614', (err, data) => {
+ if (err != null) {
+ console.error(err);
+ } else {
+ console.log(data);
+ const img = document.createElement('img');
+ document.body.appendChild(img);
+ img.src = data.img;
+ img.width = '300';
+ img.height = '500';
+ }
+});
diff --git a/Week1/homework/js-exercises/project/hyf.png b/Week1/homework/js-exercises/project/hyf.png
new file mode 100644
index 000000000..76bc5a13b
Binary files /dev/null and b/Week1/homework/js-exercises/project/hyf.png differ
diff --git a/Week1/homework/js-exercises/project/index.html b/Week1/homework/js-exercises/project/index.html
new file mode 100644
index 000000000..134bde38a
--- /dev/null
+++ b/Week1/homework/js-exercises/project/index.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+ HYF-GITHUB
+
+
+
+
+
+
+
+
+
diff --git a/Week1/homework/js-exercises/project/index.js b/Week1/homework/js-exercises/project/index.js
new file mode 100644
index 000000000..7b4792ab6
--- /dev/null
+++ b/Week1/homework/js-exercises/project/index.js
@@ -0,0 +1,81 @@
+'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 repoDetails(repo, ul) {
+ const li = createAndAppend('li', ul);
+ const table = createAndAppend('table', li);
+
+ //tr-repository
+ let tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Repository: ' });
+ let td = createAndAppend('td', tr);
+ createAndAppend('a', td, {
+ href: repo.html_url,
+ text: repo.name,
+ target: '_blank',
+ });
+
+ //tr-description
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Description: ' });
+ td = createAndAppend('td', tr, { text: repo.description });
+
+ //tr-forks
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Forks: ' });
+ td = createAndAppend('td', tr, { text: repo.forks });
+
+ //tr-update
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Updated: ' });
+ td = createAndAppend('td', tr, { text: repo.updated_at });
+ }
+
+ function main(url) {
+ createAndAppend('header', root, { text: 'HYF Repositories' });
+ fetchJSON(url, (err, repos) => {
+ const root = document.getElementById('root');
+ if (err) {
+ createAndAppend('div', root, {
+ text: err.message,
+ class: 'alert-error',
+ });
+ return;
+ }
+ const ul = createAndAppend('ul', root);
+ repos.sort((curRepo, nextRepo) => curRepo.name.localeCompare(nextRepo.name))
+ repos.forEach(repo => repoDetails(repo, ul));
+ });
+ }
+
+ const HYF_REPOS_URL =
+ 'https://api.github.com/orgs/HackYourFuture/repos?per_page=10';
+
+ window.onload = () => main(HYF_REPOS_URL);
+}
diff --git a/Week1/homework/js-exercises/project/style.css b/Week1/homework/js-exercises/project/style.css
new file mode 100644
index 000000000..185dce1bb
--- /dev/null
+++ b/Week1/homework/js-exercises/project/style.css
@@ -0,0 +1,62 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+.alert-error {
+ color: brown;
+ background-color: #f8d7da;
+ padding: 10px;
+ margin: 2px;
+ box-shadow: 5px 10px 18px #eee;
+}
+
+#root {
+ width: 80%;
+ margin: 0 10%;
+}
+
+header {
+ color: #fff;
+ background-color: #3f51b5;
+ font-size: 25px;
+ padding: 20px;
+}
+
+li {
+ border: 2px solid #ccc;
+ box-shadow: 5px 10px 18px #eee;
+ list-style: none;
+ margin: 3px;
+ padding: 15px;
+}
+@media only screen and (max-width: 610px) {
+ /* For mobile phones: */
+ #root {
+ width: 100%;
+ margin: 0 2%;
+ display: flex;
+ flex-direction: column;
+ }
+
+ header {
+ text-align: center;
+ }
+ td {
+ margin: 1%;
+ padding: 2%;
+ }
+}
+
+@media only screen and (min-width: 992px) {
+ #root {
+ width: 90%;
+ margin: 0 2%;
+ font-size: 15px;
+ }
+
+ td {
+ margin: 1%;
+ padding: 1%;
+ }
+}
diff --git a/Week1/homework/js-exercises/whoIsHere.html b/Week1/homework/js-exercises/whoIsHere.html
new file mode 100644
index 000000000..a228b9b14
--- /dev/null
+++ b/Week1/homework/js-exercises/whoIsHere.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
diff --git a/Week1/homework/js-exercises/whoIsHere.js b/Week1/homework/js-exercises/whoIsHere.js
new file mode 100644
index 000000000..4a775fa44
--- /dev/null
+++ b/Week1/homework/js-exercises/whoIsHere.js
@@ -0,0 +1,32 @@
+'use strict';
+function a(url) {
+ axios.get(url).then(data => console.log(data));
+}
+const u = 'https://www.randomuser.me/api';
+a(u);
+
+let getJSON = (url, callback) => {
+ let xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true);
+ xhr.responseType = 'json';
+
+ xhr.onload = () => {
+ let status = xhr.status;
+
+ if (status == 200) {
+ callback(null, xhr.response);
+ } else {
+ callback(status);
+ }
+ };
+
+ xhr.send();
+};
+
+getJSON('https://www.randomuser.me/api', (err, data) => {
+ if (err != null) {
+ console.error(err);
+ } else {
+ console.log(data);
+ }
+});
diff --git a/Week2/homework/Hack Your Repo2/.DS_Store b/Week2/homework/Hack Your Repo2/.DS_Store
new file mode 100644
index 000000000..5008ddfcf
Binary files /dev/null and b/Week2/homework/Hack Your Repo2/.DS_Store differ
diff --git a/Week2/homework/Hack Your Repo2/repo.html b/Week2/homework/Hack Your Repo2/repo.html
new file mode 100644
index 000000000..e1e200ec8
--- /dev/null
+++ b/Week2/homework/Hack Your Repo2/repo.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ HYF-GITHUB
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week2/homework/Hack Your Repo2/repo.js b/Week2/homework/Hack Your Repo2/repo.js
new file mode 100644
index 000000000..a713c7f6a
--- /dev/null
+++ b/Week2/homework/Hack Your Repo2/repo.js
@@ -0,0 +1,104 @@
+'use strict';
+{
+ function fetchJSON(url) {
+ return fetch(url).then(data => data.json());
+ }
+ 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 repoDetails(repo, ul) {
+ const li = createAndAppend('li', ul);
+ const table = createAndAppend('table', li);
+ //tr-repository
+ let tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Repository: ' });
+ let td = createAndAppend('td', tr);
+ createAndAppend('a', td, {
+ href: repo.html_url,
+ text: repo.name,
+ target: '_blank',
+ });
+ //tr-description
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Description: ' });
+ td = createAndAppend('td', tr, { text: repo.description });
+ //tr-forks
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Forks: ' });
+ td = createAndAppend('td', tr, { text: repo.forks });
+ //tr-update
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Updated: ' });
+ td = createAndAppend('td', tr, { text: repo.updated_at });
+ }
+ function contributorDetail(url) {
+ const select = document.createElement('select');
+ fetch(url).then((response) => { return response.json() }).then((data) => {
+ const byName = data;
+ byName.sort((curRepo, nextRepo) =>
+ curRepo.name.localeCompare(nextRepo.name),
+ );
+ byName.forEach((repo, index) => {
+ let opt = document.createElement('option');
+ opt.value = index;
+ opt.innerText = repo.name;
+ select.appendChild(opt);
+ });
+ select.addEventListener('change', () => {
+ const repo = document.getElementById('repository');
+ const contri = document.getElementById('contributor');
+ console.log("event listener called");
+ while (repo.hasChildNodes()) {
+ repo.removeChild(repo.lastChild);
+ }
+ while (contri.hasChildNodes()) {
+ contri.removeChild(contri.lastChild);
+ }
+ fetch(`https://api.github.com/repos/HackYourFuture/${
+ byName[select.value].name
+ }/contributors`).then((response) => { return response.json() })
+ .then((byName) => {
+ byName.forEach(j => {
+ const contriDiv = document.createElement('div');
+ contriDiv.setAttribute('class', 'contriDiv');
+ const h5 = document.createElement('h5');
+ const h4 = document.createElement('h4');
+ const img = document.createElement('img');
+ h5.innerText = j.login;
+ h4.innerText = j.contributions;
+ img.setAttribute('src', j.avatar_url);
+ img.width = '100';
+ contriDiv.appendChild(img);
+ contriDiv.appendChild(h5);
+ contriDiv.appendChild(h4);
+ contri.appendChild(contriDiv);
+ });
+ });
+ const ul = createAndAppend('ul', repo);
+ repoDetails(byName[select.value], ul)
+ });
+ });
+ const x = document.getElementById("dropdown");
+ x.appendChild(select);
+ const con = document.getElementById("contributor");
+ while (con.hasChildNodes()) {
+ con.removeChild(con.lastChild);
+ }
+ // con.appendChild(d);
+ }
+ function main(url) {
+ contributorDetail(url);
+ }
+ 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/Week2/homework/Hack Your Repo2/style.css b/Week2/homework/Hack Your Repo2/style.css
new file mode 100644
index 000000000..9b4208dd4
--- /dev/null
+++ b/Week2/homework/Hack Your Repo2/style.css
@@ -0,0 +1,42 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: #eee;
+}
+main {
+ width: 96%;
+ margin: 1%;
+}
+header {
+ color: #fff;
+ background-color: #3f51b5;
+ font-size: 25px;
+ padding: 20px;
+}
+
+ul {
+ list-style: none;
+}
+select {
+ margin-left: 50px;
+}
+
+section {
+ width: 100%;
+ padding: 10px;
+ margin: 2%;
+ background-color: #fff;
+ padding: 10px;
+}
+
+.contriDiv {
+ padding: 5px;
+ border-bottom: 2px solid #eee;
+ margin: 10px 0;
+ display: flex;
+ justify-content: space-between;
+
+}
diff --git a/Week3/.DS_Store b/Week3/.DS_Store
new file mode 100644
index 000000000..5008ddfcf
Binary files /dev/null and b/Week3/.DS_Store differ
diff --git a/Week3/homework/.DS_Store b/Week3/homework/.DS_Store
new file mode 100644
index 000000000..ea2513b37
Binary files /dev/null and b/Week3/homework/.DS_Store differ
diff --git a/Week3/homework/Hack Your Repo2/.DS_Store b/Week3/homework/Hack Your Repo2/.DS_Store
new file mode 100644
index 000000000..5008ddfcf
Binary files /dev/null and b/Week3/homework/Hack Your Repo2/.DS_Store differ
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/App.js b/Week3/homework/Hack Your Repo2/homework-classes/App.js
new file mode 100644
index 000000000..8788f8b85
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/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]);
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/ContributorsView.js b/Week3/homework/Hack Your Repo2/homework-classes/ContributorsView.js
new file mode 100644
index 000000000..4629fede8
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/ContributorsView.js
@@ -0,0 +1,34 @@
+'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
+ console.log('ContributorsView', contributors);
+ while (this.container.hasChildNodes()) {
+ this.container.removeChild(this.container.lastChild);
+ }
+ contributors.forEach(contributor => {
+ (this.div = createAndAppend('div', this.container, {
+ class: 'contriDiv',
+ })),
+ createAndAppend('h5', this.div, { text: contributor.login }),
+ createAndAppend('h4', this.div, { text: contributor.contributions }),
+ createAndAppend('img', this.div, { src: contributor.avatar_url });
+ });
+ }
+ }
+ window.ContributorsView = ContributorsView;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/ErrorView.js b/Week3/homework/Hack Your Repo2/homework-classes/ErrorView.js
new file mode 100644
index 000000000..67ad53087
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/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;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/HeaderView.js b/Week3/homework/Hack Your Repo2/homework-classes/HeaderView.js
new file mode 100644
index 000000000..11f9c8971
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/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 element
+ * and its children.
+ * @param {Object[]} repos An array of repository objects.
+ */
+ render(repos) {
+ createAndAppend('div', this.header, { text: this.account.name });
+ this.select = createAndAppend('select', this.header, {
+ class: 'repo-select',
+ autofocus: 'autofocus',
+ });
+
+ repos.forEach(repo =>
+ createAndAppend('option', this.select, {
+ text: repo.name,
+ value: repo.id,
+ }),
+ );
+
+ this.select.addEventListener('change', () =>
+ this.fetchData(this.select.value),
+ );
+ }
+ }
+
+ window.HeaderView = HeaderView;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/Model.js b/Week3/homework/Hack Your Repo2/homework-classes/Model.js
new file mode 100644
index 000000000..25884a133
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/Model.js
@@ -0,0 +1,53 @@
+'use strict';
+
+{
+ const { Observable } = window;
+
+ const makeUrl = ({ name, type }) =>
+ `https://api.github.com/${type}s/${name}/repos?per_page=100`;
+
+ class Model extends Observable {
+ constructor(account) {
+ super();
+ this.account = account;
+ this.state = {
+ repos: [],
+ selectedRepo: null,
+ contributors: [],
+ error: null,
+ };
+ }
+
+ async fetchData(id) {
+ const repoId = parseInt(id, 10);
+ this.state.error = null;
+ try {
+ if (this.state.repos.length === 0) {
+ const repos = await Model.fetchJSON(makeUrl(this.account));
+ this.state.repos = repos.sort((a, b) => a.name.localeCompare(b.name));
+ }
+ const index = id
+ ? this.state.repos.findIndex(repo => repo.id === repoId)
+ : 0;
+ this.state.selectedRepo = this.state.repos[index];
+ this.state.contributors = await Model.fetchJSON(
+ this.state.selectedRepo.contributors_url,
+ );
+ } catch (err) {
+ this.state.error = err;
+ }
+ this.notify(this.state);
+ }
+
+ static fetchJSON(url) {
+ return fetch(url).then(res => {
+ if (!res.ok) {
+ return new Error(`HTTP ${res.status} - ${res.statusText}`);
+ }
+ return res.status === 200 ? res.json() : null;
+ });
+ }
+ }
+
+ window.Model = Model;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/Observable.js b/Week3/homework/Hack Your Repo2/homework-classes/Observable.js
new file mode 100644
index 000000000..3eb5b2530
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/Observable.js
@@ -0,0 +1,20 @@
+'use strict';
+
+{
+ class Observable {
+ constructor() {
+ this.observers = new Set();
+ }
+
+ subscribe(observer = {}) {
+ this.observers.add(observer);
+ return () => this.observers.delete(observer);
+ }
+
+ notify(data) {
+ this.observers.forEach(observer => observer.update(data));
+ }
+ }
+
+ window.Observable = Observable;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/RepoView.js b/Week3/homework/Hack Your Repo2/homework-classes/RepoView.js
new file mode 100644
index 000000000..d4dbb2e9f
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/RepoView.js
@@ -0,0 +1,33 @@
+'use strict';
+{
+ const { createAndAppend } = window.Util;
+ class RepoView {
+ constructor(container) {
+ this.container = container;
+ }
+ update(state) {
+ if (!state.error) {
+ this.render(state.selectedRepo);
+ }
+ }
+ /**
+ * Renders the repository details.
+ * @param {Object} repo A repository object.
+ */
+ render(repo) {
+ // TODO: replace this comment and the console.log with your own code
+ console.log('RepoView', repo);
+ while (this.container.hasChildNodes()) {
+ this.container.removeChild(this.container.lastChild);
+ }
+ this.div = createAndAppend('div', this.container, { class: 'info' });
+ createAndAppend('h5', this.div, { text: 'Repository:' + repo.name });
+ createAndAppend('h5', this.div, {
+ text: 'Description:' + repo.description,
+ });
+ createAndAppend('h5', this.div, { text: 'Forks:' + repo.forks });
+ createAndAppend('h5', this.div, { text: 'Updated:' + repo.updated_at });
+ }
+ }
+ window.RepoView = RepoView;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/Util.js b/Week3/homework/Hack Your Repo2/homework-classes/Util.js
new file mode 100644
index 000000000..dc5d79a87
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/Util.js
@@ -0,0 +1,27 @@
+'use strict';
+
+{
+ class Util {
+ /**
+ * Creates an element, optionally setting its attributes, and appends
+ * the element to a parent.
+ * @param {string} name The tag name of the element to create.
+ * @param {HTMLElement} parent The parent element.
+ * @param {Object} options An object with attribute names and values.
+ */
+ static 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;
+ }
+ }
+
+ window.Util = Util;
+}
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/index.html b/Week3/homework/Hack Your Repo2/homework-classes/index.html
new file mode 100644
index 000000000..8e104b60e
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+ HYF-GITHUB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Week3/homework/Hack Your Repo2/homework-classes/style.css b/Week3/homework/Hack Your Repo2/homework-classes/style.css
new file mode 100644
index 000000000..f528b58ef
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/homework-classes/style.css
@@ -0,0 +1,41 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: #eee;
+}
+main {
+ width: 96%;
+ margin: 1%;
+}
+header {
+ color: #fff;
+ background-color: #3f51b5;
+ font-size: 25px;
+ padding: 20px;
+}
+
+ul {
+ list-style: none;
+}
+select {
+ margin-left: 50px;
+}
+
+section {
+ width: 100%;
+ padding: 10px;
+ margin: 2%;
+ background-color: #fff;
+ padding: 10px;
+}
+
+.contriDiv {
+ padding: 5px;
+ border-bottom: 2px solid #eee;
+ margin: 10px 0;
+ display: flex;
+ justify-content: space-between;
+}
diff --git a/Week3/homework/Hack Your Repo2/repo.html b/Week3/homework/Hack Your Repo2/repo.html
new file mode 100644
index 000000000..cdd29a5ba
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/repo.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ HYF-GITHUB
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Week3/homework/Hack Your Repo2/repo.js b/Week3/homework/Hack Your Repo2/repo.js
new file mode 100644
index 000000000..f218e42c6
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/repo.js
@@ -0,0 +1,121 @@
+'use strict';
+async function fetchJson(url) {
+ let response = await axios.get(url);
+ try {
+ if (response.status === 200) {
+ return response.data;
+ }
+ } catch (error) {
+ // why this if statement does not work?
+ if (response.status === 404) {
+ const err = document.createElement('div');
+ document.getElementById('root').appendChild(err);
+ err.innerText = 'somemething went wrong';
+ }
+ }
+}
+{
+ 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 repoDetails(repo, ul) {
+ const li = createAndAppend('li', ul);
+ const table = createAndAppend('table', li);
+ //tr-repository
+ let tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Repository: ' });
+ let td = createAndAppend('td', tr);
+ createAndAppend('a', td, {
+ href: repo.html_url,
+ text: repo.name,
+ target: '_blank',
+ });
+ //tr-description
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Description: ' });
+ td = createAndAppend('td', tr, { text: repo.description });
+ //tr-forks
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Forks: ' });
+ td = createAndAppend('td', tr, { text: repo.forks });
+ //tr-update
+ tr = createAndAppend('tr', table);
+ createAndAppend('th', tr, { text: 'Updated: ' });
+ td = createAndAppend('td', tr, { text: repo.updated_at });
+ }
+
+ function contributorDetail(url) {
+ const select = document.createElement('select');
+ //fetch 2
+ fetchJson(
+ 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100',
+ ).then(data => {
+ const byName = data;
+ byName.sort((curRepo, nextRepo) =>
+ curRepo.name.localeCompare(nextRepo.name),
+ );
+ byName.forEach((repo, index) => {
+ let opt = document.createElement('option');
+ opt.value = index;
+ opt.innerText = repo.name;
+ select.appendChild(opt);
+ });
+ select.addEventListener('change', () => {
+ const repo = document.getElementById('repository');
+ const contri = document.getElementById('contributor');
+ console.log('event listener called');
+ while (repo.hasChildNodes()) {
+ repo.removeChild(repo.lastChild);
+ }
+ while (contri.hasChildNodes()) {
+ contri.removeChild(contri.lastChild);
+ }
+ fetchJson(
+ `https://api.github.com/repos/HackYourFuture/${
+ byName[select.value].name
+ }/contributors`,
+ ).then(byName => {
+ byName.forEach(user => {
+ const contriDiv = document.createElement('div');
+ contriDiv.setAttribute('class', 'contriDiv');
+ const h5 = document.createElement('h5');
+ const h4 = document.createElement('h4');
+ const img = document.createElement('img');
+ h5.innerText = user.login;
+ h4.innerText = user.contributions;
+ img.setAttribute('src', user.avatar_url);
+ img.width = '100';
+ contriDiv.appendChild(img);
+ contriDiv.appendChild(h5);
+ contriDiv.appendChild(h4);
+ contri.appendChild(contriDiv);
+ });
+ });
+ const ul = createAndAppend('ul', repo);
+ repoDetails(byName[select.value], ul);
+ });
+ });
+ const x = document.getElementById('dropdown');
+ x.appendChild(select);
+ const con = document.getElementById('contributor');
+ while (con.hasChildNodes()) {
+ con.removeChild(con.lastChild);
+ }
+ // con.appendChild(d);
+ }
+ function main(url) {
+ contributorDetail(url);
+ }
+ const HYF_REPOS_URL =
+ 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
+ window.onload = () => main(HYF_REPOS_URL);
+}
diff --git a/Week3/homework/Hack Your Repo2/style.css b/Week3/homework/Hack Your Repo2/style.css
new file mode 100644
index 000000000..176ebc740
--- /dev/null
+++ b/Week3/homework/Hack Your Repo2/style.css
@@ -0,0 +1,41 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: #eee;
+}
+main {
+ width: 96%;
+ margin: 1%;
+}
+header {
+ color: #fff;
+ background-color: #3f51b5;
+ font-size: 25px;
+ padding: 20px;
+}
+
+ul {
+ list-style: none;
+}
+select {
+ margin-left: 50px;
+}
+
+section {
+ width: 100%;
+ padding: 10px;
+ margin: 2%;
+ background-color: #fff;
+ padding: 10px;
+}
+
+.contriDiv {
+ padding: 5px;
+ border-bottom: 2px solid #eee;
+ margin: 10px 0;
+ display: flex;
+ justify-content: space-between;
+}