// Internationalization (i18n) System class I18n { constructor() { this.currentLang = localStorage.getItem('language') || 'en'; this.init(); } init() { this.setLanguage(this.currentLang); this.setupLanguageSwitchers(); } setLanguage(lang) { try { this.currentLang = lang; localStorage.setItem('language', lang); // Update HTML lang attribute document.documentElement.lang = lang; // Update meta tags this.updateMetaTags(lang); // Translate all content this.translatePage(); // Update language switcher UI this.updateLanguageSwitcherUI(lang); // Update carousel cards if they exist setTimeout(() => { this.updateCarouselCards(); }, 100); } catch (error) { console.error('Error setting language:', error); } } updateMetaTags(lang) { // Update meta language tag let metaLang = document.querySelector('meta[name="language"]'); if (!metaLang) { metaLang = document.createElement('meta'); metaLang.name = 'language'; document.head.appendChild(metaLang); } metaLang.content = lang === 'ru' ? 'Russian' : 'English'; // Update Open Graph locale let ogLocale = document.querySelector('meta[property="og:locale"]'); if (!ogLocale) { ogLocale = document.createElement('meta'); ogLocale.setAttribute('property', 'og:locale'); document.head.appendChild(ogLocale); } ogLocale.content = lang === 'ru' ? 'ru_RU' : 'en_US'; } translatePage() { const elements = document.querySelectorAll('[data-i18n]'); elements.forEach(element => { const key = element.getAttribute('data-i18n'); const translation = this.getTranslation(key); if (translation) { if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') { element.placeholder = translation; } else { element.textContent = translation; } } }); // Special handling for complex elements this.translateComplexElements(); } translateComplexElements() { // Hero section title const heroTitleLine1 = document.querySelector('.hero-title-line1'); const heroTitleLine2 = document.querySelector('.hero-title-line2'); const heroTitleClick = document.querySelector('.hero-title-click'); if (heroTitleLine1) heroTitleLine1.textContent = this.getTranslation('hero_title_line1'); if (heroTitleLine2) heroTitleLine2.textContent = this.getTranslation('hero_title_line2'); if (heroTitleClick) heroTitleClick.textContent = this.getTranslation('hero_title_click'); // Hero description const heroDescription = document.querySelector('.hero-description'); if (heroDescription) { heroDescription.innerHTML = this.getTranslation('hero_description'); } // Navigation const navLinks = document.querySelectorAll('.nav-links a, .mobile-nav-links a'); navLinks.forEach(link => { const href = link.getAttribute('href'); if (href === '#about') { link.textContent = this.getTranslation('nav_about'); } else if (href === '#methodology') { link.textContent = this.getTranslation('nav_exams'); } else if (href === '#contact') { link.textContent = this.getTranslation('nav_contact'); } }); // Stats section const statsOverline = document.querySelector('.stats-overline'); const statsTitle = document.querySelector('.stats-title'); if (statsOverline) statsOverline.textContent = this.getTranslation('stats_overline'); if (statsTitle) statsTitle.textContent = this.getTranslation('stats_title'); // Stat cards const statCards = document.querySelectorAll('.stat-card'); statCards.forEach((card, index) => { const title = card.querySelector('.stat-title'); const description = card.querySelector('.stat-description'); if (index === 0) { if (title) title.textContent = this.getTranslation('stat_guarantee_title'); if (description) description.textContent = this.getTranslation('stat_guarantee_desc'); } else if (index === 1) { if (title) title.textContent = this.getTranslation('stat_years_title'); if (description) description.textContent = this.getTranslation('stat_years_desc'); } else if (index === 2) { if (title) title.textContent = this.getTranslation('stat_students_title'); if (description) description.textContent = this.getTranslation('stat_students_desc'); } }); // Methodology section const methodologyOverline = document.querySelector('.exam-types-overline'); const methodologyTitle = document.querySelector('.exam-types-title'); if (methodologyOverline) methodologyOverline.textContent = this.getTranslation('methodology_overline'); if (methodologyTitle) methodologyTitle.textContent = this.getTranslation('methodology_title'); // Accordion items this.translateAccordionItems(); // About section this.translateAboutSection(); // Success section const successOverline = document.querySelector('.success-overline'); const successTitle = document.querySelector('.success-title'); const successSubtitle = document.querySelector('.success-subtitle'); if (successOverline) successOverline.textContent = this.getTranslation('success_overline'); if (successTitle) successTitle.textContent = this.getTranslation('success_title'); if (successSubtitle) successSubtitle.textContent = this.getTranslation('success_subtitle'); // Update testimonials in carousel this.updateTestimonials(); // Contact section this.translateContactSection(); // Footer this.translateFooter(); // Breadcrumbs const breadcrumbHome = document.querySelector('.breadcrumbs span'); if (breadcrumbHome) breadcrumbHome.textContent = this.getTranslation('breadcrumb_home'); } translateAccordionItems() { // GMAT/GRE const gmatItem = document.querySelector('[data-exam="gmat"]'); if (gmatItem) { const title = gmatItem.querySelector('h3'); const subtitle = gmatItem.querySelector('.accordion-subtitle'); const description = gmatItem.querySelector('.exam-description'); const features = gmatItem.querySelectorAll('.feature-tag'); if (title) title.textContent = this.getTranslation('gmat_title'); if (subtitle) subtitle.textContent = this.getTranslation('gmat_subtitle'); if (description) description.textContent = this.getTranslation('gmat_description'); features.forEach((feature, index) => { const key = `gmat_feature${index + 1}`; feature.textContent = this.getTranslation(key); }); } // TOEFL/IELTS const toeflItem = document.querySelector('[data-exam="toefl"]'); if (toeflItem) { const title = toeflItem.querySelector('h3'); const subtitle = toeflItem.querySelector('.accordion-subtitle'); const description = toeflItem.querySelector('.exam-description'); const features = toeflItem.querySelectorAll('.feature-tag'); if (title) title.textContent = this.getTranslation('toefl_title'); if (subtitle) subtitle.textContent = this.getTranslation('toefl_subtitle'); if (description) description.textContent = this.getTranslation('toefl_description'); features.forEach((feature, index) => { const key = `toefl_feature${index + 1}`; feature.textContent = this.getTranslation(key); }); } // Admission const admissionItem = document.querySelector('[data-exam="admission"]'); if (admissionItem) { const title = admissionItem.querySelector('h3'); const subtitle = admissionItem.querySelector('.accordion-subtitle'); const description = admissionItem.querySelector('.exam-description'); const features = admissionItem.querySelectorAll('.feature-tag'); if (title) title.textContent = this.getTranslation('admission_title'); if (subtitle) subtitle.textContent = this.getTranslation('admission_subtitle'); if (description) description.textContent = this.getTranslation('admission_description'); features.forEach((feature, index) => { const key = `admission_feature${index + 1}`; feature.textContent = this.getTranslation(key); }); } // SAT/ACT const satItem = document.querySelector('[data-exam="sat-act"]'); if (satItem) { const title = satItem.querySelector('h3'); const subtitle = satItem.querySelector('.accordion-subtitle'); const description = satItem.querySelector('.exam-description'); const features = satItem.querySelectorAll('.feature-tag'); if (title) title.textContent = this.getTranslation('sat_title'); if (subtitle) subtitle.textContent = this.getTranslation('sat_subtitle'); if (description) description.textContent = this.getTranslation('sat_description'); features.forEach((feature, index) => { const key = `sat_feature${index + 1}`; feature.textContent = this.getTranslation(key); }); } } translateAboutSection() { const aboutOverline = document.querySelector('.about-overline'); const aboutTitle = document.querySelector('.about-title'); const aboutGradientText = document.querySelector('.about-title .gradient-text'); const aboutLargeText = document.querySelector('.about-description .large-text'); const aboutHighlight = document.querySelector('.about-description .highlight-block p'); const aboutDescription = document.querySelector('.about-description .text-block:last-child p'); const priceLabel = document.querySelector('.price-label'); const priceNote = document.querySelector('.price-note'); if (aboutOverline) aboutOverline.textContent = this.getTranslation('about_overline'); if (aboutTitle) { const titleText = this.getTranslation('about_title'); aboutTitle.innerHTML = `${titleText} ${this.getTranslation('about_gradient_text')}`; } if (aboutLargeText) aboutLargeText.textContent = this.getTranslation('about_large_text'); if (aboutHighlight) aboutHighlight.textContent = this.getTranslation('about_highlight'); if (aboutDescription) aboutDescription.textContent = this.getTranslation('about_description'); if (priceLabel) priceLabel.textContent = this.getTranslation('price_label'); if (priceNote) priceNote.textContent = this.getTranslation('price_note'); } translateContactSection() { const contactHeading = document.querySelector('.contact-heading'); const contactSubheading = document.querySelector('.contact-subheading'); const contactHighlight = document.querySelector('.contact-subheading .highlight-text'); const contactTelegram = document.querySelector('.contact-method-btn[href*="telegram"]'); const contactWhatsapp = document.querySelector('.contact-method-btn[href*="whatsapp"]'); const contactInstagram = document.querySelector('.contact-method-btn[href*="instagram"]'); const formHeaderTitle = document.querySelector('.form-header h3'); const formHeaderSubtitle = document.querySelector('.form-header p'); const formNameLabel = document.querySelector('label[for="firstName"]'); const formNameInput = document.querySelector('#firstName'); const formPhoneLabel = document.querySelector('label[for="phone"]'); const formPhoneInput = document.querySelector('#phone'); const formSubmit = document.querySelector('.submit-btn span'); if (contactHeading) { contactHeading.innerHTML = `${this.getTranslation('contact_heading_line1')}${this.getTranslation('contact_heading_line2')}`; } if (contactSubheading) { contactSubheading.innerHTML = `${this.getTranslation('contact_subheading')} ${this.getTranslation('contact_highlight')}`; } if (contactTelegram) contactTelegram.textContent = this.getTranslation('contact_telegram'); if (contactWhatsapp) contactWhatsapp.textContent = this.getTranslation('contact_whatsapp'); if (contactInstagram) contactInstagram.textContent = this.getTranslation('contact_instagram'); if (formHeaderTitle) formHeaderTitle.textContent = this.getTranslation('form_header_title'); if (formHeaderSubtitle) formHeaderSubtitle.textContent = this.getTranslation('form_header_subtitle'); if (formNameLabel) formNameLabel.textContent = this.getTranslation('form_name_label'); if (formNameInput) formNameInput.placeholder = this.getTranslation('form_name_placeholder'); if (formPhoneLabel) formPhoneLabel.textContent = this.getTranslation('form_phone_label'); if (formPhoneInput) formPhoneInput.placeholder = this.getTranslation('form_phone_placeholder'); if (formSubmit) formSubmit.textContent = this.getTranslation('form_submit'); } translateFooter() { const footerDescription = document.querySelector('.footer-info p'); const footerExamTypes = document.querySelector('.footer-links h4:first-of-type'); const footerServices = document.querySelector('.footer-links h4:nth-of-type(2)'); const footerContact = document.querySelector('.footer-links h4:last-of-type'); const footerCopyright = document.querySelector('.footer-bottom p'); if (footerDescription) footerDescription.textContent = this.getTranslation('footer_description'); if (footerExamTypes) footerExamTypes.textContent = this.getTranslation('footer_exam_types'); if (footerServices) footerServices.textContent = this.getTranslation('footer_services'); if (footerContact) footerContact.textContent = this.getTranslation('footer_contact'); if (footerCopyright) footerCopyright.textContent = this.getTranslation('footer_copyright'); // Footer links const footerLinks = document.querySelectorAll('.footer-links a'); footerLinks.forEach(link => { const href = link.getAttribute('href'); if (href === '#about') { link.textContent = this.getTranslation('footer_our_method'); } else if (href === '#success') { link.textContent = this.getTranslation('footer_success_stories'); } else if (href === '#contact') { link.textContent = this.getTranslation('footer_free_consultation'); } else if (href === '#contact' && link.textContent.includes('Started')) { link.textContent = this.getTranslation('footer_get_started'); } else if (href.includes('telegram')) { link.textContent = this.getTranslation('footer_telegram_support'); } else if (href.includes('mailto')) { link.textContent = this.getTranslation('footer_email_us'); } }); } getTranslation(key) { return translations[this.currentLang]?.[key] || key; } updateTestimonials() { // Update testimonials in the carousel if it exists const testimonials = document.querySelectorAll('.testimonial'); if (testimonials.length > 0) { // Only translate if current language is Russian if (this.currentLang === 'ru') { const testimonialKeys = ['testimonial_alex', 'testimonial_maria', 'testimonial_david', 'testimonial_sarah']; testimonials.forEach((testimonial, index) => { if (index < testimonialKeys.length) { const translation = this.getTranslation(testimonialKeys[index]); if (translation && translation !== testimonialKeys[index]) { testimonial.textContent = '"' + translation + '"'; } } }); } } // Update carousel cards if they exist this.updateCarouselCards(); } updateCarouselCards() { // Check if carousel exists and update current card if (typeof window.currentCard !== 'undefined' && typeof window.cards !== 'undefined' && window.cards.length > 0) { const currentCardData = window.cards[window.currentCard]; if (currentCardData) { let testimonialText = currentCardData.testimonial; // Only translate if current language is Russian if (this.currentLang === 'ru') { const testimonialKeys = ['testimonial_alex', 'testimonial_maria', 'testimonial_david', 'testimonial_sarah']; const translation = this.getTranslation(testimonialKeys[window.currentCard]); // Use translation if available and not equal to key if (translation && translation !== testimonialKeys[window.currentCard]) { testimonialText = translation; } } // Update testimonial in both front and back cards const frontTestimonial = document.querySelector('.card-face.front .testimonial'); const backTestimonial = document.querySelector('.card-face.back .testimonial'); if (frontTestimonial) { frontTestimonial.textContent = '"' + testimonialText + '"'; } if (backTestimonial) { backTestimonial.textContent = '"' + testimonialText + '"'; } } } } setupLanguageSwitchers() { const languageSwitchers = document.querySelectorAll('.lang-switch, .mobile-lang-switch'); languageSwitchers.forEach(switcher => { const links = switcher.querySelectorAll('a'); links.forEach(link => { // Remove existing event listeners to prevent duplicates link.removeEventListener('click', this.handleLanguageSwitch); // Add new event listener link.addEventListener('click', this.handleLanguageSwitch.bind(this)); }); }); } handleLanguageSwitch(e) { e.preventDefault(); e.stopPropagation(); const lang = e.target.textContent.toLowerCase(); if (lang === 'en' || lang === 'ru') { this.setLanguage(lang); } } updateLanguageSwitcherUI(lang) { const languageSwitchers = document.querySelectorAll('.lang-switch, .mobile-lang-switch'); languageSwitchers.forEach(switcher => { const links = switcher.querySelectorAll('a'); links.forEach(link => { link.classList.remove('active'); if (link.textContent.toLowerCase() === lang) { link.classList.add('active'); } }); }); } } // Initialize i18n when DOM is loaded document.addEventListener('DOMContentLoaded', () => { window.i18n = new I18n(); });