diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..e050e59c Binary files /dev/null and b/.DS_Store differ diff --git a/public/.DS_Store b/public/.DS_Store new file mode 100644 index 00000000..006a0935 Binary files /dev/null and b/public/.DS_Store differ diff --git a/public/Day-216_Quick_image_finder/.DS_Store b/public/Day-216_Quick_image_finder/.DS_Store new file mode 100644 index 00000000..0a36c0ad Binary files /dev/null and b/public/Day-216_Quick_image_finder/.DS_Store differ diff --git a/public/Day-216_Quick_image_finder/exported-assets/README.md b/public/Day-216_Quick_image_finder/exported-assets/README.md new file mode 100644 index 00000000..9736cb00 --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/README.md @@ -0,0 +1,189 @@ +# Quick Image Finder 🔍 + +A responsive web application that allows users to search for high-quality images using the Unsplash API. Enter a keyword, get instant results, and navigate through multiple images with ease. + +## Features + +✨ **Simple Search Interface** - Clean and intuitive design for easy image searching +🖼️ **High-Quality Images** - Access millions of professional photos from Unsplash +⬅️➡️ **Easy Navigation** - Browse through results with Previous/Next buttons or arrow keys +📱 **Responsive Design** - Works perfectly on desktop, tablet, and mobile devices +🎨 **Modern UI** - Beautiful gradient design with smooth animations +🔄 **Load More** - Fetch additional results without losing your place + +## Technologies Used + +- **HTML5** - Structure and content +- **CSS3** - Styling with gradients, animations, and responsive design +- **JavaScript (ES6+)** - API integration and interactivity +- **Unsplash API** - Free high-quality image database + +## Getting Started + +### Prerequisites + +- A modern web browser (Chrome, Firefox, Safari, Edge) +- Internet connection +- A free Unsplash API key + +### Step 1: Get Your Free Unsplash API Key + +1. Go to [Unsplash Developers](https://unsplash.com/developers) +2. Click **"Register as a Developer"** (or log in if you already have an account) +3. Click **"New Application"** +4. Accept the API guidelines +5. Fill in the application details: + - **Application name**: Quick Image Finder (or any name you prefer) + - **Description**: A web app for searching images +6. Click **"Create application"** +7. Copy your **Access Key** from the application page + +**Note**: The free tier allows 50 requests per hour, which is perfect for this demo project. + +### Step 2: Set Up the Project + +1. Download all three files: + - `index.html` + - `style.css` + - `script.js` + +2. Place all files in the same folder/directory + +3. Open `script.js` in a text editor + +4. Find this line at the top: + ```javascript + const API_KEY = 'YOUR_UNSPLASH_ACCESS_KEY'; + ``` + +5. Replace `'YOUR_UNSPLASH_ACCESS_KEY'` with your actual API key: + ```javascript + const API_KEY = 'your-actual-api-key-here'; + ``` + +6. Save the file + +### Step 3: Run the Application + +1. Double-click on `index.html` to open it in your default browser + - OR right-click → Open with → Choose your browser + +2. Enter a search term (e.g., "mountains", "technology", "nature") + +3. Press the **Search** button or hit Enter + +4. Navigate through results using: + - **Previous/Next buttons** + - **Arrow keys** on your keyboard + - **Load More Results** button for additional images + +## Project Structure + +``` +quick-image-finder/ +│ +├── index.html # Main HTML structure +├── style.css # All styling and animations +├── script.js # JavaScript logic and API integration +└── README.md # This file +``` + +## How It Works + +1. **User Input**: User enters a search keyword in the form +2. **API Request**: The app sends a request to Unsplash API with the search query +3. **Data Processing**: Response data is stored and the first image is displayed +4. **Navigation**: Users can browse through the 10 results per page +5. **Load More**: Clicking "Load More Results" fetches the next page of images + +## API Integration Details + +The app uses Unsplash's Search Photos endpoint: + +``` +https://api.unsplash.com/search/photos?query={searchTerm}&page={pageNumber}&per_page=10 +``` + +**Parameters:** +- `query`: The search keyword +- `page`: Page number for pagination +- `per_page`: Number of results per page (set to 10) +- `client_id`: Your API key for authentication + +## Customization Ideas + +Want to enhance this project? Here are some ideas: + +- Add filter options (orientation, color, etc.) +- Implement download functionality +- Add image favorites/bookmarking +- Create image gallery view +- Add dark mode toggle +- Implement infinite scroll +- Show more image metadata + +## Troubleshooting + +**Problem**: "Please add your Unsplash API key" error +- **Solution**: Make sure you've replaced `YOUR_UNSPLASH_ACCESS_KEY` in `script.js` with your actual key + +**Problem**: "Failed to fetch images" error +- **Solution**: Check your internet connection and verify your API key is correct + +**Problem**: No images found +- **Solution**: Try a different search term or more general keywords + +**Problem**: Images not loading +- **Solution**: Check browser console for errors (F12) and ensure all files are in the same directory + +## API Rate Limits + +- **Free tier**: 50 requests per hour +- **Recommended**: Apply for production access if you need higher limits +- The app handles errors gracefully if you exceed rate limits + +## Contributing to Open Source + +This project is perfect for: +- Learning API integration +- Practicing JavaScript async/await +- Understanding DOM manipulation +- Building portfolio projects + +Feel free to: +- Fork this project +- Add new features +- Fix bugs +- Improve the UI/UX +- Add documentation + +## License + +This project is open source and available for educational purposes. + +**Important**: When using Unsplash images, you must: +- Give credit to photographers +- Follow Unsplash's API guidelines +- Not abuse the API + +## Resources + +- [Unsplash API Documentation](https://unsplash.com/documentation) +- [Unsplash API Guidelines](https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines) +- [JavaScript Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) + +## Author + +Created as a learning project for web development students. + +## Acknowledgments + +- **Unsplash** for providing free API access +- **Unsplash photographers** for amazing images +- Web development community for tutorials and support + +--- + +**Happy coding! 🚀** + +If you have any questions or run into issues, check the browser console (F12) for detailed error messages. diff --git a/public/Day-216_Quick_image_finder/exported-assets/index.html b/public/Day-216_Quick_image_finder/exported-assets/index.html new file mode 100644 index 00000000..06b7bf28 --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/index.html @@ -0,0 +1,64 @@ + + + + + + Quick Image Finder + + + +
+
+

