diff --git a/frontend/src/components/CommentsModal.jsx b/frontend/src/components/CommentsModal.jsx index 9145094..0f817a3 100644 --- a/frontend/src/components/CommentsModal.jsx +++ b/frontend/src/components/CommentsModal.jsx @@ -16,8 +16,6 @@ export default function CommentsModal({ post, onClose, onUpdate }) { // Загрузить полные данные поста с комментариями const loadFullPost = useCallback(async () => { if (!post?._id) { - setFullPost(post || null) - setComments(post?.comments || []) return } @@ -27,29 +25,28 @@ export default function CommentsModal({ post, onClose, onUpdate }) { const foundPost = response.posts?.find(p => p._id === post._id) if (foundPost) { setFullPost(foundPost) - setComments(foundPost.comments || []) - } else { - // Fallback на переданный post - setFullPost(post) - setComments(post?.comments || []) + // Убедимся, что комментарии загружены с авторами + const commentsWithAuthors = foundPost.comments || [] + setComments(commentsWithAuthors) } } catch (error) { console.error('[CommentsModal] Ошибка загрузки поста:', error) - // Fallback на переданный post - setFullPost(post) - setComments(post?.comments || []) } finally { setLoadingPost(false) } - }, [post]) + }, [post?._id]) useEffect(() => { if (post) { + // Сначала установим переданные данные setFullPost(post) setComments(post.comments || []) - loadFullPost() + // Затем загрузим полные данные + if (post._id) { + loadFullPost() + } } - }, [post, loadFullPost]) + }, [post?._id, loadFullPost]) // Проверка на существование поста ПОСЛЕ хуков if (!post) { @@ -59,19 +56,28 @@ export default function CommentsModal({ post, onClose, onUpdate }) { const displayPost = fullPost || post const handleSubmit = async () => { - if (!comment.trim()) return + if (!comment.trim() || loading) return try { setLoading(true) hapticFeedback('light') const result = await commentPost(post._id, comment) - setComments(result.comments || []) + if (result && result.comments) { + // Обновить комментарии из ответа API + setComments(result.comments) + // Обновить полный пост + if (fullPost) { + setFullPost({ ...fullPost, comments: result.comments }) + } + } setComment('') hapticFeedback('success') - // Обновить полный пост + // Обновить данные поста await loadFullPost() - onUpdate() + if (onUpdate) { + onUpdate() + } } catch (error) { console.error('Ошибка добавления комментария:', error) hapticFeedback('error') @@ -163,9 +169,12 @@ export default function CommentsModal({ post, onClose, onUpdate }) { ) : ( comments - .filter(c => c.author) // Фильтруем комментарии без автора - .map((c, index) => ( -
+ .filter(c => c && c.author) // Фильтруем комментарии без автора + .map((c, index) => { + // Используем _id если есть, иначе index + const commentId = c._id || c.id || `comment-${index}` + return ( +
{c.author?.username{decodeHtmlEntities(c.content)}

- )) + ) + }) )} diff --git a/frontend/src/components/FollowListModal.css b/frontend/src/components/FollowListModal.css index 0976936..827793c 100644 --- a/frontend/src/components/FollowListModal.css +++ b/frontend/src/components/FollowListModal.css @@ -103,20 +103,18 @@ } .user-item-wrapper { - display: flex; - flex-direction: column; - gap: 8px; padding: 8px 16px; } .user-item { display: flex; align-items: center; - gap: 8px; + gap: 12px; cursor: pointer; transition: background 0.2s; - padding: 4px; + padding: 8px; border-radius: 8px; + position: relative; } .user-item:active { @@ -134,56 +132,56 @@ .user-info { flex: 1; min-width: 0; + display: flex; + flex-direction: column; + gap: 2px; } .user-name { - font-size: 14px; + font-size: 15px; font-weight: 600; color: var(--text-primary); - margin-bottom: 2px; + line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user-username { - font-size: 12px; + font-size: 13px; color: var(--text-secondary); + line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -/* Follow Button */ -.follow-btn { +/* Follow Button Icon */ +.follow-btn-icon { + width: 36px; + height: 36px; + border-radius: 50%; + background: var(--bg-primary); + color: var(--text-primary); + border: 1px solid var(--divider-color); display: flex; align-items: center; justify-content: center; - gap: 8px; - width: 100%; - padding: 10px 18px; - border-radius: 12px; + cursor: pointer; + transition: all 0.2s ease; + flex-shrink: 0; + margin-left: auto; +} + +.follow-btn-icon:active { + opacity: 0.7; + transform: scale(0.95); +} + +.follow-btn-icon.following { background: var(--button-accent); color: white; - border: none; - font-size: 14px; - font-weight: 600; - cursor: pointer; - transition: opacity 0.2s ease; -} - -.follow-btn:active { - opacity: 0.85; -} - -.follow-btn.following { - background: var(--bg-primary); - color: var(--text-secondary); - border: 1px solid var(--divider-color); -} - -.follow-btn span { - white-space: nowrap; + border-color: var(--button-accent); } diff --git a/frontend/src/components/FollowListModal.jsx b/frontend/src/components/FollowListModal.jsx index 664cba6..15c6e57 100644 --- a/frontend/src/components/FollowListModal.jsx +++ b/frontend/src/components/FollowListModal.jsx @@ -105,26 +105,20 @@ export default function FollowListModal({ users, title, onClose, currentUser })
@{user.username || user.firstName || 'user'}
+ + {!isOwnProfile && ( + + )} - - {!isOwnProfile && ( - - )} ) })} diff --git a/frontend/src/pages/Profile.css b/frontend/src/pages/Profile.css index 9c38705..7312de3 100644 --- a/frontend/src/pages/Profile.css +++ b/frontend/src/pages/Profile.css @@ -149,6 +149,7 @@ display: flex; align-items: center; justify-content: center; + flex-shrink: 0; } .donation-text h3 { @@ -166,7 +167,7 @@ } .donation-button { - align-self: flex-start; + width: 100%; padding: 10px 18px; border-radius: 12px; background: var(--text-primary); @@ -178,7 +179,7 @@ transition: opacity 0.2s ease; } -.donation-button:hover { +.donation-button:active { opacity: 0.85; } diff --git a/frontend/src/pages/Search.css b/frontend/src/pages/Search.css index 1939633..6c7c80d 100644 --- a/frontend/src/pages/Search.css +++ b/frontend/src/pages/Search.css @@ -121,21 +121,20 @@ width: 40px; height: 40px; border-radius: 50%; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; + background: var(--bg-primary); + color: var(--text-primary); display: flex; align-items: center; justify-content: center; flex-shrink: 0; - border: none; + border: 1px solid var(--divider-color); cursor: pointer; transition: all 0.2s ease; - box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3); } .search-submit-btn:active { transform: scale(0.95); - box-shadow: 0 2px 4px rgba(102, 126, 234, 0.2); + opacity: 0.8; } .search-submit-btn:disabled { @@ -145,7 +144,13 @@ } [data-theme="dark"] .search-submit-btn { - box-shadow: 0 2px 8px rgba(118, 75, 162, 0.4); + background: #3A3A3C; + color: #FFFFFF; + border-color: #48484A; +} + +[data-theme="dark"] .search-submit-btn:active { + background: #48484A; } .tag-suggestions {