Skip to content

Instantly share code, notes, and snippets.

@moelle89
Created September 5, 2022 11:49
Show Gist options
  • Save moelle89/ee7ecd9ead2e355d66ed1f74b168be1c to your computer and use it in GitHub Desktop.
Save moelle89/ee7ecd9ead2e355d66ed1f74b168be1c to your computer and use it in GitHub Desktop.
Unsplash search app
<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>
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`;
};
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