Skip to content

Commit

Permalink
Merge branch 'develop' into feature/advanced_search
Browse files Browse the repository at this point in the history
  • Loading branch information
manuhdez committed Oct 15, 2018
2 parents c09e24c + 1f32c9a commit f82f700
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 97 deletions.
36 changes: 32 additions & 4 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ html {
padding-bottom: 5vh;
overflow-y: scroll;
}
[contenteditable='true'] {
border-bottom: solid #00f0b5 2px;
}
.profile-info {

.user-info {
border-bottom: 2px white;
}

.user-info[contenteditable='true'] {
/* border-bottom: solid #00f0b5 2px; */
color: #05c643 !important;
}

.user-info.edited[contenteditable='true'] {
/* border-bottom: solid #f28202 2px; */
color: #f28202 !important;
}

#loader {
position: fixed;
top: 50%;
Expand Down Expand Up @@ -76,3 +84,23 @@ html {
transform: rotate(360deg);
}
}

/*
PROFILE PAGE CUSTOM STYLES
*/

#edit,
#save {
top: 10px;
right: 10px;
}

#cancel {
top: 10px;
left: 10px;
}

#remove {
bottom: 10px;
right: 10px;
}
46 changes: 32 additions & 14 deletions html/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,38 +40,57 @@

<!------ Include the above in your HEAD tag ---------->
<main class="container" id="cards-container">
<div class="w-100">
<div class="w-100 position-relative">
<i class="material-icons position-absolute" id="edit">edit</i>
<i class="material-icons position-absolute d-none" id="save">save</i>
<i class="material-icons position-absolute d-none" id="cancel">cancel</i>
<i class="material-icons position-absolute d-none text-danger" id="remove">delete</i>
<div class="jumbotron">
<div class="row">
<div class="container d-flex justify-content-center">
<img src="https://source.unsplash.com/random/350x200" alt="stack photo" class="img">
<img class="img" id="userImg" style="width: 200px; height: 200px; object-fit: contain; border-radius: 50%;">
</div>
</div>
<div class="row mt-3">
<div class="col-md-8 col-xs-12 col-sm-6 col-lg-8">
<h2></h2>
<h5 class="mt-5">Personal information</h5>
<ul class="list-group list-group-flush">
<h2 class="text-center user-info" id="name"></h2>
<h6 class="text-center text-muted mb-4 user-info" id="jobTitle"></h6>
<ul class="list-group list-group-flush mt-4 mb-4">
<li class="list-group-item d-flex">
<i class="material-icons mr-3">person</i>
<p class="m-0" id="username"></p>
<p class="m-0 w-100 user-info" id="username"></p>
</li>
<li class="list-group-item d-flex">
<i class="material-icons mr-3">email</i>
<p class="m-0" id="email"></p>
<p class="m-0 w-100 user-info" id="email"></p>
</li>
<li class="list-group-item d-flex">
<i class="material-icons mr-3">link</i>
<p class="m-0 w-100 user-info" id="website"></p>
</li>
<li class="list-group-item d-flex">
<i class="material-icons mr-3">work</i>
<p class="m-0" id="company"></p>
<p class="m-0 w-100 user-info" id="company"></p>
</li>
<li class="list-group-item d-flex">
<i class="material-icons mr-3">today</i>
<p class="m-0 w-100 user-info" id="experience"></p>
</li>
<li class="list-group-item d-flex">
<i class="material-icons mr-3">location_city</i>
<p class="m-0" id="city">Dublin, UK</p>
<i class="material-icons mr-3">translate</i>
<p class="m-0 w-100 user-info" id="languages"></p>
</li>
<li class="list-group-item d-flex">
<i class="material-icons mr-3">public</i>
<p class="m-0 w-100 user-info" id="location"></p>
</ul>
</div>
</div>
<div class="w-100 d-flex justify-content-center">
<button class="w-25 border border-info mt-2 rounded" onclick="edit()" id="edit">Edit</button>
<div class="row">
<div class="container mb-3">
<h4>Skills</h4>
</div>
<div class="container d-flex flex-wrap" id="skills"></div>
</div>
</div>
</main>
Expand All @@ -82,8 +101,7 @@ <h5 class="mt-5">Personal information</h5>
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
crossorigin="anonymous"></script>
<script src="../js/enterProfile.js"></script>
<script src="../js/edit-profile.js"></script>
<script src="../js/user-profile.js"></script>
</body>

