var viewDashboard = document.getElementById('yp-view-dashboard');
var viewIframe = document.getElementById('yp-view-iframe');
var iframeEl = document.getElementById('yp-iframe');
var iframeSpinner = document.getElementById('yp-iframe-spinner');
var iframeTitleEl = document.getElementById('yp-iframe-title');
var iframeUrlEl = document.getElementById('yp-iframe-url-label');
var langBtn = document.getElementById('yp-lang-btn');
var langPopup = document.getElementById('yp-lang-popup');
var langFlag = document.getElementById('yp-lang-flag');
var langCode = document.getElementById('yp-lang-code');
var langItems = document.querySelectorAll('.yp-lang-popup__item');
var currentIframeBaseUrl = '';
function isMobile() { return window.innerWidth <= 640; }
/* ═══════════════════════════════════════════════
СЛОВАРЬ ПЕРЕВОДОВ
═══════════════════════════════════════════════ */
var DICT = {
ru: {
'sec-work':'Работа','sec-profile':'Профиль','sec-finance':'Финансы',
'sec-exchange':'Биржа','sec-network':'Сеть','sec-knowledge':'Знания',
'sec-documents':'Документы','sec-communication':'Общение','sec-system':'Система',
'nav-home':'Главная','nav-mywork':'Моя работа','nav-myguys':'Мои подопечные',
'nav-mycv':'Моё резюме','nav-achievements':'Мои достижения','nav-health':'Моё здоровье',
'nav-finance':'Мои финансы','nav-rent':'Моя аренда','nav-exchange':'Моя биржа',
'nav-vacancy':'Биржа вакансий','nav-candidates':'Биржа кандидатов',
'nav-network':'Моя сеть','nav-partners':'Мои партнёры',
'nav-guide':'Мой ГАЙД · обучение','nav-library':'Моя энциклопедия',
'nav-docs':'Мои документы','nav-news':'Мои новости',
'nav-chats':'Мои чаты / сообщения','nav-settings':'Мои настройки',
'bc-home':'Главная','bc-current':'Дашборд',
'welcome':'Добро пожаловать, Ron 👋',
'stat-wallet':'Кошелёк $YTC','stat-learning':'Обучение',
'stat-messages':'Сообщения','stat-event':'До события',
'stat-msg-sub':'3 непрочитанных','stat-learn-sub':'↑ Модуль 4 — 97/100',
'unit-hours':'Часов','unit-mins':'Минут','unit-secs':'Секунд',
'next-event':'Следующее событие',
'info-yacht':'Яхта','info-pos':'Позиция','info-port':'Порт','info-status':'Статус',
'upcoming':'Предстоящий платёж','btn-transactions':'Все транзакции',
'learn-pct':'75% пройдено','gig-label':'Срочный гиг рядом',
'btn-messages':'Все сообщения','btn-read':'Читать далее',
'mood-title':'Как настроение?','dd-profile':'Мой профиль','dd-logout':'Выйти',
'widget-assignment':'🚤 Текущее задание','widget-wallet':'💰 Кошелёк',
'widget-learning':'🎓 Прогресс обучения','widget-messages':'💬 Сообщения и гиги',
'widget-news':'🌊 Новости отрасли'
},
en: {
'sec-work':'Work','sec-profile':'Profile','sec-finance':'Finance',
'sec-exchange':'Exchange','sec-network':'Network','sec-knowledge':'Knowledge',
'sec-documents':'Documents','sec-communication':'Communication','sec-system':'System',
'nav-home':'Home','nav-mywork':'My Work','nav-myguys':'My Crew',
'nav-mycv':'My CV','nav-achievements':'My Achievements','nav-health':'My Health',
'nav-finance':'My Finances','nav-rent':'My Rental','nav-exchange':'My Exchange',
'nav-vacancy':'Job Board','nav-candidates':'Candidates',
'nav-network':'My Network','nav-partners':'My Partners',
'nav-guide':'My GUIDE · Training','nav-library':'My Encyclopedia',
'nav-docs':'My Documents','nav-news':'My News',
'nav-chats':'My Chats / Messages','nav-settings':'My Settings',
'bc-home':'Home','bc-current':'Dashboard',
'welcome':'Welcome, Ron 👋',
'stat-wallet':'Wallet $YTC','stat-learning':'Learning',
'stat-messages':'Messages','stat-event':'Until Event',
'stat-msg-sub':'3 unread','stat-learn-sub':'↑ Module 4 — 97/100',
'unit-hours':'Hours','unit-mins':'Minutes','unit-secs':'Seconds',
'next-event':'Next Event',
'info-yacht':'Yacht','info-pos':'Position','info-port':'Port','info-status':'Status',
'upcoming':'Upcoming Payment','btn-transactions':'All Transactions',
'learn-pct':'75% completed','gig-label':'Urgent gig nearby',
'btn-messages':'All Messages','btn-read':'Read more',
'mood-title':'How are you feeling?','dd-profile':'My Profile','dd-logout':'Log out',
'widget-assignment':'🚤 Current Assignment','widget-wallet':'💰 Wallet Overview',
'widget-learning':'🎓 Learning Progress','widget-messages':'💬 Messages & Gigs',
'widget-news':'🌊 Industry Updates'
}
};
function applyLang(lang) {
var dict = DICT[lang] || DICT['ru'];
document.querySelectorAll('[data-i18n]').forEach(function(el) {
var key = el.getAttribute('data-i18n');
if (dict[key] !== undefined) el.textContent = dict[key];
});
}
/* ═══════════════════════════════════════════════
LANGUAGE
═══════════════════════════════════════════════ */
var LANG_MAP = {
ru: { flag: '🇷🇺', code: 'RU' },
en: { flag: '🇬🇧', code: 'EN' }
};
function getCurrentLang() {
try { return localStorage.getItem('app-language') || 'ru'; } catch(e) { return 'ru'; }
}
function setLanguage(lang) {
try { localStorage.setItem('app-language', lang); } catch(e) {}
document.documentElement.setAttribute('lang', lang);
updateLangUI(lang);
applyLang(lang);
reloadIframeWithLang(lang);
}
function updateLangUI(lang) {
var cfg = LANG_MAP[lang] || LANG_MAP['ru'];
if (langFlag) langFlag.textContent = cfg.flag;
if (langCode) langCode.textContent = cfg.code;
langItems.forEach(function(item) {
item.classList.toggle('yp-lang-popup__item--active', item.dataset.lang === lang);
});
}
function reloadIframeWithLang(lang) {
if (!currentIframeBaseUrl) return;
iframeSpinner.classList.remove('yp-iframe-spinner--hidden');
iframeEl.src = '';
iframeEl.src = buildLangUrl(currentIframeBaseUrl, lang);
}
function buildLangUrl(baseUrl, lang) {
try {
var u = new URL(baseUrl);
u.searchParams.set('lang', lang || getCurrentLang());
return u.toString();
} catch(e) { return baseUrl; }
}
/* postMessage — приём данных от iframe-страниц */
window.addEventListener('message', function(e) {
if (!e.data || e.data.type !== 'yp-data') return;
var d = e.data;
/* Кошелёк */
if (d.wallet !== undefined) {
var walletVal = document.querySelector('.yp-stat-card__value--cyan');
if (walletVal) walletVal.textContent = d.wallet.toLocaleString() + ' $YTC';
var balanceEl = document.querySelector('.yp-finance__balance--cyan');
if (balanceEl) balanceEl.textContent = d.wallet.toLocaleString() + ' $YTC';
}
/* Обучение */
if (d.learning !== undefined) {
var learnVal = document.querySelectorAll('.yp-stat-card__value')[1];
if (learnVal) learnVal.textContent = d.learning + '%';
var bar = document.querySelector('.yp-learning__progress-bar');
if (bar) bar.style.width = d.learning + '%';
var pct = document.querySelector('.yp-learning__pct');
if (pct) pct.textContent = d.learning + (getCurrentLang() === 'ru' ? '% пройдено' : '% completed');
}
/* Сообщения */
if (d.messages !== undefined) {
var msgVal = document.querySelectorAll('.yp-stat-card__value')[2];
if (msgVal) msgVal.textContent = d.messages;
var msgSub = document.querySelector('[data-i18n="stat-msg-sub"]');
if (msgSub) {
var lang = getCurrentLang();
msgSub.textContent = d.messages + (lang === 'ru' ? ' непрочитанных' : ' unread');
DICT.ru['stat-msg-sub'] = d.messages + ' непрочитанных';
DICT.en['stat-msg-sub'] = d.messages + ' unread';
}
var badge = document.querySelector('.yp-header__badge');
if (badge) badge.textContent = d.messages;
var unread = document.querySelector('.yp-chat__unread');
if (unread) unread.textContent = d.messages;
}
/* Яхта / позиция */
if (d.yacht !== undefined) {
document.querySelectorAll('.yp-work__info-value')[0].textContent = d.yacht;
}
if (d.position !== undefined) {
document.querySelectorAll('.yp-work__info-value')[1].textContent = d.position;
}
if (d.port !== undefined) {
document.querySelectorAll('.yp-work__info-value')[2].textContent = d.port;
}
});
/* Инициализация */
updateLangUI(getCurrentLang());
applyLang(getCurrentLang());
document.documentElement.setAttribute('lang', getCurrentLang());
/* ═══════════════════════════════════════════════
THEME
═══════════════════════════════════════════════ */
var savedTheme = (function(){ try { return localStorage.getItem('yp-theme') || 'dark'; } catch(e) { return 'dark'; } })();
applyTheme(savedTheme);
function applyTheme(t) {
document.documentElement.setAttribute('data-theme', t);
root.setAttribute('data-theme', t);
iconMoon.style.display = t === 'dark' ? 'block' : 'none';
iconSun.style.display = t === 'dark' ? 'none' : 'block';
try { localStorage.setItem('yp-theme', t); } catch(e) {}
}
themeBtn.addEventListener('click', function() {
applyTheme(document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
});
/* ═══════════════════════════════════════════════
SIDEBAR — desktop collapse
═══════════════════════════════════════════════ */
var isCollapsed = false;
function setCollapsed(v) {
if (isMobile()) return;
isCollapsed = v;
root.classList.toggle('yp-root--collapsed', v);
sidebar.classList.toggle('yp-sidebar--collapsed', v);
}
sidebarToggle.addEventListener('click', function() { setCollapsed(!isCollapsed); });
sidebarToggle.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setCollapsed(!isCollapsed); }
});
/* ═══════════════════════════════════════════════
SIDEBAR — mobile off-canvas
═══════════════════════════════════════════════ */
function showMobSidebar() {
sidebar.classList.add('yp-sidebar--mobile-open');
overlay.classList.add('yp-overlay--visible');
hamburger.setAttribute('aria-expanded', 'true');
document.body.style.overflow = 'hidden';
}
function hideMobSidebar() {
sidebar.classList.remove('yp-sidebar--mobile-open');
overlay.classList.remove('yp-overlay--visible');
hamburger.setAttribute('aria-expanded', 'false');
document.body.style.overflow = '';
}
function isMobSidebarOpen() { return sidebar.classList.contains('yp-sidebar--mobile-open'); }
hamburger.addEventListener('click', function() { isMobSidebarOpen() ? hideMobSidebar() : showMobSidebar(); });
overlay.addEventListener('click', hideMobSidebar);
window.addEventListener('resize', function() {
if (!isMobile()) { hideMobSidebar(); document.body.style.overflow = ''; }
});
/* ═══════════════════════════════════════════════
VIEW ROUTING
═══════════════════════════════════════════════ */
function showView(name) {
viewDashboard.style.display = name === 'dashboard' ? '' : 'none';
name === 'iframe'
? viewIframe.classList.add('yp-iframe-view--active')
: viewIframe.classList.remove('yp-iframe-view--active');
}
function loadIframe(baseUrl, title) {
currentIframeBaseUrl = baseUrl;
iframeTitleEl.textContent = title || '';
iframeUrlEl.textContent = baseUrl;
iframeSpinner.classList.remove('yp-iframe-spinner--hidden');
iframeEl.src = buildLangUrl(baseUrl);
showView('iframe');
}
iframeEl.addEventListener('load', function() {
iframeSpinner.classList.add('yp-iframe-spinner--hidden');
});
/* ═══════════════════════════════════════════════
NAV
═══════════════════════════════════════════════ */
var allLinks = document.querySelectorAll('.yp-sidebar__link');
allLinks.forEach(function(link) {
link.addEventListener('click', function() {
allLinks.forEach(function(l) { l.classList.remove('yp-sidebar__link--active'); });
link.classList.add('yp-sidebar__link--active');
if (link.dataset.view === 'iframe' && link.dataset.iframeUrl) {
loadIframe(link.dataset.iframeUrl, link.dataset.iframeTitle);
} else {
currentIframeBaseUrl = '';
showView('dashboard');
}
if (isMobile()) hideMobSidebar();
});
});
/* ═══════════════════════════════════════════════
DROPDOWN (profile)
═══════════════════════════════════════════════ */
var ddOpen = false;
function openDD() { ddOpen = true; dropdown.classList.add('yp-dropdown--open'); avatarBtn.setAttribute('aria-expanded', 'true'); }
function closeDD() { ddOpen = false; dropdown.classList.remove('yp-dropdown--open'); avatarBtn.setAttribute('aria-expanded', 'false'); }
avatarBtn.addEventListener('click', function(e) { e.stopPropagation(); ddOpen ? closeDD() : openDD(); });
avatarBtn.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); ddOpen ? closeDD() : openDD(); }
if (e.key === 'Escape') closeDD();
});
document.addEventListener('click', function(e) {
if (ddOpen && !dropdown.contains(e.target) && e.target !== avatarBtn) closeDD();
});
/* ═══════════════════════════════════════════════
LANGUAGE POPUP
═══════════════════════════════════════════════ */
var langOpen = false;
function openLangPopup() { langOpen = true; langPopup.classList.add('yp-lang-popup--open'); langBtn.setAttribute('aria-expanded', 'true'); }
function closeLangPopup() { langOpen = false; langPopup.classList.remove('yp-lang-popup--open'); langBtn.setAttribute('aria-expanded', 'false'); }
langBtn.addEventListener('click', function(e) { e.stopPropagation(); langOpen ? closeLangPopup() : openLangPopup(); });
langBtn.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); langOpen ? closeLangPopup() : openLangPopup(); }
if (e.key === 'Escape') closeLangPopup();
});
document.addEventListener('click', function(e) {
if (langOpen && !langPopup.contains(e.target) && e.target !== langBtn) closeLangPopup();
});
langItems.forEach(function(item) {
item.addEventListener('click', function() {
var l = item.dataset.lang;
if (l) setLanguage(l);
closeLangPopup();
});
});
/* ═══════════════════════════════════════════════
LOGOUT
═══════════════════════════════════════════════ */
function doLogout() { if (window.confirm('Вы уверены, что хотите выйти?')) { console.info('Logout'); } }
if (logoutBtn) logoutBtn.addEventListener('click', doLogout);
if (logoutDD) logoutDD.addEventListener('click', doLogout);
/* ═══════════════════════════════════════════════
ESC
═══════════════════════════════════════════════ */
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') { closeDD(); closeLangPopup(); closeMoodPopup(); if (isMobile()) hideMobSidebar(); }
});
/* ═══════════════════════════════════════════════
COUNTDOWN
═══════════════════════════════════════════════ */
var nowD = new Date();
var targetDate = new Date(nowD.getFullYear(), nowD.getMonth(), nowD.getDate(), 16, 0, 0).getTime();
if (targetDate < Date.now()) targetDate += 86400000;
var hoursEl = document.getElementById('yp-hours');
var minsEl = document.getElementById('yp-mins');
var secsEl = document.getElementById('yp-secs');
var statTimer = document.getElementById('yp-stat-timer');
function pad(n) { return String(n).padStart(2, '0'); }
function tick() {
var dist = targetDate - Date.now();
if (dist <= 0) {
[hoursEl, minsEl, secsEl].forEach(function(el) { if (el) el.textContent = '00'; });
if (statTimer) statTimer.textContent = 'Guests on board!';
return;
}
var h = Math.floor(dist / 3600000), m = Math.floor((dist % 3600000) / 60000), s = Math.floor((dist % 60000) / 1000);
if (hoursEl) hoursEl.textContent = pad(h);
if (minsEl) minsEl.textContent = pad(m);
if (secsEl) secsEl.textContent = pad(s);
if (statTimer) statTimer.textContent = pad(h) + 'ч ' + pad(m) + 'м ' + pad(s) + 'с';
}
tick(); setInterval(tick, 1000);
/* ═══════════════════════════════════════════════
DRAG & DROP
═══════════════════════════════════════════════ */
var grid = document.getElementById('yp-grid');
var dragging = null;
function getAfterEl(c, y) {
return [].slice.call(c.querySelectorAll('.yp-widget:not(.yp-widget--dragging)')).reduce(function(cl, ch) {
var b = ch.getBoundingClientRect(), o = y - b.top - b.height / 2;
return (o < 0 && o > cl.offset) ? { offset: o, element: ch } : cl;
}, { offset: -Infinity, element: null }).element;
}
document.querySelectorAll('.yp-widget').forEach(function(w) {
w.addEventListener('dragstart', function(e) { dragging = w; w.classList.add('yp-widget--dragging'); e.dataTransfer.effectAllowed = 'move'; });
w.addEventListener('dragend', function() { w.classList.remove('yp-widget--dragging'); document.querySelectorAll('.yp-widget').forEach(function(x) { x.classList.remove('yp-widget--dragover'); }); dragging = null; });
w.addEventListener('dragenter', function(e) { e.preventDefault(); if (w !== dragging) w.classList.add('yp-widget--dragover'); });
w.addEventListener('dragleave', function() { w.classList.remove('yp-widget--dragover'); });
});
if (grid) {
grid.addEventListener('dragover', function(e) {
e.preventDefault(); if (!dragging) return;
var a = getAfterEl(grid, e.clientY);
a === null ? grid.appendChild(dragging) : grid.insertBefore(dragging, a);
});
}
/* ═══════════════════════════════════════════════
MOOD
═══════════════════════════════════════════════ */
var moods = [
{emoji:'😎',label:'В ударе'},{emoji:'😊',label:'Хорошо'},{emoji:'🤩',label:'Отлично'},
{emoji:'😴',label:'Устал'},{emoji:'😤',label:'Напряжён'},{emoji:'🤔',label:'Думаю'},
{emoji:'🎉',label:'Праздник'},{emoji:'⚓',label:'Sailor'}
];
var currentMood = 0;
var moodPill = document.getElementById('yp-mood-pill');
var moodIcon = document.getElementById('yp-mood-icon');
var moodText = document.getElementById('yp-mood-text');
var moodPopup = document.getElementById('yp-mood-popup');
var moodGrid = document.getElementById('yp-mood-grid');
var moodOpen = false;
moods.forEach(function(m, i) {
var btn = document.createElement('button');
btn.className = 'yp-mood-popup__btn' + (i === currentMood ? ' yp-mood-popup__btn--active' : '');
btn.setAttribute('aria-label', m.label);
btn.setAttribute('title', m.label);
btn.innerHTML = m.emoji + '';
btn.addEventListener('click', function() {
currentMood = i;
moodIcon.textContent = m.emoji;
moodText.textContent = m.label;
moodGrid.querySelectorAll('.yp-mood-popup__btn').forEach(function(b) { b.classList.remove('yp-mood-popup__btn--active'); });
btn.classList.add('yp-mood-popup__btn--active');
closeMoodPopup();
});
moodGrid.appendChild(btn);
});
function openMoodPopup() { moodOpen = true; moodPopup.classList.add('yp-mood-popup--open'); }
function closeMoodPopup() { moodOpen = false; moodPopup.classList.remove('yp-mood-popup--open'); }
moodPill.addEventListener('click', function(e) { e.stopPropagation(); moodOpen ? closeMoodPopup() : openMoodPopup(); });
moodPill.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); moodOpen ? closeMoodPopup() : openMoodPopup(); }
});
document.addEventListener('click', function(e) {
if (moodOpen && !moodPopup.contains(e.target) && e.target !== moodPill) closeMoodPopup();
});
/* ═══════════════════════════════════════════════
WEATHER
═══════════════════════════════════════════════ */
var weatherData = [
{icon:'☀️', text:'24°C · Ясно'},
{icon:'⛅', text:'22°C · Облачно'},
{icon:'🌊', text:'24°C · Бриз'}
];
var wIdx = Math.floor(Date.now() / 86400000) % weatherData.length;
var wEl = document.getElementById('yp-weather-icon');
var wTxt = document.getElementById('yp-weather-text');
if (wEl && wTxt) { wEl.textContent = weatherData[wIdx].icon; wTxt.textContent = weatherData[wIdx].text; }
})();