兴趣小组、好友动态

Change-Id: I7aa713600dea31eb2cd5b32ecc4e257b2bbd8be1
diff --git a/src/pages/InterestGroup/GroupDetail.jsx b/src/pages/InterestGroup/GroupDetail.jsx
new file mode 100644
index 0000000..18ea23e
--- /dev/null
+++ b/src/pages/InterestGroup/GroupDetail.jsx
@@ -0,0 +1,189 @@
+import React, { useEffect, useState } from 'react';
+import { useParams } from 'wouter';
+import { useUser } from '../../context/UserContext';
+import GroupMembers from './GroupMembers';
+import GroupPosts from './GroupPosts';
+import CreatePostForm from './CreatePostForm';
+import './GroupDetail.css';
+
+const GroupDetail = () => {
+  const { groupId } = useParams();
+  console.log('GroupDetail groupId:', groupId);
+  
+  const { user } = useUser();
+  const userId = user?.userId;
+
+  const [members, setMembers] = useState([]);
+  const [posts, setPosts] = useState([]);
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(null);
+  const [showCommentForm, setShowCommentForm] = useState(null);
+  const [refetchKey, setRefetchKey] = useState(0);
+  const [showCreatePost, setShowCreatePost] = useState(false);
+  const [isMember, setIsMember] = useState(false);
+
+  useEffect(() => {
+    if (!groupId) {
+      setError('小组ID缺失');
+      setLoading(false);
+      return;
+    }
+    
+    const fetchGroupData = async () => {
+      try {
+        const res1 = await fetch(`/echo/groups/${groupId}/members`);
+        const membersData = await res1.json();
+
+        const res2 = await fetch(`/echo/groups/${groupId}/getAllPosts`);
+        const postsData = await res2.json();
+
+        if (res1.ok) {
+          setMembers(membersData.members || []);
+          setIsMember(userId && membersData.members.some(m => m.user_id === userId));
+        }
+        
+        if (res2.ok) {
+          const postsWithLikes = postsData.posts?.map(post => ({
+            ...post,
+            userLiked: false,
+            likes: post.likes || 0
+          })) || [];
+          setPosts(postsWithLikes);
+        }
+      } catch (err) {
+        setError('加载失败,请稍后重试');
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchGroupData();
+  }, [groupId, refetchKey, userId]);
+
+  const toggleLike = async (postId) => {
+    const postIndex = posts.findIndex(p => p.group_post_id === postId);
+    if (postIndex === -1) return;
+    
+    const currentPost = posts[postIndex];
+    const isLiked = currentPost.userLiked;
+    
+    try {
+      const response = await fetch(
+        `/echo/groups/${postId}/${isLiked ? 'unlike' : 'like'}`,
+        {
+          method: 'POST',
+          headers: {
+            'Content-Type': 'application/json',
+          },
+        }
+      );
+      
+      const data = await response.json();
+      if (response.ok && data.status === 'success') {
+        const updatedPosts = [...posts];
+        updatedPosts[postIndex] = {
+          ...currentPost,
+          userLiked: !isLiked,
+          likes: isLiked ? currentPost.likes - 1 : currentPost.likes + 1
+        };
+        setPosts(updatedPosts);
+        
+        setTimeout(() => {
+          setRefetchKey(prev => prev + 1);
+        }, 200);
+      } else {
+        console.error(isLiked ? '取消点赞失败' : '点赞失败:', data.message);
+      }
+    } catch (error) {
+      console.error(isLiked ? '取消点赞请求出错' : '点赞请求出错:', error);
+    }
+  };
+
+  const handleSubmitComment = async (postId, content) => {
+    if (!userId) {
+      alert('请先登录');
+      return;
+    }
+    
+    try {
+      const response = await fetch(`/echo/groups/${postId}/comment`, {
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json',
+        },
+        body: JSON.stringify({
+          userId,
+          content
+        })
+      });
+      
+      const data = await response.json();
+      if (response.ok && data.status === 'success') {
+        setPosts(prevPosts => prevPosts.map(post => 
+          post.group_post_id === postId ? 
+          {...post, comments: [...(post.comments || []), {
+            id: Date.now(),
+            userId,
+            username: user.username,
+            content,
+            time: new Date().toISOString()
+          }]} : 
+          post
+        ));
+        setShowCommentForm(null);
+        setRefetchKey(prev => prev + 1);
+      } else {
+        console.error('评论失败:', data.message);
+      }
+    } catch (error) {
+      console.error('评论请求出错:', error);
+    }
+  };
+
+  const handlePostCreated = () => {
+    setShowCreatePost(false);
+    setRefetchKey(prev => prev + 1);
+  };
+
+  if (loading) return <div className="group-detail"><p>加载中...</p></div>;
+  if (error) return <div className="group-detail"><p>{error}</p></div>;
+
+  return (
+    <div className="group-detail">
+      <h1 className="group-title">兴趣小组详情</h1>
+      
+      <GroupMembers members={members} />
+      
+      <GroupPosts 
+        posts={posts}
+        members={members}
+        userId={userId}
+        toggleLike={toggleLike}
+        handleSubmitComment={handleSubmitComment}
+        showCommentForm={showCommentForm}
+        setShowCommentForm={setShowCommentForm}
+        isMember={isMember}
+        onShowCreatePost={() => setShowCreatePost(true)}
+        loginHint={!userId ? "请登录后发布帖子" : "加入小组后即可发布帖子"}
+      />
+    
+
+      {showCreatePost && (
+        <div className="modal-overlay">
+            <div className="modal-content">
+            <button className="modal-close" onClick={() => setShowCreatePost(false)}>×</button>
+            <CreatePostForm 
+                groupId={groupId}
+                onClose={() => setShowCreatePost(false)}
+                onPostCreated={handlePostCreated}
+            />
+            </div>
+        </div>
+        )}
+
+
+    </div>
+  );
+};
+
+export default GroupDetail;
\ No newline at end of file