</html>
4 changes: 1 addition & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<title>CV App</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU"
crossorigin="anonymous">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Custom CSS styles -->
<link rel="stylesheet" href="css/styles.css">
Expand Down Expand Up @@ -44,7 +42,7 @@
</form>
</div>
</nav>
<main class="container d-flex flex-wrap justify-content-center" id="cards-container">
<main class="container d-flex flex-wrap justify-content-center align-items-start" id="cards-container">
</main>
<div id="loader">
<div class="lds-ring">
Expand Down
14 changes: 0 additions & 14 deletions js/edit-profile.js

This file was deleted.

27 changes: 0 additions & 27 deletions js/enterProfile.js

This file was deleted.

90 changes: 68 additions & 22 deletions js/infinite_scroll.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,96 @@
const cardsContainer = document.querySelector('#cards-container');
const searchInput = document.getElementById("nav-input");

// State variables to control activation of infinite scroll, page of users to request and store of all users requested
let isFetchAllowed = true;
let currentUsersPage = 1;
let loadedUsers = [];

// Initial content load from API
function fetchUsersData() {
if (searchInput.value == '') {
$.ajax({
url: "https://jsonplaceholder.typicode.com/users"
url: `https://cv-mobile-api.herokuapp.com/api/users/pages/${currentUsersPage}`
}).done((data) => {
// Show the loader while loading the content
// showLoader();
// Iterate over the data array and extract the info for each user in a card variable
data.map( (user) => {
const card = renderCard( user.name, user.username, user.email, user.company.name, user.id);
// Add the card with the user info to the DOM
cardsContainer.innerHTML += card;
// Save the user inside a collections with all loaded users
loadedUsers.push(user);
});
// Hide the loader after the content has loaded
hideLoader();

if (data.length === 10) {
data.map( (user) => {
user.highlight = [];
const card = renderCard(user);
cardsContainer.innerHTML += card;
loadedUsers.push(user);
});
// Add one to the current page of users for the next request if the page has 10 users
currentUsersPage++;

} else if (data.length < 10) {

if (data[0]._id !== loadedUsers[loadedUsers.length - 1]._id) {
data.map( (user) => {
const card = renderCard(user);
cardsContainer.innerHTML += card;
loadedUsers.push(user);
});
isFetchAllowed = false;
}
}

// Hide the loader after the content has loaded
hideLoader();
});
}
}
// Request the users data at page loading
fetchUsersData();

