bebo231312312321

Untitled

Jun 25th, 2025
615
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Comments/Comments.jsx
  2. import { useState, useEffect } from 'react';
  3. import { useTranslation } from 'react-i18next';
  4. import './comments.css';
  5. import { useAuthContext } from '../../../contexts/UserContext';
  6. import { useInitiativeContext } from '../../../contexts/InitiativeProvider';
  7. import { CommentItem } from '../CommentItem/CommentItem';
  8. import { CommentForm } from '../CommentForm/CommentForm';
  9. import { Link } from 'react-router-dom';
  10.  
  11. export const Comments = ({
  12.     initiativeId,
  13.     entityId,
  14.     entityType = 'initiative',
  15.     commentsEnabled = true,
  16.     onCommentsChange
  17. }) => {
  18.     const { t } = useTranslation();
  19.     const { isAuthentication } = useAuthContext();
  20.     const {
  21.         // Initiative functions
  22.         getComments, addComment, updateComment, deleteComment, likeComment,
  23.         // Project functions  
  24.         getProjectComments, addProjectComment, updateProjectComment, deleteProjectComment, likeProjectComment,
  25.         commentsLoading,
  26.         comments // ← Директно от контекста
  27.     } = useInitiativeContext();
  28.  
  29.     const [showCommentForm, setShowCommentForm] = useState(false);
  30.     const [isLoaded, setIsLoaded] = useState(false);
  31.  
  32.     const targetId = initiativeId || entityId;
  33.     const isProject = entityType === 'project';
  34.  
  35.     const fetchComments = isProject ? getProjectComments : getComments;
  36.     const submitComment = isProject ? addProjectComment : addComment;
  37.     const updateCommentFunc = isProject ? updateProjectComment : updateComment;
  38.     const deleteCommentFunc = isProject ? deleteProjectComment : deleteComment;
  39.     const likeCommentFunc = isProject ? likeProjectComment : likeComment;
  40.  
  41.     // Вземаме коментарите директно от контекста
  42.     const currentComments = comments[targetId] || [];
  43.  
  44.     useEffect(() => {
  45.         if (!commentsEnabled || !targetId) return;
  46.  
  47.         const loadComments = async () => {
  48.             try {
  49.                 await fetchComments(targetId);
  50.                 setIsLoaded(true);
  51.             } catch (error) {
  52.                 console.error('Error fetching comments:', error);
  53.                 setIsLoaded(true);
  54.             }
  55.         };
  56.  
  57.         loadComments();
  58.     }, [targetId, commentsEnabled, fetchComments]);
  59.  
  60.     const handleAddComment = async (content) => {
  61.         if (!isAuthentication) {
  62.             alert(t('comments.loginRequired'));
  63.             return;
  64.         }
  65.  
  66.         try {
  67.             await submitComment(targetId, content);
  68.             setShowCommentForm(false);
  69.         } catch (error) {
  70.             console.error('Error adding comment:', error);
  71.         }
  72.     };
  73.  
  74.     // Уведомяваме родителя за промяна в броя коментари
  75.     useEffect(() => {
  76.         if (onCommentsChange) {
  77.             onCommentsChange(currentComments.length);
  78.         }
  79.     }, [currentComments.length, onCommentsChange]);
  80.  
  81.     if (!commentsEnabled) {
  82.         return (
  83.             <section className="initiative-comments-section" id="comments">
  84.                 <div className="initiative-comments-disabled">
  85.                     <div className="initiative-comments-disabled-icon">🔒</div>
  86.                     <h3 className="initiative-comments-disabled-title">
  87.                         {t('comments.disabled.title')}
  88.                     </h3>
  89.                     <p className="initiative-comments-disabled-message">
  90.                         {t('comments.disabled.message')}
  91.                     </p>
  92.                 </div>
  93.             </section>
  94.         );
  95.     }
  96.  
  97.     return (
  98.         <section className="initiative-comments-section" id="comments">
  99.             <div className="initiative-comments-header">
  100.                 <h2 className="initiative-comments-section-title">
  101.                     {t('comments.title')} ({currentComments.length})
  102.                 </h2>
  103.  
  104.                 {isAuthentication && (
  105.                     <button
  106.                         className="initiative-add-comment-btn"
  107.                         onClick={() => setShowCommentForm(!showCommentForm)}
  108.                     >
  109.                         {showCommentForm ? t('comments.cancel') : t('comments.addComment')}
  110.                     </button>
  111.                 )}
  112.             </div>
  113.  
  114.             {!isAuthentication && (
  115.                 <div className="initiative-login-prompt">
  116.                     <p>{t('comments.loginPrompt')}</p>
  117.                     <Link to="/sign-up?tab=login" className="initiative-login-link">
  118.                         {t('comments.loginLink')}
  119.                     </Link>
  120.                 </div>
  121.             )}
  122.  
  123.             {showCommentForm && (
  124.                 <CommentForm
  125.                     onSubmit={handleAddComment}
  126.                     onCancel={() => setShowCommentForm(false)}
  127.                     placeholder={t('comments.placeholder')}
  128.                 />
  129.             )}
  130.  
  131.             {commentsLoading && !isLoaded ? (
  132.                 <div className="initiative-comments-loading">
  133.                     <div className="initiative-loading-spinner"></div>
  134.                     <p>{t('comments.loading')}</p>
  135.                 </div>
  136.             ) : (
  137.                 <div className="initiative-comments-list">
  138.                     {currentComments.length === 0 ? (
  139.                         <div className="initiative-no-comments">
  140.                             <div className="initiative-no-comments-icon">💬</div>
  141.                             <p>{t('comments.noComments')}</p>
  142.                         </div>
  143.                     ) : (
  144.                         currentComments
  145.                             .filter(comment => comment && comment.id)
  146.                             .map(comment => (
  147.                                 <CommentItem
  148.                                     key={comment.id}
  149.                                     comment={comment}
  150.                                     entityId={targetId}
  151.                                     entityType={entityType}
  152.                                     updateCommentFunc={updateCommentFunc}
  153.                                     deleteCommentFunc={deleteCommentFunc}
  154.                                     likeCommentFunc={likeCommentFunc}
  155.                                     addCommentFunc={submitComment}
  156.                                 />
  157.                             ))
  158.                     )}
  159.                 </div>
  160.             )}
  161.         </section>
  162.     );
  163. };
Advertisement
Add Comment
Please, Sign In to add comment