Feature: UserProfileView показывает prefs (drinks/activities/purposes)

Бэк уже отдает prefs в публичном /users/:id, но фронт не доставал.

UserProfileView:
- Принимает u.prefs.{drinks,activities,purposes}
- Словари вынесены в глобальные DRINKS/ACTIVITIES/PURPOSES (используются ProfileView и UserProfileView)
- Рендерит три секции card-b с .chip.on: 'Что пьёт' / 'Чем занимается' / 'Цели'
- Скрывает секцию если массив пуст
This commit is contained in:
root 2026-08-21 12:11:20 +00:00
parent e6d8ad0ee0
commit 34d4292538
2 changed files with 57 additions and 11 deletions

View File

@ -8,7 +8,7 @@
<script src="https://telegram.org/js/telegram-web-app.js"></script> <script src="https://telegram.org/js/telegram-web-app.js"></script>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css"> <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css">
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script> <script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
<link rel="stylesheet" href="/css/app.css?v=25"> <link rel="stylesheet" href="/css/app.css?v=26">
</head> </head>
<body> <body>
<button id="mode-toggle" title="Переключить режим">📱 Мобильный</button> <button id="mode-toggle" title="Переключить режим">📱 Мобильный</button>
@ -34,15 +34,15 @@
</button> </button>
</nav> </nav>
</div> </div>
<script src="/js/tg.js?v=25"></script> <script src="/js/tg.js?v=26"></script>
<script src="/js/api.js?v=25"></script> <script src="/js/api.js?v=26"></script>
<script src="/js/views/map.js?v=25"></script> <script src="/js/views/map.js?v=26"></script>
<script src="/js/views/chats.js?v=25"></script> <script src="/js/views/chats.js?v=26"></script>
<script src="/js/views/chat.js?v=25"></script> <script src="/js/views/chat.js?v=26"></script>
<script src="/js/views/profile.js?v=25"></script> <script src="/js/views/profile.js?v=26"></script>
<script src="/js/views/settings.js?v=25"></script> <script src="/js/views/settings.js?v=26"></script>
<script src="/js/views/onboarding.js?v=25"></script> <script src="/js/views/onboarding.js?v=26"></script>
<script src="/js/views/review.js?v=25"></script> <script src="/js/views/review.js?v=26"></script>
<script src="/js/app.js?v=25"></script> <script src="/js/app.js?v=26"></script>
</body> </body>
</html> </html>

View File

@ -200,6 +200,22 @@ const ProfileView = {
window.ProfileView = ProfileView; window.ProfileView = ProfileView;
// Словари — общие для ProfileView и UserProfileView
const DRINKS = [
['beer', '🍺 Пиво'], ['wine', '🍷 Вино'], ['whiskey', '🥃 Виски'], ['vodka', '🍸 Водка'],
['cocktail', '🍹 Коктейль'], ['rum', '🥃 Ром'], ['gin', '🍸 Джин'], ['tequila', '🌵 Текила'],
['champagne', '🍾 Шампанское'], ['non_alcoholic', '🥤 Безалкогольное'],
];
const ACTIVITIES = [
['walk', '🚶 Прогулка'], ['dinner', '🍽️ Ужин'], ['bar', '🍻 Бар'], ['cafe', '☕ Кафе'],
['travel', '✈️ Путешествие'], ['movie', '🎬 Кино'], ['concert', '🎵 Концерт'],
['sport', '⚽ Спорт'], ['gaming', '🎮 Игры'], ['reading', '📚 Чтение'],
];
const PURPOSES = [
['chat', '💬 Пообщаться'], ['drink', '🍻 Выпить'], ['walk', '🌳 Погулять'],
['dinner', '🍽️ Поужинать'], ['travel', '✈️ Поехать'], ['friendship', '🤝 Дружба'],
];
// UserProfileView — чужой профиль (read-only) — открывается по тапу на маркер на карте // UserProfileView — чужой профиль (read-only) — открывается по тапу на маркер на карте
const UserProfileView = { const UserProfileView = {
userId: null, userId: null,
@ -228,6 +244,12 @@ const UserProfileView = {
const rating = stats.rating_avg ? Number(stats.rating_avg).toFixed(1) : '—'; const rating = stats.rating_avg ? Number(stats.rating_avg).toFixed(1) : '—';
const reviewsCount = stats.rating_count || 0; const reviewsCount = stats.rating_count || 0;
// prefs чужие — подтянем из ответа /users/:id (prefs включены в публичный ответ)
const prefs = u.prefs || {};
const drinkLabels = DRINKS.filter(([k]) => (prefs.drinks || []).includes(k)).map(([, l]) => l);
const activityLabels = ACTIVITIES.filter(([k]) => (prefs.activities || []).includes(k)).map(([, l]) => l);
const purposeLabels = PURPOSES.filter(([k]) => (prefs.purposes || []).includes(k)).map(([, l]) => l);
document.getElementById('up-content').innerHTML = ` document.getElementById('up-content').innerHTML = `
<!-- Аватар и имя --> <!-- Аватар и имя -->
<div class="card-b" style="display:flex;align-items:center;gap:14px;"> <div class="card-b" style="display:flex;align-items:center;gap:14px;">
@ -248,6 +270,30 @@ const UserProfileView = {
</div> </div>
` : ''} ` : ''}
<!-- Чипы (drinks/activities/purposes) -->
${(drinkLabels.length || activityLabels.length || purposeLabels.length) ? `
<div class="row-list" style="margin-top:12px;">
${drinkLabels.length ? `
<div class="card-b">
<div style="font-size:12px;font-weight:600;color:var(--text-dim);margin-bottom:8px;">🍻 Что пьёт</div>
<div class="chip-list">${drinkLabels.map((l) => `<span class="chip on">${escapeHtml(l)}</span>`).join('')}</div>
</div>
` : ''}
${activityLabels.length ? `
<div class="card-b">
<div style="font-size:12px;font-weight:600;color:var(--text-dim);margin-bottom:8px;">🎯 Чем занимается</div>
<div class="chip-list">${activityLabels.map((l) => `<span class="chip on">${escapeHtml(l)}</span>`).join('')}</div>
</div>
` : ''}
${purposeLabels.length ? `
<div class="card-b">
<div style="font-size:12px;font-weight:600;color:var(--text-dim);margin-bottom:8px;">💡 Цели</div>
<div class="chip-list">${purposeLabels.map((l) => `<span class="chip on">${escapeHtml(l)}</span>`).join('')}</div>
</div>
` : ''}
</div>
` : ''}
<!-- Действия --> <!-- Действия -->
<div class="row-list" style="margin-top:14px;"> <div class="row-list" style="margin-top:14px;">
<button class="btn-b" id="up-message">💬 Написать</button> <button class="btn-b" id="up-message">💬 Написать</button>