-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
416a8c2
commit f1de69b
Showing
8 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!DOCTYPE html> | ||
<html lang="en-US" dir="ltr"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="robots" content="noindex, nofollow"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Random Quote Generator</title> | ||
<link rel="stylesheet" href="./styles/main.css" type="text/css"> | ||
<link rel="icon" href="./assets/images/favicon.png" type="images/png"> | ||
<script defer src="./scripts/main.js"></script> | ||
</head> | ||
<body> | ||
<div class="loader active"> | ||
<span class="loader-icon"></span> | ||
</div> | ||
<main> | ||
<section> | ||
<article class="quote active"> | ||
<div> | ||
<div class="quote-icon top"> | ||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1664 1408"><path fill="currentColor" d="M768 832v384q0 80-56 136t-136 56H192q-80 0-136-56T0 1216V512q0-104 40.5-198.5T150 150T313.5 40.5T512 0h64q26 0 45 19t19 45v128q0 26-19 45t-45 19h-64q-106 0-181 75t-75 181v32q0 40 28 68t68 28h224q80 0 136 56t56 136m896 0v384q0 80-56 136t-136 56h-384q-80 0-136-56t-56-136V512q0-104 40.5-198.5T1046 150t163.5-109.5T1408 0h64q26 0 45 19t19 45v128q0 26-19 45t-45 19h-64q-106 0-181 75t-75 181v32q0 40 28 68t68 28h224q80 0 136 56t56 136"/></svg> | ||
</div> | ||
<div class="quote-icon bottom"> | ||
<svg style="transform: rotate(180deg);" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1664 1408"><path fill="currentColor" d="M768 832v384q0 80-56 136t-136 56H192q-80 0-136-56T0 1216V512q0-104 40.5-198.5T150 150T313.5 40.5T512 0h64q26 0 45 19t19 45v128q0 26-19 45t-45 19h-64q-106 0-181 75t-75 181v32q0 40 28 68t68 28h224q80 0 136 56t56 136m896 0v384q0 80-56 136t-136 56h-384q-80 0-136-56t-56-136V512q0-104 40.5-198.5T1046 150t163.5-109.5T1408 0h64q26 0 45 19t19 45v128q0 26-19 45t-45 19h-64q-106 0-181 75t-75 181v32q0 40 28 68t68 28h224q80 0 136 56t56 136"/></svg> | ||
</div> | ||
</div> | ||
<h1 class="quote-title">QUOTE</h1> | ||
<div class="quote-content"></div> | ||
<button type="button" class="quote-generate" disabled> | ||
<svg width="14px" height="14px" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> | ||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" /> | ||
</svg> | ||
Generate | ||
</button> | ||
</article> | ||
</section> | ||
</main> | ||
</body> | ||
</html> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
"use strict"; | ||
|
||
// DOM Element Selection | ||
const quote = document.querySelector(".quote"); | ||
const quoteContent = document.querySelector(".quote-content"); | ||
const quoteGenerateBtn = document.querySelector(".quote-generate"); | ||
const loader = document.querySelector(".loader"); | ||
|
||
// Variables | ||
const errorElement = ` | ||
<div class="error"> | ||
<div class="error-icon"> | ||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" class="bi bi-exclamation-lg" viewBox="0 0 16 16"> | ||
<path d="M7.005 3.1a1 1 0 1 1 1.99 0l-.388 6.35a.61.61 0 0 1-1.214 0zM7 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0"/> | ||
</svg> | ||
</div> | ||
<h3 class="error-title">Failed to fetch</h3> | ||
<p class="error-message">There is a problem receiving the information, please try again later...</p> | ||
</div> | ||
`; | ||
let quoteElement = null; | ||
|
||
// Functions | ||
const getQuote = async function() { | ||
try { | ||
loader.classList.remove("active"); | ||
quoteGenerateBtn.setAttribute("disabled", true); | ||
quote.classList.add("active"); | ||
|
||
const response = await fetch("https://api.quotable.io/random"); | ||
|
||
if (response.ok) { | ||
const data = await response.json(); | ||
generateQuote(data); | ||
} | ||
} catch (error) { | ||
quote.innerHTML = errorElement; | ||
} finally { | ||
loader.classList.add("active"); | ||
quoteGenerateBtn.removeAttribute("disabled"); | ||
quote.classList.remove("active"); | ||
} | ||
}; | ||
|
||
const generateQuote = function(quote) { | ||
quoteElement = ` | ||
<p class="quote-text">${quote.content}</p> | ||
<h3 class="quote-author">${quote.author}</h3> | ||
<span class="quote-date">${quote.dateAdded}</span> | ||
`; | ||
quoteContent.innerHTML = quoteElement; | ||
}; | ||
|
||
|
||
// Generate Button Handler | ||
quoteGenerateBtn.addEventListener("click", getQuote); | ||
|
||
// Window Load handler | ||
window.addEventListener("load", getQuote); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
* { | ||
padding: 0px; | ||
margin: 0px; | ||
box-sizing: border-box; | ||
} | ||
|
||
@font-face { | ||
font-family: "Work-Sans"; | ||
src: url(../assets/fonts/WorkSans-Regular.ttf) format(truetype); | ||
font-weight: 400; | ||
font-display: swap; | ||
} | ||
@font-face { | ||
font-family: "Work-Sans"; | ||
src: url(../assets/fonts/WorkSans-SemiBold.ttf) format(truetype); | ||
font-weight: 600; | ||
font-display: swap; | ||
} | ||
@font-face { | ||
font-family: "Work-Sans"; | ||
src: url(../assets/fonts/WorkSans-Bold.ttf) format(truetype); | ||
font-weight: 700; | ||
font-display: swap; | ||
} | ||
|
||
body { | ||
font-family: "Work-Sans"; | ||
} | ||
section { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
position: relative; | ||
min-height: 100vh; | ||
padding: 1.25rem; | ||
background-color:hsla(269,3%,9%,1); | ||
background-image: | ||
radial-gradient(at 71% 11%, hsla(239,70%,21%,0.53) 0px, transparent 50%), | ||
radial-gradient(at 40% 81%, hsla(328,60%,14%,0.64) 0px, transparent 50%); | ||
} | ||
.quote { | ||
position: relative; | ||
max-width: 450px; | ||
width: 100%; | ||
padding: 2.25rem 2.75rem; | ||
background-color: rgba(255, 255, 255, 0.1); | ||
border: 1px solid rgba(255, 255, 255, 0.15); | ||
border-radius: 0px 50px; | ||
backdrop-filter: blur(6px); | ||
text-align: center; | ||
transition: all 0.4s ease; | ||
} | ||
.quote-icon { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
position: absolute; | ||
width: 3.5rem; | ||
height: 3.5rem; | ||
border-radius: 15px; | ||
background-color: #f9fafb; | ||
box-shadow: 0 0 20px 16px rgba(255, 255, 255, 0.050); | ||
|
||
} | ||
.quote-icon.top { | ||
top: -1.25rem; | ||
left: 1.25rem; | ||
} | ||
.quote-icon.bottom { | ||
bottom: -1.25rem; | ||
right: 1.25rem; | ||
} | ||
.quote-icon svg { | ||
color: #3f3f46; | ||
width: 1.5rem; | ||
height: 1.5rem; | ||
} | ||
.quote-title { | ||
font-size: 1.875rem; | ||
font-weight: 700; | ||
color: #f9fafb; | ||
margin-bottom: 1.5rem; | ||
} | ||
.quote-text { | ||
color: #d4d4d4; | ||
opacity: 0.9; | ||
font-size: 0.875rem; | ||
line-height: 1.4; | ||
text-align: center; | ||
margin-bottom: 1.5rem; | ||
} | ||
.quote-author { | ||
font-size: 0.875rem; | ||
font-weight: 600; | ||
color: #f9fafb; | ||
} | ||
.quote-date { | ||
color: #d4d4d4; | ||
opacity: 0.9; | ||
font-size: 0.75rem; | ||
} | ||
.quote-generate { | ||
font-family: inherit; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
gap: 0.25rem; | ||
margin: 1.5rem auto 0.4rem auto; | ||
padding: 0.625rem; | ||
background-color: rgba(255, 255, 255, 0.1); | ||
color: #d4d4d4; | ||
border: 1px solid rgba(255, 255, 255, 0.15); | ||
border-radius: 10px; | ||
outline: none; | ||
cursor: pointer; | ||
transition: all 0.3s ease; | ||
} | ||
.quote-generate:hover { | ||
color: #f9fafb; | ||
background-color: rgba(255, 255, 255, 0.16); | ||
box-shadow: 0 0 10px 6px rgba(255, 255, 255, 0.03); | ||
} | ||
.quote-generate:disabled { | ||
color: #d4d4d4; | ||
background-color: rgba(255, 255, 255, 0.1); | ||
border: 1px solid rgba(255, 255, 255, 0.15); | ||
cursor: auto; | ||
box-shadow: none; | ||
} | ||
.error-icon { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
width: 3.5rem; | ||
height: 3.5rem; | ||
border-radius: 15px; | ||
background-color: #f9fafb; | ||
margin: 0 auto; | ||
margin-top: -4rem; | ||
box-shadow: 0 0 20px 16px rgb(255, 0, 0, 0.1); | ||
} | ||
.error-icon svg { | ||
color: #dc2626; | ||
} | ||
.error-title { | ||
font-size: 1.5rem; | ||
font-weight: 700; | ||
color: #f9fafb; | ||
margin-top: 2rem; | ||
margin-bottom: 0.875rem; | ||
} | ||
.error-message { | ||
color: #d4d4d4; | ||
opacity: 0.9; | ||
font-size: 0.875rem; | ||
line-height: 1.4; | ||
text-align: center; | ||
} | ||
.active { | ||
opacity: 0; | ||
visibility: hidden; | ||
pointer-events: none; | ||
} | ||
.loader { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
position: fixed; | ||
inset: 0; | ||
z-index: 999; | ||
backdrop-filter: blur(10px); | ||
transition: all 0.4s ease; | ||
} | ||
.loader-icon { | ||
width: 50px; | ||
aspect-ratio: 1; | ||
border-radius: 50%; | ||
border: 8px solid #fff; | ||
animation: | ||
l20-1 0.8s infinite linear alternate, | ||
l20-2 1.6s infinite linear; | ||
} | ||
@keyframes l20-1{ | ||
0% {clip-path: polygon(50% 50%,0 0, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0% )} | ||
12.5% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0% )} | ||
25% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100% )} | ||
50% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100% )} | ||
62.5% {clip-path: polygon(50% 50%,100% 0, 100% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100% )} | ||
75% {clip-path: polygon(50% 50%,100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 100%, 0% 100% )} | ||
100% {clip-path: polygon(50% 50%,50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100% )} | ||
} | ||
@keyframes l20-2{ | ||
0% {transform:scaleY(1) rotate(0deg)} | ||
49.99%{transform:scaleY(1) rotate(135deg)} | ||
50% {transform:scaleY(-1) rotate(0deg)} | ||
100% {transform:scaleY(-1) rotate(-135deg)} | ||
} |