import { ApiError, ApiProfile, ApiRepository } from './interface/IGitHubApi'; export class DOMOperator { public static clearChildren($parent: HTMLElement): void { while ($parent.hasChildNodes()) { $parent.removeChild($parent.firstChild); } } public static createError( error: ApiError, username: string ): HTMLDivElement { const $error = document.createElement('div'); $error.className = 'error'; $error.innerHTML = `${error.message}`; if (error.isWrongUser) { $error.innerHTML = `Not found user: ${username}`; } if (error.resetDate) { let remainingTime = error.resetDate.getMinutes() - new Date().getMinutes(); remainingTime = remainingTime < 0 ? 60 + remainingTime : remainingTime; $error.innerHTML += `Come back after ${remainingTime} minutes`; } return $error; } public static createProfile(data: ApiProfile): HTMLDivElement { const $followButton = followButton(data.login, data.html_url); const $followers = followers(data.followers); const $followContainer = followContainer([$followButton, $followers]); const $avatar = avatar(data.avatar_url); const $name = name(data.html_url, data.name); return profile([$avatar, $name, $followContainer]); ////////////////// function appendChildren($parent: HTMLElement, nodes: HTMLElement[]): void { nodes.forEach(node => $parent.appendChild(node)); } function profile(children: HTMLElement[]): HTMLDivElement { const $profile = document.createElement('div'); $profile.classList.add('profile'); appendChildren($profile, children); return $profile; } function name(profileUrl, name): HTMLAnchorElement { const $name = document.createElement('a'); $name.href = profileUrl; $name.className = 'name'; $name.appendChild(document.createTextNode(name)); return $name; } function avatar(avatarUrl: string): HTMLImageElement { const $avatar = document.createElement('img'); $avatar.src = avatarUrl; $avatar.className = 'avatar'; return $avatar; } function followButton( username: string, followUrl: string ): HTMLAnchorElement { const $followButton = document.createElement('a'); $followButton.href = followUrl; $followButton.className = 'follow-button'; $followButton.innerHTML = 'Follow @' + username; return $followButton; } function followers(followersAmount: number): HTMLSpanElement { const $followers = document.createElement('span'); $followers.className = 'followers'; $followers.innerHTML = '' + followersAmount; return $followers; } function followContainer(children: HTMLElement[]): HTMLDivElement { const $followContainer = document.createElement('div'); $followContainer.className = 'followMe'; appendChildren($followContainer, children); return $followContainer; } } public static createTopLanguagesSection(): HTMLUListElement { const $langsList = document.createElement('ul'); $langsList.className = 'languages'; return $langsList; } public static createTopLanguagesList(langs: Record): string { return Object.keys(langs) .map(language => ({ name: language, stat: langs[language] })) .sort((a, b) => b.stat - a.stat) .slice(0, 3) .map(lang => `
  • ${lang.name}
  • `) .reduce((list, nextElement) => list + nextElement); } public static createRepositoriesHeader(headerText): HTMLSpanElement { const $repositoriesHeader = document.createElement('span'); $repositoriesHeader.className = 'header'; $repositoriesHeader.appendChild(document.createTextNode(`${headerText}`)); return $repositoriesHeader; } public static createRepositoriesList( repositories: ApiRepository[], maxRepos: number ): HTMLDivElement { const $reposList = document.createElement('div'); $reposList.className = 'repos'; repositories .slice(0, maxRepos) .map(this.createRepositoryElement) .forEach(el => $reposList.appendChild(el)); return $reposList; } private static createRepositoryElement( repository: ApiRepository ): HTMLAnchorElement { const updated = new Date(repository.updated_at); const $repoLink = document.createElement('a'); $repoLink.href = repository.html_url; $repoLink.title = repository.description; $repoLink.innerHTML = ` ${repository.name} Updated: ${updated.toLocaleDateString()} ${repository.stargazers_count} `; return $repoLink; } }