blob: 8e6068bdf9b4efba770acb4819e51bdf85313f7e [file] [log] [blame]
Krishya6bf199c2025-06-06 21:14:23 +08001import React, { useState, useEffect } from 'react';
Krishyab5ef96d2025-06-05 13:57:05 +08002import { useGroupStore } from '../../context/useGroupStore';
3import { useUser } from '../../context/UserContext';
Krishyaaffe8102025-06-08 00:44:46 +08004import { useLocation } from 'wouter';
5import './GroupDetail.css';
Krishyab5ef96d2025-06-05 13:57:05 +08006
7const GroupItem = ({ group }) => {
Krishyaaffe8102025-06-08 00:44:46 +08008 const [, setLocation] = useLocation();
9 const { handleJoinGroup, joinStatus, setJoinStatus, fetchGroupList } = useGroupStore();
Krishyab5ef96d2025-06-05 13:57:05 +080010 const { user } = useUser();
Krishya6bf199c2025-06-06 21:14:23 +080011
Krishyab5ef96d2025-06-05 13:57:05 +080012 const userId = user?.userId;
Krishya6bf199c2025-06-06 21:14:23 +080013 const groupId = group.groupId;
14
15 const [isMember, setIsMember] = useState(false);
Krishyaaffe8102025-06-08 00:44:46 +080016 const [loading, setLoading] = useState(false);
17 const [error, setError] = useState('');
Krishya6bf199c2025-06-06 21:14:23 +080018
19 useEffect(() => {
Krishya6bf199c2025-06-06 21:14:23 +080020 setIsMember(joinStatus[groupId] === '加入成功');
21 }, [joinStatus, groupId]);
22
Krishya6bf199c2025-06-06 21:14:23 +080023 useEffect(() => {
24 if (userId && groupId) {
25 checkMembershipStatus();
26 }
27 }, [userId, groupId]);
28
Krishya6bf199c2025-06-06 21:14:23 +080029 const checkMembershipStatus = async () => {
30 try {
Krishyaaffe8102025-06-08 00:44:46 +080031 const res = await fetch(`/echo/groups/${groupId}/members`);
Krishya6bf199c2025-06-06 21:14:23 +080032 const isMember = res.data.members.some(member => member.user_id === userId);
Krishya73cd8822025-06-07 15:48:41 +080033 setIsMember(isMember);
Krishya6bf199c2025-06-06 21:14:23 +080034 } catch (error) {
35 console.error('检查成员状态失败:', error);
36 }
37 };
Krishyab5ef96d2025-06-05 13:57:05 +080038
Krishya6bf199c2025-06-06 21:14:23 +080039 const handleLeaveGroup = async () => {
40 setLoading(true);
41 try {
Krishyaaffe8102025-06-08 00:44:46 +080042 const res = await fetch(`/echo/groups/${groupId}/leave`, {
43 method: 'POST',
44 headers: {
45 'Content-Type': 'application/json',
46 },
47 body: JSON.stringify({
48 user_id: userId,
49 }),
Krishya6bf199c2025-06-06 21:14:23 +080050 });
Krishyaaffe8102025-06-08 00:44:46 +080051
52 if (res.ok && res.data.status === 'success') {
53 fetchGroupList();
Krishya6bf199c2025-06-06 21:14:23 +080054 setIsMember(false);
Krishya6bf199c2025-06-06 21:14:23 +080055 group.memberCount = (group.memberCount || 0) - 1;
56 } else {
57 setError(res.data.message || '退出失败');
58 }
59 } catch (error) {
Krishyaaffe8102025-06-08 00:44:46 +080060 // console.error('退出小组失败:', error);
61 // setError('退出小组失败');
Krishya6bf199c2025-06-06 21:14:23 +080062 } finally {
63 setLoading(false);
64 }
65 };
66
Krishya6bf199c2025-06-06 21:14:23 +080067 const handleJoin = async () => {
68 setLoading(true);
69 try {
70 const res = await handleJoinGroup(groupId, userId);
71 if (res && res.status === 'success') {
72 setJoinStatus(groupId, '加入成功');
73 setIsMember(true);
Krishya6bf199c2025-06-06 21:14:23 +080074 group.memberCount = (group.memberCount || 0) + 1;
75 } else {
76 setError(res?.message || '加入失败');
77 }
78 } catch (error) {
79 console.error('加入小组失败:', error);
80 setError('加入小组失败');
81 } finally {
82 setLoading(false);
83 }
84 };
85
Krishyab5ef96d2025-06-05 13:57:05 +080086 return (
87 <div className="group-item">
88 <div className="group-content">
89 <img
90 style={{ width: '40%', height: '40%' }}
22301009e68c0dd2025-06-05 15:28:07 +080091 src={group.coverImage || 'https://picsum.photos/200/200'}
Krishyab5ef96d2025-06-05 13:57:05 +080092 alt={group.groupName}
93 className="group-cover"
94 />
95 <div className="group-info-right">
Krishya6bf199c2025-06-06 21:14:23 +080096 <h3>{group.groupName}</h3>
Krishyab5ef96d2025-06-05 13:57:05 +080097 <p style={{ color: '#BA929A' }}>{group.memberCount || 0}人加入了小组</p>
98
Krishya6bf199c2025-06-06 21:14:23 +080099 {userId && (
100 <button
Krishyaaffe8102025-06-08 00:44:46 +0800101 style={{ color: '#2167c9', background: 'none', border: 'none', padding: 0, cursor: 'pointer', fontSize: '16px' }}
102 onClick={(e) => {
103 e.stopPropagation();
104 isMember ? handleLeaveGroup() : handleJoin();
Krishya6bf199c2025-06-06 21:14:23 +0800105 }}
106 disabled={loading}
107 >
108 {loading ? '处理中...' : isMember ? '退出小组' : '+加入小组'}
109 </button>
110 )}
111 {!userId && <button disabled>请登录</button>}
Krishyab5ef96d2025-06-05 13:57:05 +0800112
Krishya6bf199c2025-06-06 21:14:23 +0800113 {error && <p style={{ color: 'red' }}>{error}</p>}
Krishyab5ef96d2025-06-05 13:57:05 +0800114 </div>
115 </div>
116
117 <div className="group-description">
118 <p>{group.description}</p>
119 </div>
120 <p>分类:{group.category}</p>
121
Krishyaaffe8102025-06-08 00:44:46 +0800122 <button
123 style={{
124 background: 'none',
125 border: 'none',
126 color: '#985F6F',
127 fontSize: '16px',
128 cursor: 'pointer',
129 textDecoration: 'underline',
130 marginBottom: '8px',
131 float: 'right',
132 clear: 'both',
133 }}
134 onClick={() => setLocation(`/group/${groupId}`)}
135 >
136 查看详情
137 </button>
Krishyab5ef96d2025-06-05 13:57:05 +0800138 </div>
139 );
140};
141
Krishya6bf199c2025-06-06 21:14:23 +0800142export default GroupItem;