diff --git a/src/autocomplete.ts b/src/autocomplete.ts index 5b89e45..d8f9c7d 100644 --- a/src/autocomplete.ts +++ b/src/autocomplete.ts @@ -1,11 +1,13 @@ import { fromEvent, Observable } from "rxjs"; import { ajax } from "rxjs/ajax"; -import { debounceTime, distinctUntilChanged, map, switchMap, tap } from "rxjs/operators"; +import { debounceTime, delay, distinctUntilChanged, filter, map, switchMap, tap, finalize, pluck } from "rxjs/operators"; import "./assets/styles/autocomplete.scss"; import "./assets/styles/styles.scss"; -import { IUser } from "./models/user.model"; +import { IRandomUserData, IUser, IUsersResponse } from "./models/user.model"; const autocompleteListEl = document.querySelector(".autocomplete__list"); +const templateEl = document.getElementById('user-card') as HTMLTemplateElement +const usersRowEl = document.querySelector('.users-row') const autocompleteUrl = "https://jsonplaceholder.typicode.com/users?username="; const usersApiUrl = "https://randomuser.me/api/?results=10"; @@ -42,29 +44,40 @@ const addUserColumn = (name: string) => { const fetchUserByName = (userName: string): Observable => ajax.getJSON(`${autocompleteUrl}${userName}`); +const fetchAllUsers = (): Observable => + ajax.getJSON(usersApiUrl); + document.addEventListener("DOMContentLoaded", init); +const showLoader = (loader: Element) => loader.classList.remove('is-hidden') +const hideLoader = (loader: Element) => loader.classList.add('is-hidden') + function init() { const autocomplete: HTMLInputElement = document.querySelector( "#autocomplete__input" ); const source$ = fromEvent(autocomplete, "input"); + const loader = document.querySelector('.fullscreen-loader') // LOADER exists in Markup, just toggle class 'is-hidden' source$ .pipe( map(e => (e.target as HTMLInputElement).value), - // TODO: add triming - // TODO: filter by min length of the 4 - // TODO: show Loader + map(value => value.trim()), + filter(value => value.length > 3), + tap(() => showLoader(loader)), debounceTime(100), distinctUntilChanged(), tap(userName => console.log("--next value", userName)), - switchMap(userName => fetchUserByName(userName)) - // TODO: add delay 300ms - // TODO: add finalize operator to hide the loader + switchMap(userName => fetchUserByName(userName)), + delay(300), + tap(() => hideLoader(loader)) ) .subscribe(renderAutocomplete); + + fetchAllUsers() + .pipe(pluck('results')) + .subscribe(renderUsersCards) } function renderAutocomplete(users: IUser[]) { @@ -74,3 +87,18 @@ function renderAutocomplete(users: IUser[]) { autocompleteListEl.innerHTML = usersListHtml.join(); } + +const renderUsersCards = (users: IRandomUserData[]) => { + const titleEl = templateEl.content.querySelector('.card-title') + const imageEl = templateEl.content.querySelector('.card-img-top') as HTMLImageElement + const buttonEl = templateEl.content.querySelector('.btn') as HTMLAnchorElement + + users.forEach((user, index) => { + titleEl.textContent = user.name.first + imageEl.src = user.picture.large + buttonEl.href = `${window.location.origin}/profile.html?userId=${index + 1}` + + const clone = document.importNode(templateEl.content, true) + usersRowEl.appendChild(clone) + }) +} diff --git a/src/models/user.model.ts b/src/models/user.model.ts index c1ef520..0aca030 100644 --- a/src/models/user.model.ts +++ b/src/models/user.model.ts @@ -26,4 +26,87 @@ export interface IUser { phone: string; website: string; company: Company; -} \ No newline at end of file +} + +interface Name { + title: string; + first: string; + last: string; +} + +interface Coordinates { + latitude: string; + longitude: string; +} + +interface Timezone { + offset: string; + description: string; +} + +interface Location { + street: string; + city: string; + state: string; + postcode: string; + coordinates: Coordinates; + timezone: Timezone; +} + +interface Login { + uuid: string; + username: string; + password: string; + salt: string; + md5: string; + sha1: string; + sha256: string; +} + +interface Dob { + date: Date; + age: number; +} + +interface Registered { + date: Date; + age: number; +} + +interface Id { + name: string; + value: string; +} + +interface Picture { + large: string; + medium: string; + thumbnail: string; +} + +export interface IRandomUserData { + gender: string; + name: Name; + location: Location; + email: string; + login: Login; + dob: Dob; + registered: Registered; + phone: string; + cell: string; + id: Id; + picture: Picture; + nat: string; +} + +interface Info { + seed: string; + results: number; + page: number; + version: string; +} + +export interface IUsersResponse { + results: IRandomUserData[]; + info: Info; +} diff --git a/src/profile.html b/src/profile.html index 0351bd7..3289b60 100644 --- a/src/profile.html +++ b/src/profile.html @@ -29,7 +29,7 @@