// Review screens — create + user-reviews list const ReviewView = { rating: 5, chatId: null, otherId: null, otherName: null, async render(root, params) { this.chatId = params.chatId; this.otherId = params.otherId; this.otherName = params.otherName; this.rating = 5; root.innerHTML = `

⭐ Отзыв

О ${escapeHtml(this.otherName || 'пользователе')}
${[1,2,3,4,5].map(n => ``).join('')}
`; document.querySelectorAll('#stars span').forEach(s => { s.onclick = () => { this.rating = parseInt(s.dataset.n, 10); document.querySelectorAll('#stars span').forEach((x, i) => { x.classList.toggle('on', i < this.rating); }); TG_APP.haptic('selection'); }; }); document.getElementById('r-submit').onclick = () => this.submit(); }, async submit() { try { await API.ReviewApi.create( this.chatId, this.rating, document.getElementById('r-body').value.trim(), document.getElementById('r-anon').checked ); TG_APP.haptic('notification'); App.toast('Отзыв отправлен ✓'); setTimeout(() => App.showView('chats'), 800); } catch (e) { TG_APP.showAlert('Ошибка: ' + e.message); } }, }; const UserReviewsView = { async render(root, params) { const userId = params.userId; const userName = params.userName || 'Пользователь'; root.innerHTML = `

⭐ Отзывы

Загрузка...
`; try { const [stats, list] = await Promise.all([ API.ReviewApi.stats(userId), API.ReviewApi.listForUser(userId), ]); const header = document.getElementById('ur-header'); header.className = 'card'; header.innerHTML = `
${stats.rating_avg ? stats.rating_avg.toFixed(1) : '—'}
${[1,2,3,4,5].map(n => ``).join('')}
${stats.rating_count} отзывов
`; const v = document.createElement('div'); v.innerHTML = '

' + escapeHtml(userName) + '

'; if (!list.reviews || list.reviews.length === 0) { v.innerHTML += '
Пока нет отзывов
'; } else { list.reviews.forEach((r) => { const card = document.createElement('div'); card.className = 'card'; card.innerHTML = `
${[1,2,3,4,5].map(n=>``).join('')}
${formatDate(r.created_at)}
${r.anonymous ? 'Аноним' : 'ID: ' + r.reviewer_id.slice(0,8)}
${r.body ? '
' + escapeHtml(r.body) + '
' : ''} `; v.appendChild(card); }); } header.parentElement.appendChild(v); } catch (e) { document.getElementById('ur-header').innerHTML = '
Ошибка: ' + e.message + '
'; } }, }; window.ReviewView = ReviewView; window.UserReviewsView = UserReviewsView;