Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Friends app #95

Merged
merged 9 commits into from
Sep 8, 2022
63 changes: 63 additions & 0 deletions submissions/asaMitaka/FriendsApp/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Friends App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="header">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you go away from semantic header and footer tags?

<a class='header__a' href="https://kottans.org/" target="_blank">Kottans</a>
</div>

<div class="mainBlock">
<div class="asideBlock">
<form name="age">
<div class="asideBlock__items">
<p>By Age</p>
<input type="radio" name="sort" id="ageMore">
<label for="ageMore">Age < </label>
<input type="radio" name="sort" id="ageLess">
<label for="ageLess">Age > </label>
</div>
<div class="asideBlock__items">
<p>By Last Name</p>
<input type="radio" name="sort" id="lastAToZ">
<label for="lastAToZ">A-Z</label>
<input type="radio" name="sort" id="lastZToA">
<label for="lastZToA">Z-A</label>
</div>
</form>

<form name="gender">
<div class="asideBlock__items">
<input type="radio" id="male"
name="gender">
<label for="male" class="gender">MALE</label>

<input type="radio" id="female"
name="gender">
<label for="female">FEMALE</label>

<input type="radio" id="all"
name="gender" checked>
<label for="all">All</label>
</div>
</form>

<div class="asideBlock__items">
<button id="reset">Reset</button>
</div>
</div>
<article class="articleBlock"></article>
</div>
<div class="footer">
<a class="footer__a" href="https://kottans.org/" target="_blank">Kottans</a>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
87 changes: 87 additions & 0 deletions submissions/asaMitaka/FriendsApp/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const url = 'https://randomuser.me/api/?results=12';
const content = document.querySelector('.articleBlock');
const form = document.forms;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have 2 forms? You should use 1 form and get it by id or something, don't rely on document.forms.

let friends = [];
let friendsCopy = [];

const data = (url) => fetch(url)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getData?

.then(handleErrors)
.then(res => res.json())
.then(res => res.results)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting a property from an object is not an asynchronous task, you don't need another .then after this one.

.then(res => {
friends = [...res];
friendsCopy = [...friends];
renderAllItemsToPage(friends);
});

function handleErrors(res) {
if (!res.ok) {
throw Error(res.statusText);
}
return res;
}

document.querySelector('.asideBlock').addEventListener('click', sortBy);
function sortBy({target}) {
const id = target.id;

switch(id) {
case 'ageMore':
friendsCopy = friendsCopy.sort((a, b) => a.dob.age - b.dob.age);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at the functions that you use for sorting. They are identical, except you change parameter order. Maybe abstract it to not repeat yourself.

break;
case 'ageLess':
friendsCopy = friendsCopy.sort((a, b) => b.dob.age - a.dob.age);
break;
case 'lastAToZ':
friendsCopy = friendsCopy.sort((a, b) => a.name.last !== b.name.last ? a.name.last < b.name.last ? -1 : 1 : 0);
break;
case 'lastZToA':
friendsCopy = friendsCopy.sort((a, b) => a.name.last !== b.name.last ? a.name.last > b.name.last ? -1 : 1 : 0);
break;
case 'male':
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is filtering, it should not belong to the sorting function.

form[0].reset();
friendsCopy = friends.filter(item => item.gender === 'male');
break;
case 'female':
form[0].reset();
friendsCopy = friends.filter(item => item.gender === 'female');
break;
case 'all':
case 'reset':
form[0].reset();
form[1].reset();
friendsCopy = [...friends];
break;
}

renderAllItemsToPage(friendsCopy);
}

function creatingProfileCard({picture, name, email, dob, phone, location, gender}) {
return `
<div class='content__item'>
<img class='content__item-img' src='${picture.medium}'>
<div class='content__item-name'>${name.title} ${name.first} ${name.last}</div>
<p class='content__item-p content__item-email'>
<a class='content__item-a' href="mailto: ${email}" target="_blank"> ${email}</a>
</p>
<p class='content__item-p'>Age: ${dob.age}</p>
<a class='content__item-a' href='${phone}'>${phone}</a>
<p class='content__item-p content__item-country'>${location.country}, ${location.city}</p>
<div class='content__item-gender'>${gender}</div>
</div>
`;
}

function renderAllItemsToPage(arr) {
content.innerHTML = '';

let acc = '';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating a string of elements, it would be better to use the map method and create an array of elements, just join them before rendering. This would allow you to manipulate this array in the future if needed.

arr.forEach(item => {
acc += creatingProfileCard(item);
});

content.innerHTML = acc;
}

data(url);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add empty lines at the end of all files.

170 changes: 170 additions & 0 deletions submissions/asaMitaka/FriendsApp/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
* {
margin: auto;
padding: auto;
box-sizing: border-box;
}

.container {
width: 100%;
max-width: 1200px;
margin-left: auto;
margin-right: auto;
background-color: #e4e4e4;
}

.header {
width: 100%;
min-height: 2.5vh;
margin-left: auto;
margin-right: auto;
background-color: #f1eaea;
}

.header__a {
text-decoration: none;
color: #000000;
}

.mainBlock {
display: flex;
min-height: 95vh;
}

.asideBlock {
background: #eeebeb;
flex-basis: 33%;
margin: 5px;
}

.asideItem {
display: flex;
justify-content: center;
padding: 20px;
}

.asideBlock__items {
display: flex;
justify-content: center;
padding: 10px 0;
border-top: .3px solid black;
border-right: .3px solid black;
border-left: .5px solid white;
border-bottom: .5px solid white;
}

.articleBlock {
background: #faf1f1;
flex-basis: 66%;
margin: 5px;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, 175px);
grid-template-rows: repeat(3, 1fr);
}

.content__item {
display: flex;
flex-direction: column;
border: 1px solid black;
border-radius: 5px;
width: 160px;
height: 250px;
margin: 10px 20px;
box-shadow: 6px 3px 11px -3px rgba(0,0,0,0.27);
}

.content__item-name {
justify-content: center;
align-self: center;
padding-bottom: 5px;
}

.content__item-img {
justify-content: center;
align-self: center;
padding: 5px 0;
}

.content__item-p {
word-break: break-all;
height: 3em;
font-size: 12px;
}

.content__item-a {
text-decoration: none;
color: #000000;
}

.content__item-a:hover {
color: #423f3f;
background-color: rgb(228, 226, 222);
}

.content__item-gender {
border-top: 1px solid black;
width: 100%;
text-align: center;
}

.content__item-country {
height: 2em;
}

.footer {
min-height: 2.5vh;
background-color: rgb(197, 186, 197);
width: 100%;
}

.footer__a {
text-decoration: none;
color: #000000;
}

input:checked {
accent-color: black;
}

input + label:hover {
accent-color: black;
background-color: #e7e5e5;
}

#reset {
transition-duration: 0.4s;
border-top: .3px solid black;
border-right: .3px solid black;
border-left: .5px solid white;
border-bottom: .5px solid white;
}

#reset:hover {
transition-duration: 0.4s;
background-color: rgb(201, 195, 195);
border-top: .5px solid white;
border-right: .5px solid white;
border-left: .3px solid black;
border-bottom: .3px solid black;
}

@media screen and (max-width: 600px) {
.asideBlock {
position: fixed;
top: 15px;
left: 0;
width: 170px;
}
.articleBlock {
margin-left: 190px;
}

body {
background-color: #e4e4e4;
}

.footer {
position: fixed;
bottom: 0;
}
}