diff --git a/public/app.js b/public/app.js index 918cf40..2e01043 100644 --- a/public/app.js +++ b/public/app.js @@ -8,6 +8,7 @@ const searchInput = document.getElementById('searchInput'); const linksContainer = document.getElementById('linksContainer'); const toastContainer = document.getElementById('toastContainer'); const archiveToggle = document.getElementById('archiveToggle'); +const scrollToTopBtn = document.getElementById('scrollToTopBtn'); // State let allLinks = []; @@ -18,6 +19,7 @@ let showArchived = false; document.addEventListener('DOMContentLoaded', () => { loadLinks(); setupEventListeners(); + setupScrollToTop(); }); // Event listeners @@ -27,6 +29,26 @@ function setupEventListeners() { archiveToggle.addEventListener('click', handleToggleArchive); } +// Setup scroll to top button +function setupScrollToTop() { + // Show/hide button based on scroll position + window.addEventListener('scroll', () => { + if (window.pageYOffset > 300) { + scrollToTopBtn.classList.add('show'); + } else { + scrollToTopBtn.classList.remove('show'); + } + }); + + // Scroll to top when button is clicked + scrollToTopBtn.addEventListener('click', () => { + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); + }); +} + // Load all links async function loadLinks() { try { diff --git a/public/index.html b/public/index.html index 80bafc6..106b03a 100644 --- a/public/index.html +++ b/public/index.html @@ -75,6 +75,12 @@
+ + diff --git a/public/styles.css b/public/styles.css index 6fe44c1..62211ff 100644 --- a/public/styles.css +++ b/public/styles.css @@ -635,6 +635,49 @@ body { } } +/* Scroll to Top Button */ +.scroll-to-top-btn { + position: fixed; + bottom: 2rem; + right: 2rem; + width: 50px; + height: 50px; + border-radius: 50%; + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: white; + border: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4); + transition: all 0.3s ease; + opacity: 0; + visibility: hidden; + transform: translateY(20px); + z-index: 999; +} + +.scroll-to-top-btn.show { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.scroll-to-top-btn:hover { + transform: translateY(-3px); + box-shadow: 0 6px 16px rgba(99, 102, 241, 0.5); +} + +.scroll-to-top-btn:active { + transform: translateY(-1px); +} + +.scroll-to-top-btn svg { + width: 24px; + height: 24px; +} + @media (max-width: 400px) { .header-right { flex-direction: column; @@ -649,5 +692,12 @@ body { width: 100%; justify-content: flex-start; } + + .scroll-to-top-btn { + bottom: 1.5rem; + right: 1.5rem; + width: 45px; + height: 45px; + } }