diff --git a/submissions/igarok88/friends-app/index.html b/submissions/igarok88/friends-app/index.html
new file mode 100644
index 0000000000..b0a4c22c55
--- /dev/null
+++ b/submissions/igarok88/friends-app/index.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+ Friends App
+
+
+
+
+
+
+
+
+
+
Sort by alphabet:
+
+
A - Z
+
Z - A
+
+ Reset
+
+
+
+
+
+
+
+
+
+
Filter by gender:
+
+
+ All
+
+
Male
+
Female
+
+
+
+
+
+
+
+
+
+
+
diff --git a/submissions/igarok88/friends-app/script.js b/submissions/igarok88/friends-app/script.js
new file mode 100644
index 0000000000..066d3627bb
--- /dev/null
+++ b/submissions/igarok88/friends-app/script.js
@@ -0,0 +1,423 @@
+(async function () {
+ const ALL_USERS_LINK =
+ "https://randomuser.me/api/?inc=name,picture,dob,email,phone,location,gender,&results=5000";
+
+ const container = document.querySelector(".container");
+ const userContainer = document.querySelector(".user__container");
+
+ const inputSearch = document.querySelector(".options-bar__search");
+
+ const arrowLeft = document.querySelector("#paginationLeft");
+ const arrowRight = document.querySelector("#paginationRight");
+
+ const numberOfUsers = document.querySelector("#numberOfUsers");
+ const totalPages = document.querySelector("#totalPages");
+ const currentPage = document.querySelector("#currentPage");
+
+ let genderValue = "all";
+ let searchValue = "";
+ let sortByAgeValue = "reset";
+ let sortByAlphabetValue = "reset";
+
+ let countPages = 1;
+
+ let minAge;
+ let maxAge;
+
+ let index1 = 0;
+ let index2 = 20;
+
+ const getUsers = async (url) => {
+ try {
+ const response = await fetch(url).then((data) => data.json());
+ const newUsers = response.results.map((user) => {
+ return {
+ name: `${user.name.first} ${user.name.last}`,
+ photoUrl: user.picture.medium,
+ age: user.dob.age,
+ email: user.email,
+ tel: user.phone,
+ location: user.location.city,
+ gender: user.gender,
+ };
+ });
+
+ return newUsers;
+ } catch (e) {
+ console.error(e);
+ userContainer.innerHTML = "Something went wrong
";
+ }
+ };
+
+ const allUsers = await getUsers(ALL_USERS_LINK);
+ let currentUsers;
+ if (allUsers) {
+ currentUsers = allUsers.concat();
+ } else {
+ return;
+ }
+
+ container.addEventListener("click", async (e) => {
+ if (e.target.closest(".options-bar__gender .options-bar__btn")) {
+ activeBtnHandler(e, ".options-bar__gender .options-bar__btn");
+
+ genderValue = e.target.getAttribute("data-value");
+
+ currentUsers = await handlerUsers(allUsers);
+ }
+
+ if (e.target.closest(".options-bar__sort-age .options-bar__btn")) {
+ activeBtnHandler(e, ".options-bar__sort-age .options-bar__btn");
+ activeBtnHandler(e, ".options-bar__sort-name-alphabet .options-bar__btn");
+
+ sortByAgeValue = e.target.getAttribute("data-value");
+
+ sortByAlphabetValue = "reset";
+
+ currentUsers = await handlerUsers(allUsers);
+ }
+
+ if (
+ e.target.closest(".options-bar__sort-name-alphabet .options-bar__btn")
+ ) {
+ activeBtnHandler(e, ".options-bar__sort-name-alphabet .options-bar__btn");
+ activeBtnHandler(e, ".options-bar__sort-age .options-bar__btn");
+
+ sortByAlphabetValue = e.target.getAttribute("data-value");
+
+ sortByAgeValue = "reset";
+
+ currentUsers = await handlerUsers(allUsers);
+ }
+
+ if (e.target.closest(".options-bar__pagination")) {
+ if (e.target.closest("#paginationRight")) {
+ const numberRemainingUsers = currentUsers.slice(index2).length;
+
+ if (numberRemainingUsers < 20 && numberRemainingUsers !== 0) {
+ index1 = currentUsers.length - numberRemainingUsers;
+
+ if (20 > currentUsers.length) {
+ index1 = 0;
+ }
+
+ index2 = currentUsers.length;
+ }
+
+ if (index2 < currentUsers.length) {
+ index1 += 20;
+ index2 += 20;
+ arrowLeft.classList.remove("options-bar__btn_disabled");
+ }
+
+ if (index2 > currentUsers.length) {
+ index2 = currentUsers.length;
+ }
+ if (index2 === currentUsers.length) {
+ arrowRight.classList.add("options-bar__btn_disabled");
+ }
+
+ if (20 >= currentUsers.length) {
+ index1 = 0;
+ index2 = currentUsers.length;
+ }
+
+ if (index1 >= 20) {
+ arrowLeft.classList.remove("options-bar__btn_disabled");
+ }
+
+ const users20 = currentUsers.slice(index1, index2);
+
+ renderUsers(users20);
+ countPages++;
+ showPaginationInfo(currentUsers);
+ }
+
+ if (e.target.closest("#paginationLeft")) {
+ if (index2 % index1) {
+ index2 -= index2 % index1;
+ index1 -= 20;
+ } else {
+ index2 -= 20;
+ index1 -= 20;
+ }
+ if (index1 <= 0) {
+ index1 = 0;
+ index2 = 20;
+ arrowLeft.classList.add("options-bar__btn_disabled");
+ }
+ if (20 >= currentUsers.length) {
+ index1 = 0;
+ index2 = currentUsers.length;
+ }
+
+ const users20 = currentUsers.slice(index1, index2);
+
+ renderUsers(users20);
+
+ const numberRemainingUsers = currentUsers.slice(index2).length;
+ if (numberRemainingUsers) {
+ arrowRight.classList.remove("options-bar__btn_disabled");
+ }
+ countPages--;
+ showPaginationInfo(currentUsers);
+ }
+ }
+ });
+
+ const renderUsers = (users) => {
+ userContainer.innerHTML = "";
+ users.forEach((user) => {
+ const { name, photoUrl, age, email, tel, location, gender } = user;
+ userContainer.innerHTML += `
+
+ `;
+ });
+ };
+ renderUsers(currentUsers.slice(0, 20));
+
+ inputSearch.addEventListener("input", async () => {
+ searchValue = inputSearch.value;
+
+ currentUsers = await handlerUsers(allUsers);
+ });
+
+ const searchUserByName = async (users, str) => {
+ const filteredUsersName = users.filter((user) => {
+ if (user.name.toLowerCase().includes(str.toLowerCase())) {
+ return user;
+ }
+ });
+
+ return filteredUsersName;
+ };
+
+ const sortByAlphabet = (users) => {
+ if (sortByAlphabetValue === "reset") {
+ return users;
+ }
+ let newUsers;
+ if (sortByAlphabetValue === "A-Z") {
+ newUsers = users.sort((user, user2) =>
+ user.name === user2.name ? 0 : user.name > user2.name ? 1 : -1
+ );
+ }
+ if (sortByAlphabetValue === "Z-A") {
+ newUsers = users.sort((user, user2) =>
+ user.name === user2.name ? 0 : user.name < user2.name ? 1 : -1
+ );
+ }
+
+ return newUsers;
+ };
+
+ const sortByAge = (users, sortAge) => {
+ if (sortAge === "reset") {
+ return users;
+ }
+ let newUsers;
+ if (sortAge === "up") {
+ newUsers = users.sort((user, user2) => user.age - user2.age);
+ }
+ if (sortAge === "down") {
+ newUsers = users.sort((user, user2) => user2.age - user.age);
+ }
+
+ return newUsers;
+ };
+
+ minAge = sortByAge(currentUsers, "up")[0].age;
+ maxAge = sortByAge(currentUsers, "up")[currentUsers.length - 1].age;
+
+ const rangeHandler = () => {
+ const controlRangeMin = (rangeMin, rangeMax, inputMin) => {
+ const [from, to] = getParsed(rangeMin, rangeMax);
+ fillSlider(rangeMin, rangeMax, "#C6C6C6", "#25daa5", rangeMax);
+ if (from > to) {
+ rangeMin.value = to;
+ inputMin.value = to;
+ } else {
+ inputMin.value = from;
+ }
+ };
+
+ const controlRangeMax = (rangeMin, rangeMax, inputMax) => {
+ const [from, to] = getParsed(rangeMin, rangeMax);
+ fillSlider(rangeMin, rangeMax, "#C6C6C6", "#25daa5", rangeMax);
+ setToggleAccessible(rangeMax);
+ if (from <= to) {
+ rangeMax.value = to;
+ inputMax.value = to;
+ } else {
+ inputMax.value = from;
+ rangeMax.value = from;
+ }
+ };
+
+ const getParsed = (currentFrom, currentTo) => {
+ const from = parseInt(currentFrom.value, 10);
+ const to = parseInt(currentTo.value, 10);
+ return [from, to];
+ };
+
+ const fillSlider = (from, to, sliderColor, rangeColor, controlSlider) => {
+ const rangeDistance = to.max - to.min;
+ const fromPosition = from.value - to.min;
+ const toPosition = to.value - to.min;
+ controlSlider.style.background = `linear-gradient(
+ to right,
+ ${sliderColor} 0%,
+ ${sliderColor} ${(fromPosition / rangeDistance) * 100}%,
+ ${rangeColor} ${(fromPosition / rangeDistance) * 100}%,
+ ${rangeColor} ${(toPosition / rangeDistance) * 100}%,
+ ${sliderColor} ${(toPosition / rangeDistance) * 100}%,
+ ${sliderColor} 100%)`;
+ };
+
+ const setToggleAccessible = (currentTarget) => {
+ const rangeMax = document.querySelector("#rangeMax");
+ if (Number(currentTarget.value) <= 0) {
+ rangeMax.style.zIndex = 2;
+ } else {
+ rangeMax.style.zIndex = 0;
+ }
+ };
+
+ const rangeMin = document.querySelector("#rangeMin");
+ const rangeMax = document.querySelector("#rangeMax");
+ const inputMin = document.querySelector("#inputMin");
+ const inputMax = document.querySelector("#inputMax");
+
+ rangeMin.setAttribute("min", minAge);
+ rangeMin.setAttribute("max", maxAge);
+ rangeMin.setAttribute("value", minAge);
+
+ rangeMax.setAttribute("min", minAge);
+ rangeMax.setAttribute("max", maxAge);
+ rangeMax.setAttribute("value", maxAge);
+
+ inputMin.setAttribute("value", minAge);
+
+ inputMax.setAttribute("value", maxAge);
+
+ fillSlider(rangeMin, rangeMax, "#C6C6C6", "#25daa5", rangeMax);
+ setToggleAccessible(rangeMax);
+
+ rangeMin.addEventListener("input", () =>
+ controlRangeMin(rangeMin, rangeMax, inputMin)
+ );
+
+ rangeMin.addEventListener("click", async () => {
+ minAge = rangeMin.value;
+ currentUsers = await handlerUsers(allUsers);
+ });
+
+ rangeMax.addEventListener("input", () =>
+ controlRangeMax(rangeMin, rangeMax, inputMax)
+ );
+ rangeMax.addEventListener("click", async () => {
+ maxAge = rangeMax.value;
+ currentUsers = await handlerUsers(allUsers);
+ });
+ };
+ rangeHandler();
+
+ const filterByAge = (users, min, max) => {
+ const filteredUsers = users.filter(
+ (user) => user.age >= min && user.age <= max
+ );
+ return filteredUsers;
+ };
+
+ const filterByGender = (users, sex) => {
+ if (sex === "all") {
+ return users;
+ }
+ const filteredUsersGender = users.filter((user) => user.gender === sex);
+
+ index1 = 0;
+ index2 = 20;
+ arrowDisabledHandler(users);
+
+ return filteredUsersGender;
+ };
+
+ const showPaginationInfo = (users) => {
+ numberOfUsers.innerHTML = users.length;
+ totalPages.innerHTML = Math.ceil(users.length / 20);
+ if (countPages < 1) {
+ countPages = 1;
+ }
+ if (countPages > Math.ceil(users.length / 20)) {
+ countPages = Math.ceil(users.length / 20);
+ }
+ currentPage.innerHTML = countPages;
+ };
+ showPaginationInfo(currentUsers);
+
+ const arrowDisabledHandler = (users) => {
+ index1 = 0;
+ index2 = 20;
+
+ if (users.length <= 20) {
+ arrowRight.classList.add("options-bar__btn_disabled");
+ arrowLeft.classList.add("options-bar__btn_disabled");
+ } else {
+ arrowRight.classList.remove("options-bar__btn_disabled");
+ arrowLeft.classList.remove("options-bar__btn_disabled");
+ }
+ arrowLeft.classList.add("options-bar__btn_disabled");
+ };
+ arrowDisabledHandler(currentUsers);
+
+ const activeBtnHandler = (e, elements) => {
+ const btns = document.querySelectorAll(elements);
+ btns.forEach((btn) => {
+ btn.classList.remove("options-bar__btn_active");
+ });
+
+ e.target.classList.add("options-bar__btn_active");
+
+ const noActiveBtns = document.querySelectorAll(
+ ".options-bar__btn_no-active"
+ );
+ noActiveBtns.forEach((btn) => {
+ btn.classList.remove("options-bar__btn_active");
+ });
+ };
+
+ const handlerUsers = async (users) => {
+ let newUsers = await searchUserByName(users, inputSearch.value);
+
+ newUsers = sortByAge(newUsers, sortByAgeValue);
+
+ newUsers = sortByAlphabet(newUsers, sortByAlphabetValue);
+
+ newUsers = filterByAge(newUsers, minAge, maxAge);
+
+ newUsers = filterByGender(newUsers, genderValue);
+
+ arrowDisabledHandler(newUsers);
+
+ renderUsers(newUsers.slice(0, 20));
+
+ countPages = 1;
+
+ showPaginationInfo(newUsers);
+
+ return newUsers;
+ };
+})();
diff --git a/submissions/igarok88/friends-app/style.css b/submissions/igarok88/friends-app/style.css
new file mode 100644
index 0000000000..0631700a7c
--- /dev/null
+++ b/submissions/igarok88/friends-app/style.css
@@ -0,0 +1,302 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: Arial;
+ font-size: 20px;
+}
+
+input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ pointer-events: all;
+ width: 24px;
+ height: 24px;
+ background-color: #fff;
+ border-radius: 50%;
+ box-shadow: 0 0 0 1px #c6c6c6;
+ cursor: pointer;
+}
+
+input[type="range"]::-moz-range-thumb {
+ -webkit-appearance: none;
+ pointer-events: all;
+ width: 24px;
+ height: 24px;
+ background-color: #fff;
+ border-radius: 50%;
+ box-shadow: 0 0 0 1px #c6c6c6;
+ cursor: pointer;
+}
+
+input[type="range"]::-webkit-slider-thumb:hover {
+ background: #f7f7f7;
+}
+
+input[type="range"]::-webkit-slider-thumb:active {
+ box-shadow: inset 0 0 3px #387bbe, 0 0 9px #387bbe;
+ -webkit-box-shadow: inset 0 0 3px #387bbe, 0 0 9px #387bbe;
+}
+
+input[type="text"]::-webkit-inner-spin-button,
+input[type="text"]::-webkit-outer-spin-button {
+ opacity: 1;
+}
+
+input[type="range"] {
+ -webkit-appearance: none;
+ appearance: none;
+ height: 2px;
+ width: 100%;
+ position: absolute;
+ background-color: #c6c6c6;
+ pointer-events: none;
+ padding-left: 20px;
+}
+
+#rangeMin {
+ right: 20px;
+ top: 1px;
+ height: 0;
+ z-index: 1;
+}
+
+.options-bar__filter-age-container {
+ padding: 10px 0;
+}
+
+.options-bar__ranges {
+ position: relative;
+ min-height: 15px;
+}
+
+.options-bar__inputs-age {
+ color: #fff;
+}
+
+.options-bar__input-age-container {
+ display: flex;
+ justify-content: space-between;
+}
+
+.options-bar__input-age-title {
+ margin: 15px 0;
+}
+
+.options-bar__input {
+ background-color: transparent;
+ margin: 15px 0;
+ text-align: center;
+ color: #fff;
+ width: 55px;
+ border: none;
+}
+
+.container {
+ margin: 0 auto;
+ display: flex;
+}
+
+.options-bar {
+ background-color: rgb(48, 175, 192);
+ min-height: 100px;
+ padding: 25px;
+}
+
+.options-bar__option {
+ padding: 10px 0;
+ border-bottom: 2px solid #fff;
+}
+
+.options-bar__search {
+ padding: 10px;
+}
+
+.options-bar__title {
+ color: #fff;
+ display: flex;
+ align-items: center;
+ padding: 10px 0;
+}
+
+.options-bar__btn-container {
+ display: flex;
+ margin: 0 -5px;
+}
+
+.options-bar__btn {
+ cursor: pointer;
+ color: #fff;
+ padding: 5px 15px;
+ margin: 5px;
+ background-color: rgb(79, 189, 154);
+ border-radius: 10px;
+ border: 1px solid #fff;
+ transition: all 0.3s ease;
+}
+
+.options-bar__btn:hover {
+ background-color: rgb(119, 121, 224);
+}
+
+.options-bar__btn_active {
+ background-color: rgb(241, 131, 131);
+}
+
+.options-bar__btn:hover.options-bar__btn_active {
+ background-color: rgb(241, 131, 131);
+}
+
+.options-bar__btn_disabled {
+ background-color: rgb(159, 185, 178);
+}
+
+.options-bar__btn:hover.options-bar__btn_disabled {
+ background-color: rgb(159, 185, 178);
+ cursor: not-allowed;
+}
+
+.options-bar__range {
+ display: flex;
+ height: 70px;
+}
+
+.user__container {
+ position: relative;
+ background-color: rgb(79, 189, 154);
+ width: 100%;
+ min-height: 100vh;
+ padding: 15px;
+ display: flex;
+ align-content: flex-start;
+ flex-wrap: wrap;
+}
+
+.user__container-spiner {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.user__container * {
+ font-size: 16px;
+}
+
+.user__card {
+ display: flex;
+ flex-direction: column;
+ color: #000;
+ width: 200px;
+ background-color: #fff;
+ text-align: center;
+ margin: 5px;
+ border-radius: 10px;
+ transition: all 0.5s ease;
+}
+
+.user__card:hover {
+ box-shadow: 0px 0px 10px 3px rgba(21, 7, 104, 0.685);
+}
+
+.user__info {
+ display: flex;
+ flex-direction: column;
+}
+
+.user__name {
+ flex: 1 1 auto;
+ color: #fff;
+ padding: 10px;
+ font-size: 18px;
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ background-color: rgb(101, 151, 209);
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+.user__name_female {
+ background-color: rgb(236, 124, 221);
+}
+
+.user__photo {
+ padding: 10px;
+ width: 200px;
+ height: 200px;
+ border-radius: 50%;
+}
+
+.user__age {
+ padding: 5px 10px;
+ font-weight: bold;
+}
+
+.user__link {
+ padding: 5px 10px;
+ font-size: 14px;
+ color: #000;
+ text-decoration: none;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+.user__link:hover {
+ text-decoration: underline;
+}
+
+.user__location {
+ font-weight: bold;
+}
+
+.user__gender {
+ padding: 10px;
+ text-transform: uppercase;
+ border-top: 1px solid #000;
+}
+
+.lds-ring {
+ display: inline-block;
+ position: relative;
+ width: 80px;
+ height: 80px;
+}
+
+.lds-ring div {
+ box-sizing: border-box;
+ display: block;
+ position: absolute;
+ width: 64px;
+ height: 64px;
+ margin: 8px;
+ border: 8px solid #fff;
+ border-radius: 50%;
+ animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
+ border-color: #fff transparent transparent transparent;
+}
+
+.lds-ring div:nth-child(1) {
+ animation-delay: -0.45s;
+}
+
+.lds-ring div:nth-child(2) {
+ animation-delay: -0.3s;
+}
+
+.lds-ring div:nth-child(3) {
+ animation-delay: -0.15s;
+}
+
+@keyframes lds-ring {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.error {
+ color: red;
+ font-size: 28px;
+}