-
-
Notifications
You must be signed in to change notification settings - Fork 184
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
Friends app #95
Changes from 7 commits
24f2253
055be7a
64e1e2e
1a3f727
23ab608
b261928
2bf8877
466171d
f1b6488
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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"> | ||
<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> |
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
let friends = []; | ||
let friendsCopy = []; | ||
|
||
const data = (url) => fetch(url) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
.then(handleErrors) | ||
.then(res => res.json()) | ||
.then(res => res.results) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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(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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 = ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
arr.forEach(item => { | ||
acc += creatingProfileCard(item); | ||
}); | ||
|
||
content.innerHTML = acc; | ||
} | ||
|
||
data(url); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add empty lines at the end of all files. |
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; | ||
} | ||
} |
There was a problem hiding this comment.
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
andfooter
tags?