Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Domains/Frontend/MiniProjects/Random-Quote-Generator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## Random Quote Generator

**Contributor:** [Aerospace Prog](https://github.com/Aerospace-prog)


This project is a simple yet engaging Random Quote Generator that fetches quotes from an external API and displays them with a clean, modern, and interactive user interface. It's designed to provide users with a fresh dose of inspiration or wisdom with each click.

### Features:

* **Dynamic Quote Fetching:** Fetches random quotes from the [Quotable API](https://api.quotable.io/) (https://api.quotable.io/random).
* **Social Media Sharing:** Easily share your favorite quotes on Twitter and Facebook.
* **Copy to Clipboard:** Quickly copy any quote to your clipboard with a single click.
* **Vibrant UI/UX:** Features a modern design with a vibrant color palette, eye-catching typography, and interactive elements.
* **Animated Background:** A subtle, animated gradient background enhances the visual appeal.
* **Smooth Transitions:** Enjoy smooth fade-in/fade-out transitions when new quotes are loaded.
* **Responsive Design:** Optimized for various screen sizes, ensuring a consistent experience on desktops, tablets, and mobile devices.

### Technologies Used:

* HTML5
* CSS3 (with animations and responsive design)
* JavaScript (ES6+)

### Usage:

1. **Clone the repository:**
```bash
git clone <repository-url>
```
2. **Navigate to the project directory:**
```bash
cd Random-Quote-Generator
```
3. **Open `index.html`:**
Simply open the `index.html` file in your web browser. For the best experience and to avoid potential CORS issues, it is recommended to serve the `index.html` file using a local web server (e.g., Python's `http.server`):
```bash
python -m http.server 8000
```
Then, open your browser and go to `http://localhost:8000`.

### Contribution:

Feel free to fork this repository, make improvements, and submit pull requests. Any contributions are welcome!

### License:

This project is open-sourced under the MIT License.
25 changes: 25 additions & 0 deletions Domains/Frontend/MiniProjects/Random-Quote-Generator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Random Quote Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Random Quote Generator</h1>
<div class="quote-box">
<p class="quote-text"></p>
<p class="quote-author"></p>
</div>
<div class="buttons">
<button class="new-quote-btn">New Quote</button>
<button class="share-twitter-btn">Share on Twitter</button>
<button class="share-facebook-btn">Share on Facebook</button>
<button class="copy-btn">Copy Quote</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
64 changes: 64 additions & 0 deletions Domains/Frontend/MiniProjects/Random-Quote-Generator/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const quoteText = document.querySelector('.quote-text');
const quoteAuthor = document.querySelector('.quote-author');
const newQuoteBtn = document.querySelector('.new-quote-btn');
const twitterBtn = document.querySelector('.share-twitter-btn');
const facebookBtn = document.querySelector('.share-facebook-btn');
const copyBtn = document.querySelector('.copy-btn');
const quoteBox = document.querySelector('.quote-box');

async function fetchQuote() {
quoteBox.classList.add('fade-out');
setTimeout(async () => {
try {
const response = await fetch('http://api.quotable.io/random');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
quoteText.textContent = data.content;
quoteAuthor.textContent = `- ${data.author || 'Unknown'}`;
quoteBox.classList.remove('fade-out');
quoteBox.classList.add('fade-in');
setTimeout(() => {
quoteBox.classList.remove('fade-in');
}, 500);
} catch (error) {
console.error('Error fetching quote:', error);
quoteText.textContent = 'Failed to fetch a quote. Please try again later.';
quoteAuthor.textContent = '';
quoteBox.classList.remove('fade-out');
quoteBox.classList.add('fade-in');
setTimeout(() => {
quoteBox.classList.remove('fade-in');
}, 500);
}
}, 500);
}

function shareTweet() {
const tweetText = `"${quoteText.textContent}" ${quoteAuthor.textContent}`;
const twitterUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(tweetText)}`;
window.open(twitterUrl, '_blank');
}

function shareFacebook() {
const facebookUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(window.location.href)}&quote=${encodeURIComponent(quoteText.textContent + ' ' + quoteAuthor.textContent)}`;
window.open(facebookUrl, '_blank');
}

function copyQuote() {
const quoteToCopy = `"${quoteText.textContent}" ${quoteAuthor.textContent}`;
navigator.clipboard.writeText(quoteToCopy).then(() => {
alert('Quote copied to clipboard!');
}).catch(err => {
console.error('Failed to copy quote: ', err);
});
}

newQuoteBtn.addEventListener('click', fetchQuote);
twitterBtn.addEventListener('click', shareTweet);
facebookBtn.addEventListener('click', shareFacebook);
copyBtn.addEventListener('click', copyQuote);

// Fetch a quote on page load
fetchQuote();
214 changes: 214 additions & 0 deletions Domains/Frontend/MiniProjects/Random-Quote-Generator/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@

body {
font-family: 'Poppins', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); /* Initial vibrant gradient background */
background-size: 400% 400%;
animation: gradientAnimation 15s ease infinite;
color: #fff;
overflow: hidden;
}

@keyframes gradientAnimation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}


