diff --git a/backend/routes/tags.js b/backend/routes/tags.js index 349b021..961abcd 100644 --- a/backend/routes/tags.js +++ b/backend/routes/tags.js @@ -19,6 +19,8 @@ router.get('/', async (req, res) => { .sort({ usageCount: -1, name: 1 }) .select('name category description usageCount'); + console.log(`[TAGS API] Found ${tags.length} tags with status 'approved'`); + // Группировка по категориям const grouped = { theme: [], @@ -33,6 +35,8 @@ router.get('/', async (req, res) => { } }); + console.log(`[TAGS API] Grouped:`, Object.keys(grouped).map(k => `${k}: ${grouped[k].length}`).join(', ')); + res.json({ tags: grouped, all: tags }); } catch (error) { logError('Ошибка получения тегов', error); diff --git a/backend/scripts/initTags.js b/backend/scripts/initTags.js index eea0696..eff0ca3 100644 --- a/backend/scripts/initTags.js +++ b/backend/scripts/initTags.js @@ -53,10 +53,20 @@ async function initTags() { for (const tagData of INITIAL_TAGS) { const existing = await Tag.findOne({ name: tagData.name }); if (!existing) { - await Tag.create(tagData); + // Явно устанавливаем статус + await Tag.create({ + ...tagData, + status: 'approved' // Явно устанавливаем статус + }); created++; console.log(`✅ Создан тег: ${tagData.name}`); } else { + // Обновляем статус существующего тега, если он не approved + if (existing.status !== 'approved') { + existing.status = 'approved'; + await existing.save(); + console.log(`✅ Обновлен статус тега: ${tagData.name}`); + } skipped++; console.log(`⏭️ Тег уже существует: ${tagData.name}`); } diff --git a/frontend/src/pages/Feed.css b/frontend/src/pages/Feed.css index 96a01cc..23f78ab 100644 --- a/frontend/src/pages/Feed.css +++ b/frontend/src/pages/Feed.css @@ -115,6 +115,15 @@ .empty-state p { color: var(--text-secondary); font-size: 16px; + text-align: center; +} + +.empty-state-hint { + color: var(--text-secondary); + font-size: 14px; + opacity: 0.7; + text-align: center; + margin-top: -8px; } .btn-primary { @@ -124,6 +133,10 @@ color: white; font-size: 16px; font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; } [data-theme="dark"] .btn-primary { diff --git a/frontend/src/pages/Feed.jsx b/frontend/src/pages/Feed.jsx index 40553aa..ee822de 100644 --- a/frontend/src/pages/Feed.jsx +++ b/frontend/src/pages/Feed.jsx @@ -1,14 +1,15 @@ import { useState, useEffect } from 'react' -import { useSearchParams } from 'react-router-dom' +import { useSearchParams, useNavigate } from 'react-router-dom' import { getPosts } from '../utils/api' import PostCard from '../components/PostCard' import CreatePostModal from '../components/CreatePostModal' -import { Plus } from 'lucide-react' +import { Plus, Settings } from 'lucide-react' import { hapticFeedback } from '../utils/telegram' import './Feed.css' export default function Feed({ user }) { const [searchParams] = useSearchParams() + const navigate = useNavigate() const [posts, setPosts] = useState([]) const [loading, setLoading] = useState(true) const [showCreateModal, setShowCreateModal] = useState(false) @@ -153,10 +154,41 @@ export default function Feed({ user }) { ) : posts.length === 0 ? (
-

Пока нет постов

- + {filter === 'interests' ? ( + <> +

Нет постов по вашим интересам

+

+ Проверьте выбранные теги в настройках профиля +

+ + + ) : filter === 'following' ? ( + <> +

Нет постов от подписок

+

+ Подпишитесь на пользователей, чтобы видеть их посты здесь +

+ + + ) : ( + <> +

Пока нет постов

+ + + )}
) : ( <> diff --git a/frontend/src/pages/Profile.css b/frontend/src/pages/Profile.css index c0585d9..9fcb041 100644 --- a/frontend/src/pages/Profile.css +++ b/frontend/src/pages/Profile.css @@ -685,6 +685,20 @@ to { transform: rotate(360deg); } } +.empty-tags-message { + padding: 24px; + text-align: center; + color: var(--text-secondary); +} + +.empty-tags-message code { + background: var(--bg-primary); + padding: 4px 8px; + border-radius: 4px; + font-size: 11px; + color: var(--text-primary); +} + /* Модалка с информацией о теге */ .tag-info-modal { max-width: 400px; diff --git a/frontend/src/pages/Profile.jsx b/frontend/src/pages/Profile.jsx index bc4fdb5..a9f6624 100644 --- a/frontend/src/pages/Profile.jsx +++ b/frontend/src/pages/Profile.jsx @@ -123,6 +123,9 @@ export default function Profile({ user, setUser }) { try { setLoadingTags(true) const data = await getTags() + console.log('[Profile] Tags data received:', data) + console.log('[Profile] Tags grouped:', data.tags) + console.log('[Profile] Tags all:', data.all) setAllTags(data.tags || { theme: [], style: [], mood: [], technical: [] }) } catch (error) { console.error('Ошибка загрузки тегов:', error) @@ -537,57 +540,72 @@ export default function Profile({ user, setUser }) {
) : ( - Object.entries(TAG_CATEGORIES).map(([categoryKey, categoryName]) => { - const categoryTags = allTags[categoryKey] || [] - if (categoryTags.length === 0) return null - - return ( -
-

{categoryName}

-
- {categoryTags.map(tag => { - const isSelected = selectedTags.includes(tag.name) - return ( -
toggleTag(tag.name)} - > -
- {tag.name} - {tag.description && ( -
{ - e.stopPropagation() - setShowTagInfo({ - name: tag.name, - description: tag.description, - category: TAG_CATEGORIES[tag.category] || tag.category - }) - hapticFeedback('light') - }} - > - - Нажмите для описания -
- )} -
-
- toggleTag(tag.name)} - onClick={(e) => e.stopPropagation()} - /> -
-
- ) - })} + (() => { + const hasAnyTags = Object.values(allTags).some(tags => tags.length > 0) + + if (!hasAnyTags) { + return ( +
+

Теги не найдены. Убедитесь, что скрипт инициализации тегов был запущен.

+

+ Запустите: node backend/scripts/initTags.js +

-
- ) - }) + ) + } + + return Object.entries(TAG_CATEGORIES).map(([categoryKey, categoryName]) => { + const categoryTags = allTags[categoryKey] || [] + if (categoryTags.length === 0) return null + + return ( +
+

{categoryName}

+
+ {categoryTags.map(tag => { + const isSelected = selectedTags.includes(tag.name) + return ( +
toggleTag(tag.name)} + > +
+ {tag.name} + {tag.description && ( +
{ + e.stopPropagation() + setShowTagInfo({ + name: tag.name, + description: tag.description, + category: TAG_CATEGORIES[tag.category] || tag.category + }) + hapticFeedback('light') + }} + > + + Нажмите для описания +
+ )} +
+
+ toggleTag(tag.name)} + onClick={(e) => e.stopPropagation()} + /> +
+
+ ) + })} +
+
+ ) + }) + })() )} {selectedTags.length > 0 && (