|
1 | 1 | 'use strict';
|
2 | 2 |
|
3 | 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 >= 200 && xhr.status <= 299) { |
11 |
| - resolve(xhr.response); |
12 |
| - } else { |
13 |
| - reject(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`)); |
14 |
| - } |
15 |
| - }; |
16 |
| - xhr.onerror = () => reject(new Error('Network request failed')); |
17 |
| - xhr.send(); |
18 |
| - }); |
| 4 | + async function fetchJSON(url) { |
| 5 | + const response = await fetch(url); |
| 6 | + if (!response.ok) { |
| 7 | + throw new Error( |
| 8 | + `Network error: ${response.status} - ${response.statusText}`, |
| 9 | + ); |
| 10 | + } |
| 11 | + return response.json(); |
19 | 12 | }
|
20 | 13 |
|
21 | 14 | function createAndAppend(name, parent, options = {}) {
|
|
58 | 51 |
|
59 | 52 | const root = document.getElementById('root');
|
60 | 53 |
|
61 |
| - function renderContributors(repo, div) { |
62 |
| - fetchJSON(repo.contributors_url) |
63 |
| - .then(contributors => { |
64 |
| - div.innerHTML = ''; |
65 |
| - |
66 |
| - contributors.forEach(contributor => { |
67 |
| - const contributorDiv = createAndAppend('div', div, { |
68 |
| - class: 'contributor-details', |
69 |
| - }); |
70 |
| - createAndAppend('img', contributorDiv, { |
71 |
| - src: contributor.avatar_url, |
72 |
| - }); |
73 |
| - createAndAppend('a', contributorDiv, { |
74 |
| - text: contributor.login, |
75 |
| - href: contributor.html_url, |
76 |
| - target: '_blank', |
77 |
| - class: 'user-name', |
78 |
| - }); |
79 |
| - createAndAppend('div', contributorDiv, { |
80 |
| - text: contributor.contributions, |
81 |
| - class: 'contributions-count', |
82 |
| - }); |
| 54 | + async function renderContributors(repo, div) { |
| 55 | + try { |
| 56 | + const contributors = await fetchJSON(repo.contributors_url); |
| 57 | + div.innerHTML = ''; |
| 58 | + contributors.forEach(contributor => { |
| 59 | + const contributorDiv = createAndAppend('div', div, { |
| 60 | + class: 'contributor-details', |
| 61 | + }); |
| 62 | + createAndAppend('img', contributorDiv, { src: contributor.avatar_url }); |
| 63 | + createAndAppend('a', contributorDiv, { |
| 64 | + text: contributor.login, |
| 65 | + href: contributor.html_url, |
| 66 | + target: '_blank', |
| 67 | + class: 'user-name', |
83 | 68 | });
|
84 |
| - }) |
85 |
| - .catch(err => { |
86 |
| - createAndAppend('div', root, { |
87 |
| - text: err.message, |
88 |
| - class: 'alert-error', |
| 69 | + createAndAppend('div', contributorDiv, { |
| 70 | + text: contributor.contributions, |
| 71 | + class: 'contributions-count', |
89 | 72 | });
|
90 | 73 | });
|
| 74 | + } catch (err) { |
| 75 | + createAndAppend('div', root, { text: err.message, class: 'alert-error' }); |
| 76 | + } |
91 | 77 | }
|
92 | 78 |
|
93 | 79 | function renderOptionElements(repos, select) {
|
|
96 | 82 | });
|
97 | 83 | }
|
98 | 84 |
|
99 |
| - function main(url) { |
| 85 | + async function main(url) { |
100 | 86 | const header = createAndAppend('header', root);
|
101 | 87 | createAndAppend('h2', header, { text: 'HYF Repositories' });
|
102 | 88 | const select = createAndAppend('select', header, {
|
103 |
| - id: 'select-btn', |
| 89 | + id: 'btn', |
104 | 90 | title: 'Select Repository',
|
105 | 91 | });
|
106 |
| - const mainContainer = createAndAppend('div', root, { |
107 |
| - id: `main-container`, |
| 92 | + const mainCont = createAndAppend('div', root, { id: `main-cont` }); |
| 93 | + const reposCont = createAndAppend('section', mainCont, { |
| 94 | + id: 'repos-cont', |
108 | 95 | });
|
109 |
| - const reposContainer = createAndAppend('section', mainContainer, { |
110 |
| - id: 'repos-container', |
| 96 | + const contributorsCont = createAndAppend('section', mainCont, { |
| 97 | + id: 'contributors-cont', |
111 | 98 | });
|
112 |
| - const contributorsContainer = createAndAppend('section', mainContainer, { |
113 |
| - id: 'contributors-container', |
114 |
| - }); |
115 |
| - createAndAppend('p', contributorsContainer, { |
| 99 | + createAndAppend('p', contributorsCont, { |
116 | 100 | text: `Contributors:`,
|
117 | 101 | id: 'contributors-title',
|
118 | 102 | });
|
119 |
| - const div = createAndAppend('div', contributorsContainer, { |
| 103 | + const div = createAndAppend('div', contributorsCont, { |
120 | 104 | id: 'list-contributions',
|
121 | 105 | });
|
122 | 106 |
|
123 |
| - fetchJSON(url) |
124 |
| - .then(repos => repos.sort((a, b) => a.name.localeCompare(b.name))) |
125 |
| - .then(repos => { |
126 |
| - renderOptionElements(repos, select); |
127 |
| - renderRepoDetails(repos[0], reposContainer); |
128 |
| - renderContributors(repos[0], div); |
| 107 | + try { |
| 108 | + const repos = await fetchJSON(url); |
| 109 | + repos.sort((a, b) => a.name.localeCompare(b.name)); |
| 110 | + renderOptionElements(repos, select); |
| 111 | + renderRepoDetails(repos[0], reposCont); |
| 112 | + renderContributors(repos[0], div); |
129 | 113 |
|
130 |
| - select.addEventListener('change', () => { |
131 |
| - const repo = repos[select.value]; |
132 |
| - renderRepoDetails(repo, reposContainer); |
133 |
| - renderContributors(repo, div); |
134 |
| - }); |
135 |
| - }) |
136 |
| - .catch(err => { |
137 |
| - createAndAppend('div', root, { |
138 |
| - text: err.message, |
139 |
| - class: 'alert-error', |
140 |
| - }); |
| 114 | + select.addEventListener('change', () => { |
| 115 | + const repo = repos[select.value]; |
| 116 | + renderRepoDetails(repo, reposCont); |
| 117 | + renderContributors(repo, div); |
141 | 118 | });
|
| 119 | + } catch (err) { |
| 120 | + createAndAppend('div', root, { text: err.message, class: 'alert-error' }); |
| 121 | + } |
142 | 122 | }
|
143 | 123 |
|
144 | 124 | const HYF_REPOS_URL =
|
|
0 commit comments