🔍 Quick Image Finder

+

Search for high-quality images instantly

+
+ +
+
+ + +
+
+ + + + + + + + +
+ + + + \ No newline at end of file diff --git a/public/Day-216_Quick_image_finder/exported-assets/script.js b/public/Day-216_Quick_image_finder/exported-assets/script.js new file mode 100644 index 00000000..21df34b4 --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/script.js @@ -0,0 +1,183 @@ +// ⚠️ IMPORTANT: Replace 'YOUR_UNSPLASH_ACCESS_KEY' with your actual Unsplash API key +// Get your free API key from: https://unsplash.com/developers + +const API_KEY = 'Paste Your api key here of unsplash';//Due to privacy issue you have to use your own images +const API_URL = 'https://api.unsplash.com/search/photos'; + +// DOM Elements +const searchForm = document.getElementById('search-form'); +const searchInput = document.getElementById('search-input'); +const resultsSection = document.getElementById('results-section'); +const resultImage = document.getElementById('result-image'); +const resultText = document.getElementById('result-text'); +const photographerName = document.getElementById('photographer-name'); +const imageLink = document.getElementById('image-link'); +const loading = document.getElementById('loading'); +const errorMessage = document.getElementById('error-message'); +const showMoreBtn = document.getElementById('show-more-btn'); +const prevBtn = document.getElementById('prev-btn'); +const nextBtn = document.getElementById('next-btn'); +const imageCounter = document.getElementById('image-counter'); + +// State management +let currentImages = []; +let currentIndex = 0; +let currentQuery = ''; +let currentPage = 1; + +// Event Listeners +searchForm.addEventListener('submit', handleSearch); +showMoreBtn.addEventListener('click', loadMoreResults); +prevBtn.addEventListener('click', showPreviousImage); +nextBtn.addEventListener('click', showNextImage); + +// Handle search submission +async function handleSearch(e) { + e.preventDefault(); + + const query = searchInput.value.trim(); + + if (!query) { + showError('Please enter a search term'); + return; + } + + // Check if API key is set + if (API_KEY === 'YOUR_UNSPLASH_ACCESS_KEY') { + showError('Please add your Unsplash API key in script.js. Get it from https://unsplash.com/developers'); + return; + } + + currentQuery = query; + currentPage = 1; + currentIndex = 0; + + await fetchImages(query, currentPage); +} + +// Fetch images from Unsplash API +async function fetchImages(query, page = 1) { + try { + hideError(); + showLoading(); + hideResults(); + + const url = `${API_URL}?query=${encodeURIComponent(query)}&page=${page}&per_page=10&client_id=${API_KEY}`; + + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`API Error: ${response.status}`); + } + + const data = await response.json(); + + hideLoading(); + + if (data.results.length === 0) { + showError(`No images found for "${query}". Try a different search term.`); + return; + } + + if (page === 1) { + currentImages = data.results; + } else { + currentImages = [...currentImages, ...data.results]; + } + + displayCurrentImage(); + showResults(); + updateNavigationButtons(); + + } catch (error) { + hideLoading(); + console.error('Error fetching images:', error); + showError('Failed to fetch images. Please check your API key and internet connection.'); + } +} + +// Display the current image +function displayCurrentImage() { + const image = currentImages[currentIndex]; + + if (!image) return; + + resultImage.src = image.urls.regular; + resultImage.alt = image.alt_description || image.description || 'Image'; + photographerName.textContent = `Photo by ${image.user.name}`; + imageLink.href = image.links.html; + resultText.textContent = `Showing results for "${currentQuery}"`; + imageCounter.textContent = `${currentIndex + 1} / ${currentImages.length}`; +} + +// Show previous image +function showPreviousImage() { + if (currentIndex > 0) { + currentIndex--; + displayCurrentImage(); + updateNavigationButtons(); + } +} + +// Show next image +function showNextImage() { + if (currentIndex < currentImages.length - 1) { + currentIndex++; + displayCurrentImage(); + updateNavigationButtons(); + } +} + +// Update navigation buttons state +function updateNavigationButtons() { + prevBtn.disabled = currentIndex === 0; + nextBtn.disabled = currentIndex === currentImages.length - 1; +} + +// Load more results (next page) +async function loadMoreResults() { + currentPage++; + await fetchImages(currentQuery, currentPage); +} + +// UI Helper Functions +function showLoading() { + loading.classList.remove('hidden'); +} + +function hideLoading() { + loading.classList.add('hidden'); +} + +function showResults() { + resultsSection.classList.remove('hidden'); +} + +function hideResults() { + resultsSection.classList.add('hidden'); +} + +function showError(message) { + errorMessage.textContent = message; + errorMessage.classList.remove('hidden'); + + // Auto-hide error after 5 seconds + setTimeout(() => { + hideError(); + }, 5000); +} + +function hideError() { + errorMessage.classList.add('hidden'); +} + +// Keyboard navigation +document.addEventListener('keydown', (e) => { + if (currentImages.length === 0) return; + + if (e.key === 'ArrowLeft') { + showPreviousImage(); + } else if (e.key === 'ArrowRight') { + showNextImage(); + } +}); diff --git a/public/Day-216_Quick_image_finder/exported-assets/script.py b/public/Day-216_Quick_image_finder/exported-assets/script.py new file mode 100644 index 00000000..69b7ebbc --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/script.py @@ -0,0 +1,72 @@ + +# Create the HTML file for the Quick Image Finder project +html_content = """ + + + + + Quick Image Finder + + + +
+
+

