Files
hotell777_260507/public/js/i18n.js
2026-05-10 21:42:31 +05:00

110 lines
3.5 KiB
JavaScript

const I18n = {
currentLang: 'ru',
translations: {},
async init() {
const savedLang = localStorage.getItem('lang') || 'ru';
await this.setLang(savedLang);
},
async setLang(lang) {
try {
const res = await fetch(`/api/translations/${lang}`);
if (!res.ok) throw new Error('Failed to load translations');
this.translations = await res.json();
this.currentLang = lang;
localStorage.setItem('lang', lang);
this.updateUI();
this.updateNavLabels();
} catch (err) {
console.error('I18n error:', err);
if (lang !== 'ru') {
await this.setLang('ru');
}
}
},
t(key, replacements = {}) {
let text = this.translations[key] || key;
Object.entries(replacements).forEach(([k, v]) => {
text = text.replace(`{${k}}`, v);
});
return text;
},
updateUI() {
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
const attr = el.getAttribute('data-i18n-attr');
const text = this.t(key);
if (attr) {
el.setAttribute(attr, text);
} else {
el.textContent = text;
}
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const key = el.getAttribute('data-i18n-placeholder');
el.placeholder = this.t(key);
});
},
updateNavLabels() {
const langBtns = document.querySelectorAll('.lang-btn');
langBtns.forEach(btn => {
btn.classList.toggle('active', btn.dataset.lang === this.currentLang);
});
},
getInitials(name) {
if (!name) return '?';
const parts = name.trim().split(/\s+/);
if (parts.length >= 2) {
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
}
return name.substring(0, 2).toUpperCase();
},
formatDate(dateStr) {
const date = new Date(dateStr);
const months = this.currentLang === 'ru'
? ['Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря']
: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
return `${months[date.getMonth()]} ${date.getFullYear()}`;
},
renderStars(count, max = 5) {
let html = '';
for (let i = 1; i <= max; i++) {
if (count >= i) {
html += '<i class="fas fa-star filled"></i>';
} else if (count >= i - 0.5) {
html += '<i class="fas fa-star-half-alt filled"></i>';
} else {
html += '<i class="far fa-star"></i>';
}
}
return html;
},
renderStarsStatic(count) {
let html = '';
const fullStars = Math.floor(count);
const hasHalf = count % 1 >= 0.5;
for (let i = 0; i < 5; i++) {
if (i < fullStars) {
html += '<i class="fas fa-star"></i>';
} else if (i === fullStars && hasHalf) {
html += '<i class="fas fa-star-half-alt"></i>';
} else {
html += '<i class="far fa-star"></i>';
}
}
return html;
}
};
window.I18n = I18n;