Compare commits
No commits in common. "b429b8bc5d7100932f8b84e0166964a2af78e896" and "6a5721598d3a4f39fdfd6a9a0a2bbd6faf4e2260" have entirely different histories.
b429b8bc5d
...
6a5721598d
134
I18N_README.md
134
I18N_README.md
@ -1,134 +0,0 @@
|
||||
# Система Интернационализации (i18n) для ExamPass
|
||||
|
||||
## Обзор
|
||||
|
||||
Система интернационализации позволяет переключаться между русским и английским языками на сайте ExamPass. Система автоматически сохраняет выбранный язык в localStorage и восстанавливает его при следующем посещении.
|
||||
|
||||
## Структура файлов
|
||||
|
||||
```
|
||||
src/js/
|
||||
├── translations.js # Файл с переводами
|
||||
├── i18n.js # Основная логика интернационализации
|
||||
└── main.js # Основной JavaScript файл (обновлен)
|
||||
```
|
||||
|
||||
## Как это работает
|
||||
|
||||
### 1. Файл переводов (`translations.js`)
|
||||
|
||||
Содержит объект `translations` с переводами для всех поддерживаемых языков:
|
||||
|
||||
```javascript
|
||||
const translations = {
|
||||
en: {
|
||||
nav_about: "About",
|
||||
hero_title_line1: "PASS ANY EXAM",
|
||||
// ... другие переводы
|
||||
},
|
||||
ru: {
|
||||
nav_about: "О нас",
|
||||
hero_title_line1: "СДАЙ ЛЮБОЙ ЭКЗАМЕН",
|
||||
// ... другие переводы
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Основная логика (`i18n.js`)
|
||||
|
||||
Класс `I18n` управляет:
|
||||
- Переключением языков
|
||||
- Сохранением выбранного языка
|
||||
- Обновлением контента на странице
|
||||
- Обновлением мета-тегов
|
||||
|
||||
### 3. HTML разметка
|
||||
|
||||
Элементы, которые нужно переводить, помечаются атрибутом `data-i18n`:
|
||||
|
||||
```html
|
||||
<a href="#about" data-i18n="nav_about">About</a>
|
||||
<h1 data-i18n="hero_title_line1">PASS ANY EXAM</h1>
|
||||
```
|
||||
|
||||
## Использование
|
||||
|
||||
### Переключение языков
|
||||
|
||||
Пользователи могут переключать язык, нажимая на кнопки "EN" или "RU" в навигации:
|
||||
|
||||
```html
|
||||
<div class="lang-switch">
|
||||
<a href="#" class="active">EN</a>
|
||||
<a href="#">RU</a>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Добавление новых переводов
|
||||
|
||||
1. Добавьте новый ключ в объект `translations` в файле `translations.js`:
|
||||
|
||||
```javascript
|
||||
const translations = {
|
||||
en: {
|
||||
new_key: "English text",
|
||||
// ...
|
||||
},
|
||||
ru: {
|
||||
new_key: "Русский текст",
|
||||
// ...
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
2. Добавьте атрибут `data-i18n` к HTML элементу:
|
||||
|
||||
```html
|
||||
<p data-i18n="new_key">Default text</p>
|
||||
```
|
||||
|
||||
### Специальные случаи
|
||||
|
||||
#### Сложные элементы
|
||||
|
||||
Для элементов с HTML разметкой внутри (например, с `<strong>` тегами) используется специальная обработка в методе `translateComplexElements()`.
|
||||
|
||||
#### Плейсхолдеры для input полей
|
||||
|
||||
Для input полей перевод применяется к атрибуту `placeholder`:
|
||||
|
||||
```html
|
||||
<input type="text" data-i18n="form_name_placeholder" placeholder="Enter your name">
|
||||
```
|
||||
|
||||
## Поддерживаемые элементы
|
||||
|
||||
Система автоматически переводит:
|
||||
|
||||
- Навигационные ссылки
|
||||
- Заголовки секций
|
||||
- Описания
|
||||
- Кнопки и формы
|
||||
- Footer ссылки
|
||||
- Мета-теги (language, og:locale)
|
||||
|
||||
## Тестирование
|
||||
|
||||
Для тестирования системы интернационализации используйте файл `test.html`. Он содержит примеры всех типов переводимых элементов.
|
||||
|
||||
## Автоматическое сохранение
|
||||
|
||||
Выбранный язык автоматически сохраняется в localStorage браузера и восстанавливается при следующем посещении сайта.
|
||||
|
||||
## SEO оптимизация
|
||||
|
||||
Система автоматически обновляет:
|
||||
- Атрибут `lang` у тега `<html>`
|
||||
- Мета-тег `language`
|
||||
- Open Graph тег `og:locale`
|
||||
|
||||
Это помогает поисковым системам правильно индексировать контент на разных языках.
|
||||
|
||||
## Совместимость
|
||||
|
||||
Система работает во всех современных браузерах и не требует дополнительных зависимостей.
|
28
robots.txt
28
robots.txt
@ -1,28 +0,0 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Sitemap
|
||||
Sitemap: https://exampass.com/sitemap.xml
|
||||
|
||||
# Crawl-delay for respectful crawling
|
||||
Crawl-delay: 1
|
||||
|
||||
# Allow all important pages
|
||||
Allow: /index.html
|
||||
Allow: /src/
|
||||
Allow: /assets/
|
||||
|
||||
# Disallow admin or private areas (if any)
|
||||
Disallow: /admin/
|
||||
Disallow: /private/
|
||||
Disallow: /temp/
|
||||
|
||||
# Allow search engines to index all content
|
||||
Allow: /#about
|
||||
Allow: /#methodology
|
||||
Allow: /#contact
|
||||
Allow: /#success
|
||||
|
||||
# Optimize for mobile
|
||||
Allow: /mobile/
|
||||
Allow: /responsive/
|
57
sitemap.xml
57
sitemap.xml
@ -1,57 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<!-- Homepage -->
|
||||
<url>
|
||||
<loc>https://exampass.com/</loc>
|
||||
<lastmod>2025-01-03</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
<xhtml:link rel="alternate" hreflang="en" href="https://exampass.com/"/>
|
||||
<xhtml:link rel="alternate" hreflang="ru" href="https://exampass.com/ru/"/>
|
||||
</url>
|
||||
|
||||
<!-- Russian version -->
|
||||
<url>
|
||||
<loc>https://exampass.com/ru/</loc>
|
||||
<lastmod>2025-01-03</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="en" href="https://exampass.com/"/>
|
||||
<xhtml:link rel="alternate" hreflang="ru" href="https://exampass.com/ru/"/>
|
||||
</url>
|
||||
|
||||
<!-- About section -->
|
||||
<url>
|
||||
<loc>https://exampass.com/#about</loc>
|
||||
<lastmod>2025-01-03</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
|
||||
<!-- Methodology section -->
|
||||
<url>
|
||||
<loc>https://exampass.com/#methodology</loc>
|
||||
<lastmod>2025-01-03</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
|
||||
<!-- Contact section -->
|
||||
<url>
|
||||
<loc>https://exampass.com/#contact</loc>
|
||||
<lastmod>2025-01-03</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
|
||||
<!-- Success stories -->
|
||||
<url>
|
||||
<loc>https://exampass.com/#success</loc>
|
||||
<lastmod>2025-01-03</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
|
||||
</urlset>
|
Binary file not shown.
Before Width: | Height: | Size: 84 KiB |
3793
src/css/style.css
3793
src/css/style.css
File diff suppressed because it is too large
Load Diff
1353
src/index.html
1353
src/index.html
File diff suppressed because it is too large
Load Diff
432
src/js/i18n.js
432
src/js/i18n.js
@ -1,432 +0,0 @@
|
||||
// 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} <span class="gradient-text">${this.getTranslation('about_gradient_text')}</span>`;
|
||||
}
|
||||
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 = `<span>${this.getTranslation('contact_heading_line1')}</span><span>${this.getTranslation('contact_heading_line2')}</span>`;
|
||||
}
|
||||
if (contactSubheading) {
|
||||
contactSubheading.innerHTML = `${this.getTranslation('contact_subheading')} <span class="highlight-text">${this.getTranslation('contact_highlight')}</span>`;
|
||||
}
|
||||
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();
|
||||
});
|
1228
src/js/main.js
1228
src/js/main.js
File diff suppressed because it is too large
Load Diff
@ -1,223 +0,0 @@
|
||||
const translations = {
|
||||
en: {
|
||||
// Navigation
|
||||
nav_about: "About",
|
||||
nav_exams: "Exams",
|
||||
nav_contact: "Contact",
|
||||
|
||||
// Hero Section
|
||||
hero_title_line1: "PASS ANY EXAM",
|
||||
hero_title_line2: "IN ONE",
|
||||
hero_title_click: "CLICK",
|
||||
hero_description: "Guaranteed admission to top-tier universities worldwide. Our revolutionary methods ensure 100% success rate - no courses, just guaranteed results to Harvard, Oxford, Cambridge, and Stanford.",
|
||||
|
||||
// Stats Section
|
||||
stats_overline: "Our Success",
|
||||
stats_title: "Our Achievements",
|
||||
stat_guarantee_title: "100% Guarantee",
|
||||
stat_guarantee_desc: "Success rate with our revolutionary methods",
|
||||
stat_years_title: "6 Years",
|
||||
stat_years_desc: "Of guaranteed university admissions",
|
||||
stat_students_title: "1000+ Students",
|
||||
stat_students_desc: "Successfully admitted to top universities worldwide",
|
||||
|
||||
// Methodology Section
|
||||
methodology_overline: "What We Guarantee",
|
||||
methodology_title: "Revolutionary Methods",
|
||||
|
||||
// GMAT/GRE
|
||||
gmat_title: "GMAT Focus Edition & GRE",
|
||||
gmat_subtitle: "Business & Graduate Schools",
|
||||
gmat_description: "Revolutionary analytical methods for elite business schools and universities. Our guaranteed approach ensures admission to Master's programs, MBA, Executive MBA, and PhD at top institutions.",
|
||||
gmat_feature1: "Quantitative Reasoning",
|
||||
gmat_feature2: "Verbal Reasoning",
|
||||
gmat_feature3: "Analytical Writing",
|
||||
gmat_feature4: "Integrated Reasoning",
|
||||
|
||||
// TOEFL/IELTS
|
||||
toefl_title: "TOEFL iBT & IELTS Indicator",
|
||||
toefl_subtitle: "English Proficiency",
|
||||
toefl_description: "Exams which evaluate your level of English, they must be passed for applying for any international studying programs, these exams are the most popular among international exams",
|
||||
toefl_feature1: "Reading Comprehension",
|
||||
toefl_feature2: "Listening Skills",
|
||||
toefl_feature3: "Speaking Practice",
|
||||
toefl_feature4: "Writing Tasks",
|
||||
|
||||
// Admission
|
||||
admission_title: "Admission Abroad",
|
||||
admission_subtitle: "University Applications",
|
||||
admission_description: "TOP World's best universities and business schools guaranteed admission: Harvard, Stanford, Oxford, LBS, Cambridge; Master of Business Administration programs, Executive MBA, Master's degree",
|
||||
admission_feature1: "Harvard University",
|
||||
admission_feature2: "Stanford University",
|
||||
admission_feature3: "Oxford University",
|
||||
admission_feature4: "Cambridge University",
|
||||
|
||||
// SAT/ACT
|
||||
sat_title: "SAT & ACT",
|
||||
sat_subtitle: "Undergraduate Admissions",
|
||||
sat_description: "Standardized tests required for undergraduate admissions to US colleges and universities. These exams evaluate critical thinking, problem-solving, and academic readiness for higher education.",
|
||||
sat_feature1: "Math & English",
|
||||
sat_feature2: "Critical Reading",
|
||||
sat_feature3: "Essay Writing",
|
||||
sat_feature4: "Science Reasoning",
|
||||
|
||||
// About Section
|
||||
about_overline: "About Us",
|
||||
about_title: "We're",
|
||||
about_gradient_text: "SnapPass",
|
||||
about_large_text: "A team of experts ready to transform the way you prepare for exams.",
|
||||
about_highlight: "Forget sleepless nights and endless courses — we do things differently.",
|
||||
about_description: "With us, everything is easy and straightforward: you'll feel confident after the very first step, and within days you'll be holding an official acceptance letter from a top‑tier university in your hands.",
|
||||
price_label: "Average Total Price",
|
||||
price_amount: "15,000",
|
||||
price_note: "The only company no one can compete with, unique and exclusive",
|
||||
|
||||
// Success Section
|
||||
success_overline: "Success Stories",
|
||||
success_title: "Real Results",
|
||||
success_subtitle: "Students who transformed their futures with our help",
|
||||
|
||||
// Contact Section
|
||||
contact_heading_line1: "READY TO",
|
||||
contact_heading_line2: "SUCCEED?",
|
||||
contact_subheading: "Transform your future today. Join thousands who achieved their dreams with our expert guidance.",
|
||||
contact_highlight: "Your success story starts here.",
|
||||
contact_telegram: "Telegram",
|
||||
contact_whatsapp: "WhatsApp",
|
||||
contact_instagram: "Instagram",
|
||||
form_header_title: "Start Your Journey",
|
||||
form_header_subtitle: "Get personalized consultation",
|
||||
form_name_label: "Full Name",
|
||||
form_name_placeholder: "Enter your name",
|
||||
form_phone_label: "Phone Number",
|
||||
form_phone_placeholder: "+1 (555) 123-4567",
|
||||
form_submit: "Get Free Consultation",
|
||||
|
||||
// Footer
|
||||
footer_description: "Your trusted partner in university admission since 2018. We help students achieve their dreams of studying at top-tier universities worldwide.",
|
||||
footer_exam_types: "Exam Types",
|
||||
footer_services: "Services",
|
||||
footer_contact: "Contact",
|
||||
footer_our_method: "Our Method",
|
||||
footer_success_stories: "Success Stories",
|
||||
footer_free_consultation: "Free Consultation",
|
||||
footer_get_started: "Get Started",
|
||||
footer_telegram_support: "Telegram Support",
|
||||
footer_email_us: "Email Us",
|
||||
footer_copyright: "© 2025 ExamPass. All rights reserved. | Helping students achieve their university dreams since 2018.",
|
||||
|
||||
// Breadcrumbs
|
||||
breadcrumb_home: "Home"
|
||||
},
|
||||
|
||||
ru: {
|
||||
// Navigation
|
||||
nav_about: "О нас",
|
||||
nav_exams: "Экзамены",
|
||||
nav_contact: "Контакты",
|
||||
|
||||
// Hero Section
|
||||
hero_title_line1: "СДАЙ ЛЮБОЙ ЭКЗАМЕН",
|
||||
hero_title_line2: "ОДНИМ",
|
||||
hero_title_click: "КЛИКОМ",
|
||||
hero_description: "Гарантированное поступление в ведущие университеты мира. Наши революционные методы обеспечивают 100% успех - никаких курсов, только гарантированные результаты в Гарвард, Оксфорд, Кембридж и Стэнфорд.",
|
||||
|
||||
// Stats Section
|
||||
stats_overline: "Наш Успех",
|
||||
stats_title: "Наши Достижения",
|
||||
stat_guarantee_title: "100% Гарантия",
|
||||
stat_guarantee_desc: "Успешность с нашими революционными методами",
|
||||
stat_years_title: "6 Лет",
|
||||
stat_years_desc: "Гарантированных поступлений в университеты",
|
||||
stat_students_title: "1000+ Студентов",
|
||||
stat_students_desc: "Успешно поступили в ведущие университеты мира",
|
||||
|
||||
// Methodology Section
|
||||
methodology_overline: "Что Мы Гарантируем",
|
||||
methodology_title: "Революционные Методы",
|
||||
|
||||
// GMAT/GRE
|
||||
gmat_title: "GMAT Focus Edition & GRE",
|
||||
gmat_subtitle: "Бизнес и Аспирантура",
|
||||
gmat_description: "Революционные аналитические методы для элитных бизнес-школ и университетов. Наш гарантированный подход обеспечивает поступление в магистратуру, MBA, Executive MBA и PhD в ведущих учреждениях.",
|
||||
gmat_feature1: "Количественное Мышление",
|
||||
gmat_feature2: "Вербальное Мышление",
|
||||
gmat_feature3: "Аналитическое Письмо",
|
||||
gmat_feature4: "Интегрированное Мышление",
|
||||
|
||||
// TOEFL/IELTS
|
||||
toefl_title: "TOEFL iBT & IELTS Indicator",
|
||||
toefl_subtitle: "Знание Английского",
|
||||
toefl_description: "Экзамены, которые оценивают ваш уровень английского языка, их необходимо сдать для подачи заявки на любые международные программы обучения, эти экзамены являются самыми популярными среди международных экзаменов",
|
||||
toefl_feature1: "Понимание Прочитанного",
|
||||
toefl_feature2: "Навыки Аудирования",
|
||||
toefl_feature3: "Разговорная Практика",
|
||||
toefl_feature4: "Письменные Задания",
|
||||
|
||||
// Admission
|
||||
admission_title: "Поступление За Границу",
|
||||
admission_subtitle: "Подача Заявок в Университеты",
|
||||
admission_description: "ТОП лучших университетов и бизнес-школ мира с гарантированным поступлением: Гарвард, Стэнфорд, Оксфорд, LBS, Кембридж; программы Master of Business Administration, Executive MBA, магистратура",
|
||||
admission_feature1: "Гарвардский Университет",
|
||||
admission_feature2: "Стэнфордский Университет",
|
||||
admission_feature3: "Оксфордский Университет",
|
||||
admission_feature4: "Кембриджский Университет",
|
||||
|
||||
// SAT/ACT
|
||||
sat_title: "SAT & ACT",
|
||||
sat_subtitle: "Поступление в Бакалавриат",
|
||||
sat_description: "Стандартизированные тесты, необходимые для поступления в бакалавриат в колледжи и университеты США. Эти экзамены оценивают критическое мышление, решение проблем и академическую готовность к высшему образованию.",
|
||||
sat_feature1: "Математика и Английский",
|
||||
sat_feature2: "Критическое Чтение",
|
||||
sat_feature3: "Написание Эссе",
|
||||
sat_feature4: "Научное Мышление",
|
||||
|
||||
// About Section
|
||||
about_overline: "О Нас",
|
||||
about_title: "Мы",
|
||||
about_gradient_text: "SnapPass",
|
||||
about_large_text: "Команда экспертов, готовая изменить способ подготовки к экзаменам.",
|
||||
about_highlight: "Забудьте о бессонных ночах и бесконечных курсах — мы делаем все по-другому.",
|
||||
about_description: "С нами все просто и понятно: вы почувствуете уверенность уже после первого шага, а через несколько дней будете держать в руках официальное письмо о зачислении в ведущий университет.",
|
||||
price_label: "Средняя Общая Стоимость",
|
||||
price_amount: "15,000",
|
||||
price_note: "Единственная компания, с которой никто не может конкурировать, уникальная и эксклюзивная",
|
||||
|
||||
// Success Section
|
||||
success_overline: "Истории Успеха",
|
||||
success_title: "Реальные Результаты",
|
||||
success_subtitle: "Студенты, которые изменили свое будущее с нашей помощью",
|
||||
|
||||
// Contact Section
|
||||
contact_heading_line1: "ГОТОВЫ",
|
||||
contact_heading_line2: "К УСПЕХУ?",
|
||||
contact_subheading: "Измените свое будущее сегодня. Присоединяйтесь к тысячам, которые достигли своих мечтаний с нашей экспертной помощью.",
|
||||
contact_highlight: "Ваша история успеха начинается здесь.",
|
||||
contact_telegram: "Телеграм",
|
||||
contact_whatsapp: "Ватсап",
|
||||
contact_instagram: "Инстаграм",
|
||||
form_header_title: "Начните Свой Путь",
|
||||
form_header_subtitle: "Получите персональную консультацию",
|
||||
form_name_label: "Полное Имя",
|
||||
form_name_placeholder: "Введите ваше имя",
|
||||
form_phone_label: "Номер Телефона",
|
||||
form_phone_placeholder: "+7 (999) 123-45-67",
|
||||
form_submit: "Получить Бесплатную Консультацию",
|
||||
|
||||
// Footer
|
||||
footer_description: "Ваш надежный партнер в поступлении в университет с 2018 года. Мы помогаем студентам достичь своих мечтаний об учебе в ведущих университетах мира.",
|
||||
footer_exam_types: "Типы Экзаменов",
|
||||
footer_services: "Услуги",
|
||||
footer_contact: "Контакты",
|
||||
footer_our_method: "Наш Метод",
|
||||
footer_success_stories: "Истории Успеха",
|
||||
footer_free_consultation: "Бесплатная Консультация",
|
||||
footer_get_started: "Начать",
|
||||
footer_telegram_support: "Поддержка в Телеграм",
|
||||
footer_email_us: "Написать Нам",
|
||||
footer_copyright: "© 2025 ExamPass. Все права защищены. | Помогаем студентам достичь своих университетских мечтаний с 2018 года.",
|
||||
|
||||
// Breadcrumbs
|
||||
breadcrumb_home: "Главная"
|
||||
}
|
||||
};
|
@ -1,18 +0,0 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Sitemaps
|
||||
Sitemap: https://exampass.com/sitemap.xml
|
||||
|
||||
# Crawl-delay for better server performance
|
||||
Crawl-delay: 1
|
||||
|
||||
# Block access to certain directories
|
||||
Disallow: /js/
|
||||
Disallow: /css/
|
||||
Disallow: /assets/universities/
|
||||
|
||||
# Allow access to important assets
|
||||
Allow: /assets/logo/
|
||||
Allow: /css/style.css
|
||||
Allow: /js/main.js
|
@ -1,3 +0,0 @@
|
||||
нужно сделать meta ссылки для сайта
|
||||
|
||||
и нужно оптимизировать seo
|
Loading…
Reference in New Issue
Block a user