🔍 Quick Image Finder

+

Search for high-quality images instantly

+
+ +
+
+ + +
+
+ + + + + + + + +
+ + + +""" + +# Save HTML file +with open('index.html', 'w', encoding='utf-8') as f: + f.write(html_content) + +print("✓ index.html created successfully") diff --git a/public/Day-216_Quick_image_finder/exported-assets/script_1.py b/public/Day-216_Quick_image_finder/exported-assets/script_1.py new file mode 100644 index 00000000..5bde3795 --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/script_1.py @@ -0,0 +1,335 @@ + +# Create the CSS file for styling +css_content = """* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; +} + +.container { + max-width: 900px; + margin: 0 auto; +} + +header { + text-align: center; + color: white; + margin-bottom: 40px; + animation: fadeInDown 0.8s ease; +} + +header h1 { + font-size: 3rem; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +.subtitle { + font-size: 1.2rem; + opacity: 0.9; +} + +.search-section { + background: white; + padding: 30px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); + margin-bottom: 30px; + animation: fadeInUp 0.8s ease; +} + +#search-form { + display: flex; + gap: 10px; +} + +#search-input { + flex: 1; + padding: 15px 20px; + font-size: 1rem; + border: 2px solid #e0e0e0; + border-radius: 10px; + transition: all 0.3s ease; +} + +#search-input:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); +} + +#search-btn { + padding: 15px 40px; + font-size: 1rem; + font-weight: bold; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border: none; + border-radius: 10px; + cursor: pointer; + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +#search-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); +} + +#search-btn:active { + transform: translateY(0); +} + +.results-section { + background: white; + padding: 30px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); + animation: fadeInUp 0.8s ease; +} + +.result-info { + margin-bottom: 20px; +} + +#result-text { + font-size: 1.1rem; + color: #333; + margin-bottom: 15px; + font-weight: 500; +} + +.navigation-buttons { + display: flex; + align-items: center; + justify-content: center; + gap: 20px; + margin-top: 15px; +} + +.nav-btn { + padding: 10px 20px; + font-size: 0.9rem; + font-weight: bold; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border: none; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +.nav-btn:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); +} + +.nav-btn:disabled { + background: #ccc; + cursor: not-allowed; + opacity: 0.6; +} + +#image-counter { + font-weight: bold; + color: #667eea; + font-size: 1rem; +} + +.image-container { + margin: 20px 0; + text-align: center; +} + +#result-image { + width: 100%; + max-height: 500px; + object-fit: cover; + border-radius: 10px; + box-shadow: 0 5px 20px rgba(0,0,0,0.2); + transition: transform 0.3s ease; +} + +#result-image:hover { + transform: scale(1.02); +} + +.image-details { + margin-top: 15px; + padding: 15px; + background: #f8f9fa; + border-radius: 8px; +} + +#photographer-name { + font-size: 1rem; + color: #555; + margin-bottom: 10px; +} + +#image-link { + display: inline-block; + padding: 8px 20px; + color: white; + background: #667eea; + text-decoration: none; + border-radius: 6px; + transition: background 0.3s ease; +} + +#image-link:hover { + background: #764ba2; +} + +#show-more-btn { + width: 100%; + padding: 15px; + font-size: 1rem; + font-weight: bold; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border: none; + border-radius: 10px; + cursor: pointer; + margin-top: 20px; + transition: all 0.3s ease; +} + +#show-more-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); +} + +.loading { + text-align: center; + background: white; + padding: 40px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); +} + +.spinner { + border: 4px solid #f3f3f3; + border-top: 4px solid #667eea; + border-radius: 50%; + width: 50px; + height: 50px; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading p { + color: #667eea; + font-size: 1.1rem; + font-weight: 500; +} + +.error-message { + background: #ff4444; + color: white; + padding: 20px; + border-radius: 10px; + text-align: center; + font-size: 1rem; + box-shadow: 0 5px 15px rgba(255, 68, 68, 0.3); +} + +.hidden { + display: none; +} + +footer { + text-align: center; + color: white; + margin-top: 40px; + padding: 20px; +} + +footer p { + margin: 5px 0; + opacity: 0.9; +} + +footer a { + color: white; + text-decoration: underline; +} + +.api-note { + font-size: 0.9rem; + background: rgba(255, 255, 255, 0.2); + padding: 10px; + border-radius: 8px; + margin-top: 10px; +} + +@keyframes fadeInDown { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Responsive Design */ +@media (max-width: 768px) { + header h1 { + font-size: 2rem; + } + + .subtitle { + font-size: 1rem; + } + + #search-form { + flex-direction: column; + } + + .search-section { + padding: 20px; + } + + .results-section { + padding: 20px; + } + + .navigation-buttons { + flex-direction: column; + gap: 10px; + } + + .nav-btn { + width: 100%; + } +}""" + +# Save CSS file +with open('style.css', 'w', encoding='utf-8') as f: + f.write(css_content) + +print("✓ style.css created successfully") diff --git a/public/Day-216_Quick_image_finder/exported-assets/script_2.py b/public/Day-216_Quick_image_finder/exported-assets/script_2.py new file mode 100644 index 00000000..9a552d4b --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/script_2.py @@ -0,0 +1,191 @@ + +# Create the JavaScript file with Unsplash API integration +js_content = """// ⚠️ IMPORTANT: Replace 'YOUR_UNSPLASH_ACCESS_KEY' with your actual Unsplash API key +// Get your free API key from: https://unsplash.com/developers + +const API_KEY = 'YOUR_UNSPLASH_ACCESS_KEY'; +const API_URL = 'https://api.unsplash.com/search/photos'; + +// DOM Elements +const searchForm = document.getElementById('search-form'); +const searchInput = document.getElementById('search-input'); +const resultsSection = document.getElementById('results-section'); +const resultImage = document.getElementById('result-image'); +const resultText = document.getElementById('result-text'); +const photographerName = document.getElementById('photographer-name'); +const imageLink = document.getElementById('image-link'); +const loading = document.getElementById('loading'); +const errorMessage = document.getElementById('error-message'); +const showMoreBtn = document.getElementById('show-more-btn'); +const prevBtn = document.getElementById('prev-btn'); +const nextBtn = document.getElementById('next-btn'); +const imageCounter = document.getElementById('image-counter'); + +// State management +let currentImages = []; +let currentIndex = 0; +let currentQuery = ''; +let currentPage = 1; + +// Event Listeners +searchForm.addEventListener('submit', handleSearch); +showMoreBtn.addEventListener('click', loadMoreResults); +prevBtn.addEventListener('click', showPreviousImage); +nextBtn.addEventListener('click', showNextImage); + +// Handle search submission +async function handleSearch(e) { + e.preventDefault(); + + const query = searchInput.value.trim(); + + if (!query) { + showError('Please enter a search term'); + return; + } + + // Check if API key is set + if (API_KEY === 'YOUR_UNSPLASH_ACCESS_KEY') { + showError('Please add your Unsplash API key in script.js. Get it from https://unsplash.com/developers'); + return; + } + + currentQuery = query; + currentPage = 1; + currentIndex = 0; + + await fetchImages(query, currentPage); +} + +// Fetch images from Unsplash API +async function fetchImages(query, page = 1) { + try { + hideError(); + showLoading(); + hideResults(); + + const url = `${API_URL}?query=${encodeURIComponent(query)}&page=${page}&per_page=10&client_id=${API_KEY}`; + + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`API Error: ${response.status}`); + } + + const data = await response.json(); + + hideLoading(); + + if (data.results.length === 0) { + showError(`No images found for "${query}". Try a different search term.`); + return; + } + + if (page === 1) { + currentImages = data.results; + } else { + currentImages = [...currentImages, ...data.results]; + } + + displayCurrentImage(); + showResults(); + updateNavigationButtons(); + + } catch (error) { + hideLoading(); + console.error('Error fetching images:', error); + showError('Failed to fetch images. Please check your API key and internet connection.'); + } +} + +// Display the current image +function displayCurrentImage() { + const image = currentImages[currentIndex]; + + if (!image) return; + + resultImage.src = image.urls.regular; + resultImage.alt = image.alt_description || image.description || 'Image'; + photographerName.textContent = `Photo by ${image.user.name}`; + imageLink.href = image.links.html; + resultText.textContent = `Showing results for "${currentQuery}"`; + imageCounter.textContent = `${currentIndex + 1} / ${currentImages.length}`; +} + +// Show previous image +function showPreviousImage() { + if (currentIndex > 0) { + currentIndex--; + displayCurrentImage(); + updateNavigationButtons(); + } +} + +// Show next image +function showNextImage() { + if (currentIndex < currentImages.length - 1) { + currentIndex++; + displayCurrentImage(); + updateNavigationButtons(); + } +} + +// Update navigation buttons state +function updateNavigationButtons() { + prevBtn.disabled = currentIndex === 0; + nextBtn.disabled = currentIndex === currentImages.length - 1; +} + +// Load more results (next page) +async function loadMoreResults() { + currentPage++; + await fetchImages(currentQuery, currentPage); +} + +// UI Helper Functions +function showLoading() { + loading.classList.remove('hidden'); +} + +function hideLoading() { + loading.classList.add('hidden'); +} + +function showResults() { + resultsSection.classList.remove('hidden'); +} + +function hideResults() { + resultsSection.classList.add('hidden'); +} + +function showError(message) { + errorMessage.textContent = message; + errorMessage.classList.remove('hidden'); + + // Auto-hide error after 5 seconds + setTimeout(() => { + hideError(); + }, 5000); +} + +function hideError() { + errorMessage.classList.add('hidden'); +} + +// Keyboard navigation +document.addEventListener('keydown', (e) => { + if (currentImages.length === 0) return; + + if (e.key === 'ArrowLeft') { + showPreviousImage(); + } else if (e.key === 'ArrowRight') { + showNextImage(); + } +});""" + +# Save JavaScript file +with open('script.js', 'w', encoding='utf-8') as f: + f.write(js_content) + +print("✓ script.js created successfully") diff --git a/public/Day-216_Quick_image_finder/exported-assets/script_3.py b/public/Day-216_Quick_image_finder/exported-assets/script_3.py new file mode 100644 index 00000000..e4ffe906 --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/script_3.py @@ -0,0 +1,216 @@ + +# Create a comprehensive README file with setup instructions +readme_content = """# Quick Image Finder 🔍 + +A responsive web application that allows users to search for high-quality images using the Unsplash API. Enter a keyword, get instant results, and navigate through multiple images with ease. + +## Features + +✨ **Simple Search Interface** - Clean and intuitive design for easy image searching +🖼️ **High-Quality Images** - Access millions of professional photos from Unsplash +⬅️➡️ **Easy Navigation** - Browse through results with Previous/Next buttons or arrow keys +📱 **Responsive Design** - Works perfectly on desktop, tablet, and mobile devices +🎨 **Modern UI** - Beautiful gradient design with smooth animations +🔄 **Load More** - Fetch additional results without losing your place + +## Technologies Used + +- **HTML5** - Structure and content +- **CSS3** - Styling with gradients, animations, and responsive design +- **JavaScript (ES6+)** - API integration and interactivity +- **Unsplash API** - Free high-quality image database + +## Getting Started + +### Prerequisites + +- A modern web browser (Chrome, Firefox, Safari, Edge) +- Internet connection +- A free Unsplash API key + +### Step 1: Get Your Free Unsplash API Key + +1. Go to [Unsplash Developers](https://unsplash.com/developers) +2. Click **"Register as a Developer"** (or log in if you already have an account) +3. Click **"New Application"** +4. Accept the API guidelines +5. Fill in the application details: + - **Application name**: Quick Image Finder (or any name you prefer) + - **Description**: A web app for searching images +6. Click **"Create application"** +7. Copy your **Access Key** from the application page + +**Note**: The free tier allows 50 requests per hour, which is perfect for this demo project. + +### Step 2: Set Up the Project + +1. Download all three files: + - `index.html` + - `style.css` + - `script.js` + +2. Place all files in the same folder/directory + +3. Open `script.js` in a text editor + +4. Find this line at the top: + ```javascript + const API_KEY = 'YOUR_UNSPLASH_ACCESS_KEY'; + ``` + +5. Replace `'YOUR_UNSPLASH_ACCESS_KEY'` with your actual API key: + ```javascript + const API_KEY = 'your-actual-api-key-here'; + ``` + +6. Save the file + +### Step 3: Run the Application + +1. Double-click on `index.html` to open it in your default browser + - OR right-click → Open with → Choose your browser + +2. Enter a search term (e.g., "mountains", "technology", "nature") + +3. Press the **Search** button or hit Enter + +4. Navigate through results using: + - **Previous/Next buttons** + - **Arrow keys** on your keyboard + - **Load More Results** button for additional images + +## Project Structure + +``` +quick-image-finder/ +│ +├── index.html # Main HTML structure +├── style.css # All styling and animations +├── script.js # JavaScript logic and API integration +└── README.md # This file +``` + +## How It Works + +1. **User Input**: User enters a search keyword in the form +2. **API Request**: The app sends a request to Unsplash API with the search query +3. **Data Processing**: Response data is stored and the first image is displayed +4. **Navigation**: Users can browse through the 10 results per page +5. **Load More**: Clicking "Load More Results" fetches the next page of images + +## API Integration Details + +The app uses Unsplash's Search Photos endpoint: + +``` +https://api.unsplash.com/search/photos?query={searchTerm}&page={pageNumber}&per_page=10 +``` + +**Parameters:** +- `query`: The search keyword +- `page`: Page number for pagination +- `per_page`: Number of results per page (set to 10) +- `client_id`: Your API key for authentication + +## Customization Ideas + +Want to enhance this project? Here are some ideas: + +- Add filter options (orientation, color, etc.) +- Implement download functionality +- Add image favorites/bookmarking +- Create image gallery view +- Add dark mode toggle +- Implement infinite scroll +- Show more image metadata + +## Troubleshooting + +**Problem**: "Please add your Unsplash API key" error +- **Solution**: Make sure you've replaced `YOUR_UNSPLASH_ACCESS_KEY` in `script.js` with your actual key + +**Problem**: "Failed to fetch images" error +- **Solution**: Check your internet connection and verify your API key is correct + +**Problem**: No images found +- **Solution**: Try a different search term or more general keywords + +**Problem**: Images not loading +- **Solution**: Check browser console for errors (F12) and ensure all files are in the same directory + +## API Rate Limits + +- **Free tier**: 50 requests per hour +- **Recommended**: Apply for production access if you need higher limits +- The app handles errors gracefully if you exceed rate limits + +## Contributing to Open Source + +This project is perfect for: +- Learning API integration +- Practicing JavaScript async/await +- Understanding DOM manipulation +- Building portfolio projects + +Feel free to: +- Fork this project +- Add new features +- Fix bugs +- Improve the UI/UX +- Add documentation + +## License + +This project is open source and available for educational purposes. + +**Important**: When using Unsplash images, you must: +- Give credit to photographers +- Follow Unsplash's API guidelines +- Not abuse the API + +## Resources + +- [Unsplash API Documentation](https://unsplash.com/documentation) +- [Unsplash API Guidelines](https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines) +- [JavaScript Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) + +## Author + +Created as a learning project for web development students. + +## Acknowledgments + +- **Unsplash** for providing free API access +- **Unsplash photographers** for amazing images +- Web development community for tutorials and support + +--- + +**Happy coding! 🚀** + +If you have any questions or run into issues, check the browser console (F12) for detailed error messages. +""" + +# Save README file +with open('README.md', 'w', encoding='utf-8') as f: + f.write(readme_content) + +print("✓ README.md created successfully") +print("\n" + "="*60) +print("✅ ALL FILES CREATED SUCCESSFULLY!") +print("="*60) +print("\nFiles created:") +print(" 1. index.html - Main HTML file") +print(" 2. style.css - Styling and animations") +print(" 3. script.js - JavaScript logic and API integration") +print(" 4. README.md - Complete documentation") +print("\n" + "="*60) +print("NEXT STEPS:") +print("="*60) +print("1. Get your free Unsplash API key from:") +print(" https://unsplash.com/developers") +print("\n2. Open script.js and replace 'YOUR_UNSPLASH_ACCESS_KEY'") +print(" with your actual API key") +print("\n3. Open index.html in your browser") +print("\n4. Start searching for images!") +print("="*60) diff --git a/public/Day-216_Quick_image_finder/exported-assets/style.css b/public/Day-216_Quick_image_finder/exported-assets/style.css new file mode 100644 index 00000000..8c0f38c2 --- /dev/null +++ b/public/Day-216_Quick_image_finder/exported-assets/style.css @@ -0,0 +1,327 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; +} + +.container { + max-width: 900px; + margin: 0 auto; +} + +header { + text-align: center; + color: white; + margin-bottom: 40px; + animation: fadeInDown 0.8s ease; +} + +header h1 { + font-size: 3rem; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0,0,0,0.3); +} + +.subtitle { + font-size: 1.2rem; + opacity: 0.9; +} + +.search-section { + background: white; + padding: 30px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); + margin-bottom: 30px; + animation: fadeInUp 0.8s ease; +} + +#search-form { + display: flex; + gap: 10px; +} + +#search-input { + flex: 1; + padding: 15px 20px; + font-size: 1rem; + border: 2px solid #e0e0e0; + border-radius: 10px; + transition: all 0.3s ease; +} + +#search-input:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); +} + +#search-btn { + padding: 15px 40px; + font-size: 1rem; + font-weight: bold; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border: none; + border-radius: 10px; + cursor: pointer; + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +#search-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); +} + +#search-btn:active { + transform: translateY(0); +} + +.results-section { + background: white; + padding: 30px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); + animation: fadeInUp 0.8s ease; +} + +.result-info { + margin-bottom: 20px; +} + +#result-text { + font-size: 1.1rem; + color: #333; + margin-bottom: 15px; + font-weight: 500; +} + +.navigation-buttons { + display: flex; + align-items: center; + justify-content: center; + gap: 20px; + margin-top: 15px; +} + +.nav-btn { + padding: 10px 20px; + font-size: 0.9rem; + font-weight: bold; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border: none; + border-radius: 8px; + cursor: pointer; + transition: all 0.3s ease; +} + +.nav-btn:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); +} + +.nav-btn:disabled { + background: #ccc; + cursor: not-allowed; + opacity: 0.6; +} + +#image-counter { + font-weight: bold; + color: #667eea; + font-size: 1rem; +} + +.image-container { + margin: 20px 0; + text-align: center; +} + +#result-image { + width: 100%; + max-height: 500px; + object-fit: cover; + border-radius: 10px; + box-shadow: 0 5px 20px rgba(0,0,0,0.2); + transition: transform 0.3s ease; +} + +#result-image:hover { + transform: scale(1.02); +} + +.image-details { + margin-top: 15px; + padding: 15px; + background: #f8f9fa; + border-radius: 8px; +} + +#photographer-name { + font-size: 1rem; + color: #555; + margin-bottom: 10px; +} + +#image-link { + display: inline-block; + padding: 8px 20px; + color: white; + background: #667eea; + text-decoration: none; + border-radius: 6px; + transition: background 0.3s ease; +} + +#image-link:hover { + background: #764ba2; +} + +#show-more-btn { + width: 100%; + padding: 15px; + font-size: 1rem; + font-weight: bold; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + border: none; + border-radius: 10px; + cursor: pointer; + margin-top: 20px; + transition: all 0.3s ease; +} + +#show-more-btn:hover { + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4); +} + +.loading { + text-align: center; + background: white; + padding: 40px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); +} + +.spinner { + border: 4px solid #f3f3f3; + border-top: 4px solid #667eea; + border-radius: 50%; + width: 50px; + height: 50px; + animation: spin 1s linear infinite; + margin: 0 auto 20px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.loading p { + color: #667eea; + font-size: 1.1rem; + font-weight: 500; +} + +.error-message { + background: #ff4444; + color: white; + padding: 20px; + border-radius: 10px; + text-align: center; + font-size: 1rem; + box-shadow: 0 5px 15px rgba(255, 68, 68, 0.3); +} + +.hidden { + display: none; +} + +footer { + text-align: center; + color: white; + margin-top: 40px; + padding: 20px; +} + +footer p { + margin: 5px 0; + opacity: 0.9; +} + +footer a { + color: white; + text-decoration: underline; +} + +.api-note { + font-size: 0.9rem; + background: rgba(255, 255, 255, 0.2); + padding: 10px; + border-radius: 8px; + margin-top: 10px; +} + +@keyframes fadeInDown { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Responsive Design */ +@media (max-width: 768px) { + header h1 { + font-size: 2rem; + } + + .subtitle { + font-size: 1rem; + } + + #search-form { + flex-direction: column; + } + + .search-section { + padding: 20px; + } + + .results-section { + padding: 20px; + } + + .navigation-buttons { + flex-direction: column; + gap: 10px; + } + + .nav-btn { + width: 100%; + } +} \ No newline at end of file