A Pen by Toluwanimi Miracle on CodePen.
Created
September 5, 2022 11:49
-
-
Save moelle89/ee7ecd9ead2e355d66ed1f74b168be1c to your computer and use it in GitHub Desktop.
Unsplash search app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Unsplash Photo Search App</title> | |
<link rel="stylesheet" href="main.css"> | |
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap" rel="stylesheet"> | |
</head> | |
<body> | |
<main> | |
<div class="container"> | |
<h1 class="h1">Unsplash Photo Search</h1> | |
<form class="js-form"> | |
<input type="text" class="search-input js-search-input" placeholder="Search high quality photos from Unsplash" autofocus> | |
<button type="submit" class="btn">Go</button> | |
</form> | |
<div class="result-stats js-result-stats"></div> | |
<div class="search-results js-search-results"></div> | |
<div class="pagination"> | |
<button class="hidden prev-btn js-prev"><a href="#top" style="text-decoration: none; color: white;">Previous page</a></button> | |
<button class="hidden next-btn js-next"><a href="#top" style="text-decoration: none; color: white;">Next page</a></button> | |
</div> | |
</div> | |
<div class="spinner js-spinner hidden"> | |
<div class="double-bounce1"></div> | |
<div class="double-bounce2"></div> | |
</div> | |
</main> | |
<footer class="footer"> | |
<p>Built by <a href="https://github.com/toluagboola" class="github-link">Tolu Agboola</a></p> | |
</footer> | |
<script type="text/javascript" src="main.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const form = document.querySelector('.js-form'); | |
form.addEventListener('submit', handleSubmit); | |
const nextBtn = document.querySelector('.js-next'); | |
const prevBtn = document.querySelector('.js-prev'); | |
let resultStats = document.querySelector('.js-result-stats'); | |
const spinner = document.querySelector('.js-spinner'); | |
let totalResults; | |
let currentPage = 1; | |
let searchQuery; | |
const apiKey = //"Your API key"; | |
nextBtn.addEventListener('click', () => { | |
currentPage += 1; | |
fetchResults(searchQuery); | |
}); | |
prevBtn.addEventListener('click', () => { | |
currentPage -= 1; | |
fetchResults(searchQuery); | |
}); | |
function pagination(totalPages) { | |
nextBtn.classList.remove('hidden'); | |
if (currentPage >= totalPages) { | |
nextBtn.classList.add('hidden'); | |
} | |
prevBtn.classList.add('hidden'); | |
if (currentPage !== 1) { | |
prevBtn.classList.remove('hidden'); | |
} | |
} | |
async function fetchResults(searchQuery) { | |
spinner.classList.remove('hidden'); | |
try { | |
const results = await searchUnsplash(searchQuery); | |
pagination(results.total_pages); | |
console.log(results); | |
displayResults(results); | |
} catch(err) { | |
console.log(err); | |
alert('Failed to search Unsplash'); | |
} | |
spinner.classList.add('hidden'); | |
} | |
function handleSubmit(event) { | |
event.preventDefault(); | |
currentPage = 1; | |
const inputValue = document.querySelector('.js-search-input').value; | |
searchQuery = inputValue.trim(); | |
console.log(searchQuery); | |
fetchResults(searchQuery); | |
} | |
async function searchUnsplash(searchQuery) { | |
const endpoint = `https://api.unsplash.com/search/photos?query=${searchQuery}&per_page=30&page=${currentPage}&client_id=${apiKey}`; | |
const response = await fetch(endpoint); | |
if (!response.ok) { | |
throw Error(response.statusText); | |
} | |
const json = await response.json(); | |
return json; | |
} | |
function displayResults(json) { | |
const searchResults = document.querySelector('.search-results'); | |
searchResults.textContent = ''; | |
json.results.forEach(result => { | |
const url = result.urls.small; | |
const unsplashLink = result.links.html; | |
const photographer = result.user.name; | |
const photographerPage = result.user.links.html; | |
searchResults.insertAdjacentHTML( | |
'beforeend', | |
`<div> | |
<a href="${unsplashLink}" target="_blank"> | |
<div class="result-item" style="background-image: url(${url});"></div> | |
</a> | |
<p class="photographer-name"> | |
<a href="${photographerPage}" target="_blank" style="color: black; text-decoration: none;">Photo by ${photographer}</a> | |
</p> | |
</div>` | |
); | |
}); | |
totalResults = json.total; | |
resultStats.textContent = `About ${totalResults} results found`; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html { | |
font-size: 62.5%; | |
box-sizing: border-box; | |
} | |
*, *::before, *::after { | |
margin: 0; | |
padding: 0; | |
box-sizing: inherit; | |
} | |
body { | |
font-family: 'Lato', sans-serif; | |
} | |
.container { | |
width: 100%; | |
max-width: 1200px; | |
margin: 0 auto; | |
padding: 30px 30px; | |
text-align: center; | |
} | |
.h1 { | |
font-size: 3em; | |
margin-bottom: 15px; | |
} | |
.search-input { | |
width: 400px; | |
height: 30px; | |
padding: 5px; | |
border-radius: 4px; | |
outline: none; | |
} | |
.btn { | |
width: 60px; | |
height: 30px; | |
color: white; | |
background: #ff0000; | |
border: none; | |
} | |
button { | |
cursor: pointer; | |
border-radius: 4px; | |
font-family: 'Lato', sans-serif; | |
} | |
button:hover { | |
background: #e60000; | |
} | |
button:focus { | |
outline: none; | |
} | |
.hidden { | |
display: none; | |
} | |
.result-stats { | |
color: gray; | |
padding-top: 15px; | |
font-size: 1.5em; | |
} | |
.search-results { | |
display: grid; | |
grid-template-columns: 1fr 1fr 1fr 1fr; | |
grid-gap: 20px; | |
padding: 25px; | |
} | |
.result-item { | |
width: 250px; | |
height: 250px; | |
padding: 5px; | |
border-radius: 4px; | |
} | |
.photographer-name { | |
padding: 7px; | |
font-size: 1.2em; | |
letter-spacing: 0.7px; | |
} | |
.photographer-name:hover { | |
text-decoration: underline; | |
} | |
.prev-btn, .next-btn { | |
margin-bottom: 20px; | |
background: #ff0000; | |
width: 100px; | |
height: 30px; | |
color: white; | |
border: none; | |
} | |
.next-btn { | |
margin-left: 10px; | |
} | |
.footer { | |
text-align: center; | |
font-size: 1.7em; | |
position: fixed; | |
background: white; | |
padding: 10px; | |
bottom: 0; | |
width:100%; | |
} | |
.github-link { | |
color: #ff0000; | |
text-decoration: none; | |
} | |
a:hover { | |
text-decoration: underline; | |
} | |
.spinner { | |
width: 40px; | |
height: 40px; | |
position: relative; | |
margin: 100px auto; | |
} | |
.double-bounce1, .double-bounce2 { | |
width: 100%; | |
height: 100%; | |
border-radius: 50%; | |
background-color: #333; | |
opacity: 0.6; | |
position: absolute; | |
top: 0; | |
left: 0; | |
-webkit-animation: sk-bounce 2.0s infinite ease-in-out; | |
animation: sk-bounce 2.0s infinite ease-in-out; | |
} | |
.double-bounce2 { | |
-webkit-animation-delay: -1.0s; | |
animation-delay: -1.0s; | |
} | |
@-webkit-keyframes sk-bounce { | |
0%, 100% { -webkit-transform: scale(0.0) } | |
50% { -webkit-transform: scale(1.0) } | |
} | |
@keyframes sk-bounce { | |
0%, 100% { | |
transform: scale(0.0); | |
-webkit-transform: scale(0.0); | |
} 50% { | |
transform: scale(1.0); | |
-webkit-transform: scale(1.0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment