diff --git a/assets/css/styles.css b/assets/css/styles.css index ae13f0d..43a40c6 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -4785,4 +4785,61 @@ body.theme-transition * { .highlight-new { animation: highlightReflection 2s ease-out; -} \ No newline at end of file +} + +/* Scroll to Top Button */ +.scroll-to-top { + position: fixed; + bottom: 2rem; + right: 2rem; + width: 3.5rem; + height: 3.5rem; + border-radius: 50%; + background-color: var(--primary-600); + color: white; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all var(--transition-medium) ease; + box-shadow: var(--shadow-xl); + border: none; + outline: none; +} + +.scroll-to-top.visible { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.scroll-to-top:not(.visible) { + transform: translateY(20px); +} + +.scroll-to-top:hover { + background-color: var(--primary-700); + transform: translateY(-5px); + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); +} + +.scroll-to-top:active { + transform: translateY(0); +} + +.scroll-to-top svg { + width: 1.5rem; + height: 1.5rem; +} + +@media (max-width: 768px) { + .scroll-to-top { + bottom: 1.5rem; + right: 1.5rem; + width: 3rem; + height: 3rem; + } +} diff --git a/assets/js/main.js b/assets/js/main.js index 013a058..da0cd1c 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -542,8 +542,54 @@ document.addEventListener('DOMContentLoaded', function () { script.src = 'assets/js/print-utils.js'; script.onload = initPrintUtils; document.head.appendChild(script); + + // 🔝 Initialize Scroll to Top button + initScrollToTop(); }); +// 🔝 Scroll to Top Functionality +function initScrollToTop() { + // Check if button already exists to prevent duplicates + if (document.querySelector('.scroll-to-top')) return; + + // Create the button element + const scrollBtn = document.createElement('button'); + scrollBtn.className = 'scroll-to-top'; + scrollBtn.setAttribute('aria-label', 'Scroll to top'); + scrollBtn.innerHTML = ` + + + + `; + + // Append to body + document.body.appendChild(scrollBtn); + + // Show/hide button on scroll + const toggleVisibility = () => { + if (window.scrollY > 300) { + scrollBtn.classList.add('visible'); + } else { + scrollBtn.classList.remove('visible'); + } + }; + + // Use debounce for performance if available + const handleScroll = window.utils && window.utils.debounce ? + window.utils.debounce(toggleVisibility, 100) : + toggleVisibility; + + window.addEventListener('scroll', handleScroll); + + // Smooth scroll to top on click + scrollBtn.addEventListener('click', () => { + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); + }); +} + // text animation function textAnimation() { const texts = ['Create', 'Build', 'Lead', 'Succeed', 'Grow']; @@ -587,9 +633,9 @@ function showNotification(message, type = 'success') { const notification = document.createElement('div'); notification.className = `notification-toast fixed top-6 right-6 px-6 py-4 rounded-xl shadow-xl z-50 max-w-sm ${type === 'success' ? 'bg-green-500' : - type === 'error' ? 'bg-red-500' : - type === 'warning' ? 'bg-yellow-500' : - 'bg-blue-500' + type === 'error' ? 'bg-red-500' : + type === 'warning' ? 'bg-yellow-500' : + 'bg-blue-500' } text-white transform transition-all duration-300 ease-out opacity-0 translate-y-2`; notification.innerHTML = ` diff --git a/index.html b/index.html index d795786..a025ccd 100644 --- a/index.html +++ b/index.html @@ -667,7 +667,6 @@

Stay Updated

- - - if (welcomeElement) { - welcomeElement.textContent = this.getWelcomeMessage(); - } - - // Update page title based on language - this.updatePageTitle(); - - // Dispatch event for other components to update - document.dispatchEvent(new CustomEvent('languageChanged', { - detail: { language: this.currentLanguage } - })); - } - - // Update page title based on language - updatePageTitle() { - const titles = { - 'en': 'BYAMN: Free Courses & Verified Certificates', - 'es': 'BYAMN: Cursos Gratuitos y Certificados Verificados', - 'fr': 'BYAMN: Cours Gratuits et Certificats Vérifiés', - 'de': 'BYAMN: Kostenlose Kurse und verifizierte Zertifikate', - 'it': 'BYAMN: Corsi Gratuiti e Certificati Verificati', - 'pt': 'BYAMN: Cursos Gratuitos e Certificados Verificados', - 'ru': 'BYAMN: Бесплатные курсы и проверенные сертификаты', - 'zh': 'BYAMN:免费课程和经过验证的证书', - 'ja': 'BYAMN:無料コースと認定済み証明書', - 'ko': 'BYAMN: 무료 강좌 및 인증된 수료증', - 'ar': 'BYAMN: دورات مجانية وشهادات موثقة', - 'hi': 'BYAMN: मुफ्त पाठ्यक्रम और सत्यापित प्रमाणपत्र' - }; - - const title = titles[this.currentLanguage] || titles[this.defaultLanguage]; - if (title && document.title) { - document.title = title; - } - } - - // Initialize language system - initialize() { - // Load saved preference first - const hasSavedPref = this.loadLanguagePreference(); - - // If no saved preference, auto-detect - if (!hasSavedPref) { - this.currentLanguage = this.detectLanguage(); - } - - // Apply language immediately - this.applyLanguage(); - - // Create language selector if needed - this.createLanguageSelector(); - } - - // Create language selector dropdown - createLanguageSelector() { - // Check if we already have a language selector - if (document.getElementById('language-selector')) { - return; - } - - // Look for user actions containers to add language selector - const userActionsDesktop = document.getElementById('user-actions-desktop'); - const userActionsMobile = document.getElementById('user-actions-mobile'); - - if (userActionsDesktop || userActionsMobile) { - // Create dropdown HTML - const dropdownHTML = ` -
- - -
- `; - - // Add to desktop version - if (userActionsDesktop) { - userActionsDesktop.insertAdjacentHTML('afterbegin', dropdownHTML); - } - - // Add to mobile version if it exists - if (userActionsMobile && userActionsMobile.parentElement) { - const mobileLanguageHTML = ` -
-
- Language - -
-
- `; - userActionsMobile.insertAdjacentHTML('beforeend', mobileLanguageHTML); - } - } - } - } - - // Initialize language detector globally - window.languageDetector = new LanguageDetector(); - - // Main JavaScript functionality - document.addEventListener('DOMContentLoaded', function () { - // Initialize language detection system - window.languageDetector.initialize(); - - // Theme toggle elements - const themeToggle = document.getElementById('theme-toggle'); - const themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon'); - const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon'); - - // Mobile menu elements - const mobileMenuButton = document.getElementById('mobile-menu-button'); - const mobileMenu = document.getElementById('mobile-menu'); - - // Set initial theme to light mode only - function initTheme() { - document.documentElement.classList.remove('dark'); - localStorage.setItem('theme', 'light'); - if (themeToggleDarkIcon) themeToggleDarkIcon.classList.add('hidden'); - if (themeToggleLightIcon) themeToggleLightIcon.classList.remove('hidden'); - } - - function toggleTheme() { - document.documentElement.classList.remove('dark'); - localStorage.setItem('theme', 'light'); - if (themeToggleDarkIcon) themeToggleDarkIcon.classList.add('hidden'); - if (themeToggleLightIcon) themeToggleLightIcon.classList.remove('hidden'); - } - - function toggleMobileMenu() { - mobileMenu.classList.toggle('hidden'); - const openIcon = document.getElementById('mobile-menu-icon-open'); - const closeIcon = document.getElementById('mobile-menu-icon-close'); - if (openIcon && closeIcon) { - openIcon.classList.toggle('hidden'); - closeIcon.classList.toggle('hidden'); - } - } - - // Initialize language selector for navigation - function updateNavWithLanguageSelector() { - const userActionsDesktop = document.getElementById('user-actions-desktop'); - const userActionsMobile = document.getElementById('user-actions-mobile'); - - if (userActionsDesktop) { - const existingLangSelector = userActionsDesktop.querySelector('#language-selector'); - if (!existingLangSelector) { - const langSelectorHTML = ` -
- - -
- `; - userActionsDesktop.insertAdjacentHTML('afterbegin', langSelectorHTML); - } - } - } - - // Text animation function - function textAnimation() { - const texts = ['Create', 'Build', 'Lead', 'Succeed', 'Grow']; - let count = 0; - let index = 0; - let currentText = ""; - let letter = ""; - - function type() { - if (count === texts.length) { - count = 0; - } - currentText = texts[count]; - letter = currentText.slice(0, ++index); - const textElement = document.getElementById("text"); - if (textElement) { - textElement.textContent = letter; - } - if (letter.length === currentText.length) { - count++; - index = 0; - setTimeout(type, 1500); //pause - } else { - setTimeout(type, 120); - } - } - - // Only start animation if element exists - if (document.getElementById("text")) { - type(); - } - } - - // Initialize theme - initTheme(); - - // Initialize text animation - textAnimation(); - - // Initialize navigation with language selector - updateNavWithLanguageSelector(); - - // Add event listeners - if (themeToggle) themeToggle.addEventListener('click', toggleTheme); - if (mobileMenuButton) mobileMenuButton.addEventListener('click', toggleMobileMenu); - - // Close mobile menu when clicking outside - document.addEventListener('click', function (event) { - if (mobileMenu && !mobileMenu.classList.contains('hidden') && - !mobileMenu.contains(event.target) && !mobileMenuButton.contains(event.target)) { - mobileMenu.classList.add('hidden'); - const openIcon = document.getElementById('mobile-menu-icon-open'); - const closeIcon = document.getElementById('mobile-menu-icon-close'); - if (openIcon && closeIcon) { - openIcon.classList.remove('hidden'); - closeIcon.classList.add('hidden'); - } - } - }); - - // Fix logo path - function fixLogoPath() { - const logoLink = document.getElementById("logoLink"); - const logoImg = document.getElementById("siteLogo"); - - if (!logoLink || !logoImg) return; - - const path = window.location.pathname; - - if (path.includes("/auth/")) { - // inside /auth/ folder - logoLink.href = "../index.html"; - logoImg.src = "../logo.png"; - } else if (path.includes("/dashboard") || path.includes("/profile") || path.includes("/settings")) { - // inside other subfolders - logoLink.href = "./index.html"; - logoImg.src = "./logo.png"; - } else { - // root pages - logoLink.href = "./index.html"; - logoImg.src = "./logo.png"; - } - } - - fixLogoPath(); - }); - - @@ -1000,11 +694,11 @@

Stay Updated

// Show loading state coursesContainer.innerHTML = ` -
-
-

Loading popular courses...

-
- `; +
+
+

Loading popular courses...

+
+ `; try { // Check if Firebase services are available @@ -1059,43 +753,43 @@

Stay Updated

} coursesHTML += ` -
-
- ${title} -
-
-
- ${category} -
- - - - ${rating} -
-
-

- ${title} -

-

- ${description} -

-
- $0 - Enroll Now -
-
-
- `; +
+
+ ${title} +
+
+
+ ${category} +
+ + + + ${rating} +
+
+

+ ${title} +

+

+ ${description} +

+
+ $0 + Enroll Now +
+
+
+ `; }); coursesContainer.innerHTML = coursesHTML; @@ -1113,23 +807,23 @@

// Show a more user-friendly error message with instructions coursesContainer.innerHTML = ` -
- - - -

Error Loading Courses

-

There was an error loading the course data.

-
-

Please make sure you've loaded the demo data into Firebase.

-

You can load the demo data by opening load-demo-data.html

-
-
- -
-
- `; +
+ + + +

Error Loading Courses

+

There was an error loading the course data.

+
+

Please make sure you've loaded the demo data into Firebase.

+

You can load the demo data by opening load-demo-data.html

+
+
+ +
+
+ `; } }