import { profile } from '../mock-data.js'; import { state } from '../state.js'; import { PROFILE_GENDER_FEMALE, PROFILE_GENDER_MALE, loadProfileSnapshot, } from '../services/user-profile-params.js'; import { buildIdentityLines } from '../services/user-connections.js'; import { renderUserAvatar } from '../components/avatar-image.js'; export const pageMeta = { id: 'profile-view', title: 'Профиль' }; function toggleText(enabled) { return enabled ? 'Yes' : 'No'; } function genderLabel(value) { if (value === PROFILE_GENDER_MALE) return 'Мужской'; if (value === PROFILE_GENDER_FEMALE) return 'Женский'; return 'Не указан'; } function escapeHtml(text) { return String(text || '') .replaceAll('&', '&') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('"', '"') .replaceAll("'", '''); } export function render({ navigate }) { const login = state.session.login || profile.login; const screen = document.createElement('section'); screen.className = 'stack profile-screen'; const topActions = document.createElement('div'); topActions.className = 'profile-top-actions'; topActions.innerHTML = ` `; topActions.querySelector('[data-top-action="edit"]')?.addEventListener('click', () => navigate('profile-edit-view')); topActions.querySelector('[data-top-action="wallet"]')?.addEventListener('click', () => navigate('wallet-view')); topActions.querySelector('[data-top-action="settings"]')?.addEventListener('click', () => navigate('settings-view')); screen.append(topActions); const card = document.createElement('div'); card.className = 'card stack profile-main-card'; const topRow = document.createElement('div'); topRow.className = 'row'; topRow.innerHTML = `
`; const statusRow = document.createElement('div'); statusRow.className = 'row profile-status-row'; statusRow.innerHTML = `
Загрузка параметров...
`; const badgesRow = document.createElement('div'); badgesRow.className = 'row'; badgesRow.innerHTML = ` `; const listWrap = document.createElement('div'); listWrap.className = 'stack profile-param-list'; const reloadBtn = statusRow.querySelector('[data-reload="true"]'); const statusLineEl = statusRow.querySelector('[data-profile-status-line="true"]'); const officialBtn = badgesRow.querySelector('[data-toggle="official"]'); const shineBtn = badgesRow.querySelector('[data-toggle="shine"]'); const identityEl = topRow.querySelector('[data-profile-identity="true"]'); const avatarSlotEl = topRow.querySelector('[data-profile-avatar-slot="true"]'); let currentFields = []; let currentToggles = []; let currentGender = 'unknown'; let currentAvatar = { value: '', source: '', txId: '', timeMs: 0 }; function syncIdentity() { if (!identityEl) return; const firstName = currentFields.find((field) => field.key === 'first_name')?.value || ''; const lastName = currentFields.find((field) => field.key === 'last_name')?.value || ''; const lines = buildIdentityLines({ login, firstName, lastName }); identityEl.innerHTML = lines.map((line, idx) => ( `
${escapeHtml(line)}
` )).join(''); } function updateAvatarUi() { if (!(avatarSlotEl instanceof HTMLElement)) return; const firstName = String(currentFields.find((field) => field.key === 'first_name')?.value || '').trim(); const lastName = String(currentFields.find((field) => field.key === 'last_name')?.value || '').trim(); avatarSlotEl.innerHTML = ''; avatarSlotEl.append(renderUserAvatar({ login, firstName, lastName, avatar: currentAvatar?.txId ? { ar: currentAvatar.txId } : null, size: 'large', className: 'profile-avatar', })); } function updateToggleButton(button, prefix, enabled) { button.textContent = `${prefix}: ${toggleText(enabled)}`; button.classList.remove('is-no', 'is-yes-official', 'is-yes-shine'); if (!enabled) { button.classList.add('is-no'); return; } if (prefix === 'Официальный') button.classList.add('is-yes-official'); else button.classList.add('is-yes-shine'); } function updateTogglesUi() { const official = currentToggles.find((item) => item.key === 'official') || { enabled: false }; const shine = currentToggles.find((item) => item.key === 'shine') || { enabled: false }; updateToggleButton(officialBtn, 'Официальный', official.enabled); updateToggleButton(shineBtn, 'Сияющий', shine.enabled); } function renderFields(fields) { listWrap.innerHTML = ''; fields.forEach((field) => { const row = document.createElement('div'); row.className = 'card profile-param-item row'; const value = String(field.value || '').trim() || 'не заполнено'; row.innerHTML = `
${field.label}: ${escapeHtml(value)}
`; listWrap.append(row); if (field.key === 'last_name') { const genderRow = document.createElement('div'); genderRow.className = 'card profile-param-item row'; genderRow.innerHTML = `
Пол: ${escapeHtml(genderLabel(currentGender))}
`; listWrap.append(genderRow); } }); } async function refreshProfileSnapshot() { try { if (statusLineEl instanceof HTMLElement) { statusLineEl.className = 'status-line'; statusLineEl.textContent = 'Загрузка параметров...'; } const snapshot = await loadProfileSnapshot(login); currentFields = Array.isArray(snapshot.fields) ? snapshot.fields : []; currentToggles = Array.isArray(snapshot.toggles) ? snapshot.toggles : []; currentGender = snapshot.gender || 'unknown'; currentAvatar = snapshot.avatar || { value: '', source: '', txId: '', timeMs: 0 }; syncIdentity(); updateAvatarUi(); updateTogglesUi(); renderFields(currentFields); if (statusLineEl instanceof HTMLElement) { statusLineEl.className = 'status-line is-available'; statusLineEl.textContent = 'Профиль обновлён.'; } } catch (error) { if (statusLineEl instanceof HTMLElement) { statusLineEl.className = 'status-line is-unavailable'; statusLineEl.textContent = `Ошибка загрузки профиля: ${error?.message || 'unknown'}`; } } } const showToggleInfo = (toggleKey) => { const item = currentToggles.find((entry) => entry.key === toggleKey); const isEnabled = Boolean(item?.enabled); if (toggleKey === 'official') { status.className = 'status-line is-available'; if (statusLineEl instanceof HTMLElement) statusLineEl.className = 'status-line is-available'; if (statusLineEl instanceof HTMLElement) statusLineEl.textContent = isEnabled ? 'Аккаунт является официальным.' : 'Аккаунт не является официальным.'; return; } if (statusLineEl instanceof HTMLElement) statusLineEl.className = 'status-line is-available'; if (statusLineEl instanceof HTMLElement) statusLineEl.textContent = isEnabled ? 'Аккаунт является сияющим.' : 'Аккаунт не является сияющим.'; }; reloadBtn?.addEventListener('click', refreshProfileSnapshot); officialBtn?.addEventListener('click', () => showToggleInfo('official')); shineBtn?.addEventListener('click', () => showToggleInfo('shine')); card.append(topRow, badgesRow, statusRow, listWrap); screen.append(card); updateAvatarUi(); refreshProfileSnapshot(); return screen; }