.container {
background: rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 40px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
text-align: center;
max-width: 600px;
width: 90%;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
animation: fadeIn 1s ease-out;
}


.quote-box {
margin-bottom: 30px;
min-height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: opacity 0.5s ease-in-out, transform 0.5s ease-in-out; /* Smooth transition for quote content */
}

.quote-box.fade-out {
opacity: 0;
transform: translateY(-20px);
}

.quote-box.fade-in {
opacity: 1;
transform: translateY(0);
}


h1 {
font-size: 2.5em;
margin-bottom: 30px;
color: #fff;
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.4);
}


.quote-box {
margin-bottom: 30px;
min-height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.quote-text {
font-size: 1.8em;
font-style: italic;
margin-bottom: 15px;
line-height: 1.4;
color: #e0e0e0;
text-shadow: 1px 1px 5px rgba(0, 0, 0, 0.3);
}

.quote-author {
font-size: 1.2em;
font-weight: 500;
color: #c0c0c0;
}


.buttons {
display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap;
}


button {
background: linear-gradient(45deg, #ff6b6b, #ffa500);
color: #fff;
border: none;
padding: 12px 25px;
border-radius: 30px;
font-size: 1em;
cursor: pointer;
outline: none;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
text-transform: uppercase;
letter-spacing: 1px;
}

button:hover {
transform: translateY(-3px) scale(1.02);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
background: linear-gradient(45deg, #ffa500, #ff6b6b);
}

button:active {
transform: translateY(0) scale(0.98);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
}


.new-quote-btn {
background: linear-gradient(45deg, #00c6ff, #0072ff);
}

.new-quote-btn:hover {
background: linear-gradient(45deg, #0072ff, #00c6ff);
}

.share-twitter-btn {
background: linear-gradient(45deg, #1da1f2, #00acee);
}

.share-twitter-btn:hover {
background: linear-gradient(45deg, #00acee, #1da1f2);
}

.share-facebook-btn {
background: linear-gradient(45deg, #3b5998, #8b9dc3);
}

.share-facebook-btn:hover {
background: linear-gradient(45deg, #8b9dc3, #3b5998);
}

.copy-btn {
background: linear-gradient(45deg, #28a745, #218838);
}

.copy-btn:hover {
background: linear-gradient(45deg, #218838, #28a745);
}


@media (max-width: 768px) {
.quote-box {
width: 90%;
padding: 20px;
}

.quote-text {
font-size: 1.5em;
}

.quote-author {
font-size: 1em;
}

.buttons button {
padding: 10px 15px;
font-size: 0.9em;
}
}

@media (max-width: 480px) {
.quote-text {
font-size: 1.2em;
}

.quote-author {
font-size: 0.9em;
}

.buttons {
flex-direction: column;
}

.buttons button {
width: 100%;
margin-bottom: 10px;
}
}


@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Loading