// Create an html card template with the user data
function renderCard(name, userName, email, company, userId, highlight) {
function renderCard(user) {
const {
name,
username,
jobTitle,
company,
email,
languages,
skills,
_id,
location,
experience,
profilePicture,
highlight
} = user;

var template_cards = (
'<div class="card shadow m-3" style="width: 90%; height: 60%;">' +
'<img class="card-img-top" src="https://source.unsplash.com/random/500x300" alt="Card image cap">' +
'<div class="card-body">' +
'<h5 class="card-title"><b' + (highlight === 'name' ? ' class="bg-warning"' : '') + '>' + name + '</b></h5>' +
'<p class="card-text">Username: <b' + (highlight === 'username' ? ' class="bg-warning"' : '') + '>' + userName + '</b></p>' +
'<p class="card-text">Email: <b' + (highlight === 'email' ? ' class="bg-warning"' : '') + '>' + email + '</b></p>' +
'<p class="card-text">Company: <b' + (highlight === 'company' ? ' class="bg-warning"' : '') + '>' + company + '</b></p>' +
'<a href="./html/profile.html?id=' + userId + '" class="btn btn-primary">View Profile</a>' +
'<div class="card shadow m-3 p-4" style="width: 90%; height: auto;">' +
'<img class="card-img-top m-auto" src="' + profilePicture + '" alt="' + name + ' Profile picture" style="height:150px; width:150px; border-radius:50%;">' +
'<div class="card-body p-0 mt-2">' +
'<h2 class="card-title text-center mb-2"><span' + (highlight ? highlight.includes('name') ? ' class="bg-warning"' : '': '') + '>' + name + '</span></h2>' +
'<h6 class="card-title text-center text-muted mb-4"><span' + (highlight ? highlight.includes('jobTitle') ? ' class="bg-warning"' : '': '') + '>' + jobTitle + '</span></h6>' +
'<p class="card-text d-flex align-items-center"><i class="material-icons mr-3">person</i> <span' + (highlight ? highlight.includes('username') ? ' class="bg-warning"' : '' : '') + '>' + username + '</span></p>' +
'<p class="card-text d-flex align-items-center"><i class="material-icons mr-3">email</i> <span' + (highlight ? highlight.includes('email') ? ' class="bg-warning"' : '' : '') + '>' + email + '</span></p>' +
'<p class="card-text d-flex align-items-center"><i class="material-icons mr-3">work</i> <span' + (highlight ? highlight.includes('company') ? ' class="bg-warning"' : '' : '') + '>' + company + '</span></p>' +
'<p class="card-text d-flex align-items-center"><i class="material-icons mr-3">public</i> <span' + (highlight ? highlight.includes('location') ? ' class="bg-warning"' : '' : '') + '>' + location.city + ', ' + location.country + '</span></p>' +
'<a href="./html/profile.html?id=' + _id + '" class="btn btn-primary mt-3">View Profile</a>' +
'</div>' +
'</div>'
// '<p class="card-text d-flex align-items-center"><i class="material-icons mr-3">today</i> <span' + (highlight.includes('experience') ? ' class="bg-warning"' : '') + '>' + experience + '</span></p>' +
// '<p class="card-text d-flex align-items-center"><i class="material-icons mr-3">translate</i> <span' + (highlight.includes('languages') ? ' class="bg-warning"' : '') + '>' + languages.join(', ') + '</span></p>' +
// '<div class="container-fluid p-0 mt-4 d-flex flex-wrap">' + createBadges(skills) + '</div>' +
);

return template_cards;
}

function createBadges(skills) {
const skillBadges = [];

skills.forEach( skill => {
skillBadges.push(`<h5 class="mr-2"><span class="badge badge-pill badge-success p-2">${skill}</span></h5>`);
});

return skillBadges.join('');
}

function showLoader() {
loader.style.display = 'block';
}
Expand Down
41 changes: 28 additions & 13 deletions js/search_bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,37 @@ searchInput.addEventListener("keyup", function(e) {
// User data separated for type
const filteredResults = {
name: [],
jobTitle: [],
username: [],
email: [],
company: []
}

function filterByData(input, reference, store, user) {
if (input.toLowerCase() === reference.slice(0, input.length).toLowerCase()) {
function filterByData(input, reference, store, user, coincidence) {
if (reference.toLowerCase().includes(input.toLowerCase())) {
user.highlight.includes(coincidence) ? '' : user.highlight.push(coincidence);
store.push(user);
} else {
let position = user.highlight.indexOf(coincidence);
user.highlight.includes(coincidence) && position !== -1 ? user.highlight.splice(position, 1) : '';
}
}

function renderCategoryOfFilteredUsers(category, categoryName) {
category.forEach( (user) => {
const card = renderCard( user.name, user.username, user.email, user.company.name, user.id, categoryName);
function renderFilteredResults() {
const userArray = [];

for (key in filteredResults) {
filteredResults[key].forEach( user => {
if (userArray.indexOf(user) == -1) {
userArray.push(user);
}
});
}

userArray.forEach( user => {
const card = renderCard(user);
cardsContainer.innerHTML += card;
})
});
}

if (searchTerm) {
Expand All @@ -34,30 +49,30 @@ searchInput.addEventListener("keyup", function(e) {
// Save user data inside an object for future comparison
const userData = {
name: user.name,
jobTitle: user.jobTitle,
username: user.username,
email: user.email,
company: user.company.name
company: user.company
}

// Grab each userData property and filter it into the searchResult object
for (let dataType in userData) {
filterByData(searchTerm, userData[dataType], filteredResults[dataType], user);
filterByData(searchTerm, userData[dataType], filteredResults[dataType], user, dataType);
}
});

// Once the users have been filtered render them into the DOM
for (let category in filteredResults) {
renderCategoryOfFilteredUsers(filteredResults[category], category);
}
renderFilteredResults();

} else {
// Allow infinite scroll again
isFetchAllowed = true;
// Empty the cardContainer with the filtered Results
cardsContainer.innerHTML = '';
// Render the default users loaded with the initial ajax call and render them into the DOM again
loadedUsers.forEach((user, index) => {
const card = renderCard( user.name, user.username, user.email, user.company.name, index);
loadedUsers.forEach((user) => {
user.highlight = [];
const card = renderCard(user);
cardsContainer.innerHTML += card;
});
}
Expand Down
Loading

0 comments on commit f82f700

Please sign in to comment.